@prisma-next/target-sqlite 0.16.0-dev.22 → 0.16.0-dev.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/codecs-DGgo--O0.d.mts.map +1 -1
  2. package/dist/codecs.mjs +25 -6
  3. package/dist/codecs.mjs.map +1 -1
  4. package/dist/control.d.mts.map +1 -1
  5. package/dist/control.mjs +10 -5
  6. package/dist/control.mjs.map +1 -1
  7. package/dist/errors-B1JPoWDh.mjs +38 -0
  8. package/dist/errors-B1JPoWDh.mjs.map +1 -0
  9. package/dist/migration.mjs +2 -2
  10. package/dist/{op-factory-call-8pTnIHhR.mjs → op-factory-call-BkqsWGiy.mjs} +39 -13
  11. package/dist/op-factory-call-BkqsWGiy.mjs.map +1 -0
  12. package/dist/op-factory-call.d.mts.map +1 -1
  13. package/dist/op-factory-call.mjs +1 -1
  14. package/dist/{planner-sc4nqpzL.mjs → planner-BY62rsnv.mjs} +9 -5
  15. package/dist/planner-BY62rsnv.mjs.map +1 -0
  16. package/dist/{planner-produced-sqlite-migration-CWmvnJi4.mjs → planner-produced-sqlite-migration-BGcreGfL.mjs} +3 -3
  17. package/dist/{planner-produced-sqlite-migration-CWmvnJi4.mjs.map → planner-produced-sqlite-migration-BGcreGfL.mjs.map} +1 -1
  18. package/dist/planner-produced-sqlite-migration.mjs +1 -1
  19. package/dist/planner.mjs +1 -1
  20. package/dist/{render-ops-BDW2tUeR.mjs → render-ops-BAw6MQWl.mjs} +7 -2
  21. package/dist/render-ops-BAw6MQWl.mjs.map +1 -0
  22. package/dist/render-ops.d.mts.map +1 -1
  23. package/dist/render-ops.mjs +1 -1
  24. package/dist/runtime.mjs +1 -1
  25. package/dist/{sql-utils-CV8Bdgtc.mjs → sql-utils-BMteAbKH.mjs} +15 -15
  26. package/dist/sql-utils-BMteAbKH.mjs.map +1 -0
  27. package/dist/sql-utils.d.mts +1 -6
  28. package/dist/sql-utils.d.mts.map +1 -1
  29. package/dist/sql-utils.mjs +2 -2
  30. package/dist/{sqlite-contract-view-B8qeCczc.mjs → sqlite-contract-view-DthhfCpb.mjs} +3 -2
  31. package/dist/sqlite-contract-view-DthhfCpb.mjs.map +1 -0
  32. package/dist/{sqlite-migration-CLXPhPxF.mjs → sqlite-migration-DrZIdg3i.mjs} +4 -34
  33. package/dist/sqlite-migration-DrZIdg3i.mjs.map +1 -0
  34. package/package.json +18 -18
  35. package/src/core/codecs.ts +33 -6
  36. package/src/core/control-target.ts +3 -1
  37. package/src/core/errors.ts +24 -0
  38. package/src/core/migrations/column-ddl-rendering.ts +4 -2
  39. package/src/core/migrations/op-factory-call.ts +41 -8
  40. package/src/core/migrations/planner-ddl-builders.ts +10 -3
  41. package/src/core/migrations/render-ops.ts +4 -1
  42. package/src/core/migrations/runner.ts +6 -2
  43. package/src/core/sql-utils.ts +10 -21
  44. package/src/core/sqlite-unbound-database.ts +4 -1
  45. package/src/exports/sql-utils.ts +1 -1
  46. package/dist/op-factory-call-8pTnIHhR.mjs.map +0 -1
  47. package/dist/planner-sc4nqpzL.mjs.map +0 -1
  48. package/dist/render-ops-BDW2tUeR.mjs.map +0 -1
  49. package/dist/sql-utils-CV8Bdgtc.mjs.map +0 -1
  50. package/dist/sqlite-contract-view-B8qeCczc.mjs.map +0 -1
  51. package/dist/sqlite-migration-CLXPhPxF.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"planner-produced-sqlite-migration-CWmvnJi4.mjs","names":["#calls","#meta","#destination","#spaceId","#snapshotsImportPath","#lowerer","#operationsCache"],"sources":["../src/core/migrations/render-typescript.ts","../src/core/migrations/planner-produced-sqlite-migration.ts"],"sourcesContent":["/**\n * Polymorphic TypeScript emitter for the SQLite migration IR. Mirrors the\n * Postgres `render-typescript.ts` — different base-class + factory module\n * specifier, same overall shape.\n */\n\nimport {\n contractSnapshotJsonSpecifier,\n contractSnapshotTypesSpecifier,\n type OpFactoryCall,\n} from '@prisma-next/framework-components/control';\nimport { detectScaffoldRuntime, shebangLineFor } from '@prisma-next/migration-tools/migration-ts';\nimport { type ImportRequirement, renderImports } from '@prisma-next/ts-render';\n\nexport interface RenderMigrationMeta {\n readonly from: string | null;\n readonly to: string;\n /** POSIX-relative path from the migration package dir to `migrations/snapshots`, e.g. '../../snapshots'. */\n readonly snapshotsImportPath: string;\n}\n\n/**\n * Always-present base imports for the rendered scaffold. Both come from\n * `@prisma-next/sqlite/migration` so an authored SQLite\n * `migration.ts` only needs a single dependency for its base class and\n * its CLI entrypoint. Mirrors Postgres's `BASE_IMPORTS`.\n *\n * - `Migration` — the facade re-export fixes the `SqlMigration`\n * generic to `SqlitePlanTargetDetails` and the abstract `targetId` to\n * `'sqlite'`.\n * - `MigrationCLI` — the migration-file CLI entrypoint, re-exported from\n * `@prisma-next/cli/migration-cli`. Loads `prisma-next.config.ts`,\n * assembles a `ControlStack`, and instantiates the migration class.\n */\nconst BASE_IMPORTS: readonly ImportRequirement[] = [\n { moduleSpecifier: '@prisma-next/sqlite/migration', symbol: 'Migration' },\n { moduleSpecifier: '@prisma-next/sqlite/migration', symbol: 'MigrationCLI' },\n];\n\nexport function renderCallsToTypeScript(\n calls: ReadonlyArray<OpFactoryCall>,\n meta: RenderMigrationMeta,\n): string {\n const imports = buildImports(calls, meta);\n const operationsBody = calls.map((c) => c.renderTypeScript()).join(',\\n');\n const hasStart = meta.from !== null;\n const startField = hasStart ? [' override readonly startContractJson = startContract;'] : [];\n\n return [\n shebangLineFor(detectScaffoldRuntime()),\n imports,\n '',\n `export default class M extends Migration<${hasStart ? 'Start' : 'never'}, End> {`,\n ...startField,\n ' override readonly endContractJson = endContract;',\n '',\n ' override get operations() {',\n ' return [',\n indent(operationsBody, 6),\n ' ];',\n ' }',\n '}',\n '',\n 'MigrationCLI.run(import.meta.url, M);',\n '',\n ].join('\\n');\n}\n\nfunction buildImports(calls: ReadonlyArray<OpFactoryCall>, meta: RenderMigrationMeta): string {\n const requirements: ImportRequirement[] = [...BASE_IMPORTS, ...contractImports(meta)];\n for (const call of calls) {\n for (const req of call.importRequirements()) {\n requirements.push(req);\n }\n }\n return renderImports(requirements);\n}\n\n/**\n * The committed contract-JSON imports the scaffold reads its from/to identity\n * from, resolved to the deduplicated snapshot store under\n * `meta.snapshotsImportPath`. The end snapshot is always present; the start\n * snapshot is added only for a non-baseline migration (`meta.from !== null`).\n * The matching `Contract` type imports (aliased `Start`/`End`) feed the\n * `Migration<Start, End>` generics. Baseline emits `Migration<never, End>` with\n * no start imports — `never` is the honest \"no prior contract\" Start.\n */\nfunction contractImports(meta: RenderMigrationMeta): readonly ImportRequirement[] {\n const reqs: ImportRequirement[] = [\n {\n moduleSpecifier: contractSnapshotJsonSpecifier(meta.snapshotsImportPath, meta.to),\n symbol: 'endContract',\n kind: 'default',\n attributes: { type: 'json' },\n },\n {\n moduleSpecifier: contractSnapshotTypesSpecifier(meta.snapshotsImportPath, meta.to),\n symbol: 'Contract',\n alias: 'End',\n typeOnly: true,\n },\n ];\n if (meta.from !== null) {\n reqs.push({\n moduleSpecifier: contractSnapshotJsonSpecifier(meta.snapshotsImportPath, meta.from),\n symbol: 'startContract',\n kind: 'default',\n attributes: { type: 'json' },\n });\n reqs.push({\n moduleSpecifier: contractSnapshotTypesSpecifier(meta.snapshotsImportPath, meta.from),\n symbol: 'Contract',\n alias: 'Start',\n typeOnly: true,\n });\n }\n return reqs;\n}\n\nfunction indent(text: string, spaces: number): string {\n const pad = ' '.repeat(spaces);\n return text\n .split('\\n')\n .map((line) => (line.trim() ? `${pad}${line}` : line))\n .join('\\n');\n}\n","import type { SqlMigrationPlanOperation } from '@prisma-next/family-sql/control';\nimport type { ExecuteRequestLowerer } from '@prisma-next/family-sql/control-adapter';\nimport type {\n MigrationPlanWithAuthoringSurface,\n OpFactoryCall,\n} from '@prisma-next/framework-components/control';\nimport type { MigrationMeta } from '@prisma-next/migration-tools/migration';\nimport type { SqlitePlanTargetDetails } from './planner-target-details';\nimport { renderOps } from './render-ops';\nimport { renderCallsToTypeScript } from './render-typescript';\nimport { SqliteMigration } from './sqlite-migration';\n\ntype Op = SqlMigrationPlanOperation<SqlitePlanTargetDetails>;\n\nexport interface SqliteMigrationDestinationInfo {\n readonly storageHash: string;\n readonly profileHash?: string;\n}\n\nexport class TypeScriptRenderableSqliteMigration\n extends SqliteMigration\n implements MigrationPlanWithAuthoringSurface\n{\n readonly #calls: readonly OpFactoryCall[];\n readonly #meta: MigrationMeta;\n readonly #destination: SqliteMigrationDestinationInfo;\n readonly #spaceId: string;\n readonly #snapshotsImportPath: string;\n readonly #lowerer: ExecuteRequestLowerer | undefined;\n #operationsCache: readonly (Op | Promise<Op>)[] | undefined;\n\n constructor(\n calls: readonly OpFactoryCall[],\n meta: MigrationMeta,\n spaceId: string,\n snapshotsImportPath: string,\n destination?: SqliteMigrationDestinationInfo,\n lowerer?: ExecuteRequestLowerer,\n ) {\n super();\n this.#calls = calls;\n this.#meta = meta;\n this.#spaceId = spaceId;\n this.#snapshotsImportPath = snapshotsImportPath;\n this.#destination = destination ?? { storageHash: meta.to };\n this.#lowerer = lowerer;\n }\n\n override get operations(): readonly (Op | Promise<Op>)[] {\n this.#operationsCache ??= renderOps(this.#calls, this.#lowerer);\n return this.#operationsCache;\n }\n\n override describe(): MigrationMeta {\n return this.#meta;\n }\n\n override get destination(): SqliteMigrationDestinationInfo {\n return this.#destination;\n }\n\n /**\n * Contract space this planner-produced plan applies to. Threaded\n * from {@link SqlMigrationPlannerPlanOptions.spaceId} so the runner\n * keys the marker row by the right space when executing the plan.\n */\n get spaceId(): string {\n return this.#spaceId;\n }\n\n renderTypeScript(): string {\n return renderCallsToTypeScript(this.#calls, {\n from: this.#meta.from,\n to: this.#meta.to,\n snapshotsImportPath: this.#snapshotsImportPath,\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAkCA,MAAM,eAA6C,CACjD;CAAE,iBAAiB;CAAiC,QAAQ;AAAY,GACxE;CAAE,iBAAiB;CAAiC,QAAQ;AAAe,CAC7E;AAEA,SAAgB,wBACd,OACA,MACQ;CACR,MAAM,UAAU,aAAa,OAAO,IAAI;CACxC,MAAM,iBAAiB,MAAM,KAAK,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,KAAK;CACxE,MAAM,WAAW,KAAK,SAAS;CAC/B,MAAM,aAAa,WAAW,CAAC,wDAAwD,IAAI,CAAC;CAE5F,OAAO;EACL,eAAe,sBAAsB,CAAC;EACtC;EACA;EACA,4CAA4C,WAAW,UAAU,QAAQ;EACzE,GAAG;EACH;EACA;EACA;EACA;EACA,OAAO,gBAAgB,CAAC;EACxB;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;AACb;AAEA,SAAS,aAAa,OAAqC,MAAmC;CAC5F,MAAM,eAAoC,CAAC,GAAG,cAAc,GAAG,gBAAgB,IAAI,CAAC;CACpF,KAAK,MAAM,QAAQ,OACjB,KAAK,MAAM,OAAO,KAAK,mBAAmB,GACxC,aAAa,KAAK,GAAG;CAGzB,OAAO,cAAc,YAAY;AACnC;;;;;;;;;;AAWA,SAAS,gBAAgB,MAAyD;CAChF,MAAM,OAA4B,CAChC;EACE,iBAAiB,8BAA8B,KAAK,qBAAqB,KAAK,EAAE;EAChF,QAAQ;EACR,MAAM;EACN,YAAY,EAAE,MAAM,OAAO;CAC7B,GACA;EACE,iBAAiB,+BAA+B,KAAK,qBAAqB,KAAK,EAAE;EACjF,QAAQ;EACR,OAAO;EACP,UAAU;CACZ,CACF;CACA,IAAI,KAAK,SAAS,MAAM;EACtB,KAAK,KAAK;GACR,iBAAiB,8BAA8B,KAAK,qBAAqB,KAAK,IAAI;GAClF,QAAQ;GACR,MAAM;GACN,YAAY,EAAE,MAAM,OAAO;EAC7B,CAAC;EACD,KAAK,KAAK;GACR,iBAAiB,+BAA+B,KAAK,qBAAqB,KAAK,IAAI;GACnF,QAAQ;GACR,OAAO;GACP,UAAU;EACZ,CAAC;CACH;CACA,OAAO;AACT;AAEA,SAAS,OAAO,MAAc,QAAwB;CACpD,MAAM,MAAM,IAAI,OAAO,MAAM;CAC7B,OAAO,KACJ,MAAM,IAAI,CAAC,CACX,KAAK,SAAU,KAAK,KAAK,IAAI,GAAG,MAAM,SAAS,IAAK,CAAC,CACrD,KAAK,IAAI;AACd;;;AC1GA,IAAa,sCAAb,cACU,gBAEV;CACE;CACA;CACA;CACA;CACA;CACA;CACA;CAEA,YACE,OACA,MACA,SACA,qBACA,aACA,SACA;EACA,MAAM;EACN,KAAKA,SAAS;EACd,KAAKC,QAAQ;EACb,KAAKE,WAAW;EAChB,KAAKC,uBAAuB;EAC5B,KAAKF,eAAe,eAAe,EAAE,aAAa,KAAK,GAAG;EAC1D,KAAKG,WAAW;CAClB;CAEA,IAAa,aAA4C;EACvD,KAAKC,qBAAqB,UAAU,KAAKN,QAAQ,KAAKK,QAAQ;EAC9D,OAAO,KAAKC;CACd;CAEA,WAAmC;EACjC,OAAO,KAAKL;CACd;CAEA,IAAa,cAA8C;EACzD,OAAO,KAAKC;CACd;;;;;;CAOA,IAAI,UAAkB;EACpB,OAAO,KAAKC;CACd;CAEA,mBAA2B;EACzB,OAAO,wBAAwB,KAAKH,QAAQ;GAC1C,MAAM,KAAKC,MAAM;GACjB,IAAI,KAAKA,MAAM;GACf,qBAAqB,KAAKG;EAC5B,CAAC;CACH;AACF"}
1
+ {"version":3,"file":"planner-produced-sqlite-migration-BGcreGfL.mjs","names":["#calls","#meta","#destination","#spaceId","#snapshotsImportPath","#lowerer","#operationsCache"],"sources":["../src/core/migrations/render-typescript.ts","../src/core/migrations/planner-produced-sqlite-migration.ts"],"sourcesContent":["/**\n * Polymorphic TypeScript emitter for the SQLite migration IR. Mirrors the\n * Postgres `render-typescript.ts` — different base-class + factory module\n * specifier, same overall shape.\n */\n\nimport {\n contractSnapshotJsonSpecifier,\n contractSnapshotTypesSpecifier,\n type OpFactoryCall,\n} from '@prisma-next/framework-components/control';\nimport { detectScaffoldRuntime, shebangLineFor } from '@prisma-next/migration-tools/migration-ts';\nimport { type ImportRequirement, renderImports } from '@prisma-next/ts-render';\n\nexport interface RenderMigrationMeta {\n readonly from: string | null;\n readonly to: string;\n /** POSIX-relative path from the migration package dir to `migrations/snapshots`, e.g. '../../snapshots'. */\n readonly snapshotsImportPath: string;\n}\n\n/**\n * Always-present base imports for the rendered scaffold. Both come from\n * `@prisma-next/sqlite/migration` so an authored SQLite\n * `migration.ts` only needs a single dependency for its base class and\n * its CLI entrypoint. Mirrors Postgres's `BASE_IMPORTS`.\n *\n * - `Migration` — the facade re-export fixes the `SqlMigration`\n * generic to `SqlitePlanTargetDetails` and the abstract `targetId` to\n * `'sqlite'`.\n * - `MigrationCLI` — the migration-file CLI entrypoint, re-exported from\n * `@prisma-next/cli/migration-cli`. Loads `prisma-next.config.ts`,\n * assembles a `ControlStack`, and instantiates the migration class.\n */\nconst BASE_IMPORTS: readonly ImportRequirement[] = [\n { moduleSpecifier: '@prisma-next/sqlite/migration', symbol: 'Migration' },\n { moduleSpecifier: '@prisma-next/sqlite/migration', symbol: 'MigrationCLI' },\n];\n\nexport function renderCallsToTypeScript(\n calls: ReadonlyArray<OpFactoryCall>,\n meta: RenderMigrationMeta,\n): string {\n const imports = buildImports(calls, meta);\n const operationsBody = calls.map((c) => c.renderTypeScript()).join(',\\n');\n const hasStart = meta.from !== null;\n const startField = hasStart ? [' override readonly startContractJson = startContract;'] : [];\n\n return [\n shebangLineFor(detectScaffoldRuntime()),\n imports,\n '',\n `export default class M extends Migration<${hasStart ? 'Start' : 'never'}, End> {`,\n ...startField,\n ' override readonly endContractJson = endContract;',\n '',\n ' override get operations() {',\n ' return [',\n indent(operationsBody, 6),\n ' ];',\n ' }',\n '}',\n '',\n 'MigrationCLI.run(import.meta.url, M);',\n '',\n ].join('\\n');\n}\n\nfunction buildImports(calls: ReadonlyArray<OpFactoryCall>, meta: RenderMigrationMeta): string {\n const requirements: ImportRequirement[] = [...BASE_IMPORTS, ...contractImports(meta)];\n for (const call of calls) {\n for (const req of call.importRequirements()) {\n requirements.push(req);\n }\n }\n return renderImports(requirements);\n}\n\n/**\n * The committed contract-JSON imports the scaffold reads its from/to identity\n * from, resolved to the deduplicated snapshot store under\n * `meta.snapshotsImportPath`. The end snapshot is always present; the start\n * snapshot is added only for a non-baseline migration (`meta.from !== null`).\n * The matching `Contract` type imports (aliased `Start`/`End`) feed the\n * `Migration<Start, End>` generics. Baseline emits `Migration<never, End>` with\n * no start imports — `never` is the honest \"no prior contract\" Start.\n */\nfunction contractImports(meta: RenderMigrationMeta): readonly ImportRequirement[] {\n const reqs: ImportRequirement[] = [\n {\n moduleSpecifier: contractSnapshotJsonSpecifier(meta.snapshotsImportPath, meta.to),\n symbol: 'endContract',\n kind: 'default',\n attributes: { type: 'json' },\n },\n {\n moduleSpecifier: contractSnapshotTypesSpecifier(meta.snapshotsImportPath, meta.to),\n symbol: 'Contract',\n alias: 'End',\n typeOnly: true,\n },\n ];\n if (meta.from !== null) {\n reqs.push({\n moduleSpecifier: contractSnapshotJsonSpecifier(meta.snapshotsImportPath, meta.from),\n symbol: 'startContract',\n kind: 'default',\n attributes: { type: 'json' },\n });\n reqs.push({\n moduleSpecifier: contractSnapshotTypesSpecifier(meta.snapshotsImportPath, meta.from),\n symbol: 'Contract',\n alias: 'Start',\n typeOnly: true,\n });\n }\n return reqs;\n}\n\nfunction indent(text: string, spaces: number): string {\n const pad = ' '.repeat(spaces);\n return text\n .split('\\n')\n .map((line) => (line.trim() ? `${pad}${line}` : line))\n .join('\\n');\n}\n","import type { SqlMigrationPlanOperation } from '@prisma-next/family-sql/control';\nimport type { ExecuteRequestLowerer } from '@prisma-next/family-sql/control-adapter';\nimport type {\n MigrationPlanWithAuthoringSurface,\n OpFactoryCall,\n} from '@prisma-next/framework-components/control';\nimport type { MigrationMeta } from '@prisma-next/migration-tools/migration';\nimport type { SqlitePlanTargetDetails } from './planner-target-details';\nimport { renderOps } from './render-ops';\nimport { renderCallsToTypeScript } from './render-typescript';\nimport { SqliteMigration } from './sqlite-migration';\n\ntype Op = SqlMigrationPlanOperation<SqlitePlanTargetDetails>;\n\nexport interface SqliteMigrationDestinationInfo {\n readonly storageHash: string;\n readonly profileHash?: string;\n}\n\nexport class TypeScriptRenderableSqliteMigration\n extends SqliteMigration\n implements MigrationPlanWithAuthoringSurface\n{\n readonly #calls: readonly OpFactoryCall[];\n readonly #meta: MigrationMeta;\n readonly #destination: SqliteMigrationDestinationInfo;\n readonly #spaceId: string;\n readonly #snapshotsImportPath: string;\n readonly #lowerer: ExecuteRequestLowerer | undefined;\n #operationsCache: readonly (Op | Promise<Op>)[] | undefined;\n\n constructor(\n calls: readonly OpFactoryCall[],\n meta: MigrationMeta,\n spaceId: string,\n snapshotsImportPath: string,\n destination?: SqliteMigrationDestinationInfo,\n lowerer?: ExecuteRequestLowerer,\n ) {\n super();\n this.#calls = calls;\n this.#meta = meta;\n this.#spaceId = spaceId;\n this.#snapshotsImportPath = snapshotsImportPath;\n this.#destination = destination ?? { storageHash: meta.to };\n this.#lowerer = lowerer;\n }\n\n override get operations(): readonly (Op | Promise<Op>)[] {\n this.#operationsCache ??= renderOps(this.#calls, this.#lowerer);\n return this.#operationsCache;\n }\n\n override describe(): MigrationMeta {\n return this.#meta;\n }\n\n override get destination(): SqliteMigrationDestinationInfo {\n return this.#destination;\n }\n\n /**\n * Contract space this planner-produced plan applies to. Threaded\n * from {@link SqlMigrationPlannerPlanOptions.spaceId} so the runner\n * keys the marker row by the right space when executing the plan.\n */\n get spaceId(): string {\n return this.#spaceId;\n }\n\n renderTypeScript(): string {\n return renderCallsToTypeScript(this.#calls, {\n from: this.#meta.from,\n to: this.#meta.to,\n snapshotsImportPath: this.#snapshotsImportPath,\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAkCA,MAAM,eAA6C,CACjD;CAAE,iBAAiB;CAAiC,QAAQ;AAAY,GACxE;CAAE,iBAAiB;CAAiC,QAAQ;AAAe,CAC7E;AAEA,SAAgB,wBACd,OACA,MACQ;CACR,MAAM,UAAU,aAAa,OAAO,IAAI;CACxC,MAAM,iBAAiB,MAAM,KAAK,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,KAAK;CACxE,MAAM,WAAW,KAAK,SAAS;CAC/B,MAAM,aAAa,WAAW,CAAC,wDAAwD,IAAI,CAAC;CAE5F,OAAO;EACL,eAAe,sBAAsB,CAAC;EACtC;EACA;EACA,4CAA4C,WAAW,UAAU,QAAQ;EACzE,GAAG;EACH;EACA;EACA;EACA;EACA,OAAO,gBAAgB,CAAC;EACxB;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;AACb;AAEA,SAAS,aAAa,OAAqC,MAAmC;CAC5F,MAAM,eAAoC,CAAC,GAAG,cAAc,GAAG,gBAAgB,IAAI,CAAC;CACpF,KAAK,MAAM,QAAQ,OACjB,KAAK,MAAM,OAAO,KAAK,mBAAmB,GACxC,aAAa,KAAK,GAAG;CAGzB,OAAO,cAAc,YAAY;AACnC;;;;;;;;;;AAWA,SAAS,gBAAgB,MAAyD;CAChF,MAAM,OAA4B,CAChC;EACE,iBAAiB,8BAA8B,KAAK,qBAAqB,KAAK,EAAE;EAChF,QAAQ;EACR,MAAM;EACN,YAAY,EAAE,MAAM,OAAO;CAC7B,GACA;EACE,iBAAiB,+BAA+B,KAAK,qBAAqB,KAAK,EAAE;EACjF,QAAQ;EACR,OAAO;EACP,UAAU;CACZ,CACF;CACA,IAAI,KAAK,SAAS,MAAM;EACtB,KAAK,KAAK;GACR,iBAAiB,8BAA8B,KAAK,qBAAqB,KAAK,IAAI;GAClF,QAAQ;GACR,MAAM;GACN,YAAY,EAAE,MAAM,OAAO;EAC7B,CAAC;EACD,KAAK,KAAK;GACR,iBAAiB,+BAA+B,KAAK,qBAAqB,KAAK,IAAI;GACnF,QAAQ;GACR,OAAO;GACP,UAAU;EACZ,CAAC;CACH;CACA,OAAO;AACT;AAEA,SAAS,OAAO,MAAc,QAAwB;CACpD,MAAM,MAAM,IAAI,OAAO,MAAM;CAC7B,OAAO,KACJ,MAAM,IAAI,CAAC,CACX,KAAK,SAAU,KAAK,KAAK,IAAI,GAAG,MAAM,SAAS,IAAK,CAAC,CACrD,KAAK,IAAI;AACd;;;AC1GA,IAAa,sCAAb,cACU,gBAEV;CACE;CACA;CACA;CACA;CACA;CACA;CACA;CAEA,YACE,OACA,MACA,SACA,qBACA,aACA,SACA;EACA,MAAM;EACN,KAAKA,SAAS;EACd,KAAKC,QAAQ;EACb,KAAKE,WAAW;EAChB,KAAKC,uBAAuB;EAC5B,KAAKF,eAAe,eAAe,EAAE,aAAa,KAAK,GAAG;EAC1D,KAAKG,WAAW;CAClB;CAEA,IAAa,aAA4C;EACvD,KAAKC,qBAAqB,UAAU,KAAKN,QAAQ,KAAKK,QAAQ;EAC9D,OAAO,KAAKC;CACd;CAEA,WAAmC;EACjC,OAAO,KAAKL;CACd;CAEA,IAAa,cAA8C;EACzD,OAAO,KAAKC;CACd;;;;;;CAOA,IAAI,UAAkB;EACpB,OAAO,KAAKC;CACd;CAEA,mBAA2B;EACzB,OAAO,wBAAwB,KAAKH,QAAQ;GAC1C,MAAM,KAAKC,MAAM;GACjB,IAAI,KAAKA,MAAM;GACf,qBAAqB,KAAKG;EAC5B,CAAC;CACH;AACF"}
@@ -1,2 +1,2 @@
1
- import { t as TypeScriptRenderableSqliteMigration } from "./planner-produced-sqlite-migration-CWmvnJi4.mjs";
1
+ import { t as TypeScriptRenderableSqliteMigration } from "./planner-produced-sqlite-migration-BGcreGfL.mjs";
2
2
  export { TypeScriptRenderableSqliteMigration };
package/dist/planner.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { n as createSqliteMigrationPlanner, t as SqliteMigrationPlanner } from "./planner-sc4nqpzL.mjs";
1
+ import { n as createSqliteMigrationPlanner, t as SqliteMigrationPlanner } from "./planner-BY62rsnv.mjs";
2
2
  export { SqliteMigrationPlanner, createSqliteMigrationPlanner };
@@ -1,9 +1,14 @@
1
+ import { n as sqliteError } from "./errors-B1JPoWDh.mjs";
1
2
  import { blindCast } from "@prisma-next/utils/casts";
2
3
  import { isThenable } from "@prisma-next/utils/promise";
3
4
  //#region src/core/migrations/render-ops.ts
4
5
  function assertSqliteOp(op, callFactoryName) {
5
6
  const targetId = blindCast(op).target?.id;
6
- if (targetId !== "sqlite") throw new Error(`renderOps: expected sqlite op but got target.id="${String(targetId)}" for op.id="${op.id}" (factoryName="${callFactoryName}"). An OpFactoryCall produced an op for a different target on the sqlite planner path; check the call's target binding.`);
7
+ if (targetId !== "sqlite") throw sqliteError("MIGRATION.TARGET_MISMATCH", `renderOps: expected sqlite op but got target.id="${String(targetId)}" for op.id="${op.id}" (factoryName="${callFactoryName}"). An OpFactoryCall produced an op for a different target on the sqlite planner path; check the call's target binding.`, { meta: {
8
+ opId: op.id,
9
+ targetId: String(targetId),
10
+ factoryName: callFactoryName
11
+ } });
7
12
  }
8
13
  function renderOps(calls, lowerer) {
9
14
  return calls.map((c) => {
@@ -19,4 +24,4 @@ function renderOps(calls, lowerer) {
19
24
  //#endregion
20
25
  export { renderOps as t };
21
26
 
22
- //# sourceMappingURL=render-ops-BDW2tUeR.mjs.map
27
+ //# sourceMappingURL=render-ops-BAw6MQWl.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-ops-BAw6MQWl.mjs","names":[],"sources":["../src/core/migrations/render-ops.ts"],"sourcesContent":["import type { SqlMigrationPlanOperation } from '@prisma-next/family-sql/control';\nimport type { ExecuteRequestLowerer } from '@prisma-next/family-sql/control-adapter';\nimport type {\n MigrationPlanOperation,\n OpFactoryCall,\n} from '@prisma-next/framework-components/control';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { isThenable } from '@prisma-next/utils/promise';\nimport { sqliteError } from '../errors';\nimport type { SqlitePlanTargetDetails } from './planner-target-details';\n\ntype Op = SqlMigrationPlanOperation<SqlitePlanTargetDetails>;\n\nfunction assertSqliteOp(op: MigrationPlanOperation, callFactoryName: string): asserts op is Op {\n const targetId = blindCast<\n { target?: { id?: string } },\n 'op.target is present on concrete SqlMigrationPlanOperation but absent on the framework MigrationPlanOperation base'\n >(op).target?.id;\n if (targetId !== 'sqlite') {\n throw sqliteError(\n 'MIGRATION.TARGET_MISMATCH',\n `renderOps: expected sqlite op but got target.id=\"${String(targetId)}\" for op.id=\"${op.id}\" (factoryName=\"${callFactoryName}\"). An OpFactoryCall produced an op for a different target on the sqlite planner path; check the call's target binding.`,\n { meta: { opId: op.id, targetId: String(targetId), factoryName: callFactoryName } },\n );\n }\n}\n\nexport function renderOps(\n calls: readonly OpFactoryCall[],\n lowerer?: ExecuteRequestLowerer,\n): (Op | Promise<Op>)[] {\n return calls.map((c) => {\n const opOrPromise = blindCast<\n { toOp(lowerer?: ExecuteRequestLowerer): Op | Promise<Op> },\n 'SQLite OpFactoryCall.toOp accepts an optional ExecuteRequestLowerer; the framework interface omits it because not all targets need a lowerer — the SQLite target overrides with this extended signature'\n >(c).toOp(lowerer);\n if (isThenable(opOrPromise)) {\n return opOrPromise.then((op) => {\n assertSqliteOp(op, c.factoryName);\n return op;\n });\n }\n assertSqliteOp(opOrPromise, c.factoryName);\n return opOrPromise;\n });\n}\n"],"mappings":";;;;AAaA,SAAS,eAAe,IAA4B,iBAA2C;CAC7F,MAAM,WAAW,UAGf,EAAE,CAAC,CAAC,QAAQ;CACd,IAAI,aAAa,UACf,MAAM,YACJ,6BACA,oDAAoD,OAAO,QAAQ,EAAE,eAAe,GAAG,GAAG,kBAAkB,gBAAgB,0HAC5H,EAAE,MAAM;EAAE,MAAM,GAAG;EAAI,UAAU,OAAO,QAAQ;EAAG,aAAa;CAAgB,EAAE,CACpF;AAEJ;AAEA,SAAgB,UACd,OACA,SACsB;CACtB,OAAO,MAAM,KAAK,MAAM;EACtB,MAAM,cAAc,UAGlB,CAAC,CAAC,CAAC,KAAK,OAAO;EACjB,IAAI,WAAW,WAAW,GACxB,OAAO,YAAY,MAAM,OAAO;GAC9B,eAAe,IAAI,EAAE,WAAW;GAChC,OAAO;EACT,CAAC;EAEH,eAAe,aAAa,EAAE,WAAW;EACzC,OAAO;CACT,CAAC;AACH"}
@@ -1 +1 @@
1
- {"version":3,"file":"render-ops.d.mts","names":[],"sources":["../src/core/migrations/render-ops.ts"],"mappings":";;;;;KAUK,KAAK,0BAA0B;iBAcpB,UACd,gBAAgB,iBAChB,UAAU,yBACR,KAAK,QAAQ"}
1
+ {"version":3,"file":"render-ops.d.mts","names":[],"sources":["../src/core/migrations/render-ops.ts"],"mappings":";;;;;KAWK,KAAK,0BAA0B;iBAgBpB,UACd,gBAAgB,iBAChB,UAAU,yBACR,KAAK,QAAQ"}
@@ -1,2 +1,2 @@
1
- import { t as renderOps } from "./render-ops-BDW2tUeR.mjs";
1
+ import { t as renderOps } from "./render-ops-BAw6MQWl.mjs";
2
2
  export { renderOps };
package/dist/runtime.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as sqliteTargetDescriptorMetaRuntime } from "./descriptor-meta-runtime-BkXK3OjD.mjs";
2
- import { n as SqliteContractSerializer, t as SqliteContractView } from "./sqlite-contract-view-B8qeCczc.mjs";
2
+ import { n as SqliteContractSerializer, t as SqliteContractView } from "./sqlite-contract-view-DthhfCpb.mjs";
3
3
  //#region src/core/runtime-target.ts
4
4
  const sqliteRuntimeTargetDescriptor = {
5
5
  ...sqliteTargetDescriptorMetaRuntime,
@@ -1,3 +1,4 @@
1
+ import { n as sqliteError } from "./errors-B1JPoWDh.mjs";
1
2
  //#region src/core/sql-utils.ts
2
3
  /**
3
4
  * Shared SQL utility functions for the SQLite target.
@@ -10,26 +11,25 @@
10
11
  * cyclic workspace dependency that would arise if `target-sqlite` reached
11
12
  * back into `adapter-sqlite` for these primitives.
12
13
  */
13
- var SqlEscapeError = class extends Error {
14
- value;
15
- kind;
16
- constructor(message, value, kind) {
17
- super(message);
18
- this.value = value;
19
- this.kind = kind;
20
- this.name = "SqlEscapeError";
21
- }
22
- };
23
14
  function quoteIdentifier(identifier) {
24
- if (identifier.length === 0) throw new SqlEscapeError("Identifier cannot be empty", identifier, "identifier");
25
- if (identifier.includes("\0")) throw new SqlEscapeError("Identifier cannot contain null bytes", identifier.replace(/\0/g, "\\0"), "identifier");
15
+ if (identifier.length === 0) throw sqliteError("CONTRACT.IDENTIFIER_INVALID", "Identifier cannot be empty", { meta: {
16
+ value: identifier,
17
+ context: "identifier"
18
+ } });
19
+ if (identifier.includes("\0")) throw sqliteError("CONTRACT.IDENTIFIER_INVALID", "Identifier cannot contain null bytes", { meta: {
20
+ value: identifier.replace(/\0/g, "\\0"),
21
+ context: "identifier"
22
+ } });
26
23
  return `"${identifier.replace(/"/g, "\"\"")}"`;
27
24
  }
28
25
  function escapeLiteral(value) {
29
- if (value.includes("\0")) throw new SqlEscapeError("Literal value cannot contain null bytes", value.replace(/\0/g, "\\0"), "literal");
26
+ if (value.includes("\0")) throw sqliteError("CONTRACT.IDENTIFIER_INVALID", "Literal value cannot contain null bytes", { meta: {
27
+ value: value.replace(/\0/g, "\\0"),
28
+ context: "literal"
29
+ } });
30
30
  return value.replace(/'/g, "''");
31
31
  }
32
32
  //#endregion
33
- export { escapeLiteral as n, quoteIdentifier as r, SqlEscapeError as t };
33
+ export { quoteIdentifier as n, escapeLiteral as t };
34
34
 
35
- //# sourceMappingURL=sql-utils-CV8Bdgtc.mjs.map
35
+ //# sourceMappingURL=sql-utils-BMteAbKH.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-utils-BMteAbKH.mjs","names":[],"sources":["../src/core/sql-utils.ts"],"sourcesContent":["/**\n * Shared SQL utility functions for the SQLite target.\n *\n * These functions handle safe SQL identifier and literal escaping. They\n * live in `target-sqlite` (mirroring `target-postgres/src/core/sql-utils.ts`)\n * so both the control adapter (used at emit time) and the runtime adapter\n * (used at execute time) can depend on them through a single one-way edge:\n * `adapter-sqlite → target-sqlite`. Hosting them target-side avoids the\n * cyclic workspace dependency that would arise if `target-sqlite` reached\n * back into `adapter-sqlite` for these primitives.\n */\n\nimport { sqliteError } from './errors';\n\nexport function quoteIdentifier(identifier: string): string {\n if (identifier.length === 0) {\n throw sqliteError('CONTRACT.IDENTIFIER_INVALID', 'Identifier cannot be empty', {\n meta: { value: identifier, context: 'identifier' },\n });\n }\n if (identifier.includes('\\0')) {\n throw sqliteError('CONTRACT.IDENTIFIER_INVALID', 'Identifier cannot contain null bytes', {\n meta: { value: identifier.replace(/\\0/g, '\\\\0'), context: 'identifier' },\n });\n }\n return `\"${identifier.replace(/\"/g, '\"\"')}\"`;\n}\n\nexport function escapeLiteral(value: string): string {\n if (value.includes('\\0')) {\n throw sqliteError('CONTRACT.IDENTIFIER_INVALID', 'Literal value cannot contain null bytes', {\n meta: { value: value.replace(/\\0/g, '\\\\0'), context: 'literal' },\n });\n }\n return value.replace(/'/g, \"''\");\n}\n"],"mappings":";;;;;;;;;;;;;AAcA,SAAgB,gBAAgB,YAA4B;CAC1D,IAAI,WAAW,WAAW,GACxB,MAAM,YAAY,+BAA+B,8BAA8B,EAC7E,MAAM;EAAE,OAAO;EAAY,SAAS;CAAa,EACnD,CAAC;CAEH,IAAI,WAAW,SAAS,IAAI,GAC1B,MAAM,YAAY,+BAA+B,wCAAwC,EACvF,MAAM;EAAE,OAAO,WAAW,QAAQ,OAAO,KAAK;EAAG,SAAS;CAAa,EACzE,CAAC;CAEH,OAAO,IAAI,WAAW,QAAQ,MAAM,MAAI,EAAE;AAC5C;AAEA,SAAgB,cAAc,OAAuB;CACnD,IAAI,MAAM,SAAS,IAAI,GACrB,MAAM,YAAY,+BAA+B,2CAA2C,EAC1F,MAAM;EAAE,OAAO,MAAM,QAAQ,OAAO,KAAK;EAAG,SAAS;CAAU,EACjE,CAAC;CAEH,OAAO,MAAM,QAAQ,MAAM,IAAI;AACjC"}
@@ -10,13 +10,8 @@
10
10
  * cyclic workspace dependency that would arise if `target-sqlite` reached
11
11
  * back into `adapter-sqlite` for these primitives.
12
12
  */
13
- declare class SqlEscapeError extends Error {
14
- readonly value: string;
15
- readonly kind: 'identifier' | 'literal';
16
- constructor(message: string, value: string, kind: 'identifier' | 'literal');
17
- }
18
13
  declare function quoteIdentifier(identifier: string): string;
19
14
  declare function escapeLiteral(value: string): string;
20
15
  //#endregion
21
- export { SqlEscapeError, escapeLiteral, quoteIdentifier };
16
+ export { escapeLiteral, quoteIdentifier };
22
17
  //# sourceMappingURL=sql-utils.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sql-utils.d.mts","names":[],"sources":["../src/core/sql-utils.ts"],"mappings":";;;;;;;;;;;;cAYa,uBAAuB;WAGhB;WACA;cAFhB,iBACgB,eACA;;iBAOJ,gBAAgB;iBAchB,cAAc"}
1
+ {"version":3,"file":"sql-utils.d.mts","names":[],"sources":["../src/core/sql-utils.ts"],"mappings":";;;;;;;;;;;;iBAcgB,gBAAgB;iBAchB,cAAc"}
@@ -1,2 +1,2 @@
1
- import { n as escapeLiteral, r as quoteIdentifier, t as SqlEscapeError } from "./sql-utils-CV8Bdgtc.mjs";
2
- export { SqlEscapeError, escapeLiteral, quoteIdentifier };
1
+ import { n as quoteIdentifier, t as escapeLiteral } from "./sql-utils-BMteAbKH.mjs";
2
+ export { escapeLiteral, quoteIdentifier };
@@ -1,3 +1,4 @@
1
+ import { n as sqliteError } from "./errors-B1JPoWDh.mjs";
1
2
  import { SqlNamespaceBase } from "@prisma-next/sql-contract/types";
2
3
  import { UNBOUND_NAMESPACE_ID, freezeNode, hydrateNamespaceEntities } from "@prisma-next/framework-components/ir";
3
4
  import { blindCast } from "@prisma-next/utils/casts";
@@ -64,7 +65,7 @@ var SqliteUnboundDatabase = class SqliteUnboundDatabase extends SqliteDatabase {
64
65
  }
65
66
  };
66
67
  function buildSqliteNamespace(input) {
67
- if (input.id !== UNBOUND_NAMESPACE_ID) throw new Error(`buildSqliteNamespace: SQLite has no schema concept; the only valid namespace id is "${UNBOUND_NAMESPACE_ID}" (received "${input.id}").`);
68
+ if (input.id !== UNBOUND_NAMESPACE_ID) throw sqliteError("CONTRACT.NAMESPACE_INVALID", `buildSqliteNamespace: SQLite has no schema concept; the only valid namespace id is "${UNBOUND_NAMESPACE_ID}" (received "${input.id}").`, { meta: { received: input.id } });
68
69
  const tableKind = input.entries["table"];
69
70
  const tableCount = tableKind !== void 0 ? Object.keys(tableKind).length : 0;
70
71
  const hasUnknownKinds = Object.keys(input.entries).some((kind) => kind !== "table");
@@ -134,4 +135,4 @@ const SqliteContractView = {
134
135
  //#endregion
135
136
  export { sqliteCreateNamespace as i, SqliteContractSerializer as n, SqliteUnboundDatabase as r, SqliteContractView as t };
136
137
 
137
- //# sourceMappingURL=sqlite-contract-view-B8qeCczc.mjs.map
138
+ //# sourceMappingURL=sqlite-contract-view-DthhfCpb.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-contract-view-DthhfCpb.mjs","names":[],"sources":["../src/core/sqlite-unbound-database.ts","../src/core/sqlite-contract-serializer.ts","../src/core/sqlite-contract-view.ts"],"sourcesContent":["import {\n freezeNode,\n hydrateNamespaceEntities,\n UNBOUND_NAMESPACE_ID,\n} from '@prisma-next/framework-components/ir';\nimport { tableEntityKind } from '@prisma-next/sql-contract/entity-kinds';\nimport {\n SqlNamespaceBase,\n type SqlNamespaceEntries,\n type SqlNamespaceInput,\n type StorageTable,\n} from '@prisma-next/sql-contract/types';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { sqliteError } from './errors';\n\nexport type SqliteDatabaseInput = {\n readonly id: string;\n readonly entries: SqlNamespaceEntries;\n};\n\nconst SQLITE_NAMESPACE_KIND = 'sqlite-namespace' as const;\n\n/**\n * SQLite namespace concretion carrying table metadata under\n * `entries.table` and unqualified `qualifyTable()` emission for runtime\n * SQL rendering.\n */\nexport class SqliteDatabase extends SqlNamespaceBase {\n declare readonly kind: string;\n\n readonly id: string;\n readonly entries: SqlNamespaceEntries;\n\n constructor(input: SqliteDatabaseInput) {\n super();\n this.id = input.id;\n\n const dispatched = hydrateNamespaceEntities(\n input.entries,\n new Map([['table', tableEntityKind]]),\n 'carry',\n );\n\n this.entries = Object.freeze(\n blindCast<\n SqlNamespaceEntries,\n \"SQLite's table-only descriptor map hydrates table→StorageTable and carries every other kind raw, so this open-dict result satisfies SqlNamespaceEntries; the descriptor Map erases the per-kind Node type from the return.\"\n >(dispatched),\n );\n Object.defineProperty(this, 'kind', {\n value: SQLITE_NAMESPACE_KIND,\n writable: false,\n enumerable: false,\n configurable: true,\n });\n freezeNode(this);\n }\n\n get table(): Readonly<Record<string, StorageTable>> {\n return this.entries.table ?? Object.freeze({});\n }\n\n qualifier(): string {\n return '';\n }\n\n qualifyTable(tableName: string): string {\n return `\"${tableName}\"`;\n }\n}\n\n/**\n * SQLite target `Namespace` concretion. SQLite has no schema or\n * database-namespacing concept at the SQL level — there is exactly one\n * effective namespace per connection, so the target ships a single\n * singleton bound to the framework's `UNBOUND_NAMESPACE_ID` slot.\n *\n * Qualifier emission elides the prefix entirely: rendered DDL and\n * queries look unqualified (`CREATE TABLE \"users\" (...)`), matching\n * SQLite's native dialect. Call sites stay polymorphic — they ask the\n * namespace for its qualifier and consume the empty/unqualified result\n * the same way Postgres consumes a `\"schema\"` prefix.\n *\n * The SQLite PSL interpreter rejects every explicit `namespace { … }`\n * block with a diagnostic naming SQLite; only the implicit\n * `__unspecified__` AST bucket reaches the SQLite interpreter, which\n * lowers it to this singleton.\n */\nexport class SqliteUnboundDatabase extends SqliteDatabase {\n static readonly instance: SqliteUnboundDatabase = new SqliteUnboundDatabase();\n\n private constructor() {\n super({ id: UNBOUND_NAMESPACE_ID, entries: { table: {} } });\n }\n}\n\nexport function buildSqliteNamespace(\n input: SqlNamespaceInput,\n): SqliteDatabase | SqliteUnboundDatabase {\n if (input.id !== UNBOUND_NAMESPACE_ID) {\n throw sqliteError(\n 'CONTRACT.NAMESPACE_INVALID',\n `buildSqliteNamespace: SQLite has no schema concept; the only valid namespace id is \"${UNBOUND_NAMESPACE_ID}\" (received \"${input.id}\").`,\n { meta: { received: input.id } },\n );\n }\n const tableKind = input.entries['table'];\n const tableCount = tableKind !== undefined ? Object.keys(tableKind).length : 0;\n const hasUnknownKinds = Object.keys(input.entries).some((kind) => kind !== 'table');\n if (tableCount === 0 && !hasUnknownKinds) {\n return SqliteUnboundDatabase.instance;\n }\n return new SqliteDatabase({ id: input.id, entries: input.entries });\n}\n\n/**\n * Target-supplied `Namespace` factory the SQLite target plumbs through\n * `defineContract({ createNamespace })`. SQLite has only one\n * effective namespace slot — the framework `UNBOUND_NAMESPACE_ID`\n * sentinel — so the factory always returns the singleton or a fresh\n * `SqliteDatabase` for the unbound slot with tables. The SQL family's\n * defensive validation in `defineContract` already rejects\n * user-declared SQLite namespaces, so this throw is a structural\n * safety net rather than a user-facing surface.\n */\nexport function sqliteCreateNamespace(\n input: SqlNamespaceInput,\n): SqliteDatabase | SqliteUnboundDatabase {\n return buildSqliteNamespace(input);\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport { SqlContractSerializerBase } from '@prisma-next/family-sql/ir';\nimport type { Namespace } from '@prisma-next/framework-components/ir';\nimport type { SqlNamespaceInput, SqlStorage } from '@prisma-next/sql-contract/types';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport type { JsonObject } from '@prisma-next/utils/json';\nimport { buildSqliteNamespace } from './sqlite-unbound-database';\n\n/**\n * SQLite target `ContractSerializer` concretion. Mirrors the Postgres\n * shape: inherits the full SQL-family deserialization pipeline and\n * materialises namespace entries as SQLite database concretions that\n * expose `qualifyTable()` for runtime SQL rendering.\n */\nexport class SqliteContractSerializer extends SqlContractSerializerBase<Contract<SqlStorage>> {\n constructor() {\n super(new Map());\n }\n\n protected override hydrateSqlNamespaceEntry(\n nsId: string,\n raw: Record<string, unknown>,\n ): Namespace | SqlNamespaceInput {\n const hydrated = blindCast<\n SqlNamespaceInput,\n 'raw is always plain JSON, so super.hydrateSqlNamespaceEntry returns SqlNamespaceInput'\n >(super.hydrateSqlNamespaceEntry(nsId, raw));\n return buildSqliteNamespace(hydrated);\n }\n\n override serializeContract(contract: Contract<SqlStorage>): JsonObject {\n const { storage, ...rest } = contract;\n const namespacesJson: Record<string, JsonObject> = {};\n for (const [nsId, ns] of Object.entries(storage.namespaces)) {\n namespacesJson[nsId] = {\n id: ns.id,\n entries: this.serializeNamespaceEntries(ns.entries),\n };\n }\n return blindCast<\n JsonObject,\n 'rest + storage are serialized plain values; spread preserves JSON-clean contract envelope'\n >({\n ...rest,\n storage: {\n storageHash: String(storage.storageHash),\n namespaces: namespacesJson,\n ...(storage.types !== undefined ? { types: this.serializeJsonObject(storage.types) } : {}),\n },\n });\n }\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport {\n buildSqlSingleNamespaceView,\n type SqlSingleNamespaceView,\n} from '@prisma-next/sql-contract/contract-view';\nimport type { SqlStorage } from '@prisma-next/sql-contract/types';\nimport { SqliteContractSerializer } from './sqlite-contract-serializer';\n\n/**\n * A SQLite contract view: the deserialized contract intersected with by-name\n * accessors. It is substitutable for `Contract` (carries `storage`, `domain`,\n * …) and also exposes the single default namespace unwrapped with the SQL\n * built-in kinds promoted:\n *\n * ```ts\n * const view = SqliteContractView.fromJson<Contract>(contractJson);\n * view.table.users // typed table leaf\n * view.entries.policy.X // pack-contributed kind (singular key)\n * view.storage // the full contract is still present\n * ```\n *\n * SQLite has `sql.enums: false`, so it never emits `valueSet` entries; the\n * `valueSet` slot is therefore an empty map.\n */\nexport type SqliteContractView<TContract extends Contract<SqlStorage> = Contract<SqlStorage>> =\n SqlSingleNamespaceView<TContract>;\n\nexport const SqliteContractView = {\n /** Wrap an already-deserialized SQLite contract in a view. */\n from<TContract extends Contract<SqlStorage>>(contract: TContract): SqliteContractView<TContract> {\n return buildSqlSingleNamespaceView(contract);\n },\n\n /** Deserialize a SQLite contract JSON envelope and wrap it in a view. */\n fromJson<TContract extends Contract<SqlStorage> = Contract<SqlStorage>>(\n json: unknown,\n ): SqliteContractView<TContract> {\n const contract = new SqliteContractSerializer().deserializeContract<TContract>(json);\n return buildSqlSingleNamespaceView(contract);\n },\n};\n"],"mappings":";;;;;;;;AAoBA,MAAM,wBAAwB;;;;;;AAO9B,IAAa,iBAAb,cAAoC,iBAAiB;CAGnD;CACA;CAEA,YAAY,OAA4B;EACtC,MAAM;EACN,KAAK,KAAK,MAAM;EAEhB,MAAM,aAAa,yBACjB,MAAM,yBACN,IAAI,IAAI,CAAC,CAAC,SAAS,eAAe,CAAC,CAAC,GACpC,OACF;EAEA,KAAK,UAAU,OAAO,OACpB,UAGE,UAAU,CACd;EACA,OAAO,eAAe,MAAM,QAAQ;GAClC,OAAO;GACP,UAAU;GACV,YAAY;GACZ,cAAc;EAChB,CAAC;EACD,WAAW,IAAI;CACjB;CAEA,IAAI,QAAgD;EAClD,OAAO,KAAK,QAAQ,SAAS,OAAO,OAAO,CAAC,CAAC;CAC/C;CAEA,YAAoB;EAClB,OAAO;CACT;CAEA,aAAa,WAA2B;EACtC,OAAO,IAAI,UAAU;CACvB;AACF;;;;;;;;;;;;;;;;;;AAmBA,IAAa,wBAAb,MAAa,8BAA8B,eAAe;CACxD,OAAgB,WAAkC,IAAI,sBAAsB;CAE5E,cAAsB;EACpB,MAAM;GAAE,IAAI;GAAsB,SAAS,EAAE,OAAO,CAAC,EAAE;EAAE,CAAC;CAC5D;AACF;AAEA,SAAgB,qBACd,OACwC;CACxC,IAAI,MAAM,OAAO,sBACf,MAAM,YACJ,8BACA,uFAAuF,qBAAqB,eAAe,MAAM,GAAG,MACpI,EAAE,MAAM,EAAE,UAAU,MAAM,GAAG,EAAE,CACjC;CAEF,MAAM,YAAY,MAAM,QAAQ;CAChC,MAAM,aAAa,cAAc,KAAA,IAAY,OAAO,KAAK,SAAS,CAAC,CAAC,SAAS;CAC7E,MAAM,kBAAkB,OAAO,KAAK,MAAM,OAAO,CAAC,CAAC,MAAM,SAAS,SAAS,OAAO;CAClF,IAAI,eAAe,KAAK,CAAC,iBACvB,OAAO,sBAAsB;CAE/B,OAAO,IAAI,eAAe;EAAE,IAAI,MAAM;EAAI,SAAS,MAAM;CAAQ,CAAC;AACpE;;;;;;;;;;;AAYA,SAAgB,sBACd,OACwC;CACxC,OAAO,qBAAqB,KAAK;AACnC;;;;;;;;;ACnHA,IAAa,2BAAb,cAA8C,0BAAgD;CAC5F,cAAc;EACZ,sBAAM,IAAI,IAAI,CAAC;CACjB;CAEA,yBACE,MACA,KAC+B;EAK/B,OAAO,qBAJU,UAGf,MAAM,yBAAyB,MAAM,GAAG,CACP,CAAC;CACtC;CAEA,kBAA2B,UAA4C;EACrE,MAAM,EAAE,SAAS,GAAG,SAAS;EAC7B,MAAM,iBAA6C,CAAC;EACpD,KAAK,MAAM,CAAC,MAAM,OAAO,OAAO,QAAQ,QAAQ,UAAU,GACxD,eAAe,QAAQ;GACrB,IAAI,GAAG;GACP,SAAS,KAAK,0BAA0B,GAAG,OAAO;EACpD;EAEF,OAAO,UAGL;GACA,GAAG;GACH,SAAS;IACP,aAAa,OAAO,QAAQ,WAAW;IACvC,YAAY;IACZ,GAAI,QAAQ,UAAU,KAAA,IAAY,EAAE,OAAO,KAAK,oBAAoB,QAAQ,KAAK,EAAE,IAAI,CAAC;GAC1F;EACF,CAAC;CACH;AACF;;;ACxBA,MAAa,qBAAqB;;CAEhC,KAA6C,UAAoD;EAC/F,OAAO,4BAA4B,QAAQ;CAC7C;;CAGA,SACE,MAC+B;EAE/B,OAAO,4BADU,IAAI,yBAAyB,CAAC,CAAC,oBAA+B,IACrC,CAAC;CAC7C;AACF"}
@@ -1,39 +1,9 @@
1
- import { a as DropColumnCall, l as RecreateTableCall, n as CreateIndexCall, o as DropIndexCall, r as CreateTableCall, s as DropTableCall, t as AddColumnCall } from "./op-factory-call-8pTnIHhR.mjs";
2
- import { t as SqliteContractView } from "./sqlite-contract-view-B8qeCczc.mjs";
1
+ import { t as errorSqliteMigrationStackMissing } from "./errors-B1JPoWDh.mjs";
2
+ import { a as DropColumnCall, l as RecreateTableCall, n as CreateIndexCall, o as DropIndexCall, r as CreateTableCall, s as DropTableCall, t as AddColumnCall } from "./op-factory-call-BkqsWGiy.mjs";
3
+ import { t as SqliteContractView } from "./sqlite-contract-view-DthhfCpb.mjs";
3
4
  import { blindCast } from "@prisma-next/utils/casts";
4
5
  import { Migration } from "@prisma-next/family-sql/migration";
5
6
  import { MigrationContractViews } from "@prisma-next/migration-tools/migration";
6
- import { CliStructuredError } from "@prisma-next/errors/control";
7
- //#region src/core/errors.ts
8
- /**
9
- * A `SqliteMigration` operation that needs the materialized control adapter
10
- * — named by `operation` (e.g. `createTable`, `dropColumn`, `recreateTable`) —
11
- * was invoked, but the migration was constructed without a `ControlStack`.
12
- * Concrete authoring usage always goes through the migration CLI entrypoint,
13
- * which assembles a stack from the loaded `prisma-next.config.ts`; reaching this
14
- * error means a test fixture or ad-hoc consumer instantiated `SqliteMigration`
15
- * with the no-arg form (legal for `operations` / `describe` introspection only).
16
- *
17
- * The `operation` argument is required so every throw site names the operation
18
- * that actually failed; a new operation cannot inherit a misattributed message.
19
- *
20
- * Distinct from `MIGRATION.UNFILLED_PLACEHOLDER` (placeholder not filled)
21
- * because the missing input is the stack itself, not the per-operation
22
- * contract.
23
- *
24
- * Lives in `@prisma-next/target-sqlite/errors` rather than the shared
25
- * framework migration errors module because the failure is target-specific:
26
- * the contract it talks about (`SqliteMigration`, the SQLite control
27
- * adapter, the SQLite-target stack) only exists in this package.
28
- */
29
- function errorSqliteMigrationStackMissing(operation) {
30
- return new CliStructuredError("MIGRATION.SQLITE_CONTROL_STACK_MISSING", `SqliteMigration.${operation} requires a control adapter`, {
31
- why: `SqliteMigration.${operation} was invoked on an instance constructed without a ControlStack, so the stored controlAdapter is undefined and the operation cannot lower its DDL node.`,
32
- fix: "Construct the migration via the migration CLI entrypoint (which assembles a ControlStack from the loaded prisma-next.config.ts), or pass a ControlStack containing a SQLite adapter to the migration constructor in test fixtures.",
33
- meta: { operation }
34
- });
35
- }
36
- //#endregion
37
7
  //#region src/core/migrations/sqlite-migration.ts
38
8
  /**
39
9
  * Target-owned base class for SQLite migrations. Fixes the `SqlMigration`
@@ -121,4 +91,4 @@ var SqliteMigration = class extends Migration {
121
91
  //#endregion
122
92
  export { SqliteMigration as t };
123
93
 
124
- //# sourceMappingURL=sqlite-migration-CLXPhPxF.mjs.map
94
+ //# sourceMappingURL=sqlite-migration-DrZIdg3i.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-migration-DrZIdg3i.mjs","names":["SqlMigration","#endView","#startView"],"sources":["../src/core/migrations/sqlite-migration.ts"],"sourcesContent":["import type { Contract } from '@prisma-next/contract/types';\nimport type {\n MigrationOperationClass,\n SqlMigrationPlanOperation,\n} from '@prisma-next/family-sql/control';\nimport type { SqlControlAdapter } from '@prisma-next/family-sql/control-adapter';\nimport { Migration as SqlMigration } from '@prisma-next/family-sql/migration';\nimport type { ControlStack } from '@prisma-next/framework-components/control';\nimport { MigrationContractViews } from '@prisma-next/migration-tools/migration';\nimport type { SqlStorage } from '@prisma-next/sql-contract/types';\nimport type { DdlColumn, DdlTableConstraint } from '@prisma-next/sql-relational-core/ast';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { errorSqliteMigrationStackMissing } from '../errors';\nimport { SqliteContractView } from '../sqlite-contract-view';\nimport {\n AddColumnCall,\n CreateIndexCall,\n CreateTableCall,\n DropColumnCall,\n DropIndexCall,\n DropTableCall,\n RecreateTableCall,\n} from './op-factory-call';\nimport type { SqliteColumnSpec, SqliteIndexSpec, SqliteTableSpec } from './operations/shared';\nimport type { SqlitePlanTargetDetails } from './planner-target-details';\n\ntype Op = SqlMigrationPlanOperation<SqlitePlanTargetDetails>;\n\n/**\n * Target-owned base class for SQLite migrations. Fixes the `SqlMigration`\n * generic to `SqlitePlanTargetDetails` and the abstract `targetId` to the\n * SQLite literal, so both user-authored migrations and renderer-generated\n * scaffolds can extend `SqliteMigration` directly without redeclaring\n * target-local identity.\n *\n * The constructor materializes a single SQLite `SqlControlAdapter` from\n * `stack.adapter.create(stack)` and stores it; the protected instance methods\n * forward to the corresponding `*Call` with that stored adapter, so user\n * migrations can write `this.createTable({...})` without threading the adapter\n * through every call.\n *\n * Binds the framework base's `Start` / `End` contract generics so a subclass\n * that assigns its snapshot-store `contract.json` imports to\n * `startContractJson` / `endContractJson` gets fully-typed view accessors:\n * `this.endContract` is a `SqliteContractView<End>`\n * (sole namespace unwrapped to the root — `this.endContract.table.<name>`),\n * built lazily from the JSON fields via the shared `MigrationContractViews`\n * helper. Mirrors `MongoMigration`'s view getters; the framework base derives\n * `describe()` from the same JSON.\n */\nexport abstract class SqliteMigration<\n Start extends Contract<SqlStorage> = Contract<SqlStorage>,\n End extends Contract<SqlStorage> = Contract<SqlStorage>,\n> extends SqlMigration<SqlitePlanTargetDetails, 'sqlite', Start, End> {\n readonly targetId = 'sqlite' as const;\n\n /**\n * Materialized SQLite control adapter, created once per migration\n * instance from the injected stack. `undefined` only when the migration\n * was instantiated without a stack (test fixtures); `controlAdapterFor`\n * throws a MIGRATION.SQLITE_CONTROL_STACK_MISSING in that case to surface the misuse.\n */\n protected readonly controlAdapter: SqlControlAdapter<'sqlite'> | undefined;\n\n #endView = new MigrationContractViews<SqliteContractView<End>>(this, 'SqliteMigration', (json) =>\n SqliteContractView.fromJson<End>(json),\n );\n #startView = new MigrationContractViews<SqliteContractView<Start>>(\n this,\n 'SqliteMigration',\n (json) => SqliteContractView.fromJson<Start>(json),\n );\n\n constructor(stack?: ControlStack<'sql', 'sqlite'>) {\n super(stack);\n this.controlAdapter = stack?.adapter\n ? blindCast<\n SqlControlAdapter<'sqlite'>,\n 'The SQLite descriptor create() returns SqlControlAdapter<sqlite>; typed as wider ControlAdapterInstance at the framework boundary'\n >(stack.adapter.create(stack))\n : undefined;\n }\n\n /**\n * Returns the materialized control adapter, or throws a MIGRATION.SQLITE_CONTROL_STACK_MISSING naming\n * `operation` when the migration was constructed without a `ControlStack`.\n * Single home for the null-check that every DDL/DML method shares.\n */\n private controlAdapterFor(operation: string): SqlControlAdapter<'sqlite'> {\n if (!this.controlAdapter) {\n throw errorSqliteMigrationStackMissing(operation);\n }\n return this.controlAdapter;\n }\n\n /**\n * The typed SQLite view over this migration's end-state contract — sole\n * namespace unwrapped to the root, so `this.endContract.table.<name>` etc.\n * Throws if no `endContractJson` was provided.\n */\n get endContract(): SqliteContractView<End> {\n return this.#endView.endContract;\n }\n\n /**\n * The typed SQLite view over this migration's start-state contract, or\n * `null` for a baseline migration (no `startContractJson`).\n */\n get startContract(): SqliteContractView<Start> | null {\n return this.#startView.startContract;\n }\n\n protected createTable(options: {\n readonly table: string;\n readonly ifNotExists?: boolean;\n readonly columns: readonly DdlColumn[];\n readonly constraints?: readonly DdlTableConstraint[];\n }): Promise<Op> {\n return new CreateTableCall(options.table, options.columns, options.constraints).toOp(\n this.controlAdapterFor('createTable'),\n );\n }\n\n protected dropTable(options: { readonly table: string }): Promise<Op> {\n return new DropTableCall(options.table).toOp(this.controlAdapterFor('dropTable'));\n }\n\n protected addColumn(options: {\n readonly table: string;\n readonly column: SqliteColumnSpec;\n }): Promise<Op> {\n return new AddColumnCall(options.table, options.column).toOp(\n this.controlAdapterFor('addColumn'),\n );\n }\n\n protected dropColumn(options: { readonly table: string; readonly column: string }): Promise<Op> {\n return new DropColumnCall(options.table, options.column).toOp(\n this.controlAdapterFor('dropColumn'),\n );\n }\n\n protected createIndex(options: {\n readonly table: string;\n readonly index: string;\n readonly columns: readonly string[];\n }): Promise<Op> {\n return new CreateIndexCall(options.table, options.index, options.columns).toOp(\n this.controlAdapterFor('createIndex'),\n );\n }\n\n protected dropIndex(options: { readonly table: string; readonly index: string }): Promise<Op> {\n return new DropIndexCall(options.table, options.index).toOp(\n this.controlAdapterFor('dropIndex'),\n );\n }\n\n protected recreateTable(options: {\n readonly tableName: string;\n readonly contractTable: SqliteTableSpec;\n readonly schemaColumnNames: readonly string[];\n readonly indexes: readonly SqliteIndexSpec[];\n readonly summary: string;\n readonly postchecks: readonly { readonly description: string; readonly sql: string }[];\n readonly operationClass: MigrationOperationClass;\n }): Promise<Op> {\n return new RecreateTableCall(options).toOp(this.controlAdapterFor('recreateTable'));\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDA,IAAsB,kBAAtB,cAGUA,UAA4D;CACpE,WAAoB;;;;;;;CAQpB;CAEA,WAAW,IAAI,uBAAgD,MAAM,oBAAoB,SACvF,mBAAmB,SAAc,IAAI,CACvC;CACA,aAAa,IAAI,uBACf,MACA,oBACC,SAAS,mBAAmB,SAAgB,IAAI,CACnD;CAEA,YAAY,OAAuC;EACjD,MAAM,KAAK;EACX,KAAK,iBAAiB,OAAO,UACzB,UAGE,MAAM,QAAQ,OAAO,KAAK,CAAC,IAC7B,KAAA;CACN;;;;;;CAOA,kBAA0B,WAAgD;EACxE,IAAI,CAAC,KAAK,gBACR,MAAM,iCAAiC,SAAS;EAElD,OAAO,KAAK;CACd;;;;;;CAOA,IAAI,cAAuC;EACzC,OAAO,KAAKC,SAAS;CACvB;;;;;CAMA,IAAI,gBAAkD;EACpD,OAAO,KAAKC,WAAW;CACzB;CAEA,YAAsB,SAKN;EACd,OAAO,IAAI,gBAAgB,QAAQ,OAAO,QAAQ,SAAS,QAAQ,WAAW,CAAC,CAAC,KAC9E,KAAK,kBAAkB,aAAa,CACtC;CACF;CAEA,UAAoB,SAAkD;EACpE,OAAO,IAAI,cAAc,QAAQ,KAAK,CAAC,CAAC,KAAK,KAAK,kBAAkB,WAAW,CAAC;CAClF;CAEA,UAAoB,SAGJ;EACd,OAAO,IAAI,cAAc,QAAQ,OAAO,QAAQ,MAAM,CAAC,CAAC,KACtD,KAAK,kBAAkB,WAAW,CACpC;CACF;CAEA,WAAqB,SAA2E;EAC9F,OAAO,IAAI,eAAe,QAAQ,OAAO,QAAQ,MAAM,CAAC,CAAC,KACvD,KAAK,kBAAkB,YAAY,CACrC;CACF;CAEA,YAAsB,SAIN;EACd,OAAO,IAAI,gBAAgB,QAAQ,OAAO,QAAQ,OAAO,QAAQ,OAAO,CAAC,CAAC,KACxE,KAAK,kBAAkB,aAAa,CACtC;CACF;CAEA,UAAoB,SAA0E;EAC5F,OAAO,IAAI,cAAc,QAAQ,OAAO,QAAQ,KAAK,CAAC,CAAC,KACrD,KAAK,kBAAkB,WAAW,CACpC;CACF;CAEA,cAAwB,SAQR;EACd,OAAO,IAAI,kBAAkB,OAAO,CAAC,CAAC,KAAK,KAAK,kBAAkB,eAAe,CAAC;CACpF;AACF"}
package/package.json CHANGED
@@ -1,30 +1,30 @@
1
1
  {
2
2
  "name": "@prisma-next/target-sqlite",
3
- "version": "0.16.0-dev.22",
3
+ "version": "0.16.0-dev.24",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "dependencies": {
8
- "@prisma-next/cli": "0.16.0-dev.22",
9
- "@prisma-next/contract": "0.16.0-dev.22",
10
- "@prisma-next/errors": "0.16.0-dev.22",
11
- "@prisma-next/family-sql": "0.16.0-dev.22",
12
- "@prisma-next/framework-components": "0.16.0-dev.22",
13
- "@prisma-next/migration-tools": "0.16.0-dev.22",
14
- "@prisma-next/sql-contract": "0.16.0-dev.22",
15
- "@prisma-next/sql-errors": "0.16.0-dev.22",
16
- "@prisma-next/sql-relational-core": "0.16.0-dev.22",
17
- "@prisma-next/sql-runtime": "0.16.0-dev.22",
18
- "@prisma-next/sql-schema-ir": "0.16.0-dev.22",
19
- "@prisma-next/ts-render": "0.16.0-dev.22",
20
- "@prisma-next/utils": "0.16.0-dev.22",
8
+ "@prisma-next/cli": "0.16.0-dev.24",
9
+ "@prisma-next/contract": "0.16.0-dev.24",
10
+ "@prisma-next/errors": "0.16.0-dev.24",
11
+ "@prisma-next/family-sql": "0.16.0-dev.24",
12
+ "@prisma-next/framework-components": "0.16.0-dev.24",
13
+ "@prisma-next/migration-tools": "0.16.0-dev.24",
14
+ "@prisma-next/sql-contract": "0.16.0-dev.24",
15
+ "@prisma-next/sql-errors": "0.16.0-dev.24",
16
+ "@prisma-next/sql-relational-core": "0.16.0-dev.24",
17
+ "@prisma-next/sql-runtime": "0.16.0-dev.24",
18
+ "@prisma-next/sql-schema-ir": "0.16.0-dev.24",
19
+ "@prisma-next/ts-render": "0.16.0-dev.24",
20
+ "@prisma-next/utils": "0.16.0-dev.24",
21
21
  "@standard-schema/spec": "1.1.0"
22
22
  },
23
23
  "devDependencies": {
24
- "@prisma-next/driver-sqlite": "0.16.0-dev.22",
25
- "@prisma-next/test-utils": "0.16.0-dev.22",
26
- "@prisma-next/tsconfig": "0.16.0-dev.22",
27
- "@prisma-next/tsdown": "0.16.0-dev.22",
24
+ "@prisma-next/driver-sqlite": "0.16.0-dev.24",
25
+ "@prisma-next/test-utils": "0.16.0-dev.24",
26
+ "@prisma-next/tsconfig": "0.16.0-dev.24",
27
+ "@prisma-next/tsdown": "0.16.0-dev.24",
28
28
  "tsdown": "0.22.8",
29
29
  "typescript": "5.9.3",
30
30
  "vitest": "4.1.10"
@@ -38,6 +38,7 @@ import {
38
38
  SQLITE_REAL_CODEC_ID,
39
39
  SQLITE_TEXT_CODEC_ID,
40
40
  } from './codec-ids';
41
+ import { sqliteError } from './errors';
41
42
 
42
43
  export class SqliteTextCodec extends CodecImpl<
43
44
  typeof SQLITE_TEXT_CODEC_ID,
@@ -170,7 +171,13 @@ export class SqliteBlobCodec extends CodecImpl<
170
171
  }
171
172
  decodeJson(json: JsonValue): Uint8Array {
172
173
  if (typeof json !== 'string') {
173
- throw new TypeError('sqlite/blob@1 contract value must be a base64 string');
174
+ throw sqliteError(
175
+ 'RUNTIME.DECODE_FAILED',
176
+ 'sqlite/blob@1 contract value must be a base64 string',
177
+ {
178
+ meta: { codecId: SQLITE_BLOB_CODEC_ID, received: typeof json },
179
+ },
180
+ );
174
181
  }
175
182
  return new Uint8Array(Buffer.from(json, 'base64'));
176
183
  }
@@ -204,7 +211,11 @@ export class SqliteDatetimeCodec extends CodecImpl<
204
211
  private parseDate(value: string): Date {
205
212
  const date = new Date(value);
206
213
  if (Number.isNaN(date.getTime())) {
207
- throw new TypeError(`sqlite/datetime@1 value must be a valid ISO-8601 string: ${value}`);
214
+ throw sqliteError(
215
+ 'RUNTIME.DECODE_FAILED',
216
+ `sqlite/datetime@1 value must be a valid ISO-8601 string: ${value}`,
217
+ { meta: { codecId: SQLITE_DATETIME_CODEC_ID, received: value } },
218
+ );
208
219
  }
209
220
  return date;
210
221
  }
@@ -219,7 +230,11 @@ export class SqliteDatetimeCodec extends CodecImpl<
219
230
  }
220
231
  decodeJson(json: JsonValue): Date {
221
232
  if (typeof json !== 'string') {
222
- throw new TypeError('sqlite/datetime@1 contract value must be an ISO-8601 string');
233
+ throw sqliteError(
234
+ 'RUNTIME.DECODE_FAILED',
235
+ 'sqlite/datetime@1 contract value must be an ISO-8601 string',
236
+ { meta: { codecId: SQLITE_DATETIME_CODEC_ID, received: typeof json } },
237
+ );
223
238
  }
224
239
  return this.parseDate(json);
225
240
  }
@@ -296,16 +311,28 @@ export class SqliteBigintCodec extends CodecImpl<
296
311
  encodeJson(value: bigint): JsonValue {
297
312
  const number = Number(value);
298
313
  if (!Number.isSafeInteger(number)) {
299
- throw new TypeError('sqlite/bigint@1 database JSON value must be a safe integer');
314
+ throw sqliteError(
315
+ 'RUNTIME.ENCODE_FAILED',
316
+ 'sqlite/bigint@1 database JSON value must be a safe integer',
317
+ { meta: { codecId: SQLITE_BIGINT_CODEC_ID, received: String(value) } },
318
+ );
300
319
  }
301
320
  return number;
302
321
  }
303
322
  decodeJson(json: JsonValue): bigint {
304
323
  if (typeof json !== 'number') {
305
- throw new TypeError('sqlite/bigint@1 database JSON value must be a number');
324
+ throw sqliteError(
325
+ 'RUNTIME.DECODE_FAILED',
326
+ 'sqlite/bigint@1 database JSON value must be a number',
327
+ { meta: { codecId: SQLITE_BIGINT_CODEC_ID, received: typeof json } },
328
+ );
306
329
  }
307
330
  if (!Number.isSafeInteger(json)) {
308
- throw new TypeError('sqlite/bigint@1 database JSON value must be a safe integer');
331
+ throw sqliteError(
332
+ 'RUNTIME.DECODE_FAILED',
333
+ 'sqlite/bigint@1 database JSON value must be a safe integer',
334
+ { meta: { codecId: SQLITE_BIGINT_CODEC_ID, received: json } },
335
+ );
309
336
  }
310
337
  return BigInt(json);
311
338
  }
@@ -12,6 +12,7 @@ import {
12
12
  relationalNodeGranularity,
13
13
  } from '@prisma-next/sql-schema-ir/types';
14
14
  import { sqliteTargetDescriptorMeta } from './descriptor-meta';
15
+ import { sqliteError } from './errors';
15
16
  import { diffSqliteSchema, sqliteContractToSchema } from './migrations/diff-database-schema';
16
17
  import { createSqliteMigrationPlanner } from './migrations/planner';
17
18
  import type { SqlitePlanTargetDetails } from './migrations/planner-target-details';
@@ -49,7 +50,8 @@ const sqliteControlTargetDescriptor: SqlControlTargetDescriptor<'sqlite', Sqlite
49
50
  // encodes that invariant at runtime + narrows the generic
50
51
  // to `Contract<SqlStorage>` without a blind cast.
51
52
  if (!isSqlContract(contract)) {
52
- throw new Error(
53
+ throw sqliteError(
54
+ 'CONTRACT.TARGET_MISMATCH',
53
55
  'sqliteControlTargetDescriptor.contractToSchema received a non-SQL contract; expected Contract<SqlStorage>',
54
56
  );
55
57
  }
@@ -1,4 +1,28 @@
1
1
  import { CliStructuredError } from '@prisma-next/errors/control';
2
+ import type { StructuredError, StructuredErrorOptions } from '@prisma-next/utils/structured-error';
3
+ import { structuredError } from '@prisma-next/utils/structured-error';
4
+
5
+ export type SqliteTargetErrorCode =
6
+ | 'CONTRACT.CONSTRAINT_INVALID'
7
+ | 'CONTRACT.DEFAULT_INVALID'
8
+ | 'CONTRACT.IDENTIFIER_INVALID'
9
+ | 'CONTRACT.NAMESPACE_INVALID'
10
+ | 'CONTRACT.NATIVE_TYPE_INVALID'
11
+ | 'CONTRACT.TARGET_MISMATCH'
12
+ | 'CONTRACT.TYPE_UNKNOWN'
13
+ | 'MIGRATION.CONTRACT_SPACE_VIOLATION'
14
+ | 'MIGRATION.SQLITE_CONTROL_STACK_MISSING'
15
+ | 'MIGRATION.TARGET_MISMATCH'
16
+ | 'RUNTIME.DECODE_FAILED'
17
+ | 'RUNTIME.ENCODE_FAILED';
18
+
19
+ export function sqliteError(
20
+ code: SqliteTargetErrorCode,
21
+ message: string,
22
+ options?: StructuredErrorOptions,
23
+ ): StructuredError {
24
+ return structuredError(code, message, options);
25
+ }
2
26
 
3
27
  /**
4
28
  * A `SqliteMigration` operation that needs the materialized control adapter
@@ -10,6 +10,7 @@ import {
10
10
  } from '@prisma-next/sql-relational-core/ast';
11
11
  import type { SqlColumnIR, SqlTableIR } from '@prisma-next/sql-schema-ir/types';
12
12
  import { blindCast } from '@prisma-next/utils/casts';
13
+ import { assertNever, InternalError } from '@prisma-next/utils/internal-error';
13
14
  import type { SqliteColumnSpec } from './operations/shared';
14
15
  import { buildColumnDefaultSql, buildColumnTypeSql } from './planner-ddl-builders';
15
16
 
@@ -28,7 +29,7 @@ function columnLike(
28
29
  column: SqlColumnIR,
29
30
  ): Pick<StorageColumn, 'nativeType' | 'codecId' | 'nullable' | 'many' | 'typeParams' | 'default'> {
30
31
  if (column.codecRef === undefined || column.codecBaseNativeType === undefined) {
31
- throw new Error(
32
+ throw new InternalError(
32
33
  `columnLike: expected column "${column.name}" carries no codec identity — the expected tree must be derived via contractToSchemaIR for planning`,
33
34
  );
34
35
  }
@@ -69,7 +70,8 @@ function sqliteDefaultToDdlColumnDefault(
69
70
  return new FunctionColumnDefault(columnDefault.expression);
70
71
  default: {
71
72
  const exhaustive: never = columnDefault;
72
- throw new Error(
73
+ return assertNever(
74
+ exhaustive,
73
75
  `sqliteDefaultToDdlColumnDefault: unhandled kind "${blindCast<{ kind: string }, 'exhaustiveness: surface the unhandled default kind'>(exhaustive).kind}"`,
74
76
  );
75
77
  }