{"version":3,"file":"index.mjs","names":[],"sources":["../src/json-to-ts-source.ts","../src/render-imports.ts","../src/ts-expression.ts"],"sourcesContent":["/**\n * Pure JSON-to-TypeScript-source printer.\n *\n * This module is the second stage of the codec → TS pipeline:\n *\n *     jsValue  →  codec.encodeJson  →  JsonValue  →  jsonToTsSource  →  TS source text\n *\n * Stage 1 (`codec.encodeJson`) is a codec responsibility — date serialization,\n * opaque domain types (vector, bigint, uuid), JSON canonicalization. Stage 2\n * (this module) is a pure JSON-to-TS printer that must never grow type-specific\n * branches.\n *\n * To render a non-JSON JS value (Date, Vector, BigInt, Buffer, …), encode it\n * through the relevant codec's `encodeJson` first. Adding special cases to\n * this file is not the answer — that's what codecs are for.\n */\n\nexport type JsonValue = string | number | boolean | null | readonly JsonValue[] | JsonObject;\nexport type JsonObject = { readonly [key: string]: JsonValue | undefined };\n\n/**\n * Render a JSON-compatible value as a TypeScript source-text literal.\n *\n * Accepts `unknown` for ergonomics with structural types (e.g. `ColumnSpec`,\n * `ForeignKeySpec`) whose fields are all JSON-compatible but whose interfaces\n * lack the index signature TypeScript requires for `JsonObject` assignability.\n * Non-JSON values (Date, Symbol, Function, etc.) throw at runtime.\n */\nexport function jsonToTsSource(value: unknown): string {\n  if (value === undefined) return 'undefined';\n  if (value === null) return 'null';\n  if (typeof value === 'string') return JSON.stringify(value);\n  if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n  if (Array.isArray(value)) {\n    if (value.length === 0) return '[]';\n    const items = value.map((v: unknown) => jsonToTsSource(v));\n    const singleLine = `[${items.join(', ')}]`;\n    if (singleLine.length <= 80) return singleLine;\n    return `[\\n${items.map((i) => `  ${i}`).join(',\\n')},\\n]`;\n  }\n  if (typeof value === 'object') {\n    const entries = Object.entries(value).filter(([, v]) => v !== undefined);\n    if (entries.length === 0) return '{}';\n    const items = entries.map(([k, v]) => `${renderKey(k)}: ${jsonToTsSource(v)}`);\n    const singleLine = `{ ${items.join(', ')} }`;\n    if (singleLine.length <= 80) return singleLine;\n    return `{\\n${items.map((i) => `  ${i}`).join(',\\n')},\\n}`;\n  }\n  throw new Error(`jsonToTsSource: unsupported value type \"${typeof value}\"`);\n}\n\nfunction renderKey(key: string): string {\n  if (key === '__proto__') return JSON.stringify(key);\n  return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : JSON.stringify(key);\n}\n","import type { ImportRequirement } from './ts-expression';\n\n/**\n * Render an aggregated `import` block from a flat list of\n * `ImportRequirement`s. Each target's migration renderer collects\n * requirements polymorphically from its call nodes and pipes them here.\n *\n * The emitter invariants:\n *\n * - **One line per module specifier.** Named imports are aggregated and\n *   emitted sorted; a single default symbol is combined onto the same line\n *   when attributes agree (`import def, { a, b } from \"m\";`). Aliased symbols\n *   render `symbol as alias`. When every symbol for a module is `typeOnly`,\n *   the statement collapses to `import type { … }`; a module mixing value\n *   and type symbols prefixes the type-only ones (`import { type T, v }`).\n *   Exception: a fully type-only statement that has both a default and one or\n *   more named bindings splits to two lines (`import type D from \"m\";` then\n *   `import type { N } from \"m\";`) because TypeScript rejects\n *   `import type D, { N } from \"m\"` (TS1363).\n * - **At most one default symbol per module.** Two conflicting default\n *   symbols on the same specifier throw — the user's renderer can't\n *   guess which one they meant.\n * - **Attribute unanimity per module.** All requirements for the same\n *   module specifier must carry the same (or no) `attributes` map.\n *   Divergent attribute maps throw — they can't collapse to one line\n *   and there's no user-resolvable recovery at this layer.\n * - **Distinct (symbol, alias) pairs are distinct bindings.** TypeScript\n *   permits importing the same export under multiple local names, so\n *   `{ A }` + `{ A as B }` renders as `import { A, A as B } from \"m\"` and\n *   `{ A as B }` + `{ A as C }` renders as `import { A as B, A as C } from \"m\"`.\n *   Truly identical `(symbol, alias)` pairs still collapse to one binding,\n *   merging `typeOnly` by AND.\n * - **Deterministic ordering.** Modules are emitted sorted by specifier;\n *   within a module, named bindings are emitted sorted by `(symbol, alias)`\n *   using JavaScript code-unit comparison, with the un-aliased form (no\n *   alias) treated as alias `\"\"` so it sorts before any aliased form of the\n *   same symbol.\n *\n * Returns a string containing one import line per module, joined by `\\n`\n * (no trailing newline). An empty requirement list returns `\"\"`.\n */\nexport function renderImports(requirements: readonly ImportRequirement[]): string {\n  const byModule = aggregateByModule(requirements);\n  const entries = [...byModule.entries()].sort(([a], [b]) => a.localeCompare(b));\n  return entries\n    .map(([moduleSpecifier, group]) => renderModuleImport(moduleSpecifier, group))\n    .join('\\n');\n}\n\ninterface NamedBinding {\n  symbol: string;\n  alias: string | null;\n  typeOnly: boolean;\n}\n\ninterface ModuleImportGroup {\n  readonly named: Map<string, NamedBinding>;\n  defaultSymbol: string | null;\n  defaultTypeOnly: boolean;\n  attributes: Readonly<Record<string, string>> | null;\n  attributesSet: boolean;\n}\n\nfunction aggregateByModule(\n  requirements: readonly ImportRequirement[],\n): Map<string, ModuleImportGroup> {\n  const byModule = new Map<string, ModuleImportGroup>();\n  for (const req of requirements) {\n    let group = byModule.get(req.moduleSpecifier);\n    if (!group) {\n      group = {\n        named: new Map(),\n        defaultSymbol: null,\n        defaultTypeOnly: true,\n        attributes: null,\n        attributesSet: false,\n      };\n      byModule.set(req.moduleSpecifier, group);\n    }\n    mergeRequirementIntoGroup(req, group);\n  }\n  return byModule;\n}\n\nfunction mergeRequirementIntoGroup(req: ImportRequirement, group: ModuleImportGroup): void {\n  const kind = req.kind ?? 'named';\n  const typeOnly = req.typeOnly === true;\n  if (kind === 'default') {\n    if (group.defaultSymbol !== null && group.defaultSymbol !== req.symbol) {\n      throw new Error(\n        `Conflicting default imports for module \"${req.moduleSpecifier}\": ` +\n          `\"${group.defaultSymbol}\" and \"${req.symbol}\". Only one default symbol is allowed per module.`,\n      );\n    }\n    group.defaultSymbol = req.symbol;\n    group.defaultTypeOnly = group.defaultTypeOnly && typeOnly;\n  } else {\n    const alias = req.alias && req.alias !== req.symbol ? req.alias : null;\n    const key = namedBindingKey(req.symbol, alias);\n    const existing = group.named.get(key);\n    if (existing) {\n      existing.typeOnly = existing.typeOnly && typeOnly;\n    } else {\n      group.named.set(key, { symbol: req.symbol, alias, typeOnly });\n    }\n  }\n  mergeAttributes(req, group);\n}\n\nfunction mergeAttributes(req: ImportRequirement, group: ModuleImportGroup): void {\n  const incoming = req.attributes ?? null;\n  if (!group.attributesSet) {\n    group.attributes = incoming;\n    group.attributesSet = true;\n    return;\n  }\n  if (!attributesEqual(group.attributes, incoming)) {\n    throw new Error(\n      `Conflicting import attributes for module \"${req.moduleSpecifier}\": ` +\n        `${stringifyAttributes(group.attributes)} vs ${stringifyAttributes(incoming)}.`,\n    );\n  }\n}\n\nfunction attributesEqual(\n  a: Readonly<Record<string, string>> | null,\n  b: Readonly<Record<string, string>> | null,\n): boolean {\n  if (a === b) return true;\n  if (a === null || b === null) return false;\n  const aKeys = Object.keys(a).sort();\n  const bKeys = Object.keys(b).sort();\n  if (aKeys.length !== bKeys.length) return false;\n  for (let i = 0; i < aKeys.length; i++) {\n    const key = aKeys[i];\n    if (key !== bKeys[i]) return false;\n    if (a[key as string] !== b[key as string]) return false;\n  }\n  return true;\n}\n\nfunction stringifyAttributes(attrs: Readonly<Record<string, string>> | null): string {\n  if (attrs === null) return '(none)';\n  const entries = Object.entries(attrs)\n    .sort(([a], [b]) => a.localeCompare(b))\n    .map(([k, v]) => `${k}: ${JSON.stringify(v)}`);\n  return `{ ${entries.join(', ')} }`;\n}\n\nfunction renderModuleImport(moduleSpecifier: string, group: ModuleImportGroup): string {\n  const typeOnlyStatement = isStatementTypeOnly(group);\n  const attrs = buildAttributesClause(group.attributes);\n  const hasDefault = group.defaultSymbol !== null;\n  const hasNamed = group.named.size > 0;\n  if (typeOnlyStatement && hasDefault && hasNamed) {\n    const defaultLine = `import type ${group.defaultSymbol} from '${moduleSpecifier}'${attrs};`;\n    const namedClause = renderNamedBindingsList(group, true);\n    const namedLine = `import type { ${namedClause} } from '${moduleSpecifier}'${attrs};`;\n    return `${defaultLine}\\n${namedLine}`;\n  }\n  const keyword = typeOnlyStatement ? 'import type' : 'import';\n  const clause = buildImportClause(group, typeOnlyStatement);\n  return `${keyword} ${clause} from '${moduleSpecifier}'${attrs};`;\n}\n\nfunction isStatementTypeOnly(group: ModuleImportGroup): boolean {\n  const hasDefault = group.defaultSymbol !== null;\n  const hasNamed = group.named.size > 0;\n  if (!hasDefault && !hasNamed) return false;\n  if (hasDefault && !group.defaultTypeOnly) return false;\n  for (const binding of group.named.values()) {\n    if (!binding.typeOnly) return false;\n  }\n  return true;\n}\n\nfunction buildImportClause(group: ModuleImportGroup, statementTypeOnly: boolean): string {\n  const hasNamed = group.named.size > 0;\n  const hasDefault = group.defaultSymbol !== null;\n  const namedClause = hasNamed ? renderNamedBindingsList(group, statementTypeOnly) : '';\n  if (hasDefault && hasNamed) {\n    return `${group.defaultSymbol}, { ${namedClause} }`;\n  }\n  if (hasDefault) {\n    return group.defaultSymbol as string;\n  }\n  return `{ ${namedClause} }`;\n}\n\nfunction renderNamedBindingsList(group: ModuleImportGroup, statementTypeOnly: boolean): string {\n  return [...group.named.values()]\n    .sort(compareNamedBindings)\n    .map((binding) => renderNamedBinding(binding, statementTypeOnly))\n    .join(', ');\n}\n\nfunction compareNamedBindings(a: NamedBinding, b: NamedBinding): number {\n  if (a.symbol !== b.symbol) return a.symbol < b.symbol ? -1 : 1;\n  const aAlias = a.alias ?? '';\n  const bAlias = b.alias ?? '';\n  if (aAlias === bAlias) return 0;\n  return aAlias < bAlias ? -1 : 1;\n}\n\nfunction namedBindingKey(symbol: string, alias: string | null): string {\n  return `${symbol}\\x00${alias ?? ''}`;\n}\n\nfunction renderNamedBinding(binding: NamedBinding, statementTypeOnly: boolean): string {\n  const prefix = !statementTypeOnly && binding.typeOnly ? 'type ' : '';\n  const aliasClause = binding.alias !== null ? ` as ${binding.alias}` : '';\n  return `${prefix}${binding.symbol}${aliasClause}`;\n}\n\nfunction buildAttributesClause(attrs: Readonly<Record<string, string>> | null): string {\n  if (attrs === null) return '';\n  const entries = Object.entries(attrs)\n    .sort(([a], [b]) => a.localeCompare(b))\n    .map(([k, v]) => `${k}: ${JSON.stringify(v)}`);\n  if (entries.length === 0) return '';\n  return ` with { ${entries.join(', ')} }`;\n}\n","/**\n * Declarative contribution to the `import` block of a rendered TypeScript\n * source file. Each node in an IR declares which symbols it needs from which\n * modules; the top-level renderer deduplicates across nodes and emits one\n * `import { a, b, c } from \"…\"` line per module.\n *\n * `kind` defaults to `\"named\"` (e.g. `import { a } from \"m\"`). Setting it to\n * `\"default\"` emits `import a from \"m\"`. `attributes`, if provided, emits an\n * import attributes clause (`with { type: \"json\" }`) verbatim — required for\n * JSON module imports in the rendered scaffolds.\n *\n * `alias`, when present and different from `symbol`, renders `symbol as alias`.\n * `typeOnly` marks the symbol as a type import: when every symbol contributed\n * for a module is `typeOnly`, the whole statement collapses to\n * `import type { … } from \"m\"`; when a module mixes value and type symbols, the\n * type-only ones carry a per-specifier `type` prefix (`import { type T, val }`).\n */\nexport interface ImportRequirement {\n  readonly moduleSpecifier: string;\n  readonly symbol: string;\n  readonly kind?: 'named' | 'default';\n  readonly attributes?: Readonly<Record<string, string>>;\n  readonly alias?: string;\n  readonly typeOnly?: boolean;\n}\n\n/**\n * Abstract base class for any IR node that can be emitted as a TypeScript\n * expression and declare its own import requirements.\n *\n * A top-level renderer walks an array of these polymorphically, concatenates\n * `renderTypeScript()` results, and aggregates `importRequirements()` into a\n * deduplicated import block.\n */\nexport abstract class TsExpression {\n  abstract renderTypeScript(): string;\n  abstract importRequirements(): readonly ImportRequirement[];\n}\n"],"mappings":"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"}