import { VeloTransformation } from './types.js'; import { isArray, isPlainObject } from 'lodash'; import { reduceTransformation, stripJsonPathRootPrefix, } from '@wix/motion-edm-autogen-transformations-core'; const QUERY_OPERATOR_PREFIX = '$'; enum QuerySections { FILTER = 'filter', SORT = 'sort', FIELDS = 'fields', } type QueryObject = { [key: string]: any; }; type QueryFilter = { [key: string]: any; }; type QuerySort = { fieldName: string; order: any }[]; type QueryFields = string[]; const CommonTransformations: Record = { _id: `${QUERY_OPERATOR_PREFIX}.id`, _createdDate: `${QUERY_OPERATOR_PREFIX}.createdDate`, _updatedDate: `${QUERY_OPERATOR_PREFIX}.updatedDate`, }; export function resolveQueryFieldsTransformationPaths( transformation: VeloTransformation, ): Record { return ( reduceTransformation(transformation, { visitors: { NestedSimpleTransformationExpression(acc: any, path: any, value: any) { acc[path] = stripJsonPathRootPrefix(value); }, MapArrayItems(acc: any, path: any, sourceArrayExpression: any) { acc[path] = stripJsonPathRootPrefix(sourceArrayExpression); }, }, accumulator: {}, }) || {} ); } export function toPlatformizedQuery( query: QueryObject, transformations: VeloTransformation, ) { const allTransformations = { ...CommonTransformations, ...transformations, }; const transformationPaths = resolveQueryFieldsTransformationPaths(allTransformations); return Object.entries(query).reduce((transformedQuery, [key, value]) => { if (key === QuerySections.FILTER) { transformedQuery[key] = value ? transformQueryFilter(value, transformationPaths) : undefined; } else if (key === QuerySections.SORT) { transformedQuery[key] = transformQuerySort(value, transformationPaths); } else if (key === QuerySections.FIELDS) { transformedQuery[key] = transformQueryFields(value, transformationPaths); } else { transformedQuery[key] = value; } return transformedQuery; }, {} as QueryObject); } function transformQueryFilter( filter: QueryFilter, transformationPaths: Record, ) { return Object.entries(filter).reduce( (transformedFilter, [filedOrOperator, value]) => { const key = filedOrOperator.startsWith(QUERY_OPERATOR_PREFIX) ? filedOrOperator : transformationPaths[filedOrOperator] || filedOrOperator; if (isPlainObject(value)) { transformedFilter[key] = transformQueryFilter( value, transformationPaths, ); } else if (isArray(value)) { transformedFilter[key] = value.map((x) => isPlainObject(x) ? transformQueryFilter(x, transformationPaths) : x, ); } else { transformedFilter[key] = value; } return transformedFilter; }, {} as QueryFilter, ); } function transformQuerySort( sort: QuerySort, transformationPaths: Record, ) { return sort.map(({ fieldName, order }) => ({ fieldName: transformationPaths[fieldName] || fieldName, ...(order ? { order } : {}), })); } function transformQueryFields( fields: QueryFields, transformationPaths: Record, ) { return fields.map((field) => transformationPaths[field] || field); }