import { DynamoEntity , EntityTarget , TRANSFORM_TYPE } from '@typedorm/common' ; import { DocumentClient } from 'aws-sdk/clients/dynamodb' ; import { plainToClassFromExist } from 'class-transformer' ; import { unParseKey } from '../../helpers/unparse-key' ; import { Connection } from '../connection/connection' ; import { BaseTransformer , MetadataOptions } from './base-transformer' ; /**
 * Note: To use any of the base transformer methods, this default entity transformer should be used
 */ export class EntityTransformer extends BaseTransformer { constructor ( connection ) { super ( connection ) ; } param entityClass param dynamoEntity fromDynamoEntity < Entity > ( entityClass , dynamoEntity , metadataOptions ? ) { const entityMetadata = this . connection . getEntityByTarget ( entityClass ) ; this . connection . logger . logTransform ( { requestId : metadataOptions ?. requestId , operation : TRANSFORM_TYPE . RESPONSE , prefix : 'Before' , entityName : entityMetadata . name , primaryKey : null , body : dynamoEntity , } ) ; const vanillaAttributesToInclude = entityMetadata . attributes . filter ( attr => ! attr . hidden ) . map ( attr => attr . name ) ; const primaryKeyAttributesToInclude = Object . keys ( entityMetadata . schema . primaryKey . attributes ) . filter ( attr => ! vanillaAttributesToInclude . includes ( attr ) ) ; const entityInternalAttributeKeys = entityMetadata . internalAttributes . map ( attr => attr . name ) ; const entityHiddenAttributeKeys = entityMetadata . attributes . filter ( attr => attr . hidden ) . map ( attr => attr . name ) ; const entityMetadataSchemaIndexes = entityMetadata . schema . indexes ?? { } ; const indexAttributesToInclude = Object . keys ( entityMetadataSchemaIndexes ) . map ( key => { return Object . keys ( entityMetadataSchemaIndexes [ key ] . attributes ?? { } ) ; } ) . flat ( ) . filter ( attr => ! vanillaAttributesToInclude . includes ( attr ) ) ; const plainEntityAttributes = Object . keys ( dynamoEntity ) . reduce ( ( acc , key ) => { if ( primaryKeyAttributesToInclude . includes ( key ) || indexAttributesToInclude . includes ( key ) || entityInternalAttributeKeys . includes ( key ) || entityHiddenAttributeKeys . includes ( key ) ) { return acc ; } ( acc as any ) [ key ] = ( dynamoEntity as any ) [ key ] ; return acc ; } , { } as Object ) ; const reflectedConstructor = Reflect . construct ( Object , [ ] , entityClass ) ; const deserializedEntityAttributes = JSON . parse ( JSON . stringify ( plainEntityAttributes ) ) ; const transformedEntity = plainToClassFromExist ( reflectedConstructor , deserializedEntityAttributes ) ; this . connection . logger . logTransform ( { requestId : metadataOptions ?. requestId , operation : TRANSFORM_TYPE . RESPONSE , prefix : 'After' , entityName : entityMetadata . name , primaryKey : null , body : transformedEntity , } ) ; return transformedEntity ; } fromDynamoKeyToAttributes < Entity > ( entityClass , dynamoKey ) { const entityMetadata = this . connection . getEntityByTarget ( entityClass ) ; const primaryKeyAttributes = entityMetadata . schema . primaryKey . attributes ; const interpolations = entityMetadata . schema . primaryKey ?. metadata ?. _interpolations ?? { } ; const rawAttributes = Object . entries ( primaryKeyAttributes ) . reduce ( ( acc , [ keyName , keyPattern ] ) => { const unParsed = unParseKey ( keyPattern , dynamoKey [ keyName ] , interpolations [ keyName ] ?? [ ] ) ; acc = { ... acc , ... unParsed } ; return acc ; } , { } ) ; const attributes = Object . entries ( rawAttributes ) . reduce ( ( acc , [ attrName , value ] ) => { const attrMetadata = entityMetadata . attributes . find ( attr => attr . name === attrName ) ; if ( ! attrMetadata ) { throw new Error ( `Failed to reverse transform attribute ${ attrName }, it was referenced in schema but it is not known to entity ${ entityClass . name }` ) ; } if ( ( attrMetadata . type === 'Boolean' || attrMetadata . type === 'Number' ) && value ) { acc [ attrName ] = JSON . parse ( value ) ; } else { acc [ attrName ] = value ; } return acc ; } , { } as Record < string , any > ) ; return attributes ; } }