{"version":3,"sources":["../src/compact.ts"],"sourcesContent":["import type { MetorialMapper } from './types';\n\nexport type CompactTarget = string | 0 | 1;\n\nexport type CompactField =\n  | string\n  | readonly [source: string, target: CompactTarget]\n  | readonly [source: string, target: CompactTarget, descriptor: CompactDescriptor];\n\nexport type CompactFields = readonly CompactField[];\n\nexport type CompactKind = 0 | 1 | 2 | 3 | 4 | 5;\n\nexport type CompactBranch = readonly [kind: CompactKind, descriptor: CompactDescriptor];\n\nexport type CompactDescriptor =\n  | 0\n  | 4\n  | 5\n  | 6\n  | 8\n  | readonly [7, CompactDescriptor]\n  | readonly [1, CompactFields]\n  | readonly [2, CompactDescriptor]\n  | readonly [3, readonly CompactBranch[]];\n\ntype CompiledField = readonly [source: string, target: string, descriptor: CompiledDescriptor];\n\ntype CompiledDescriptor =\n  | 0\n  | 4\n  | readonly [1, readonly CompiledField[], ReadonlySet<string>, ReadonlySet<string>]\n  | readonly [2, CompiledDescriptor]\n  | readonly [3, readonly (CompiledDescriptor | undefined)[]];\n\nlet camelCase = (source: string) =>\n  source.replace(/_([a-z])/g, (_, letter: string) => letter.toUpperCase());\n\nlet patternCache = new Map<5 | 6 | 8, CompiledDescriptor>();\n\nlet compile = (descriptor: CompactDescriptor, flags: number): CompiledDescriptor => {\n  if (typeof descriptor === 'number') {\n    if (descriptor === 0 || descriptor === 4) return descriptor;\n    if (descriptor !== 5 && descriptor !== 6 && descriptor !== 8) {\n      throw new Error(`Unsupported compact descriptor ${descriptor}.`);\n    }\n\n    let cached = patternCache.get(descriptor);\n    if (cached !== undefined) return cached;\n\n    let fields: CompactFields =\n      descriptor === 5\n        ? [\n            ['gt', 0, 4],\n            ['lt', 0, 4]\n          ]\n        : descriptor === 6\n          ? ['has_more_before', 'has_more_after']\n          : [\n              ['created_at', 1, 4],\n              ['updated_at', 1, 4]\n            ];\n    let compiled = compile([1, fields], 0);\n    patternCache.set(descriptor, compiled);\n\n    return compiled;\n  }\n\n  if (descriptor[0] === 7) {\n    return compile(\n      [\n        1,\n        [\n          ['items', 0, [2, descriptor[1]]],\n          ['pagination', 0, 6]\n        ]\n      ],\n      flags\n    );\n  }\n\n  if (descriptor[0] === 1) {\n    let fields: CompiledField[] = [];\n\n    for (let field of descriptor[1]) {\n      let source = typeof field === 'string' ? field : field[0];\n      let target = typeof field === 'string' ? 1 : field[1];\n      let name = target === 0 ? source : target === 1 ? camelCase(source) : target;\n      let implicit: 0 | 4 = (flags & 1) !== 0 && source.endsWith('_at') ? 4 : 0;\n      let child = compile(\n        typeof field === 'string' ? implicit : (field[2] ?? implicit),\n        flags\n      );\n\n      if (source !== name || child !== 0) fields.push([source, name, child]);\n    }\n\n    if (!fields.length) return 0;\n\n    return [\n      1,\n      fields,\n      new Set(fields.map(field => field[0])),\n      new Set(fields.map(field => field[1]))\n    ];\n  }\n\n  if (descriptor[0] === 2) {\n    let child = compile(descriptor[1], flags);\n    return child === 0 ? 0 : [2, child];\n  }\n\n  let branches: (CompiledDescriptor | undefined)[] = [];\n\n  for (let [kind, child] of descriptor[1]) {\n    branches[kind] = compile(child, flags);\n  }\n\n  if (branches.every(branch => branch === undefined || branch === 0)) return 0;\n\n  return [3, branches];\n};\n\nlet toDate = (input: any) => {\n  if (input instanceof Date) return input;\n\n  if (typeof input === 'string' || typeof input === 'number') {\n    let date = new Date(input);\n    if (!isNaN(date.getTime())) return date;\n  }\n\n  return input;\n};\n\nlet kindOf = (input: any): CompactKind | undefined => {\n  if (Array.isArray(input)) return 1;\n  if (input instanceof Date) return 2;\n  if (typeof input === 'object' && input !== null) return 0;\n  if (typeof input === 'string') return 3;\n  if (typeof input === 'number') return 4;\n  if (typeof input === 'boolean') return 5;\n\n  return undefined;\n};\n\nlet setField = (output: any, key: string, value: any) => {\n  if (key === '__proto__') {\n    Object.defineProperty(output, key, {\n      value,\n      enumerable: true,\n      configurable: true,\n      writable: true\n    });\n  } else {\n    output[key] = value;\n  }\n};\n\nlet transform = (descriptor: CompiledDescriptor, input: any, to: boolean): any => {\n  if (descriptor === 0) return input;\n  if (descriptor === 4) return toDate(input);\n\n  if (descriptor[0] === 1) {\n    if (typeof input !== 'object' || input === null) return input;\n\n    let output: any = {};\n    let consumed = descriptor[to ? 3 : 2];\n\n    for (let [source, target, child] of descriptor[1]) {\n      let from = to ? target : source;\n      if (!Object.prototype.propertyIsEnumerable.call(input, from)) continue;\n\n      setField(output, to ? source : target, transform(child, input[from], to));\n    }\n\n    for (let key of Object.keys(input)) {\n      if (!consumed.has(key)) setField(output, key, input[key]);\n    }\n\n    return output;\n  }\n\n  if (descriptor[0] === 2) {\n    if (!Array.isArray(input) || !input.length) return input;\n\n    return input.map(item => transform(descriptor[1], item, to));\n  }\n\n  let kind = kindOf(input);\n  if (kind === undefined) return input;\n\n  let branch = descriptor[1][kind];\n  if (branch !== undefined) return transform(branch, input, to);\n\n  if ((kind === 3 || kind === 4) && descriptor[1][2] === 4) return toDate(input);\n\n  return input;\n};\n\nexport let createMapper = <T = any>(\n  descriptor: CompactDescriptor,\n  flags = 0\n): MetorialMapper<T> => {\n  let compiled = compile(descriptor, flags);\n\n  return {\n    transformFrom: (input: any): T => transform(compiled, input, false),\n    transformTo: (input: any) => transform(compiled, input, true)\n  };\n};\n\nexport let mapObject = <T = any>(fields: CompactFields, flags = 0): MetorialMapper<T> =>\n  createMapper<T>([1, fields], flags);\n"],"mappings":"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","names":[]}