UNPKG

@strapi/utils

Version:

Shared utilities for the Strapi packages

1 lines 12.3 kB
{"version":3,"file":"factory.mjs","sources":["../../src/traverse/factory.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-loop-func */\nimport { isNil, pick } from 'lodash/fp';\n\nimport {\n AnyAttribute,\n Attribute,\n ComponentAttribute,\n DynamicZoneAttribute,\n Model,\n RelationalAttribute,\n} from '../types';\n\nexport interface Path {\n raw: string | null;\n attribute: string | null;\n}\n\nexport interface Parent {\n attribute?: Attribute;\n key: string | null;\n path: Path;\n schema: Model;\n}\n\nexport interface TraverseOptions {\n schema: Model;\n path?: Path;\n parent?: Parent;\n getModel(uid: string): Model;\n}\n\nexport interface VisitorOptions {\n data: unknown;\n value: unknown;\n schema: Model;\n key: string;\n attribute?: AnyAttribute;\n path: Path;\n parent?: Parent;\n getModel(uid: string): Model;\n}\n\nexport type Traverse = (\n visitor: Visitor,\n options: TraverseOptions,\n data: unknown\n) => Promise<unknown>;\n\nexport interface Visitor {\n (visitorOptions: VisitorOptions, opts: Pick<TransformUtils, 'set' | 'remove'>): void;\n}\n\ninterface Interceptor<T = unknown> {\n predicate(data: unknown): data is T;\n handler(\n visitor: Visitor,\n options: TraverseOptions,\n data: T,\n recurseOptions: { recurse: Traverse }\n ): void;\n}\n\ninterface ParseUtils<T> {\n transform(data: T): unknown;\n remove(key: string, data: T): unknown;\n set(key: string, value: unknown, data: T): unknown;\n keys(data: T): string[];\n get(key: string, data: T): unknown;\n}\n\ninterface Parser<T = unknown> {\n predicate(data: unknown): data is T;\n parser(data: T): ParseUtils<T>;\n}\n\ninterface Ignore {\n (ctx: Context): boolean;\n}\n\ninterface AttributeHandler<AttributeType = Attribute> {\n predicate(ctx: Context<AttributeType>): boolean;\n handler(ctx: Context<AttributeType>, opts: Pick<TransformUtils, 'set' | 'recurse'>): void;\n}\ninterface CommonHandler<AttributeType = Attribute> {\n predicate(ctx: Context<AttributeType>): boolean;\n handler(ctx: Context<AttributeType>, opts: Pick<TransformUtils, 'set' | 'recurse'>): void;\n}\n\nexport interface TransformUtils {\n remove(key: string): void;\n set(key: string, value: unknown): void;\n recurse: Traverse;\n}\n\ninterface Context<AttributeType = Attribute> {\n key: string;\n value: unknown;\n attribute: AttributeType;\n schema: Model;\n path: Path;\n data: unknown;\n visitor: Visitor;\n parent?: Parent;\n getModel(uid: string): Model;\n}\n\ninterface State {\n parsers: Parser[];\n interceptors: Interceptor[];\n ignore: Ignore[];\n handlers: {\n attributes: AttributeHandler[];\n common: CommonHandler[];\n };\n}\n\nconst DEFAULT_PATH = { raw: null, attribute: null } satisfies Path;\n\nexport default () => {\n const state: State = {\n parsers: [],\n interceptors: [],\n ignore: [],\n handlers: {\n attributes: [],\n common: [],\n },\n };\n\n const traverse: Traverse = async (visitor, options, data) => {\n const { path = DEFAULT_PATH, parent, schema, getModel } = options ?? {};\n\n // interceptors\n for (const { predicate, handler } of state.interceptors) {\n if (predicate(data)) {\n return handler(visitor, options, data, { recurse: traverse });\n }\n }\n\n // parsers\n const parser = state.parsers.find((parser) => parser.predicate(data))?.parser;\n const utils = parser?.(data);\n\n // Return the data untouched if we don't know how to traverse it\n if (!utils) {\n return data;\n }\n\n // main loop\n let out = utils.transform(data);\n const keys = utils.keys(out);\n\n for (const key of keys) {\n const attribute = schema?.attributes?.[key];\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 // visitors\n const visitorOptions: VisitorOptions = {\n key,\n value: utils.get(key, out),\n attribute,\n schema,\n path: newPath,\n data: out,\n getModel,\n parent,\n };\n\n const transformUtils: TransformUtils = {\n remove(key) {\n out = utils.remove(key, out);\n },\n set(key, value) {\n out = utils.set(key, value, out);\n },\n recurse: traverse,\n };\n\n await visitor(visitorOptions, pick(['remove', 'set'], transformUtils));\n\n const value = utils.get(key, out);\n\n const createContext = (): Context => ({\n key,\n value,\n attribute,\n schema,\n path: newPath,\n data: out,\n visitor,\n getModel,\n parent,\n });\n\n // ignore\n const ignoreCtx = createContext();\n const shouldIgnore = state.ignore.some((predicate) => predicate(ignoreCtx));\n\n if (shouldIgnore) {\n continue;\n }\n\n // handlers\n const handlers = [...state.handlers.common, ...state.handlers.attributes];\n\n for await (const handler of handlers) {\n const ctx = createContext();\n const pass = await handler.predicate(ctx);\n\n if (pass) {\n await handler.handler(ctx, pick(['recurse', 'set'], transformUtils));\n }\n }\n }\n\n return out;\n };\n\n return {\n traverse,\n\n intercept<T>(predicate: Interceptor<T>['predicate'], handler: Interceptor<T>['handler']) {\n state.interceptors.push({ predicate, handler });\n return this;\n },\n\n parse<T>(predicate: Parser<T>['predicate'], parser: Parser<T>['parser']) {\n state.parsers.push({ predicate, parser });\n return this;\n },\n\n ignore(predicate: Ignore) {\n state.ignore.push(predicate);\n return this;\n },\n\n on(predicate: CommonHandler['predicate'], handler: CommonHandler['handler']) {\n state.handlers.common.push({ predicate, handler });\n return this;\n },\n\n onAttribute(predicate: AttributeHandler['predicate'], handler: AttributeHandler['handler']) {\n state.handlers.attributes.push({ predicate, handler });\n return this;\n },\n\n onRelation(handler: AttributeHandler<RelationalAttribute>['handler']) {\n return this.onAttribute(({ attribute }) => attribute?.type === 'relation', handler);\n },\n\n onMedia(handler: AttributeHandler<RelationalAttribute>['handler']) {\n return this.onAttribute(({ attribute }) => attribute?.type === 'media', handler);\n },\n\n onComponent(handler: AttributeHandler<ComponentAttribute>['handler']) {\n return this.onAttribute(({ attribute }) => attribute?.type === 'component', handler);\n },\n\n onDynamicZone(handler: AttributeHandler<DynamicZoneAttribute>['handler']) {\n return this.onAttribute(({ attribute }) => attribute?.type === 'dynamiczone', handler);\n },\n };\n};\n"],"names":["DEFAULT_PATH","raw","attribute","state","parsers","interceptors","ignore","handlers","attributes","common","traverse","visitor","options","data","path","parent","schema","getModel","predicate","handler","recurse","parser","find","utils","out","transform","keys","key","newPath","isNil","visitorOptions","value","get","transformUtils","remove","set","pick","createContext","ignoreCtx","shouldIgnore","some","ctx","pass","intercept","push","parse","on","onAttribute","onRelation","type","onMedia","onComponent","onDynamicZone"],"mappings":";;AAoHA,MAAMA,YAAAA,GAAe;IAAEC,GAAAA,EAAK,IAAA;IAAMC,SAAAA,EAAW;AAAK,CAAA;AAElD,sBAAe,CAAA,IAAA;AACb,IAAA,MAAMC,KAAAA,GAAe;AACnBC,QAAAA,OAAAA,EAAS,EAAE;AACXC,QAAAA,YAAAA,EAAc,EAAE;AAChBC,QAAAA,MAAAA,EAAQ,EAAE;QACVC,QAAAA,EAAU;AACRC,YAAAA,UAAAA,EAAY,EAAE;AACdC,YAAAA,MAAAA,EAAQ;AACV;AACF,KAAA;IAEA,MAAMC,QAAAA,GAAqB,OAAOC,OAAAA,EAASC,OAAAA,EAASC,IAAAA,GAAAA;AAClD,QAAA,MAAM,EAAEC,IAAAA,GAAOd,YAAY,EAAEe,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAE,GAAGL,OAAAA,IAAW,EAAC;;QAGtE,KAAK,MAAM,EAAEM,SAAS,EAAEC,OAAO,EAAE,IAAIhB,KAAAA,CAAME,YAAY,CAAE;AACvD,YAAA,IAAIa,UAAUL,IAAAA,CAAAA,EAAO;gBACnB,OAAOM,OAAAA,CAAQR,OAAAA,EAASC,OAAAA,EAASC,IAAAA,EAAM;oBAAEO,OAAAA,EAASV;AAAS,iBAAA,CAAA;AAC7D,YAAA;AACF,QAAA;;QAGA,MAAMW,MAAAA,GAASlB,KAAAA,CAAMC,OAAO,CAACkB,IAAI,CAAC,CAACD,MAAAA,GAAWA,MAAAA,CAAOH,SAAS,CAACL,IAAAA,CAAAA,CAAAA,EAAQQ,MAAAA;AACvE,QAAA,MAAME,QAAQF,MAAAA,GAASR,IAAAA,CAAAA;;AAGvB,QAAA,IAAI,CAACU,KAAAA,EAAO;YACV,OAAOV,IAAAA;AACT,QAAA;;QAGA,IAAIW,GAAAA,GAAMD,KAAAA,CAAME,SAAS,CAACZ,IAAAA,CAAAA;QAC1B,MAAMa,IAAAA,GAAOH,KAAAA,CAAMG,IAAI,CAACF,GAAAA,CAAAA;QAExB,KAAK,MAAMG,OAAOD,IAAAA,CAAM;AACtB,YAAA,MAAMxB,SAAAA,GAAYc,MAAAA,EAAQR,UAAAA,GAAamB,GAAAA,CAAI;AAE3C,YAAA,MAAMC,OAAAA,GAAU;AAAE,gBAAA,GAAGd;AAAK,aAAA;AAE1Bc,YAAAA,OAAAA,CAAQ3B,GAAG,GAAG4B,KAAAA,CAAMf,IAAAA,CAAKb,GAAG,CAAA,GAAI0B,GAAAA,GAAM,CAAA,EAAGb,IAAAA,CAAKb,GAAG,CAAC,CAAC,EAAE0B,GAAAA,CAAAA,CAAK;YAE1D,IAAI,CAACE,MAAM3B,SAAAA,CAAAA,EAAY;AACrB0B,gBAAAA,OAAAA,CAAQ1B,SAAS,GAAG2B,KAAAA,CAAMf,IAAAA,CAAKZ,SAAS,CAAA,GAAIyB,GAAAA,GAAM,CAAA,EAAGb,IAAAA,CAAKZ,SAAS,CAAC,CAAC,EAAEyB,GAAAA,CAAAA,CAAK;AAC9E,YAAA;;AAGA,YAAA,MAAMG,cAAAA,GAAiC;AACrCH,gBAAAA,GAAAA;gBACAI,KAAAA,EAAOR,KAAAA,CAAMS,GAAG,CAACL,GAAAA,EAAKH,GAAAA,CAAAA;AACtBtB,gBAAAA,SAAAA;AACAc,gBAAAA,MAAAA;gBACAF,IAAAA,EAAMc,OAAAA;gBACNf,IAAAA,EAAMW,GAAAA;AACNP,gBAAAA,QAAAA;AACAF,gBAAAA;AACF,aAAA;AAEA,YAAA,MAAMkB,cAAAA,GAAiC;AACrCC,gBAAAA,MAAAA,CAAAA,CAAOP,GAAG,EAAA;oBACRH,GAAAA,GAAMD,KAAAA,CAAMW,MAAM,CAACP,GAAAA,EAAKH,GAAAA,CAAAA;AAC1B,gBAAA,CAAA;gBACAW,GAAAA,CAAAA,CAAIR,GAAG,EAAEI,KAAK,EAAA;AACZP,oBAAAA,GAAAA,GAAMD,KAAAA,CAAMY,GAAG,CAACR,GAAAA,EAAKI,KAAAA,EAAOP,GAAAA,CAAAA;AAC9B,gBAAA,CAAA;gBACAJ,OAAAA,EAASV;AACX,aAAA;YAEA,MAAMC,OAAAA,CAAQmB,gBAAgBM,IAAAA,CAAK;AAAC,gBAAA,QAAA;AAAU,gBAAA;aAAM,EAAEH,cAAAA,CAAAA,CAAAA;AAEtD,YAAA,MAAMF,KAAAA,GAAQR,KAAAA,CAAMS,GAAG,CAACL,GAAAA,EAAKH,GAAAA,CAAAA;YAE7B,MAAMa,aAAAA,GAAgB,KAAgB;AACpCV,oBAAAA,GAAAA;AACAI,oBAAAA,KAAAA;AACA7B,oBAAAA,SAAAA;AACAc,oBAAAA,MAAAA;oBACAF,IAAAA,EAAMc,OAAAA;oBACNf,IAAAA,EAAMW,GAAAA;AACNb,oBAAAA,OAAAA;AACAM,oBAAAA,QAAAA;AACAF,oBAAAA;iBACF,CAAA;;AAGA,YAAA,MAAMuB,SAAAA,GAAYD,aAAAA,EAAAA;YAClB,MAAME,YAAAA,GAAepC,MAAMG,MAAM,CAACkC,IAAI,CAAC,CAACtB,YAAcA,SAAAA,CAAUoB,SAAAA,CAAAA,CAAAA;AAEhE,YAAA,IAAIC,YAAAA,EAAc;AAChB,gBAAA;AACF,YAAA;;AAGA,YAAA,MAAMhC,QAAAA,GAAW;mBAAIJ,KAAAA,CAAMI,QAAQ,CAACE,MAAM;mBAAKN,KAAAA,CAAMI,QAAQ,CAACC;AAAW,aAAA;YAEzE,WAAW,MAAMW,WAAWZ,QAAAA,CAAU;AACpC,gBAAA,MAAMkC,GAAAA,GAAMJ,aAAAA,EAAAA;AACZ,gBAAA,MAAMK,IAAAA,GAAO,MAAMvB,OAAAA,CAAQD,SAAS,CAACuB,GAAAA,CAAAA;AAErC,gBAAA,IAAIC,IAAAA,EAAM;AACR,oBAAA,MAAMvB,OAAAA,CAAQA,OAAO,CAACsB,GAAAA,EAAKL,IAAAA,CAAK;AAAC,wBAAA,SAAA;AAAW,wBAAA;qBAAM,EAAEH,cAAAA,CAAAA,CAAAA;AACtD,gBAAA;AACF,YAAA;AACF,QAAA;QAEA,OAAOT,GAAAA;AACT,IAAA,CAAA;IAEA,OAAO;AACLd,QAAAA,QAAAA;QAEAiC,SAAAA,CAAAA,CAAazB,SAAsC,EAAEC,OAAkC,EAAA;YACrFhB,KAAAA,CAAME,YAAY,CAACuC,IAAI,CAAC;AAAE1B,gBAAAA,SAAAA;AAAWC,gBAAAA;AAAQ,aAAA,CAAA;AAC7C,YAAA,OAAO,IAAI;AACb,QAAA,CAAA;QAEA0B,KAAAA,CAAAA,CAAS3B,SAAiC,EAAEG,MAA2B,EAAA;YACrElB,KAAAA,CAAMC,OAAO,CAACwC,IAAI,CAAC;AAAE1B,gBAAAA,SAAAA;AAAWG,gBAAAA;AAAO,aAAA,CAAA;AACvC,YAAA,OAAO,IAAI;AACb,QAAA,CAAA;AAEAf,QAAAA,MAAAA,CAAAA,CAAOY,SAAiB,EAAA;YACtBf,KAAAA,CAAMG,MAAM,CAACsC,IAAI,CAAC1B,SAAAA,CAAAA;AAClB,YAAA,OAAO,IAAI;AACb,QAAA,CAAA;QAEA4B,EAAAA,CAAAA,CAAG5B,SAAqC,EAAEC,OAAiC,EAAA;AACzEhB,YAAAA,KAAAA,CAAMI,QAAQ,CAACE,MAAM,CAACmC,IAAI,CAAC;AAAE1B,gBAAAA,SAAAA;AAAWC,gBAAAA;AAAQ,aAAA,CAAA;AAChD,YAAA,OAAO,IAAI;AACb,QAAA,CAAA;QAEA4B,WAAAA,CAAAA,CAAY7B,SAAwC,EAAEC,OAAoC,EAAA;AACxFhB,YAAAA,KAAAA,CAAMI,QAAQ,CAACC,UAAU,CAACoC,IAAI,CAAC;AAAE1B,gBAAAA,SAAAA;AAAWC,gBAAAA;AAAQ,aAAA,CAAA;AACpD,YAAA,OAAO,IAAI;AACb,QAAA,CAAA;AAEA6B,QAAAA,UAAAA,CAAAA,CAAW7B,OAAyD,EAAA;YAClE,OAAO,IAAI,CAAC4B,WAAW,CAAC,CAAC,EAAE7C,SAAS,EAAE,GAAKA,SAAAA,EAAW+C,IAAAA,KAAS,UAAA,EAAY9B,OAAAA,CAAAA;AAC7E,QAAA,CAAA;AAEA+B,QAAAA,OAAAA,CAAAA,CAAQ/B,OAAyD,EAAA;YAC/D,OAAO,IAAI,CAAC4B,WAAW,CAAC,CAAC,EAAE7C,SAAS,EAAE,GAAKA,SAAAA,EAAW+C,IAAAA,KAAS,OAAA,EAAS9B,OAAAA,CAAAA;AAC1E,QAAA,CAAA;AAEAgC,QAAAA,WAAAA,CAAAA,CAAYhC,OAAwD,EAAA;YAClE,OAAO,IAAI,CAAC4B,WAAW,CAAC,CAAC,EAAE7C,SAAS,EAAE,GAAKA,SAAAA,EAAW+C,IAAAA,KAAS,WAAA,EAAa9B,OAAAA,CAAAA;AAC9E,QAAA,CAAA;AAEAiC,QAAAA,aAAAA,CAAAA,CAAcjC,OAA0D,EAAA;YACtE,OAAO,IAAI,CAAC4B,WAAW,CAAC,CAAC,EAAE7C,SAAS,EAAE,GAAKA,SAAAA,EAAW+C,IAAAA,KAAS,aAAA,EAAe9B,OAAAA,CAAAA;AAChF,QAAA;AACF,KAAA;AACF,CAAA;;;;"}