@strapi/utils
Version:
Shared utilities for the Strapi packages
1 lines • 12.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}\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 }, 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\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 res[i] = await method(visitor, newPath, 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 res[i] = await traverseMediaTarget(visitor, newPath, 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 res[i] = await traverseComponent(visitor, newPath, 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 res[i] = await visitDynamicZoneEntry(visitor, newPath, 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","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","isMediaAttribute","type","component","remove","set","curry"],"mappings":"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"}