@strapi/utils
Version:
Shared utilities for the Strapi packages
1 lines • 14.4 kB
Source Map (JSON)
{"version":3,"file":"traverse-entity.mjs","sources":["../src/traverse-entity.ts"],"sourcesContent":["import { clone, isObject, isArray, isNil, curry } from 'lodash/fp';\n\nimport type { Attribute, AnyAttribute, Model, Data } from './types';\nimport { isRelationalAttribute, isMediaAttribute } from './content-types';\n\nexport type VisitorUtils = ReturnType<typeof createVisitorUtils>;\n\nexport interface VisitorOptions {\n data: Record<string, unknown>;\n schema: Model;\n key: string;\n value: Data[keyof Data];\n attribute?: AnyAttribute;\n path: Path;\n getModel(uid: string): Model;\n parent?: Parent;\n}\n\nexport type Visitor = (visitorOptions: VisitorOptions, visitorUtils: VisitorUtils) => void;\n\nexport interface Path {\n raw: string | null;\n attribute: string | null;\n rawWithIndices?: string | null;\n}\n\nexport interface TraverseOptions {\n schema: Model;\n path?: Path;\n parent?: Parent;\n getModel(uid: string): Model;\n}\n\nexport interface Parent {\n attribute?: Attribute;\n key: string | null;\n path: Path;\n schema: Model;\n}\n\nconst traverseEntity = async (visitor: Visitor, options: TraverseOptions, entity: Data) => {\n const { path = { raw: null, attribute: null, rawWithIndices: null }, schema, getModel } = options;\n\n let parent = options.parent;\n\n const traverseMorphRelationTarget = async (visitor: Visitor, path: Path, entry: Data) => {\n const targetSchema = getModel(entry.__type!);\n\n const traverseOptions: TraverseOptions = { schema: targetSchema, path, getModel, parent };\n\n return traverseEntity(visitor, traverseOptions, entry);\n };\n\n const traverseRelationTarget =\n (schema: Model) => async (visitor: Visitor, path: Path, entry: Data) => {\n const traverseOptions: TraverseOptions = { schema, path, getModel, parent };\n\n return traverseEntity(visitor, traverseOptions, entry);\n };\n\n const traverseMediaTarget = async (visitor: Visitor, path: Path, entry: Data) => {\n const targetSchemaUID = 'plugin::upload.file';\n const targetSchema = getModel(targetSchemaUID);\n\n const traverseOptions: TraverseOptions = { schema: targetSchema, path, getModel, parent };\n\n return traverseEntity(visitor, traverseOptions, entry);\n };\n\n const traverseComponent = async (visitor: Visitor, path: Path, schema: Model, entry: Data) => {\n const traverseOptions: TraverseOptions = { schema, path, getModel, parent };\n\n return traverseEntity(visitor, traverseOptions, entry);\n };\n\n const visitDynamicZoneEntry = async (visitor: Visitor, path: Path, entry: Data) => {\n const targetSchema = getModel(entry.__component!);\n const traverseOptions: TraverseOptions = { schema: targetSchema, path, getModel, parent };\n\n return traverseEntity(visitor, traverseOptions, entry);\n };\n\n // End recursion\n if (!isObject(entity) || isNil(schema)) {\n return entity;\n }\n\n // Don't mutate the original entity object\n // only clone at 1st level as the next level will get clone when traversed\n const copy = clone(entity);\n const visitorUtils = createVisitorUtils({ data: copy });\n\n const keys = Object.keys(copy);\n for (let i = 0; i < keys.length; i += 1) {\n const key = keys[i];\n // Retrieve the attribute definition associated to the key from the schema\n const attribute = schema.attributes[key] as AnyAttribute | undefined;\n\n const newPath = { ...path };\n\n newPath.raw = isNil(path.raw) ? key : `${path.raw}.${key}`;\n newPath.rawWithIndices = isNil(path.rawWithIndices) ? key : `${path.rawWithIndices}.${key}`;\n\n if (!isNil(attribute)) {\n newPath.attribute = isNil(path.attribute) ? key : `${path.attribute}.${key}`;\n }\n\n // Visit the current attribute\n const visitorOptions: VisitorOptions = {\n data: copy,\n schema,\n key,\n value: copy[key],\n attribute,\n path: newPath,\n getModel,\n parent,\n };\n\n await visitor(visitorOptions, visitorUtils);\n\n // Extract the value for the current key (after calling the visitor)\n const value = copy[key];\n\n // Ignore Nil values or attributes\n if (isNil(value) || isNil(attribute)) {\n continue;\n }\n\n // The current attribute becomes the parent once visited\n parent = { schema, key, attribute, path: newPath };\n\n if (isRelationalAttribute(attribute)) {\n const isMorphRelation = attribute.relation.toLowerCase().startsWith('morph');\n\n const method = isMorphRelation\n ? traverseMorphRelationTarget\n : traverseRelationTarget(getModel(attribute.target!));\n\n if (isArray(value)) {\n const res = new Array(value.length);\n for (let i = 0; i < value.length; i += 1) {\n const arrayPath = {\n ...newPath,\n rawWithIndices: isNil(newPath.rawWithIndices)\n ? `${i}`\n : `${newPath.rawWithIndices}.${i}`,\n };\n res[i] = await method(visitor, arrayPath, value[i]);\n }\n copy[key] = res;\n } else {\n copy[key] = await method(visitor, newPath, value as Data);\n }\n\n continue;\n }\n\n if (isMediaAttribute(attribute)) {\n // need to update copy\n if (isArray(value)) {\n const res = new Array(value.length);\n for (let i = 0; i < value.length; i += 1) {\n const arrayPath = {\n ...newPath,\n rawWithIndices: isNil(newPath.rawWithIndices)\n ? `${i}`\n : `${newPath.rawWithIndices}.${i}`,\n };\n res[i] = await traverseMediaTarget(visitor, arrayPath, value[i]);\n }\n copy[key] = res;\n } else {\n copy[key] = await traverseMediaTarget(visitor, newPath, value as Data);\n }\n\n continue;\n }\n\n if (attribute.type === 'component') {\n const targetSchema = getModel(attribute.component);\n\n if (isArray(value)) {\n const res: Data[] = new Array(value.length);\n for (let i = 0; i < value.length; i += 1) {\n const arrayPath = {\n ...newPath,\n rawWithIndices: isNil(newPath.rawWithIndices)\n ? `${i}`\n : `${newPath.rawWithIndices}.${i}`,\n };\n res[i] = await traverseComponent(visitor, arrayPath, targetSchema, value[i]);\n }\n copy[key] = res;\n } else {\n copy[key] = await traverseComponent(visitor, newPath, targetSchema, value as Data);\n }\n\n continue;\n }\n\n if (attribute.type === 'dynamiczone' && isArray(value)) {\n const res = new Array(value.length);\n for (let i = 0; i < value.length; i += 1) {\n const arrayPath = {\n ...newPath,\n rawWithIndices: isNil(newPath.rawWithIndices) ? `${i}` : `${newPath.rawWithIndices}.${i}`,\n };\n res[i] = await visitDynamicZoneEntry(visitor, arrayPath, value[i]);\n }\n copy[key] = res;\n\n continue;\n }\n }\n\n return copy;\n};\n\nconst createVisitorUtils = ({ data }: { data: Data }) => ({\n remove(key: string) {\n delete data[key];\n },\n\n set(key: string, value: Data) {\n data[key] = value;\n },\n});\n\nexport default curry(traverseEntity);\n"],"names":["traverseEntity","visitor","options","entity","path","raw","attribute","rawWithIndices","schema","getModel","parent","traverseMorphRelationTarget","entry","targetSchema","__type","traverseOptions","traverseRelationTarget","traverseMediaTarget","targetSchemaUID","traverseComponent","visitDynamicZoneEntry","__component","isObject","isNil","copy","clone","visitorUtils","createVisitorUtils","data","keys","Object","i","length","key","attributes","newPath","visitorOptions","value","isRelationalAttribute","isMorphRelation","relation","toLowerCase","startsWith","method","target","isArray","res","Array","arrayPath","isMediaAttribute","type","component","remove","set","curry"],"mappings":"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"}