{"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":"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"}