123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- import { SubstrateEvent } from '../../generated/indexer'
- import {
- IPropertyIdWithName,
- IClassEntity,
- IProperty,
- IBatchOperation,
- ICreateEntityOperation,
- IEntity,
- IReference,
- } from '../types'
- import Debug from 'debug'
- import { ParametrizedClassPropertyValue, UpdatePropertyValuesOperation } from '@joystream/types/content-directory'
- import { createType } from '@joystream/types'
- const debug = Debug('mappings:cd:decode')
- function stringIfyEntityId(event: SubstrateEvent): string {
- const { 1: entityId } = event.params
- return entityId.value as string
- }
- function setProperties<T>({ extrinsic, blockNumber }: SubstrateEvent, propNamesWithId: IPropertyIdWithName): T {
- if (extrinsic === undefined) throw Error('Undefined extrinsic')
- const { 3: newPropertyValues } = extrinsic!.args
- const properties: { [key: string]: any; reference?: IReference } = {}
- for (const [k, v] of Object.entries(newPropertyValues.value)) {
- const propertyName = propNamesWithId[k]
- const singlePropVal = createType('InputPropertyValue', v as any).asType('Single')
- properties[propertyName] = singlePropVal.isOfType('Reference')
- ? { entityId: singlePropVal.asType('Reference').toJSON(), existing: true }
- : singlePropVal.value.toJSON()
- }
- properties.version = blockNumber
- debug(`Entity properties: ${JSON.stringify(properties)}`)
- return properties as T
- }
- function getClassEntity(event: SubstrateEvent): IClassEntity {
- const { 0: classId } = event.extrinsic!.args
- const { 1: entityId } = event.params
- return {
- entityId: (entityId.value as unknown) as number,
- classId: (classId.value as unknown) as number,
- }
- }
- /**
- * When entity is creation through `transaction` extrinsic we use this function to parse
- * entity properties it looks quite similar to `setProperties` function
- * @param properties
- * @param propertyNamesWithId
- */
- function setEntityPropertyValues<T>(properties: IProperty[], propertyNamesWithId: IPropertyIdWithName): T {
- const entityProperties: { [key: string]: any; reference?: IReference } = {}
- for (const [propId, propName] of Object.entries(propertyNamesWithId)) {
- // get the property value by id
- const p = properties.find((p) => p.id === propId)
- if (!p) continue
- entityProperties[propName] = p.reference ? p.reference : p.value
- }
- // debug(`Entity properties ${JSON.stringify(entityProperties)}`)
- return entityProperties as T
- }
- // Decode entity property values
- function getEntityProperties(propertyValues: ParametrizedClassPropertyValue[]): IProperty[] {
- const properties: IProperty[] = []
- const entityPropertyValues = createType('Vec<ParametrizedClassPropertyValue>', propertyValues)
- entityPropertyValues.map((pv: ParametrizedClassPropertyValue) => {
- const v = createType('ParametrizedPropertyValue', pv.value)
- const propertyId = pv.in_class_index.toJSON()
- let reference
- let value
- if (v.isOfType('InputPropertyValue')) {
- const inputPropVal = v.asType('InputPropertyValue')
- value = inputPropVal.isOfType('Single')
- ? inputPropVal.asType('Single').value.toJSON()
- : inputPropVal.asType('Vector').value.toJSON()
- if (inputPropVal.isOfType('Single')) {
- if (inputPropVal.asType('Single').isOfType('Reference')) {
- reference = { entityId: value as number, existing: true }
- }
- }
- } else if (v.isOfType('InternalEntityJustAdded')) {
- value = v.asType('InternalEntityJustAdded').toJSON()
- reference = { entityId: value as number, existing: false }
- } else {
- // TODO: Add support for v.asType('InternalEntityVec')
- throw Error('InternalEntityVec property type is not supported yet!')
- }
- properties.push({ id: `${propertyId}`, value, reference })
- })
- return properties
- }
- function getOperations({ extrinsic }: SubstrateEvent): IBatchOperation {
- const operations = createType('Vec<OperationType>', extrinsic!.args[1].value as any)
- const updatePropertyValuesOperations: IEntity[] = []
- const addSchemaSupportToEntityOperations: IEntity[] = []
- const createEntityOperations: ICreateEntityOperation[] = []
- for (const operation of operations) {
- if (operation.isOfType('CreateEntity')) {
- const cep = operation.asType('CreateEntity')
- createEntityOperations.push({ classId: cep.class_id.toJSON() })
- } else if (operation.isOfType('AddSchemaSupportToEntity')) {
- const op = operation.asType('AddSchemaSupportToEntity')
- const pe = createType('ParameterizedEntity', op.entity_id)
- const entity: IEntity = {
- properties: getEntityProperties(op.parametrized_property_values),
- }
- if (pe.isOfType('InternalEntityJustAdded')) {
- entity.indexOf = pe.asType('InternalEntityJustAdded').toJSON()
- } else {
- entity.entityId = pe.asType('ExistingEntity').toJSON()
- }
- addSchemaSupportToEntityOperations.push(entity)
- } else {
- updatePropertyValuesOperations.push(makeEntity(operation.asType('UpdatePropertyValues')))
- }
- }
- return {
- updatePropertyValuesOperations,
- addSchemaSupportToEntityOperations,
- createEntityOperations,
- }
- }
- function makeEntity(upv: UpdatePropertyValuesOperation): IEntity {
- const entity: IEntity = {
- properties: getEntityProperties(upv.new_parametrized_property_values),
- }
- const pe = createType('ParameterizedEntity', upv.entity_id)
- if (pe.isOfType('InternalEntityJustAdded')) {
- entity.indexOf = pe.asType('InternalEntityJustAdded').toJSON()
- } else {
- entity.entityId = pe.asType('ExistingEntity').toJSON()
- }
- return entity
- }
- export const decode = {
- stringIfyEntityId,
- getClassEntity,
- setEntityPropertyValues,
- getEntityProperties,
- getOperations,
- setProperties,
- }
|