import { cloneDeep, set } from 'lodash'; import { parseLeanSchemaRef } from './serialization/index.js'; import { Payload } from './serializer/domain.js'; import { transformError as cloudEdmTransformError, transformResponseMessage, } from '@wix/motion-edm-autogen-transformations'; import { builtinCustomFunctions } from '@wix/motion-edm-autogen-p13n'; import { FqdnTransformation } from './types.js'; export type VeloTransformation = any; export const RootPath = Symbol('RootPath'); export enum FqdnDirection { TO_VELO, FROM_VELO, } export function transformFqdn( payload: Payload, fqdnTransformation: FqdnTransformation, ) { const { transformation } = fqdnTransformation; return fqdnTransformation.paths.reduce((payload, path) => { const pathToFqdn = typeof path === 'string' ? (path as string) : ''; return new FqdnTransformationHandler({ entity: payload, transformation, pathToFqdn, }).transformEntity(); }, payload); } interface FqdnTransformationHandlerParams { entity: any; pathToFqdn: string; transformation: VeloTransformation; direction?: FqdnDirection; } export class FqdnTransformationHandler { private readonly path: string[]; private readonly entity: any; private readonly transformation: VeloTransformation; constructor({ entity, pathToFqdn, transformation, }: FqdnTransformationHandlerParams) { this.path = pathToFqdn.split('.'); this.entity = cloneDeep(entity); this.transformation = transformation; } transformEntity(entity: any = this.entity, index: number = 0) { const currentPath = this.path[index]; if (!currentPath) { return transformResponseMessage( entity, this.transformation, builtinCustomFunctions, ); } const { schemaName, schemaType } = parseLeanSchemaRef(currentPath); const currentEntity = entity[schemaName]; if (!currentEntity) { return entity; } let transformedEntity; if (schemaType === 'Array') { transformedEntity = this.transformArray(currentEntity, index + 1); } else if (schemaType === 'Map') { transformedEntity = this.transformMap(currentEntity, index + 1); } else { transformedEntity = this.transformEntity(currentEntity, index + 1); } set(entity, schemaName, transformedEntity); return entity; } private transformArray = (entitiesArray: any[], index: number) => { return entitiesArray.map((entity: any) => this.transformEntity(entity, index), ); }; private transformMap = (entitiesMap: Record, index: number) => { return Object.entries(entitiesMap).reduce>( (acc, [key, entity]) => { acc[key] = this.transformEntity(entity, index); return acc; }, {}, ); }; } export function transformError( httpClientError: any, transformation?: VeloTransformation, argumentNames?: string[], ): Error { const expectedErrorStructure = { requestId: httpClientError.requestId, response: httpClientError.response?.data, httpStatus: httpClientError.response?.status, runtimeError: !httpClientError.response ? httpClientError : undefined, }; return cloudEdmTransformError( expectedErrorStructure, transformation, argumentNames, ); }