@prisma-next/ts-render
Advanced tools
| import type { StructuredError, StructuredErrorOptions } from '@prisma-next/utils/structured-error'; | ||
| import { structuredError } from '@prisma-next/utils/structured-error'; | ||
| export type ContractCode = `CONTRACT.${ContractSubcode}`; | ||
| type ContractSubcode = 'PACK_CONTRIBUTION_INVALID'; | ||
| export function contractError( | ||
| code: ContractCode, | ||
| message: string, | ||
| options?: StructuredErrorOptions, | ||
| ): StructuredError { | ||
| return structuredError(code, message, options); | ||
| } |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.d.mts","names":[],"sources":["../src/json-to-ts-source.ts","../src/ts-expression.ts","../src/render-imports.ts"],"mappings":";;;;;;;;;;;;;;;;;KAiBY,wDAAwD,cAAc;KACtE;YAAyB,cAAc;;;;;;;;;;iBAUnC,eAAe;;;;;;;;;;;;;;;;;;;;UCXd;WACN;WACA;WACA;WACA,aAAa,SAAS;WACtB;WACA;;;;;;;;;;uBAWW;WACX;WACA,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBCU1B,cAAc,uBAAuB"} | ||
| {"version":3,"file":"index.d.mts","names":[],"sources":["../src/json-to-ts-source.ts","../src/ts-expression.ts","../src/render-imports.ts"],"mappings":";;;;;;;;;;;;;;;;;KAmBY,wDAAwD,cAAc;KACtE;YAAyB,cAAc;;;;;;;;;;iBAUnC,eAAe;;;;;;;;;;;;;;;;;;;;UCbd;WACN;WACA;WACA;WACA,aAAa,SAAS;WACtB;WACA;;;;;;;;;;uBAWW;WACX;WACA,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBCW1B,cAAc,uBAAuB"} |
+25
-2
@@ -0,3 +1,21 @@ | ||
| import { InternalError } from "@prisma-next/utils/internal-error"; | ||
| import { structuredError } from "@prisma-next/utils/structured-error"; | ||
| //#region src/json-to-ts-source.ts | ||
| /** | ||
| * Pure JSON-to-TypeScript-source printer. | ||
| * | ||
| * This module is the second stage of the codec → TS pipeline: | ||
| * | ||
| * jsValue → codec.encodeJson → JsonValue → jsonToTsSource → TS source text | ||
| * | ||
| * Stage 1 (`codec.encodeJson`) is a codec responsibility — date serialization, | ||
| * opaque domain types (vector, bigint, uuid), JSON canonicalization. Stage 2 | ||
| * (this module) is a pure JSON-to-TS printer that must never grow type-specific | ||
| * branches. | ||
| * | ||
| * To render a non-JSON JS value (Date, Vector, BigInt, Buffer, …), encode it | ||
| * through the relevant codec's `encodeJson` first. Adding special cases to | ||
| * this file is not the answer — that's what codecs are for. | ||
| */ | ||
| /** | ||
| * Render a JSON-compatible value as a TypeScript source-text literal. | ||
@@ -30,3 +48,3 @@ * | ||
| } | ||
| throw new Error(`jsonToTsSource: unsupported value type "${typeof value}"`); | ||
| throw new InternalError(`jsonToTsSource: unsupported value type "${typeof value}"`); | ||
| } | ||
@@ -41,2 +59,7 @@ function renderKey(key) { | ||
| //#endregion | ||
| //#region src/contract-errors.ts | ||
| function contractError(code, message, options) { | ||
| return structuredError(code, message, options); | ||
| } | ||
| //#endregion | ||
| //#region src/render-imports.ts | ||
@@ -133,3 +156,3 @@ /** | ||
| } | ||
| if (!attributesEqual(group.attributes, incoming)) throw new Error(`Conflicting import attributes for module "${req.moduleSpecifier}": ${stringifyAttributes(group.attributes)} vs ${stringifyAttributes(incoming)}.`); | ||
| if (!attributesEqual(group.attributes, incoming)) throw contractError("CONTRACT.PACK_CONTRIBUTION_INVALID", `Conflicting import attributes for module "${req.moduleSpecifier}": ${stringifyAttributes(group.attributes)} vs ${stringifyAttributes(incoming)}.`, { meta: { moduleSpecifier: req.moduleSpecifier } }); | ||
| } | ||
@@ -136,0 +159,0 @@ function attributesEqual(a, b) { |
@@ -1,1 +0,1 @@ | ||
| {"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 stringifyLiteral(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 stringifyLiteral(key);\n return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : stringifyLiteral(key);\n}\n\n// JSON.stringify leaves U+2028/U+2029 unescaped; embedded raw in JS/TS source\n// those characters can terminate the string literal, so escape them explicitly.\nfunction stringifyLiteral(value: string): string {\n return JSON.stringify(value)\n .replace(/\\u2028/g, '\\\\u2028')\n .replace(/\\u2029/g, '\\\\u2029');\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 * - **Usually one line per module specifier.** Named imports are aggregated\n * and emitted sorted; a single default symbol is combined onto the same\n * line when attributes agree (`import def, { a, b } from \"m\";`). Aliased\n * symbols render `symbol as alias`. When every symbol for a module is\n * `typeOnly`, the statement collapses to `import type { … }`; a module\n * mixing value and type symbols prefixes the type-only ones\n * (`import { type T, v }`). Exceptions that split into multiple lines: a\n * fully type-only statement with both a default and one or more named\n * bindings (`import type D from \"m\";` then `import type { N } from \"m\";`,\n * because TypeScript rejects `import type D, { N } from \"m\"` — TS1363),\n * and multiple distinct default symbols (see below).\n * - **Multiple distinct default symbols per module are allowed.** JS permits\n * re-importing the same specifier under different default-binding names\n * (`import a from 'm'; import b from 'm';`), so each distinct default\n * symbol renders its own `import` line, sorted alphabetically; a repeated\n * requirement for the same symbol still collapses into one binding,\n * merging `typeOnly` by AND.\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 or more import lines per module (see the\n * splitting exceptions above), joined by `\\n` (no trailing newline). An\n * 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 readonly defaults: Map<string, 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 defaults: new Map(),\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 const existingTypeOnly = group.defaults.get(req.symbol);\n group.defaults.set(\n req.symbol,\n existingTypeOnly === undefined ? typeOnly : existingTypeOnly && typeOnly,\n );\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 attrs = buildAttributesClause(group.attributes);\n const defaultEntries = [...group.defaults.entries()].sort(([a], [b]) => a.localeCompare(b));\n const hasNamed = group.named.size > 0;\n\n // More than one distinct default symbol can't share a single import\n // clause (`import a, b from 'm'` isn't valid syntax), so each gets its\n // own line; named bindings (if any) follow on their own line.\n if (defaultEntries.length > 1) {\n const defaultLines = defaultEntries.map(\n ([symbol, typeOnly]) =>\n `import ${typeOnly ? 'type ' : ''}${symbol} from '${moduleSpecifier}'${attrs};`,\n );\n if (!hasNamed) return defaultLines.join('\\n');\n return [...defaultLines, renderNamedOnlyStatement(moduleSpecifier, group, attrs)].join('\\n');\n }\n\n const defaultEntry = defaultEntries[0];\n const hasDefault = defaultEntry !== undefined;\n const [defaultSymbol, defaultTypeOnly] = defaultEntry ?? [null, true];\n const typeOnlyStatement = isStatementTypeOnly(hasDefault, defaultTypeOnly, group);\n if (typeOnlyStatement && hasDefault && hasNamed) {\n const defaultLine = `import type ${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(defaultSymbol, group, typeOnlyStatement);\n return `${keyword} ${clause} from '${moduleSpecifier}'${attrs};`;\n}\n\nfunction renderNamedOnlyStatement(\n moduleSpecifier: string,\n group: ModuleImportGroup,\n attrs: string,\n): string {\n const typeOnlyStatement = [...group.named.values()].every((binding) => binding.typeOnly);\n const keyword = typeOnlyStatement ? 'import type' : 'import';\n const namedClause = renderNamedBindingsList(group, typeOnlyStatement);\n return `${keyword} { ${namedClause} } from '${moduleSpecifier}'${attrs};`;\n}\n\nfunction isStatementTypeOnly(\n hasDefault: boolean,\n defaultTypeOnly: boolean,\n group: ModuleImportGroup,\n): boolean {\n const hasNamed = group.named.size > 0;\n if (!hasDefault && !hasNamed) return false;\n if (hasDefault && !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(\n defaultSymbol: string | null,\n group: ModuleImportGroup,\n statementTypeOnly: boolean,\n): string {\n const hasNamed = group.named.size > 0;\n const hasDefault = defaultSymbol !== null;\n const namedClause = hasNamed ? renderNamedBindingsList(group, statementTypeOnly) : '';\n if (hasDefault && hasNamed) {\n return `${defaultSymbol}, { ${namedClause} }`;\n }\n if (hasDefault) {\n return defaultSymbol;\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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"} | ||
| {"version":3,"file":"index.mjs","names":[],"sources":["../src/json-to-ts-source.ts","../src/contract-errors.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\nimport { InternalError } from '@prisma-next/utils/internal-error';\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 stringifyLiteral(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 InternalError(`jsonToTsSource: unsupported value type \"${typeof value}\"`);\n}\n\nfunction renderKey(key: string): string {\n if (key === '__proto__') return stringifyLiteral(key);\n return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : stringifyLiteral(key);\n}\n\n// JSON.stringify leaves U+2028/U+2029 unescaped; embedded raw in JS/TS source\n// those characters can terminate the string literal, so escape them explicitly.\nfunction stringifyLiteral(value: string): string {\n return JSON.stringify(value)\n .replace(/\\u2028/g, '\\\\u2028')\n .replace(/\\u2029/g, '\\\\u2029');\n}\n","import type { StructuredError, StructuredErrorOptions } from '@prisma-next/utils/structured-error';\nimport { structuredError } from '@prisma-next/utils/structured-error';\n\nexport type ContractCode = `CONTRACT.${ContractSubcode}`;\n\ntype ContractSubcode = 'PACK_CONTRIBUTION_INVALID';\n\nexport function contractError(\n code: ContractCode,\n message: string,\n options?: StructuredErrorOptions,\n): StructuredError {\n return structuredError(code, message, options);\n}\n","import { contractError } from './contract-errors';\nimport 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 * - **Usually one line per module specifier.** Named imports are aggregated\n * and emitted sorted; a single default symbol is combined onto the same\n * line when attributes agree (`import def, { a, b } from \"m\";`). Aliased\n * symbols render `symbol as alias`. When every symbol for a module is\n * `typeOnly`, the statement collapses to `import type { … }`; a module\n * mixing value and type symbols prefixes the type-only ones\n * (`import { type T, v }`). Exceptions that split into multiple lines: a\n * fully type-only statement with both a default and one or more named\n * bindings (`import type D from \"m\";` then `import type { N } from \"m\";`,\n * because TypeScript rejects `import type D, { N } from \"m\"` — TS1363),\n * and multiple distinct default symbols (see below).\n * - **Multiple distinct default symbols per module are allowed.** JS permits\n * re-importing the same specifier under different default-binding names\n * (`import a from 'm'; import b from 'm';`), so each distinct default\n * symbol renders its own `import` line, sorted alphabetically; a repeated\n * requirement for the same symbol still collapses into one binding,\n * merging `typeOnly` by AND.\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 or more import lines per module (see the\n * splitting exceptions above), joined by `\\n` (no trailing newline). An\n * 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 readonly defaults: Map<string, 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 defaults: new Map(),\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 const existingTypeOnly = group.defaults.get(req.symbol);\n group.defaults.set(\n req.symbol,\n existingTypeOnly === undefined ? typeOnly : existingTypeOnly && typeOnly,\n );\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 contractError(\n 'CONTRACT.PACK_CONTRIBUTION_INVALID',\n `Conflicting import attributes for module \"${req.moduleSpecifier}\": ` +\n `${stringifyAttributes(group.attributes)} vs ${stringifyAttributes(incoming)}.`,\n { meta: { moduleSpecifier: req.moduleSpecifier } },\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 attrs = buildAttributesClause(group.attributes);\n const defaultEntries = [...group.defaults.entries()].sort(([a], [b]) => a.localeCompare(b));\n const hasNamed = group.named.size > 0;\n\n // More than one distinct default symbol can't share a single import\n // clause (`import a, b from 'm'` isn't valid syntax), so each gets its\n // own line; named bindings (if any) follow on their own line.\n if (defaultEntries.length > 1) {\n const defaultLines = defaultEntries.map(\n ([symbol, typeOnly]) =>\n `import ${typeOnly ? 'type ' : ''}${symbol} from '${moduleSpecifier}'${attrs};`,\n );\n if (!hasNamed) return defaultLines.join('\\n');\n return [...defaultLines, renderNamedOnlyStatement(moduleSpecifier, group, attrs)].join('\\n');\n }\n\n const defaultEntry = defaultEntries[0];\n const hasDefault = defaultEntry !== undefined;\n const [defaultSymbol, defaultTypeOnly] = defaultEntry ?? [null, true];\n const typeOnlyStatement = isStatementTypeOnly(hasDefault, defaultTypeOnly, group);\n if (typeOnlyStatement && hasDefault && hasNamed) {\n const defaultLine = `import type ${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(defaultSymbol, group, typeOnlyStatement);\n return `${keyword} ${clause} from '${moduleSpecifier}'${attrs};`;\n}\n\nfunction renderNamedOnlyStatement(\n moduleSpecifier: string,\n group: ModuleImportGroup,\n attrs: string,\n): string {\n const typeOnlyStatement = [...group.named.values()].every((binding) => binding.typeOnly);\n const keyword = typeOnlyStatement ? 'import type' : 'import';\n const namedClause = renderNamedBindingsList(group, typeOnlyStatement);\n return `${keyword} { ${namedClause} } from '${moduleSpecifier}'${attrs};`;\n}\n\nfunction isStatementTypeOnly(\n hasDefault: boolean,\n defaultTypeOnly: boolean,\n group: ModuleImportGroup,\n): boolean {\n const hasNamed = group.named.size > 0;\n if (!hasDefault && !hasNamed) return false;\n if (hasDefault && !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(\n defaultSymbol: string | null,\n group: ModuleImportGroup,\n statementTypeOnly: boolean,\n): string {\n const hasNamed = group.named.size > 0;\n const hasDefault = defaultSymbol !== null;\n const namedClause = hasNamed ? renderNamedBindingsList(group, statementTypeOnly) : '';\n if (hasDefault && hasNamed) {\n return `${defaultSymbol}, { ${namedClause} }`;\n }\n if (hasDefault) {\n return defaultSymbol;\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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"} |
+6
-4
| { | ||
| "name": "@prisma-next/ts-render", | ||
| "version": "0.16.0-dev.30", | ||
| "version": "0.16.0-dev.31", | ||
| "license": "Apache-2.0", | ||
@@ -8,6 +8,8 @@ "type": "module", | ||
| "description": "TypeScript source-text rendering utilities: JSON-to-TS literal printer and abstract expression base class", | ||
| "dependencies": {}, | ||
| "dependencies": { | ||
| "@prisma-next/utils": "0.16.0-dev.31" | ||
| }, | ||
| "devDependencies": { | ||
| "@prisma-next/tsconfig": "0.16.0-dev.30", | ||
| "@prisma-next/tsdown": "0.16.0-dev.30", | ||
| "@prisma-next/tsconfig": "0.16.0-dev.31", | ||
| "@prisma-next/tsdown": "0.16.0-dev.31", | ||
| "tsdown": "0.22.8", | ||
@@ -14,0 +16,0 @@ "typescript": "5.9.3", |
@@ -18,2 +18,4 @@ /** | ||
| import { InternalError } from '@prisma-next/utils/internal-error'; | ||
| export type JsonValue = string | number | boolean | null | readonly JsonValue[] | JsonObject; | ||
@@ -50,3 +52,3 @@ export type JsonObject = { readonly [key: string]: JsonValue | undefined }; | ||
| } | ||
| throw new Error(`jsonToTsSource: unsupported value type "${typeof value}"`); | ||
| throw new InternalError(`jsonToTsSource: unsupported value type "${typeof value}"`); | ||
| } | ||
@@ -53,0 +55,0 @@ |
@@ -0,1 +1,2 @@ | ||
| import { contractError } from './contract-errors'; | ||
| import type { ImportRequirement } from './ts-expression'; | ||
@@ -118,5 +119,7 @@ | ||
| if (!attributesEqual(group.attributes, incoming)) { | ||
| throw new Error( | ||
| throw contractError( | ||
| 'CONTRACT.PACK_CONTRIBUTION_INVALID', | ||
| `Conflicting import attributes for module "${req.moduleSpecifier}": ` + | ||
| `${stringifyAttributes(group.attributes)} vs ${stringifyAttributes(incoming)}.`, | ||
| { meta: { moduleSpecifier: req.moduleSpecifier } }, | ||
| ); | ||
@@ -123,0 +126,0 @@ } |
70229
3.99%12
9.09%596
7%2
100%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added