@prisma-next/target-sqlite 0.15.0-dev.3 → 0.15.0-dev.5
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.
- package/dist/control.mjs +1 -1
- package/dist/migration.mjs +2 -2
- package/dist/{op-factory-call-CAAyaPyg.mjs → op-factory-call-BlMqc5G_.mjs} +4 -3
- package/dist/op-factory-call-BlMqc5G_.mjs.map +1 -0
- package/dist/op-factory-call.mjs +1 -1
- package/dist/{planner-DNvbcExu.mjs → planner-CxbLEZHF.mjs} +17 -56
- package/dist/planner-CxbLEZHF.mjs.map +1 -0
- package/dist/{planner-produced-sqlite-migration-DhAaGkSM.mjs → planner-produced-sqlite-migration-D5415zDp.mjs} +2 -2
- package/dist/{planner-produced-sqlite-migration-DhAaGkSM.mjs.map → planner-produced-sqlite-migration-D5415zDp.mjs.map} +1 -1
- package/dist/planner-produced-sqlite-migration.mjs +1 -1
- package/dist/planner.d.mts.map +1 -1
- package/dist/planner.mjs +1 -1
- package/dist/{sqlite-migration-DQq045KG.mjs → sqlite-migration-WdRHavfF.mjs} +2 -2
- package/dist/{sqlite-migration-DQq045KG.mjs.map → sqlite-migration-WdRHavfF.mjs.map} +1 -1
- package/package.json +18 -18
- package/src/core/migrations/issue-planner.ts +16 -59
- package/src/core/migrations/operations/tables.ts +3 -2
- package/src/core/migrations/planner-strategies.ts +4 -3
- package/src/core/migrations/planner.ts +3 -2
- package/dist/op-factory-call-CAAyaPyg.mjs.map +0 -1
- package/dist/planner-DNvbcExu.mjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as renderOps } from "./render-ops-BDW2tUeR.mjs";
|
|
2
|
-
import { t as SqliteMigration } from "./sqlite-migration-
|
|
2
|
+
import { t as SqliteMigration } from "./sqlite-migration-WdRHavfF.mjs";
|
|
3
3
|
import { renderImports } from "@prisma-next/ts-render";
|
|
4
4
|
import { detectScaffoldRuntime, shebangLineFor } from "@prisma-next/migration-tools/migration-ts";
|
|
5
5
|
//#region src/core/migrations/render-typescript.ts
|
|
@@ -137,4 +137,4 @@ var TypeScriptRenderableSqliteMigration = class extends SqliteMigration {
|
|
|
137
137
|
//#endregion
|
|
138
138
|
export { TypeScriptRenderableSqliteMigration as t };
|
|
139
139
|
|
|
140
|
-
//# sourceMappingURL=planner-produced-sqlite-migration-
|
|
140
|
+
//# sourceMappingURL=planner-produced-sqlite-migration-D5415zDp.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planner-produced-sqlite-migration-
|
|
1
|
+
{"version":3,"file":"planner-produced-sqlite-migration-D5415zDp.mjs","names":["#calls","#meta","#destination","#spaceId","#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 type { OpFactoryCall } 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}\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. `end-contract.json` is always present; `start-contract.json` is added\n * only for a non-baseline migration (`meta.from !== null`). The matching\n * `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: './end-contract.json',\n symbol: 'endContract',\n kind: 'default',\n attributes: { type: 'json' },\n },\n { moduleSpecifier: './end-contract', symbol: 'Contract', alias: 'End', typeOnly: true },\n ];\n if (meta.from !== null) {\n reqs.push({\n moduleSpecifier: './start-contract.json',\n symbol: 'startContract',\n kind: 'default',\n attributes: { type: 'json' },\n });\n reqs.push({\n moduleSpecifier: './start-contract',\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 #lowerer: ExecuteRequestLowerer | undefined;\n #operationsCache: readonly (Op | Promise<Op>)[] | undefined;\n\n constructor(\n calls: readonly OpFactoryCall[],\n meta: MigrationMeta,\n spaceId: string,\n destination?: SqliteMigrationDestinationInfo,\n lowerer?: ExecuteRequestLowerer,\n ) {\n super();\n this.#calls = calls;\n this.#meta = meta;\n this.#spaceId = spaceId;\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 });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AA4BA,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;;;;;;;;;AAUA,SAAS,gBAAgB,MAAyD;CAChF,MAAM,OAA4B,CAChC;EACE,iBAAiB;EACjB,QAAQ;EACR,MAAM;EACN,YAAY,EAAE,MAAM,OAAO;CAC7B,GACA;EAAE,iBAAiB;EAAkB,QAAQ;EAAY,OAAO;EAAO,UAAU;CAAK,CACxF;CACA,IAAI,KAAK,SAAS,MAAM;EACtB,KAAK,KAAK;GACR,iBAAiB;GACjB,QAAQ;GACR,MAAM;GACN,YAAY,EAAE,MAAM,OAAO;EAC7B,CAAC;EACD,KAAK,KAAK;GACR,iBAAiB;GACjB,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;;;AC9FA,IAAa,sCAAb,cACU,gBAEV;CACE;CACA;CACA;CACA;CACA;CACA;CAEA,YACE,OACA,MACA,SACA,aACA,SACA;EACA,MAAM;EACN,KAAKA,SAAS;EACd,KAAKC,QAAQ;EACb,KAAKE,WAAW;EAChB,KAAKD,eAAe,eAAe,EAAE,aAAa,KAAK,GAAG;EAC1D,KAAKE,WAAW;CAClB;CAEA,IAAa,aAA4C;EACvD,KAAKC,qBAAqB,UAAU,KAAKL,QAAQ,KAAKI,QAAQ;EAC9D,OAAO,KAAKC;CACd;CAEA,WAAmC;EACjC,OAAO,KAAKJ;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;EACjB,CAAC;CACH;AACF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as TypeScriptRenderableSqliteMigration } from "./planner-produced-sqlite-migration-
|
|
1
|
+
import { t as TypeScriptRenderableSqliteMigration } from "./planner-produced-sqlite-migration-D5415zDp.mjs";
|
|
2
2
|
export { TypeScriptRenderableSqliteMigration };
|
package/dist/planner.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planner.d.mts","names":[],"sources":["../src/core/migrations/planner.ts"],"mappings":";;;;;;;;;
|
|
1
|
+
{"version":3,"file":"planner.d.mts","names":[],"sources":["../src/core/migrations/planner.ts"],"mappings":";;;;;;;;;iBAgCgB,4BAAA,CACd,OAAA,EAAS,qBAAA,GACR,sBAAsB;AAAA,KAIb,gBAAA;EAAA,SACG,IAAA;EAAA,SAA0B,IAAA,EAAM,mCAAA;AAAA,IAC3C,uBAAuB;;;;;;AANF;AAIzB;;;;;;;;;AAE2B;cAkBd,sBAAA,YACA,mBAAA,CAAoB,uBAAA,GAA0B,gBAAA;EAAA;cAI7C,OAAA,EAAS,qBAAA;EAIrB,IAAA,CAAK,OAAA;IAAA,SACM,QAAA;IAAA,SACA,MAAA;IAAA,SACA,MAAA,EAAQ,wBAAA;IAY2B;;;;;;;;;;IAAA,SADnC,YAAA,EAAc,QAAA;IAAA,SACd,mBAAA,EAAqB,aAAA,CAAc,8BAAA;IAvBW;;;;;IAAA,SA6B9C,OAAA;IApBA;;;;IAAA,SAyBA,SAAA,GAAY,eAAA;EAAA,IACnB,gBAAA;EAIJ,cAAA,CACE,OAAA,EAAS,wBAAA,EACT,OAAA,WACC,mCAAA;EAAA,QAaK,OAAA;EAAA,QA0DA,oBAAA;EApFG;;;;;;;;;;;;;;AA8HgB;;;;;;;;;;;;;;;EA9HhB,QA8HH,mBAAA;AAAA"}
|
package/dist/planner.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as createSqliteMigrationPlanner, t as SqliteMigrationPlanner } from "./planner-
|
|
1
|
+
import { n as createSqliteMigrationPlanner, t as SqliteMigrationPlanner } from "./planner-CxbLEZHF.mjs";
|
|
2
2
|
export { SqliteMigrationPlanner, createSqliteMigrationPlanner };
|
|
@@ -1,4 +1,4 @@
|
|
|
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-
|
|
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-BlMqc5G_.mjs";
|
|
2
2
|
import { t as SqliteContractView } from "./sqlite-contract-view-B8qeCczc.mjs";
|
|
3
3
|
import { blindCast } from "@prisma-next/utils/casts";
|
|
4
4
|
import { Migration } from "@prisma-next/family-sql/migration";
|
|
@@ -120,4 +120,4 @@ var SqliteMigration = class extends Migration {
|
|
|
120
120
|
//#endregion
|
|
121
121
|
export { SqliteMigration as t };
|
|
122
122
|
|
|
123
|
-
//# sourceMappingURL=sqlite-migration-
|
|
123
|
+
//# sourceMappingURL=sqlite-migration-WdRHavfF.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite-migration-DQq045KG.mjs","names":["SqlMigration","#endView","#startView"],"sources":["../src/core/errors.ts","../src/core/migrations/sqlite-migration.ts"],"sourcesContent":["import { CliStructuredError } from '@prisma-next/errors/control';\n\n/**\n * A `SqliteMigration` operation that needs the materialized control adapter\n * — named by `operation` (e.g. `createTable`, `dropColumn`, `recreateTable`) —\n * was invoked, but the migration was constructed without a `ControlStack`.\n * Concrete authoring usage always goes through the migration CLI entrypoint,\n * which assembles a stack from the loaded `prisma-next.config.ts`; reaching this\n * error means a test fixture or ad-hoc consumer instantiated `SqliteMigration`\n * with the no-arg form (legal for `operations` / `describe` introspection only).\n *\n * The `operation` argument is required so every throw site names the operation\n * that actually failed; a new operation cannot inherit a misattributed message.\n *\n * Distinct from `PN-MIG-2001` (placeholder not filled) because the missing\n * input is the stack itself, not the per-operation contract.\n *\n * Lives in `@prisma-next/target-sqlite/errors` rather than the shared\n * framework migration errors module because the failure is target-specific:\n * the contract it talks about (`SqliteMigration`, the SQLite control\n * adapter, the SQLite-target stack) only exists in this package.\n */\nexport function errorSqliteMigrationStackMissing(operation: string): CliStructuredError {\n return new CliStructuredError('2008', `SqliteMigration.${operation} requires a control adapter`, {\n domain: 'MIG',\n 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.`,\n 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.',\n meta: { operation },\n });\n}\n","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 `start-contract.json` / `end-contract.json` imports gets\n * fully-typed view accessors: `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 PN-MIG-2008 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 PN-MIG-2008 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":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,iCAAiC,WAAuC;CACtF,OAAO,IAAI,mBAAmB,QAAQ,mBAAmB,UAAU,8BAA8B;EAC/F,QAAQ;EACR,KAAK,mBAAmB,UAAU;EAClC,KAAK;EACL,MAAM,EAAE,UAAU;CACpB,CAAC;AACH;;;;;;;;;;;;;;;;;;;;;;;;ACoBA,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"}
|
|
1
|
+
{"version":3,"file":"sqlite-migration-WdRHavfF.mjs","names":["SqlMigration","#endView","#startView"],"sources":["../src/core/errors.ts","../src/core/migrations/sqlite-migration.ts"],"sourcesContent":["import { CliStructuredError } from '@prisma-next/errors/control';\n\n/**\n * A `SqliteMigration` operation that needs the materialized control adapter\n * — named by `operation` (e.g. `createTable`, `dropColumn`, `recreateTable`) —\n * was invoked, but the migration was constructed without a `ControlStack`.\n * Concrete authoring usage always goes through the migration CLI entrypoint,\n * which assembles a stack from the loaded `prisma-next.config.ts`; reaching this\n * error means a test fixture or ad-hoc consumer instantiated `SqliteMigration`\n * with the no-arg form (legal for `operations` / `describe` introspection only).\n *\n * The `operation` argument is required so every throw site names the operation\n * that actually failed; a new operation cannot inherit a misattributed message.\n *\n * Distinct from `PN-MIG-2001` (placeholder not filled) because the missing\n * input is the stack itself, not the per-operation contract.\n *\n * Lives in `@prisma-next/target-sqlite/errors` rather than the shared\n * framework migration errors module because the failure is target-specific:\n * the contract it talks about (`SqliteMigration`, the SQLite control\n * adapter, the SQLite-target stack) only exists in this package.\n */\nexport function errorSqliteMigrationStackMissing(operation: string): CliStructuredError {\n return new CliStructuredError('2008', `SqliteMigration.${operation} requires a control adapter`, {\n domain: 'MIG',\n 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.`,\n 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.',\n meta: { operation },\n });\n}\n","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 `start-contract.json` / `end-contract.json` imports gets\n * fully-typed view accessors: `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 PN-MIG-2008 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 PN-MIG-2008 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":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,iCAAiC,WAAuC;CACtF,OAAO,IAAI,mBAAmB,QAAQ,mBAAmB,UAAU,8BAA8B;EAC/F,QAAQ;EACR,KAAK,mBAAmB,UAAU;EAClC,KAAK;EACL,MAAM,EAAE,UAAU;CACpB,CAAC;AACH;;;;;;;;;;;;;;;;;;;;;;;;ACoBA,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.15.0-dev.
|
|
3
|
+
"version": "0.15.0-dev.5",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@prisma-next/cli": "0.15.0-dev.
|
|
9
|
-
"@prisma-next/contract": "0.15.0-dev.
|
|
10
|
-
"@prisma-next/errors": "0.15.0-dev.
|
|
11
|
-
"@prisma-next/family-sql": "0.15.0-dev.
|
|
12
|
-
"@prisma-next/framework-components": "0.15.0-dev.
|
|
13
|
-
"@prisma-next/migration-tools": "0.15.0-dev.
|
|
14
|
-
"@prisma-next/sql-contract": "0.15.0-dev.
|
|
15
|
-
"@prisma-next/sql-errors": "0.15.0-dev.
|
|
16
|
-
"@prisma-next/sql-relational-core": "0.15.0-dev.
|
|
17
|
-
"@prisma-next/sql-runtime": "0.15.0-dev.
|
|
18
|
-
"@prisma-next/sql-schema-ir": "0.15.0-dev.
|
|
19
|
-
"@prisma-next/ts-render": "0.15.0-dev.
|
|
20
|
-
"@prisma-next/utils": "0.15.0-dev.
|
|
8
|
+
"@prisma-next/cli": "0.15.0-dev.5",
|
|
9
|
+
"@prisma-next/contract": "0.15.0-dev.5",
|
|
10
|
+
"@prisma-next/errors": "0.15.0-dev.5",
|
|
11
|
+
"@prisma-next/family-sql": "0.15.0-dev.5",
|
|
12
|
+
"@prisma-next/framework-components": "0.15.0-dev.5",
|
|
13
|
+
"@prisma-next/migration-tools": "0.15.0-dev.5",
|
|
14
|
+
"@prisma-next/sql-contract": "0.15.0-dev.5",
|
|
15
|
+
"@prisma-next/sql-errors": "0.15.0-dev.5",
|
|
16
|
+
"@prisma-next/sql-relational-core": "0.15.0-dev.5",
|
|
17
|
+
"@prisma-next/sql-runtime": "0.15.0-dev.5",
|
|
18
|
+
"@prisma-next/sql-schema-ir": "0.15.0-dev.5",
|
|
19
|
+
"@prisma-next/ts-render": "0.15.0-dev.5",
|
|
20
|
+
"@prisma-next/utils": "0.15.0-dev.5",
|
|
21
21
|
"@standard-schema/spec": "1.1.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@prisma-next/driver-sqlite": "0.15.0-dev.
|
|
25
|
-
"@prisma-next/test-utils": "0.15.0-dev.
|
|
26
|
-
"@prisma-next/tsconfig": "0.15.0-dev.
|
|
27
|
-
"@prisma-next/tsdown": "0.15.0-dev.
|
|
24
|
+
"@prisma-next/driver-sqlite": "0.15.0-dev.5",
|
|
25
|
+
"@prisma-next/test-utils": "0.15.0-dev.5",
|
|
26
|
+
"@prisma-next/tsconfig": "0.15.0-dev.5",
|
|
27
|
+
"@prisma-next/tsdown": "0.15.0-dev.5",
|
|
28
28
|
"tsdown": "0.22.3",
|
|
29
29
|
"typescript": "5.9.3",
|
|
30
30
|
"vitest": "4.1.10"
|
|
@@ -21,6 +21,7 @@ import type {
|
|
|
21
21
|
} from '@prisma-next/family-sql/control';
|
|
22
22
|
import type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';
|
|
23
23
|
import type { SchemaDiffIssue } from '@prisma-next/framework-components/control';
|
|
24
|
+
import { issueOutcome, orderIssuesByDependencies } from '@prisma-next/framework-components/control';
|
|
24
25
|
import { defaultIndexName } from '@prisma-next/sql-schema-ir/naming';
|
|
25
26
|
import {
|
|
26
27
|
RelationalSchemaNodeKind,
|
|
@@ -63,51 +64,6 @@ import {
|
|
|
63
64
|
|
|
64
65
|
export type { CallMigrationStrategy, StrategyContext };
|
|
65
66
|
|
|
66
|
-
// ============================================================================
|
|
67
|
-
// Node-keyed issue ordering (dependency order)
|
|
68
|
-
// ============================================================================
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Re-keys the legacy `ISSUE_KIND_ORDER` (kind string → priority number) on
|
|
72
|
-
* `(nodeKind, reason)`. Numbers are preserved from the legacy table so the
|
|
73
|
-
* dependency intent stays legible; the final emission order is actually
|
|
74
|
-
* fixed downstream by category bucketing (create-table → add-column →
|
|
75
|
-
* create-index → recreate → drop-column → drop-index → drop-table), so this
|
|
76
|
-
* only breaks ties within a single bucket.
|
|
77
|
-
*/
|
|
78
|
-
export function nodeIssueOrder(issue: SchemaDiffIssue): number {
|
|
79
|
-
const node = issueNode(issue);
|
|
80
|
-
if (node === undefined) return 99;
|
|
81
|
-
switch (node.nodeKind) {
|
|
82
|
-
case RelationalSchemaNodeKind.foreignKey:
|
|
83
|
-
return issue.reason === 'not-expected' ? 10 : 60;
|
|
84
|
-
case RelationalSchemaNodeKind.unique:
|
|
85
|
-
return issue.reason === 'not-expected' ? 11 : 51;
|
|
86
|
-
case RelationalSchemaNodeKind.primaryKey:
|
|
87
|
-
return issue.reason === 'not-expected' ? 12 : 50;
|
|
88
|
-
case RelationalSchemaNodeKind.index:
|
|
89
|
-
return issue.reason === 'not-expected' ? 13 : 52;
|
|
90
|
-
case RelationalSchemaNodeKind.columnDefault:
|
|
91
|
-
if (issue.reason === 'not-expected') return 14;
|
|
92
|
-
return issue.reason === 'not-found' ? 42 : 43;
|
|
93
|
-
case RelationalSchemaNodeKind.column:
|
|
94
|
-
if (issue.reason === 'not-expected') return 15;
|
|
95
|
-
return issue.reason === 'not-found' ? 30 : 40;
|
|
96
|
-
case RelationalSchemaNodeKind.table:
|
|
97
|
-
return issue.reason === 'not-expected' ? 16 : 20;
|
|
98
|
-
case RelationalSchemaNodeKind.check:
|
|
99
|
-
if (issue.reason === 'not-found') return 53;
|
|
100
|
-
return issue.reason === 'not-expected' ? 54 : 55;
|
|
101
|
-
default:
|
|
102
|
-
return 99;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/** Deterministic tiebreak within an order bucket: the diff path itself already encodes table → child → grandchild. */
|
|
107
|
-
export function nodeIssueKey(issue: SchemaDiffIssue): string {
|
|
108
|
-
return issue.path.join(' ');
|
|
109
|
-
}
|
|
110
|
-
|
|
111
67
|
// ============================================================================
|
|
112
68
|
// Subtree coalescing — the planner's responsibility per the differ's contract
|
|
113
69
|
// ============================================================================
|
|
@@ -126,7 +82,9 @@ export function coalesceSubtreeIssues(
|
|
|
126
82
|
issues: readonly SchemaDiffIssue[],
|
|
127
83
|
): readonly SchemaDiffIssue[] {
|
|
128
84
|
const collapsingPaths = issues
|
|
129
|
-
.filter(
|
|
85
|
+
.filter(
|
|
86
|
+
(issue) => issueOutcome(issue) === 'not-found' || issueOutcome(issue) === 'not-expected',
|
|
87
|
+
)
|
|
130
88
|
.map((issue) => issue.path);
|
|
131
89
|
if (collapsingPaths.length === 0) return issues;
|
|
132
90
|
return issues.filter(
|
|
@@ -273,14 +231,14 @@ function buildCreateTableCalls(table: SqlTableIR): SqliteOpFactoryCall[] {
|
|
|
273
231
|
function mapTableIssue(
|
|
274
232
|
issue: SchemaDiffIssue,
|
|
275
233
|
): Result<readonly SqliteOpFactoryCall[], SqlPlannerConflict> {
|
|
276
|
-
if (issue
|
|
234
|
+
if (issueOutcome(issue) === 'not-found') {
|
|
277
235
|
const table = blindCast<
|
|
278
236
|
SqlTableIR,
|
|
279
237
|
'a not-found table issue always carries the expected table node'
|
|
280
238
|
>(issue.expected);
|
|
281
239
|
return ok(buildCreateTableCalls(table));
|
|
282
240
|
}
|
|
283
|
-
if (issue
|
|
241
|
+
if (issueOutcome(issue) === 'not-expected') {
|
|
284
242
|
const table = blindCast<
|
|
285
243
|
SqlTableIR,
|
|
286
244
|
'a not-expected table issue always carries the actual table node'
|
|
@@ -309,7 +267,7 @@ function mapColumnIssue(
|
|
|
309
267
|
),
|
|
310
268
|
);
|
|
311
269
|
}
|
|
312
|
-
if (issue
|
|
270
|
+
if (issueOutcome(issue) === 'not-found') {
|
|
313
271
|
const column = blindCast<
|
|
314
272
|
SqlColumnIR,
|
|
315
273
|
'a not-found column issue always carries the expected column node'
|
|
@@ -322,7 +280,7 @@ function mapColumnIssue(
|
|
|
322
280
|
const inline = table !== undefined && isInlineAutoincrementPrimaryKeyNode(table, column);
|
|
323
281
|
return ok([new AddColumnCall(tableName, columnSpecFromNode(column, inline))]);
|
|
324
282
|
}
|
|
325
|
-
if (issue
|
|
283
|
+
if (issueOutcome(issue) === 'not-expected') {
|
|
326
284
|
const column = blindCast<
|
|
327
285
|
SqlColumnIR,
|
|
328
286
|
'a not-expected column issue always carries the actual column node'
|
|
@@ -356,7 +314,7 @@ function mapIndexIssue(
|
|
|
356
314
|
),
|
|
357
315
|
);
|
|
358
316
|
}
|
|
359
|
-
if (issue
|
|
317
|
+
if (issueOutcome(issue) === 'not-found') {
|
|
360
318
|
const index = blindCast<
|
|
361
319
|
SqlIndexIR,
|
|
362
320
|
'a not-found index issue always carries the expected index node'
|
|
@@ -364,7 +322,7 @@ function mapIndexIssue(
|
|
|
364
322
|
const indexName = index.name ?? defaultIndexName(tableName, index.columns);
|
|
365
323
|
return ok([new CreateIndexCall(tableName, indexName, index.columns)]);
|
|
366
324
|
}
|
|
367
|
-
if (issue
|
|
325
|
+
if (issueOutcome(issue) === 'not-expected') {
|
|
368
326
|
const index = blindCast<
|
|
369
327
|
SqlIndexIR,
|
|
370
328
|
'a not-expected index issue always carries the actual index node'
|
|
@@ -504,13 +462,12 @@ export function planIssues(
|
|
|
504
462
|
}
|
|
505
463
|
}
|
|
506
464
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
});
|
|
465
|
+
// Dependency-graph order: a topological sort over the issues' `dependsOn`
|
|
466
|
+
// cross-links and containment edges (edge direction from the ordering law's
|
|
467
|
+
// presence rule), path-tiebroken for determinism. `classifyCall` bucketing
|
|
468
|
+
// downstream fixes the coarse create/recreate/drop sequence; this settles
|
|
469
|
+
// the order within each bucket.
|
|
470
|
+
const sorted = orderIssuesByDependencies(remaining);
|
|
514
471
|
|
|
515
472
|
const defaultCalls: SqliteOpFactoryCall[] = [];
|
|
516
473
|
const conflicts: SqlPlannerConflict[] = [];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { MigrationOperationClass } from '@prisma-next/family-sql/control';
|
|
2
2
|
import type { ExecuteRequestLowerer } from '@prisma-next/family-sql/control-adapter';
|
|
3
3
|
import type { SchemaDiffIssue } from '@prisma-next/framework-components/control';
|
|
4
|
+
import { issueOutcome } from '@prisma-next/framework-components/control';
|
|
4
5
|
import { RelationalSchemaNodeKind, type SqlColumnIR } from '@prisma-next/sql-schema-ir/types';
|
|
5
6
|
import { blindCast } from '@prisma-next/utils/casts';
|
|
6
7
|
import { tableExistsAst } from '../../../contract-free/checks';
|
|
@@ -294,7 +295,7 @@ export function buildRecreatePostchecks(
|
|
|
294
295
|
|
|
295
296
|
for (const issue of issues) {
|
|
296
297
|
const nodeKind = nodeKindOf(issue);
|
|
297
|
-
if (nodeKind === RelationalSchemaNodeKind.column && issue
|
|
298
|
+
if (nodeKind === RelationalSchemaNodeKind.column && issueOutcome(issue) === 'not-equal') {
|
|
298
299
|
const columnName = columnNameFromNode(issue);
|
|
299
300
|
if (columnName === undefined) continue;
|
|
300
301
|
const c = escapeLiteral(columnName);
|
|
@@ -325,7 +326,7 @@ export function buildRecreatePostchecks(
|
|
|
325
326
|
const columnName = columnNameFromDefaultIssuePath(issue);
|
|
326
327
|
if (columnName === undefined) continue;
|
|
327
328
|
const c = escapeLiteral(columnName);
|
|
328
|
-
if (issue
|
|
329
|
+
if (issueOutcome(issue) === 'not-expected') {
|
|
329
330
|
checks.push({
|
|
330
331
|
description: `verify "${columnName}" has no default on "${tableName}"`,
|
|
331
332
|
sql: `SELECT COUNT(*) > 0 FROM pragma_table_info('${t}') WHERE name = '${c}' AND dflt_value IS NULL`,
|
|
@@ -19,6 +19,7 @@ import type {
|
|
|
19
19
|
} from '@prisma-next/family-sql/control';
|
|
20
20
|
import type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';
|
|
21
21
|
import type { SchemaDiffIssue } from '@prisma-next/framework-components/control';
|
|
22
|
+
import { issueOutcome } from '@prisma-next/framework-components/control';
|
|
22
23
|
import { defaultIndexName } from '@prisma-next/sql-schema-ir/naming';
|
|
23
24
|
import {
|
|
24
25
|
RelationalSchemaNodeKind,
|
|
@@ -78,7 +79,7 @@ function classifyNodeIssue(issue: SchemaDiffIssue): 'widening' | 'destructive' |
|
|
|
78
79
|
>(node).nodeKind;
|
|
79
80
|
switch (nodeKind) {
|
|
80
81
|
case RelationalSchemaNodeKind.column: {
|
|
81
|
-
if (issue
|
|
82
|
+
if (issueOutcome(issue) !== 'not-equal') return null;
|
|
82
83
|
const expected = blindCast<SqlColumnIR, 'a not-equal column issue carries the expected node'>(
|
|
83
84
|
issue.expected,
|
|
84
85
|
);
|
|
@@ -91,7 +92,7 @@ function classifyNodeIssue(issue: SchemaDiffIssue): 'widening' | 'destructive' |
|
|
|
91
92
|
return expected.nullable ? 'widening' : 'destructive';
|
|
92
93
|
}
|
|
93
94
|
case RelationalSchemaNodeKind.columnDefault:
|
|
94
|
-
return issue
|
|
95
|
+
return issueOutcome(issue) === 'not-expected' ? 'destructive' : 'widening';
|
|
95
96
|
case RelationalSchemaNodeKind.primaryKey:
|
|
96
97
|
case RelationalSchemaNodeKind.foreignKey:
|
|
97
98
|
case RelationalSchemaNodeKind.unique:
|
|
@@ -206,7 +207,7 @@ export const nullabilityTighteningBackfillStrategy: CallMigrationStrategy = (iss
|
|
|
206
207
|
const calls: SqliteOpFactoryCall[] = [];
|
|
207
208
|
for (const issue of issues) {
|
|
208
209
|
if (
|
|
209
|
-
issue
|
|
210
|
+
issueOutcome(issue) !== 'not-equal' ||
|
|
210
211
|
issue.expected === undefined ||
|
|
211
212
|
issue.actual === undefined
|
|
212
213
|
) {
|
|
@@ -18,6 +18,7 @@ import type {
|
|
|
18
18
|
SchemaDiffIssue,
|
|
19
19
|
SchemaOwnership,
|
|
20
20
|
} from '@prisma-next/framework-components/control';
|
|
21
|
+
import { issueOutcome } from '@prisma-next/framework-components/control';
|
|
21
22
|
import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
|
|
22
23
|
import { RelationalSchemaNodeKind, type SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';
|
|
23
24
|
import { buildSqlitePlanDiff } from './diff-database-schema';
|
|
@@ -229,7 +230,7 @@ export class SqliteMigrationPlanner
|
|
|
229
230
|
});
|
|
230
231
|
const coalesced = coalesceSubtreeIssues(rawIssues);
|
|
231
232
|
const owned = retainUnownedExtras(coalesced, options.ownership);
|
|
232
|
-
const issues = strict ? owned : owned.filter((issue) => issue
|
|
233
|
+
const issues = strict ? owned : owned.filter((issue) => issueOutcome(issue) !== 'not-expected');
|
|
233
234
|
return { expected, actual, issues };
|
|
234
235
|
}
|
|
235
236
|
}
|
|
@@ -266,7 +267,7 @@ function retainUnownedExtras(
|
|
|
266
267
|
): readonly SchemaDiffIssue[] {
|
|
267
268
|
if (ownership === undefined) return issues;
|
|
268
269
|
return issues.filter((issue) => {
|
|
269
|
-
if (issue
|
|
270
|
+
if (issueOutcome(issue) !== 'not-expected') return true;
|
|
270
271
|
const node = issueNode(issue);
|
|
271
272
|
if (node === undefined || node.nodeKind !== RelationalSchemaNodeKind.table) return true;
|
|
272
273
|
const tableName = issue.path[1];
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"op-factory-call-CAAyaPyg.mjs","names":["contractFreeDdl.createTable"],"sources":["../src/core/migrations/planner-ddl-builders.ts","../src/core/migrations/operations/shared.ts","../src/core/migrations/operations/columns.ts","../src/core/migrations/operations/tables.ts","../src/core/migrations/op-factory-call.ts"],"sourcesContent":["/**\n * Low-level DDL fragment builders for SQLite migrations.\n *\n * These helpers consume `StorageColumn` (the contract shape, possibly with\n * `typeRef`) and produce string fragments. They are called once per column\n * at the call-construction boundary in `issue-planner.ts` / strategies to\n * build flat `SqliteColumnSpec`s; the operation factories themselves never\n * see `StorageColumn` or `storageTypes`.\n */\n\nimport type {\n StorageColumn,\n StorageTable,\n StorageTypeInstance,\n} from '@prisma-next/sql-contract/types';\nimport { escapeLiteral, quoteIdentifier } from '../sql-utils';\n\ntype SqliteColumnDefault = StorageColumn['default'];\n\nconst SAFE_NATIVE_TYPE_PATTERN = /^[a-zA-Z][a-zA-Z0-9_ ]*$/;\n\nfunction assertSafeNativeType(nativeType: string): void {\n if (!SAFE_NATIVE_TYPE_PATTERN.test(nativeType)) {\n throw new Error(\n `Unsafe native type name in contract: \"${nativeType}\". ` +\n 'Native type names must match /^[a-zA-Z][a-zA-Z0-9_ ]*$/',\n );\n }\n}\n\nfunction assertSafeDefaultExpression(expression: string): void {\n if (expression.includes(';') || /--|\\/\\*|\\bSELECT\\b/i.test(expression)) {\n throw new Error(\n `Unsafe default expression in contract: \"${expression}\". ` +\n 'Default expressions must not contain semicolons, SQL comment tokens, or subqueries.',\n );\n }\n}\n\n/**\n * Renders the column's DDL type token (e.g. `\"INTEGER\"`, `\"TEXT\"`).\n * Resolves `typeRef` against `storageTypes` and validates the resulting\n * native type against a safe-identifier pattern.\n */\nexport function buildColumnTypeSql(\n column: StorageColumn,\n storageTypes: Record<string, StorageTypeInstance> = {},\n): string {\n const resolved = resolveColumnTypeMetadata(column, storageTypes);\n assertSafeNativeType(resolved.nativeType);\n return resolved.nativeType.toUpperCase();\n}\n\n/**\n * Renders the column's `DEFAULT …` clause. Returns the empty string when\n * there is no default, and also when the default is `autoincrement()` —\n * SQLite encodes that as `INTEGER PRIMARY KEY AUTOINCREMENT` inline on the\n * column definition, not as a separate DEFAULT.\n */\nexport function buildColumnDefaultSql(columnDefault: SqliteColumnDefault | undefined): string {\n if (!columnDefault) return '';\n\n switch (columnDefault.kind) {\n case 'literal':\n return `DEFAULT ${renderDefaultLiteral(columnDefault.value)}`;\n case 'function': {\n if (columnDefault.expression === 'autoincrement()') return '';\n if (columnDefault.expression === 'now()') return \"DEFAULT (datetime('now'))\";\n assertSafeDefaultExpression(columnDefault.expression);\n return `DEFAULT (${columnDefault.expression})`;\n }\n }\n}\n\nexport function renderDefaultLiteral(value: unknown): string {\n if (value instanceof Date) {\n return `'${escapeLiteral(value.toISOString())}'`;\n }\n if (typeof value === 'string') {\n return `'${escapeLiteral(value)}'`;\n }\n if (typeof value === 'number' || typeof value === 'bigint') {\n return String(value);\n }\n if (typeof value === 'boolean') {\n return value ? '1' : '0';\n }\n if (value === null) {\n return 'NULL';\n }\n return `'${escapeLiteral(JSON.stringify(value))}'`;\n}\n\nexport function buildCreateIndexSql(\n tableName: string,\n indexName: string,\n columns: readonly string[],\n unique = false,\n): string {\n const uniqueKeyword = unique ? 'UNIQUE ' : '';\n return `CREATE ${uniqueKeyword}INDEX ${quoteIdentifier(indexName)} ON ${quoteIdentifier(tableName)} (${columns.map(quoteIdentifier).join(', ')})`;\n}\n\nexport function buildDropIndexSql(indexName: string): string {\n return `DROP INDEX IF EXISTS ${quoteIdentifier(indexName)}`;\n}\n\n/**\n * True when the column is rendered inline as `INTEGER PRIMARY KEY\n * AUTOINCREMENT`. Requires the column's default to be `autoincrement()` and\n * the column to be the sole member of the table's primary key — anything\n * else falls back to a separate PRIMARY KEY constraint with a default\n * AUTOINCREMENT semantics expressed elsewhere.\n */\nexport function isInlineAutoincrementPrimaryKey(table: StorageTable, columnName: string): boolean {\n if (table.primaryKey?.columns.length !== 1) return false;\n if (table.primaryKey.columns[0] !== columnName) return false;\n const column = table.columns[columnName];\n return column?.default?.kind === 'function' && column.default.expression === 'autoincrement()';\n}\n\ntype ResolvedColumnTypeMetadata = Pick<StorageColumn, 'nativeType' | 'codecId' | 'typeParams'>;\n\nexport function resolveColumnTypeMetadata(\n column: StorageColumn,\n storageTypes: Record<string, StorageTypeInstance>,\n): ResolvedColumnTypeMetadata {\n if (!column.typeRef) {\n return column;\n }\n const referencedType = storageTypes[column.typeRef];\n if (!referencedType) {\n throw new Error(\n `Storage type \"${column.typeRef}\" referenced by column is not defined in storage.types.`,\n );\n }\n return {\n codecId: referencedType.codecId,\n nativeType: referencedType.nativeType,\n typeParams: referencedType.typeParams,\n };\n}\n","import type {\n SqlMigrationPlanOperation,\n SqlMigrationPlanOperationStep,\n} from '@prisma-next/family-sql/control';\nimport { REFERENTIAL_ACTION_SQL } from '@prisma-next/sql-contract/referential-action-sql';\nimport type { ReferentialAction } from '@prisma-next/sql-contract/types';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { quoteIdentifier } from '../../sql-utils';\nimport type { SqlitePlanTargetDetails } from '../planner-target-details';\n\nexport type Op = SqlMigrationPlanOperation<SqlitePlanTargetDetails>;\n\nexport function step(\n description: string,\n sql: string,\n params?: readonly unknown[],\n): SqlMigrationPlanOperationStep {\n return { description, sql, ...ifDefined('params', params) };\n}\n\n/**\n * Flat, fully-resolved column shape consumed by `createTable`, `addColumn`,\n * and `recreateTable`. Codec / `typeRef` / default expansion happens at the\n * call-construction site (in the issue-planner / strategies) so the\n * operation factories deal only in pre-rendered SQL fragments — mirrors the\n * Postgres `ColumnSpec` pattern.\n *\n * - `typeSql` is the column's DDL type token (e.g. `\"INTEGER\"`, `\"TEXT\"`).\n * - `defaultSql` is the full `DEFAULT …` clause (or empty when there is no\n * default and when the column is rendered as `INTEGER PRIMARY KEY\n * AUTOINCREMENT`, since SQLite forbids a default on an autoincrement PK).\n * - `inlineAutoincrementPrimaryKey` directs the renderer to emit\n * `INTEGER PRIMARY KEY AUTOINCREMENT` inline and to skip the table-level\n * primary-key constraint for this column. SQLite-specific: the column\n * becomes an alias for `rowid` only when this exact form is used.\n */\nexport interface SqliteColumnSpec {\n readonly name: string;\n readonly typeSql: string;\n readonly defaultSql: string;\n readonly nullable: boolean;\n readonly inlineAutoincrementPrimaryKey?: boolean;\n}\n\nexport interface SqlitePrimaryKeySpec {\n readonly columns: readonly string[];\n}\n\nexport interface SqliteUniqueSpec {\n readonly columns: readonly string[];\n readonly name?: string;\n}\n\nexport interface SqliteForeignKeySpec {\n readonly columns: readonly string[];\n readonly references: {\n readonly table: string;\n readonly columns: readonly string[];\n };\n readonly name?: string;\n readonly onDelete?: ReferentialAction;\n readonly onUpdate?: ReferentialAction;\n}\n\n/**\n * Flat shape of a contract table for DDL emission. Used by both\n * `createTable` (additive) and `recreateTable` (widening/destructive).\n */\nexport interface SqliteTableSpec {\n readonly columns: readonly SqliteColumnSpec[];\n readonly primaryKey?: SqlitePrimaryKeySpec;\n readonly uniques?: readonly SqliteUniqueSpec[];\n readonly foreignKeys?: readonly SqliteForeignKeySpec[];\n}\n\n/**\n * Index recreation spec for `recreateTable`. Both declared indexes and\n * FK-backing indexes flatten to the same shape; the planner dedupes by\n * column-set before constructing the call.\n */\nexport interface SqliteIndexSpec {\n readonly name: string;\n readonly columns: readonly string[];\n}\n\n/**\n * Renders a single column's inline DDL fragment within a `CREATE TABLE`\n * statement. Honours the `inlineAutoincrementPrimaryKey` flag — SQLite\n * treats `INTEGER PRIMARY KEY AUTOINCREMENT` as a special form that aliases\n * `rowid`, and the column must not carry a `DEFAULT` or repeat `NOT NULL`.\n */\nexport function renderColumnDefinition(column: SqliteColumnSpec): string {\n const parts: string[] = [quoteIdentifier(column.name), column.typeSql];\n if (column.inlineAutoincrementPrimaryKey) {\n parts.push('PRIMARY KEY AUTOINCREMENT');\n } else {\n if (column.defaultSql) parts.push(column.defaultSql);\n if (!column.nullable) parts.push('NOT NULL');\n }\n return parts.join(' ');\n}\n\n/**\n * Renders an inline FOREIGN KEY constraint clause for a `CREATE TABLE`\n * body. Every `SqliteForeignKeySpec` is constraint-bearing by construction\n * (`tableSpecFromNode` only ever builds specs from schema-IR FK nodes, which\n * are themselves constraint-only — a non-constraint FK contributes no node).\n */\nexport function renderForeignKeyClause(fk: SqliteForeignKeySpec): string {\n const name = fk.name ? `CONSTRAINT ${quoteIdentifier(fk.name)} ` : '';\n let sql = `${name}FOREIGN KEY (${fk.columns.map(quoteIdentifier).join(', ')}) REFERENCES ${quoteIdentifier(fk.references.table)} (${fk.references.columns.map(quoteIdentifier).join(', ')})`;\n if (fk.onDelete !== undefined) {\n sql += ` ON DELETE ${REFERENTIAL_ACTION_SQL[fk.onDelete]}`;\n }\n if (fk.onUpdate !== undefined) {\n sql += ` ON UPDATE ${REFERENTIAL_ACTION_SQL[fk.onUpdate]}`;\n }\n return sql;\n}\n","import type { ExecuteRequestLowerer } from '@prisma-next/family-sql/control-adapter';\nimport { columnExistsAst } from '../../../contract-free/checks';\nimport { quoteIdentifier } from '../../sql-utils';\nimport { buildTargetDetails } from '../planner-target-details';\nimport { type Op, type SqliteColumnSpec, step } from './shared';\n\nexport function addColumnExecuteSql(tableName: string, column: SqliteColumnSpec): string {\n const parts = [\n `ALTER TABLE ${quoteIdentifier(tableName)}`,\n `ADD COLUMN ${quoteIdentifier(column.name)} ${column.typeSql}`,\n column.defaultSql,\n column.nullable ? '' : 'NOT NULL',\n ].filter(Boolean);\n return parts.join(' ');\n}\n\nexport function dropColumnExecuteSql(tableName: string, columnName: string): string {\n return `ALTER TABLE ${quoteIdentifier(tableName)} DROP COLUMN ${quoteIdentifier(columnName)}`;\n}\n\nexport async function addColumn(\n tableName: string,\n column: SqliteColumnSpec,\n lowerer: ExecuteRequestLowerer,\n): Promise<Op> {\n const checks = columnExistsAst(tableName, column.name);\n const absent = await lowerer.lowerToExecuteRequest(checks.columnAbsent());\n const present = await lowerer.lowerToExecuteRequest(checks.columnPresent());\n return {\n id: `column.${tableName}.${column.name}`,\n label: `Add column ${column.name} on ${tableName}`,\n summary: `Adds column ${column.name} on ${tableName}`,\n operationClass: 'additive',\n target: { id: 'sqlite', details: buildTargetDetails('column', column.name, tableName) },\n precheck: [step(`ensure column \"${column.name}\" is missing`, absent.sql, absent.params)],\n execute: [step(`add column \"${column.name}\"`, addColumnExecuteSql(tableName, column))],\n postcheck: [step(`verify column \"${column.name}\" exists`, present.sql, present.params)],\n };\n}\n\nexport async function dropColumn(\n tableName: string,\n columnName: string,\n lowerer: ExecuteRequestLowerer,\n): Promise<Op> {\n const checks = columnExistsAst(tableName, columnName);\n const present = await lowerer.lowerToExecuteRequest(checks.columnPresent());\n const absent = await lowerer.lowerToExecuteRequest(checks.columnAbsent());\n return {\n id: `dropColumn.${tableName}.${columnName}`,\n label: `Drop column ${columnName} on ${tableName}`,\n summary: `Drops column ${columnName} on ${tableName} which is not in the contract`,\n operationClass: 'destructive',\n target: { id: 'sqlite', details: buildTargetDetails('column', columnName, tableName) },\n precheck: [\n step(`ensure column \"${columnName}\" exists on \"${tableName}\"`, present.sql, present.params),\n ],\n execute: [\n step(\n `drop column \"${columnName}\" from \"${tableName}\"`,\n dropColumnExecuteSql(tableName, columnName),\n ),\n ],\n postcheck: [\n step(`verify column \"${columnName}\" is gone from \"${tableName}\"`, absent.sql, absent.params),\n ],\n };\n}\n","import type { MigrationOperationClass } from '@prisma-next/family-sql/control';\nimport type { ExecuteRequestLowerer } from '@prisma-next/family-sql/control-adapter';\nimport type { SchemaDiffIssue } from '@prisma-next/framework-components/control';\nimport { RelationalSchemaNodeKind, type SqlColumnIR } from '@prisma-next/sql-schema-ir/types';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { tableExistsAst } from '../../../contract-free/checks';\nimport { stripOuterParens } from '../../default-normalizer';\nimport { escapeLiteral, quoteIdentifier } from '../../sql-utils';\nimport { buildCreateIndexSql } from '../planner-ddl-builders';\nimport { buildTargetDetails } from '../planner-target-details';\nimport {\n type Op,\n renderColumnDefinition,\n renderForeignKeyClause,\n type SqliteIndexSpec,\n type SqliteTableSpec,\n step,\n} from './shared';\n\ntype CheckStep = { sql: string; params?: readonly unknown[] };\n\nasync function tableExistsSteps(\n lowerer: ExecuteRequestLowerer,\n tableName: string,\n): Promise<{ present: CheckStep; absent: CheckStep }> {\n const checks = tableExistsAst(tableName);\n const present = await lowerer.lowerToExecuteRequest(checks.tablePresent());\n const absent = await lowerer.lowerToExecuteRequest(checks.tableAbsent());\n return { present, absent };\n}\n\n/**\n * Renders the body of a `CREATE TABLE <name> ( … )` statement from a flat\n * `SqliteTableSpec`. SQLite's `INTEGER PRIMARY KEY AUTOINCREMENT` form is\n * inline on the column; the table-level PRIMARY KEY clause is emitted only\n * when no column carries `inlineAutoincrementPrimaryKey`.\n */\nfunction renderCreateTableSql(tableName: string, spec: SqliteTableSpec): string {\n const columnDefs = spec.columns.map(renderColumnDefinition);\n\n const constraintDefs: string[] = [];\n const hasInlinePk = spec.columns.some((c) => c.inlineAutoincrementPrimaryKey);\n if (spec.primaryKey && !hasInlinePk) {\n constraintDefs.push(`PRIMARY KEY (${spec.primaryKey.columns.map(quoteIdentifier).join(', ')})`);\n }\n\n for (const u of spec.uniques ?? []) {\n const name = u.name ? `CONSTRAINT ${quoteIdentifier(u.name)} ` : '';\n constraintDefs.push(`${name}UNIQUE (${u.columns.map(quoteIdentifier).join(', ')})`);\n }\n\n for (const fk of spec.foreignKeys ?? []) {\n const clause = renderForeignKeyClause(fk);\n if (clause) constraintDefs.push(clause);\n }\n\n const allDefs = [...columnDefs, ...constraintDefs];\n return `CREATE TABLE ${quoteIdentifier(tableName)} (\\n ${allDefs.join(',\\n ')}\\n)`;\n}\n\nexport async function createTable(\n tableName: string,\n spec: SqliteTableSpec,\n lowerer: ExecuteRequestLowerer,\n): Promise<Op> {\n const { present, absent } = await tableExistsSteps(lowerer, tableName);\n return {\n id: `table.${tableName}`,\n label: `Create table ${tableName}`,\n summary: `Creates table ${tableName} with required columns`,\n operationClass: 'additive',\n target: { id: 'sqlite', details: buildTargetDetails('table', tableName) },\n precheck: [step(`ensure table \"${tableName}\" does not exist`, absent.sql, absent.params)],\n execute: [step(`create table \"${tableName}\"`, renderCreateTableSql(tableName, spec))],\n postcheck: [step(`verify table \"${tableName}\" exists`, present.sql, present.params)],\n };\n}\n\nexport async function dropTable(tableName: string, lowerer: ExecuteRequestLowerer): Promise<Op> {\n const { present, absent } = await tableExistsSteps(lowerer, tableName);\n return {\n id: `dropTable.${tableName}`,\n label: `Drop table ${tableName}`,\n summary: `Drops table ${tableName} which is not in the contract`,\n operationClass: 'destructive',\n target: { id: 'sqlite', details: buildTargetDetails('table', tableName) },\n precheck: [step(`ensure table \"${tableName}\" exists`, present.sql, present.params)],\n execute: [step(`drop table \"${tableName}\"`, `DROP TABLE ${quoteIdentifier(tableName)}`)],\n postcheck: [step(`verify table \"${tableName}\" is gone`, absent.sql, absent.params)],\n };\n}\n\nexport interface RecreateTableArgs {\n readonly tableName: string;\n /** New (post-recreate) shape of the table. Same flat spec as `createTable`. */\n readonly contractTable: SqliteTableSpec;\n /**\n * Names of columns that exist in the live (pre-recreate) schema. Used to\n * compute the `INSERT INTO temp ... SELECT ... FROM old` column list — only\n * shared columns are copied, so dropped columns are left behind and added\n * columns come from defaults.\n */\n readonly schemaColumnNames: readonly string[];\n /**\n * Indexes (declared + FK-backing, deduped by column-set) to recreate after\n * the table has been replaced. The planner pre-merges these.\n */\n readonly indexes: readonly SqliteIndexSpec[];\n /** Human-readable summary of the change, built by the planner from issues. */\n readonly summary: string;\n /**\n * Per-issue postcheck steps appended after the structural postchecks. The\n * planner pre-builds these via `buildRecreatePostchecks` so the call IR\n * carries flat, serializable data only — no `SchemaDiffIssue` references.\n */\n readonly postchecks: readonly { readonly description: string; readonly sql: string }[];\n readonly operationClass: MigrationOperationClass;\n}\n\nexport async function recreateTable(\n args: RecreateTableArgs,\n lowerer: ExecuteRequestLowerer,\n): Promise<Op> {\n const {\n tableName,\n contractTable,\n schemaColumnNames,\n indexes,\n summary,\n postchecks,\n operationClass,\n } = args;\n const tempName = `_prisma_new_${tableName}`;\n const liveSet = new Set(schemaColumnNames);\n const sharedColumns = contractTable.columns.filter((c) => liveSet.has(c.name)).map((c) => c.name);\n const columnList = sharedColumns.map(quoteIdentifier).join(', ');\n\n const indexStatements = indexes.map((idx) => ({\n description: `recreate index \"${idx.name}\" on \"${tableName}\"`,\n sql: buildCreateIndexSql(tableName, idx.name, idx.columns),\n }));\n\n // If the contract retains no columns from the live table, an `INSERT INTO\n // tmp () SELECT FROM old` is invalid SQL — and would also be a no-op since\n // there's nothing to copy. Skip the copy step in that case; the new\n // (empty) table replaces the old one directly.\n const copyStep =\n sharedColumns.length > 0\n ? [\n step(\n `copy data from \"${tableName}\" to \"${tempName}\"`,\n `INSERT INTO ${quoteIdentifier(tempName)} (${columnList}) SELECT ${columnList} FROM ${quoteIdentifier(tableName)}`,\n ),\n ]\n : [];\n\n const tableSteps = await tableExistsSteps(lowerer, tableName);\n const tempSteps = await tableExistsSteps(lowerer, tempName);\n\n return {\n id: `recreateTable.${tableName}`,\n label: `Recreate table ${tableName}`,\n summary,\n operationClass,\n target: { id: 'sqlite', details: buildTargetDetails('table', tableName) },\n precheck: [\n step(`ensure table \"${tableName}\" exists`, tableSteps.present.sql, tableSteps.present.params),\n step(\n `ensure temp table \"${tempName}\" does not exist`,\n tempSteps.absent.sql,\n tempSteps.absent.params,\n ),\n ],\n execute: [\n step(\n `create new table \"${tempName}\" with desired schema`,\n renderCreateTableSql(tempName, contractTable),\n ),\n ...copyStep,\n step(`drop old table \"${tableName}\"`, `DROP TABLE ${quoteIdentifier(tableName)}`),\n step(\n `rename \"${tempName}\" to \"${tableName}\"`,\n `ALTER TABLE ${quoteIdentifier(tempName)} RENAME TO ${quoteIdentifier(tableName)}`,\n ),\n ...indexStatements,\n ],\n postcheck: [\n step(`verify table \"${tableName}\" exists`, tableSteps.present.sql, tableSteps.present.params),\n step(\n `verify temp table \"${tempName}\" is gone`,\n tempSteps.absent.sql,\n tempSteps.absent.params,\n ),\n ...postchecks,\n ],\n };\n}\n\n/**\n * Build a one-line summary of a recreate-table operation from the schema-diff\n * issues that triggered it. Lives next to `recreateTable` so the planner\n * (which has the issues) can produce the same description the factory\n * used to build inline. Keeping the formatting target-side keeps\n * `RecreateTableCall` issue-free at the IR layer. `SchemaDiffIssue` carries\n * no rendered message, so this renders one from each issue's path.\n */\nexport function buildRecreateSummary(\n tableName: string,\n issues: readonly SchemaDiffIssue[],\n): string {\n const messages = issues.map((i) => i.path.join('/')).join('; ');\n return `Recreates table ${tableName} to apply schema changes: ${messages}`;\n}\n\nfunction nodeKindOf(issue: SchemaDiffIssue): string | undefined {\n const node = issue.expected ?? issue.actual;\n if (node === undefined) return undefined;\n return blindCast<{ readonly nodeKind: string }, 'every diff-tree node declares nodeKind'>(node)\n .nodeKind;\n}\n\n/** Mirrors `SqlColumnIR.isEqualTo`'s type comparison, isolated so a `not-equal` column issue's postcheck can target type drift and nullability drift independently. */\nfunction columnTypeChanged(expected: SqlColumnIR, actual: SqlColumnIR): boolean {\n if (expected.resolvedNativeType !== undefined && actual.resolvedNativeType !== undefined) {\n return expected.resolvedNativeType !== actual.resolvedNativeType;\n }\n return (\n expected.nativeType !== actual.nativeType || Boolean(expected.many) !== Boolean(actual.many)\n );\n}\n\n/**\n * Returns the columns the contract expects as the table's primary key. Picks\n * up SQLite's inline `INTEGER PRIMARY KEY AUTOINCREMENT` form when no\n * explicit `primaryKey` clause is set on the spec.\n */\nfunction expectedPrimaryKeyColumns(spec: SqliteTableSpec): readonly string[] {\n if (spec.primaryKey) return spec.primaryKey.columns;\n const inlinePk = spec.columns.find((c) => c.inlineAutoincrementPrimaryKey);\n return inlinePk ? [inlinePk.name] : [];\n}\n\nfunction quoteSqlList(values: readonly string[]): string {\n return values.map((v) => `'${escapeLiteral(v)}'`).join(', ');\n}\n\nfunction columnNameFromNode(issue: SchemaDiffIssue): string | undefined {\n const node = issue.expected ?? issue.actual;\n if (node === undefined) return undefined;\n return blindCast<\n { readonly name: string },\n 'a column or column-default issue node carries name (default nodes read the owning column name off the diff path instead)'\n >(node).name;\n}\n\n/**\n * A column-default issue's own node has no back-reference to its owning\n * column — it's a transient child built by `SqlColumnIR.children()`. The\n * column's id (`column:<name>`) is always the diff path's second-to-last\n * segment for a default issue (`[..., tableId, columnId, 'default']`), so\n * the name is recovered from the path rather than the node.\n */\nfunction columnNameFromDefaultIssuePath(issue: SchemaDiffIssue): string | undefined {\n const columnId = issue.path[issue.path.length - 2];\n if (columnId === undefined) return undefined;\n const prefix = 'column:';\n return columnId.startsWith(prefix) ? columnId.slice(prefix.length) : columnId;\n}\n\n/**\n * Per-issue postchecks verifying the recreated table's shape against the\n * expected spec. Column-level issues (`sql-column` `not-equal`,\n * `sql-column-default` any reason) emit one targeted check each;\n * constraint-level issues (`sql-primary-key`, `sql-unique`, `sql-foreign-key`,\n * any reason) emit one `pragma_*`-driven check per declared constraint in the\n * expected spec, so a recreated table with the right columns but the wrong\n * PK / unique / FK shape fails the postcheck instead of passing silently.\n * Exported so the planner can pre-build the list at construction time and\n * `RecreateTableCall` doesn't have to carry `SchemaDiffIssue` objects through\n * to render time.\n */\nexport function buildRecreatePostchecks(\n tableName: string,\n issues: readonly SchemaDiffIssue[],\n spec: SqliteTableSpec,\n): Array<{ description: string; sql: string }> {\n const checks: Array<{ description: string; sql: string }> = [];\n const t = escapeLiteral(tableName);\n const byName = new Map(spec.columns.map((c) => [c.name, c]));\n\n let hasPkIssue = false;\n let hasUniqueIssue = false;\n let hasFkIssue = false;\n\n for (const issue of issues) {\n const nodeKind = nodeKindOf(issue);\n if (nodeKind === RelationalSchemaNodeKind.column && issue.reason === 'not-equal') {\n const columnName = columnNameFromNode(issue);\n if (columnName === undefined) continue;\n const c = escapeLiteral(columnName);\n const expected = blindCast<SqlColumnIR, 'a not-equal column issue carries the expected node'>(\n issue.expected,\n );\n const actual = blindCast<SqlColumnIR, 'a not-equal column issue carries the actual node'>(\n issue.actual,\n );\n if (expected.nullable !== actual.nullable) {\n checks.push({\n description: `verify \"${columnName}\" nullability on \"${tableName}\"`,\n sql: `SELECT COUNT(*) > 0 FROM pragma_table_info('${t}') WHERE name = '${c}' AND \"notnull\" = ${expected.nullable ? 0 : 1}`,\n });\n }\n if (columnTypeChanged(expected, actual)) {\n const colSpec = byName.get(columnName);\n if (colSpec) {\n checks.push({\n description: `verify \"${columnName}\" type on \"${tableName}\"`,\n sql: `SELECT COUNT(*) > 0 FROM pragma_table_info('${t}') WHERE name = '${c}' AND LOWER(type) = '${escapeLiteral(colSpec.typeSql.toLowerCase())}'`,\n });\n }\n }\n continue;\n }\n if (nodeKind === RelationalSchemaNodeKind.columnDefault) {\n const columnName = columnNameFromDefaultIssuePath(issue);\n if (columnName === undefined) continue;\n const c = escapeLiteral(columnName);\n if (issue.reason === 'not-expected') {\n checks.push({\n description: `verify \"${columnName}\" has no default on \"${tableName}\"`,\n sql: `SELECT COUNT(*) > 0 FROM pragma_table_info('${t}') WHERE name = '${c}' AND dflt_value IS NULL`,\n });\n continue;\n }\n // not-found (missing) or not-equal (drift) — both want the expected\n // default SQL present on the live column.\n const colSpec = byName.get(columnName);\n const expectedRaw = colSpec?.defaultSql.startsWith('DEFAULT ')\n ? // SQLite's pragma_table_info.dflt_value strips outer parens for\n // expression defaults (per the SQLite docs), so `(datetime('now'))`\n // is stored as `datetime('now')`. Strip them here so the postcheck\n // matches.\n stripOuterParens(colSpec.defaultSql.slice('DEFAULT '.length))\n : null;\n if (expectedRaw) {\n checks.push({\n description: `verify \"${columnName}\" default on \"${tableName}\"`,\n sql: `SELECT COUNT(*) > 0 FROM pragma_table_info('${t}') WHERE name = '${c}' AND dflt_value = '${escapeLiteral(expectedRaw)}'`,\n });\n }\n continue;\n }\n if (nodeKind === RelationalSchemaNodeKind.primaryKey) hasPkIssue = true;\n if (nodeKind === RelationalSchemaNodeKind.unique) hasUniqueIssue = true;\n if (nodeKind === RelationalSchemaNodeKind.foreignKey) hasFkIssue = true;\n }\n\n // Constraint-level issues — emit one postcheck per declared constraint in\n // the expected spec when *any* issue of that kind fires, since recreate\n // rebuilds the entire table at once.\n\n if (hasPkIssue) {\n const pkColumns = expectedPrimaryKeyColumns(spec);\n // Verify pragma_table_info reports exactly these columns as PK members\n // (count + named membership); zero columns expected ⇒ no PK at all.\n const colCount = pkColumns.length;\n if (colCount === 0) {\n checks.push({\n description: `verify \"${tableName}\" has no primary key`,\n sql: `SELECT (SELECT COUNT(*) FROM pragma_table_info('${t}') WHERE pk > 0) = 0`,\n });\n } else {\n checks.push({\n description: `verify primary key on \"${tableName}\"`,\n sql:\n `SELECT (SELECT COUNT(*) FROM pragma_table_info('${t}') WHERE pk > 0) = ${colCount}` +\n ` AND (SELECT COUNT(*) FROM pragma_table_info('${t}') WHERE pk > 0 AND name IN (${quoteSqlList(pkColumns)})) = ${colCount}`,\n });\n }\n }\n\n if (hasUniqueIssue) {\n for (const u of spec.uniques ?? []) {\n const colCount = u.columns.length;\n const description = u.name\n ? `verify unique constraint \"${u.name}\" on \"${tableName}\"`\n : `verify unique constraint (${u.columns.join(', ')}) on \"${tableName}\"`;\n // Match any unique index whose covered columns are exactly the expected\n // set. Order is intentionally not checked — SQLite's unique-index\n // identity is column-set, not column-sequence.\n checks.push({\n description,\n sql:\n `SELECT EXISTS (SELECT 1 FROM pragma_index_list('${t}') l` +\n ` WHERE l.\"unique\" = 1` +\n ` AND (SELECT COUNT(*) FROM pragma_index_info(l.name)) = ${colCount}` +\n ` AND (SELECT COUNT(*) FROM pragma_index_info(l.name) WHERE name IN (${quoteSqlList(u.columns)})) = ${colCount})`,\n });\n }\n }\n\n if (hasFkIssue) {\n for (const fk of spec.foreignKeys ?? []) {\n const refTable = escapeLiteral(fk.references.table);\n const colCount = fk.columns.length;\n // Build a `SUM(CASE WHEN (\"from\",\"to\") IN ((…)) …)` so the check works\n // for both single- and multi-column FKs without depending on FK row\n // ordering inside `pragma_foreign_key_list`.\n const tuples = fk.columns\n .map((from, i) => {\n const to = fk.references.columns[i] ?? from;\n return `('${escapeLiteral(from)}', '${escapeLiteral(to)}')`;\n })\n .join(', ');\n const description = `verify foreign key (${fk.columns.join(', ')}) → ${fk.references.table}(${fk.references.columns.join(', ')}) on \"${tableName}\"`;\n checks.push({\n description,\n sql:\n `SELECT EXISTS (SELECT 1 FROM pragma_foreign_key_list('${t}') f` +\n ` WHERE f.\"table\" = '${refTable}'` +\n ' GROUP BY f.id' +\n ` HAVING COUNT(*) = ${colCount}` +\n ` AND SUM(CASE WHEN (f.\"from\", f.\"to\") IN (${tuples}) THEN 1 ELSE 0 END) = ${colCount})`,\n });\n }\n }\n\n return checks;\n}\n","/**\n * SQLite migration IR: one concrete `*Call` class per pure factory under\n * `operations/`, plus a shared `SqliteOpFactoryCallNode` abstract base.\n *\n * Each call class carries fully-resolved literal arguments. `CreateTableCall`\n * holds structured `DdlColumn[]` + `DdlTableConstraint[]` and lowers via the\n * adapter's DDL path; other call classes carry flat SQL fragments. Codec /\n * `typeRef` / default expansion happens upstream in the issue-planner /\n * strategies, mirroring the Postgres `ColumnSpec` pattern.\n */\n\nimport { errorUnfilledPlaceholder } from '@prisma-next/errors/migration';\nimport type {\n MigrationOperationClass,\n SqlMigrationPlanOperation,\n} from '@prisma-next/family-sql/control';\nimport type { ExecuteRequestLowerer, Lowerer } from '@prisma-next/family-sql/control-adapter';\nimport type { OpFactoryCall as FrameworkOpFactoryCall } from '@prisma-next/framework-components/control';\nimport type {\n AnyDdlColumnDefault,\n DdlColumn,\n DdlTableConstraint,\n} from '@prisma-next/sql-relational-core/ast';\nimport { type ImportRequirement, jsonToTsSource, TsExpression } from '@prisma-next/ts-render';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { columnExistsAst, indexExistsAst, tableExistsAst } from '../../contract-free/checks';\nimport * as contractFreeDdl from '../../contract-free/ddl';\nimport { quoteIdentifier } from '../sql-utils';\nimport { addColumnExecuteSql, dropColumnExecuteSql } from './operations/columns';\nimport type { SqliteColumnSpec, SqliteIndexSpec, SqliteTableSpec } from './operations/shared';\nimport { step } from './operations/shared';\nimport { recreateTable } from './operations/tables';\nimport { buildCreateIndexSql, buildDropIndexSql } from './planner-ddl-builders';\nimport type { SqlitePlanTargetDetails } from './planner-target-details';\nimport { buildTargetDetails } from './planner-target-details';\n\ntype Op = SqlMigrationPlanOperation<SqlitePlanTargetDetails>;\n\nconst TARGET_MIGRATION_MODULE = '@prisma-next/sqlite/migration';\n\nabstract class SqliteOpFactoryCallNode extends TsExpression implements FrameworkOpFactoryCall {\n abstract readonly factoryName: string;\n abstract readonly operationClass: MigrationOperationClass;\n abstract readonly label: string;\n abstract toOp(lowerer?: Lowerer): Op | Promise<Op>;\n\n importRequirements(): readonly ImportRequirement[] {\n return [{ moduleSpecifier: TARGET_MIGRATION_MODULE, symbol: this.factoryName }];\n }\n\n protected freeze(): void {\n Object.freeze(this);\n }\n}\n\n// ============================================================================\n// Table\n// ============================================================================\n\n// ---------------------------------------------------------------------------\n// TypeScript rendering helpers for DdlColumn / DdlTableConstraint\n// ---------------------------------------------------------------------------\n\nfunction renderDdlColumnDefault(def: AnyDdlColumnDefault | undefined): string {\n if (!def) return '';\n if (def.kind === 'literal') {\n return `lit(${jsonToTsSource(def.value)})`;\n }\n return `fn(${jsonToTsSource(def.expression)})`;\n}\n\nfunction renderDdlColumnAsTsCall(column: DdlColumn): string {\n const opts: string[] = [];\n if (column.notNull) opts.push('notNull: true');\n if (column.primaryKey) opts.push('primaryKey: true');\n if (column.default) opts.push(`default: ${renderDdlColumnDefault(column.default)}`);\n const optsStr = opts.length > 0 ? `, { ${opts.join(', ')} }` : '';\n return `col(${jsonToTsSource(column.name)}, ${jsonToTsSource(column.type)}${optsStr})`;\n}\n\nfunction renderDdlConstraintAsTsCall(constraint: DdlTableConstraint): string {\n switch (constraint.kind) {\n case 'primary-key': {\n const nameOpt = constraint.name ? `, { name: ${jsonToTsSource(constraint.name)} }` : '';\n return `primaryKey(${jsonToTsSource(constraint.columns)}${nameOpt})`;\n }\n case 'foreign-key': {\n const opts: string[] = [];\n if (constraint.name) opts.push(`name: ${jsonToTsSource(constraint.name)}`);\n if (constraint.onDelete) opts.push(`onDelete: ${jsonToTsSource(constraint.onDelete)}`);\n if (constraint.onUpdate) opts.push(`onUpdate: ${jsonToTsSource(constraint.onUpdate)}`);\n const optsStr = opts.length > 0 ? `, { ${opts.join(', ')} }` : '';\n return `foreignKey(${jsonToTsSource(constraint.columns)}, ${jsonToTsSource(constraint.refTable)}, ${jsonToTsSource(constraint.refColumns)}${optsStr})`;\n }\n case 'unique': {\n const nameOpt = constraint.name ? `, { name: ${jsonToTsSource(constraint.name)} }` : '';\n return `unique(${jsonToTsSource(constraint.columns)}${nameOpt})`;\n }\n case 'check-expression':\n throw new Error(\n `SQLite does not support expression CHECK constraints (constraint \"${constraint.name}\"). ` +\n 'Scalar-array columns and their element-non-null checks are Postgres-only.',\n );\n }\n}\n\nfunction constraintImportSymbols(constraints: readonly DdlTableConstraint[] | undefined): string[] {\n if (!constraints || constraints.length === 0) return [];\n const symbols = new Set<string>();\n for (const c of constraints) {\n if (c.kind === 'primary-key') symbols.add('primaryKey');\n else if (c.kind === 'foreign-key') symbols.add('foreignKey');\n else if (c.kind === 'unique') symbols.add('unique');\n }\n return [...symbols];\n}\n\nfunction defaultImportSymbols(columns: readonly DdlColumn[]): string[] {\n const symbols = new Set<string>();\n for (const col of columns) {\n if (col.default?.kind === 'literal') symbols.add('lit');\n else if (col.default?.kind === 'function') symbols.add('fn');\n }\n return [...symbols];\n}\n\nexport class CreateTableCall extends SqliteOpFactoryCallNode {\n readonly factoryName = 'createTable' as const;\n readonly operationClass = 'additive' as const;\n readonly tableName: string;\n readonly columns: readonly DdlColumn[];\n readonly constraints: readonly DdlTableConstraint[] | undefined;\n readonly label: string;\n\n constructor(\n tableName: string,\n columns: readonly DdlColumn[],\n constraints?: readonly DdlTableConstraint[],\n ) {\n super();\n this.tableName = tableName;\n this.columns = Object.freeze([...columns]);\n this.constraints = constraints ? Object.freeze([...constraints]) : undefined;\n this.label = `Create table ${tableName}`;\n this.freeze();\n }\n\n async toOp(lowerer?: ExecuteRequestLowerer): Promise<Op> {\n if (lowerer === undefined) {\n throw new Error(\n `CreateTableCall.toOp: a DDL lowerer is required on the SQLite planner path (table \"${this.tableName}\"). Pass the control adapter to createSqliteMigrationPlanner.`,\n );\n }\n const ddlNode = contractFreeDdl.createTable({\n table: this.tableName,\n columns: this.columns,\n ...ifDefined('constraints', this.constraints),\n });\n const statement = await lowerer.lowerToExecuteRequest(ddlNode);\n const tableName = this.tableName;\n const tableChecks = tableExistsAst(tableName);\n const absent = await lowerer.lowerToExecuteRequest(tableChecks.tableAbsent());\n const present = await lowerer.lowerToExecuteRequest(tableChecks.tablePresent());\n return {\n id: `table.${tableName}`,\n label: `Create table ${tableName}`,\n summary: `Creates table ${tableName} with required columns`,\n operationClass: 'additive',\n target: { id: 'sqlite', details: buildTargetDetails('table', tableName) },\n precheck: [step(`ensure table \"${tableName}\" does not exist`, absent.sql, absent.params)],\n execute: [\n {\n description: `create table \"${tableName}\"`,\n sql: statement.sql,\n params: statement.params ?? [],\n },\n ],\n postcheck: [step(`verify table \"${tableName}\" exists`, present.sql, present.params)],\n };\n }\n\n renderTypeScript(): string {\n const columnsList = this.columns.map(renderDdlColumnAsTsCall).join(', ');\n const constraintsList = this.constraints\n ? this.constraints.map(renderDdlConstraintAsTsCall).join(', ')\n : undefined;\n\n const opts: string[] = [];\n opts.push(`table: ${jsonToTsSource(this.tableName)}`);\n opts.push(`columns: [${columnsList}]`);\n if (constraintsList) opts.push(`constraints: [${constraintsList}]`);\n\n return `this.createTable({ ${opts.join(', ')} })`;\n }\n\n override importRequirements(): readonly ImportRequirement[] {\n const req: ImportRequirement[] = [];\n if (this.columns.length > 0) {\n req.push({ moduleSpecifier: TARGET_MIGRATION_MODULE, symbol: 'col' });\n for (const sym of defaultImportSymbols(this.columns)) {\n req.push({ moduleSpecifier: TARGET_MIGRATION_MODULE, symbol: sym });\n }\n }\n for (const sym of constraintImportSymbols(this.constraints)) {\n req.push({ moduleSpecifier: TARGET_MIGRATION_MODULE, symbol: sym });\n }\n return req;\n }\n}\n\nexport class DropTableCall extends SqliteOpFactoryCallNode {\n readonly factoryName = 'dropTable' as const;\n readonly operationClass = 'destructive' as const;\n readonly tableName: string;\n readonly label: string;\n\n constructor(tableName: string) {\n super();\n this.tableName = tableName;\n this.label = `Drop table ${tableName}`;\n this.freeze();\n }\n\n async toOp(lowerer?: ExecuteRequestLowerer): Promise<Op> {\n if (lowerer === undefined) {\n throw new Error(\n `DropTableCall.toOp: a lowerer is required on the SQLite planner path (table \"${this.tableName}\"). Pass the control adapter to createSqliteMigrationPlanner.`,\n );\n }\n const checks = tableExistsAst(this.tableName);\n const present = await lowerer.lowerToExecuteRequest(checks.tablePresent());\n const absent = await lowerer.lowerToExecuteRequest(checks.tableAbsent());\n return {\n id: `dropTable.${this.tableName}`,\n label: `Drop table ${this.tableName}`,\n summary: `Drops table ${this.tableName} which is not in the contract`,\n operationClass: 'destructive',\n target: { id: 'sqlite', details: buildTargetDetails('table', this.tableName) },\n precheck: [step(`ensure table \"${this.tableName}\" exists`, present.sql, present.params)],\n execute: [\n step(`drop table \"${this.tableName}\"`, `DROP TABLE ${quoteIdentifier(this.tableName)}`),\n ],\n postcheck: [step(`verify table \"${this.tableName}\" is gone`, absent.sql, absent.params)],\n };\n }\n\n renderTypeScript(): string {\n return `this.dropTable({ table: ${jsonToTsSource(this.tableName)} })`;\n }\n\n override importRequirements(): readonly ImportRequirement[] {\n return [];\n }\n}\n\nexport class RecreateTableCall extends SqliteOpFactoryCallNode {\n readonly factoryName = 'recreateTable' as const;\n readonly operationClass: MigrationOperationClass;\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 label: string;\n\n constructor(args: {\n tableName: string;\n contractTable: SqliteTableSpec;\n schemaColumnNames: readonly string[];\n indexes: readonly SqliteIndexSpec[];\n summary: string;\n postchecks: readonly { readonly description: string; readonly sql: string }[];\n operationClass: MigrationOperationClass;\n }) {\n super();\n this.tableName = args.tableName;\n this.contractTable = args.contractTable;\n this.schemaColumnNames = args.schemaColumnNames;\n this.indexes = args.indexes;\n this.summary = args.summary;\n this.postchecks = args.postchecks;\n this.operationClass = args.operationClass;\n this.label = `Recreate table ${args.tableName}`;\n this.freeze();\n }\n\n async toOp(lowerer?: ExecuteRequestLowerer): Promise<Op> {\n if (lowerer === undefined) {\n throw new Error(\n `RecreateTableCall.toOp: a lowerer is required on the SQLite planner path (table \"${this.tableName}\"). Pass the control adapter to createSqliteMigrationPlanner.`,\n );\n }\n return recreateTable(\n {\n tableName: this.tableName,\n contractTable: this.contractTable,\n schemaColumnNames: this.schemaColumnNames,\n indexes: this.indexes,\n summary: this.summary,\n postchecks: this.postchecks,\n operationClass: this.operationClass,\n },\n lowerer,\n );\n }\n\n renderTypeScript(): string {\n const args = {\n tableName: this.tableName,\n contractTable: this.contractTable,\n schemaColumnNames: this.schemaColumnNames,\n indexes: this.indexes,\n summary: this.summary,\n postchecks: this.postchecks,\n operationClass: this.operationClass,\n };\n return `this.recreateTable(${jsonToTsSource(args)})`;\n }\n\n override importRequirements(): readonly ImportRequirement[] {\n return [];\n }\n}\n\n// ============================================================================\n// Column\n// ============================================================================\n\nexport class AddColumnCall extends SqliteOpFactoryCallNode {\n readonly factoryName = 'addColumn' as const;\n readonly operationClass = 'additive' as const;\n readonly tableName: string;\n readonly columnName: string;\n readonly column: SqliteColumnSpec;\n readonly label: string;\n\n constructor(tableName: string, column: SqliteColumnSpec) {\n super();\n this.tableName = tableName;\n this.columnName = column.name;\n this.column = column;\n this.label = `Add column ${column.name} on ${tableName}`;\n this.freeze();\n }\n\n async toOp(lowerer?: ExecuteRequestLowerer): Promise<Op> {\n if (lowerer === undefined) {\n throw new Error(\n `AddColumnCall.toOp: a lowerer is required on the SQLite planner path (column \"${this.column.name}\" on table \"${this.tableName}\"). Pass the control adapter to createSqliteMigrationPlanner.`,\n );\n }\n const checks = columnExistsAst(this.tableName, this.column.name);\n const absent = await lowerer.lowerToExecuteRequest(checks.columnAbsent());\n const present = await lowerer.lowerToExecuteRequest(checks.columnPresent());\n return {\n id: `column.${this.tableName}.${this.column.name}`,\n label: `Add column ${this.column.name} on ${this.tableName}`,\n summary: `Adds column ${this.column.name} on ${this.tableName}`,\n operationClass: 'additive',\n target: {\n id: 'sqlite',\n details: buildTargetDetails('column', this.column.name, this.tableName),\n },\n precheck: [step(`ensure column \"${this.column.name}\" is missing`, absent.sql, absent.params)],\n execute: [\n step(`add column \"${this.column.name}\"`, addColumnExecuteSql(this.tableName, this.column)),\n ],\n postcheck: [step(`verify column \"${this.column.name}\" exists`, present.sql, present.params)],\n };\n }\n\n renderTypeScript(): string {\n return `this.addColumn({ table: ${jsonToTsSource(this.tableName)}, column: ${jsonToTsSource(this.column)} })`;\n }\n\n override importRequirements(): readonly ImportRequirement[] {\n return [];\n }\n}\n\nexport class DropColumnCall extends SqliteOpFactoryCallNode {\n readonly factoryName = 'dropColumn' as const;\n readonly operationClass = 'destructive' as const;\n readonly tableName: string;\n readonly columnName: string;\n readonly label: string;\n\n constructor(tableName: string, columnName: string) {\n super();\n this.tableName = tableName;\n this.columnName = columnName;\n this.label = `Drop column ${columnName} on ${tableName}`;\n this.freeze();\n }\n\n async toOp(lowerer?: ExecuteRequestLowerer): Promise<Op> {\n if (lowerer === undefined) {\n throw new Error(\n `DropColumnCall.toOp: a lowerer is required on the SQLite planner path (column \"${this.columnName}\" on table \"${this.tableName}\"). Pass the control adapter to createSqliteMigrationPlanner.`,\n );\n }\n const checks = columnExistsAst(this.tableName, this.columnName);\n const present = await lowerer.lowerToExecuteRequest(checks.columnPresent());\n const absent = await lowerer.lowerToExecuteRequest(checks.columnAbsent());\n return {\n id: `dropColumn.${this.tableName}.${this.columnName}`,\n label: `Drop column ${this.columnName} on ${this.tableName}`,\n summary: `Drops column ${this.columnName} on ${this.tableName} which is not in the contract`,\n operationClass: 'destructive',\n target: {\n id: 'sqlite',\n details: buildTargetDetails('column', this.columnName, this.tableName),\n },\n precheck: [\n step(\n `ensure column \"${this.columnName}\" exists on \"${this.tableName}\"`,\n present.sql,\n present.params,\n ),\n ],\n execute: [\n step(\n `drop column \"${this.columnName}\" from \"${this.tableName}\"`,\n dropColumnExecuteSql(this.tableName, this.columnName),\n ),\n ],\n postcheck: [\n step(\n `verify column \"${this.columnName}\" is gone from \"${this.tableName}\"`,\n absent.sql,\n absent.params,\n ),\n ],\n };\n }\n\n renderTypeScript(): string {\n return `this.dropColumn({ table: ${jsonToTsSource(this.tableName)}, column: ${jsonToTsSource(this.columnName)} })`;\n }\n\n override importRequirements(): readonly ImportRequirement[] {\n return [];\n }\n}\n\n// ============================================================================\n// Index\n// ============================================================================\n\nexport class CreateIndexCall extends SqliteOpFactoryCallNode {\n readonly factoryName = 'createIndex' as const;\n readonly operationClass = 'additive' as const;\n readonly tableName: string;\n readonly indexName: string;\n readonly columns: readonly string[];\n readonly label: string;\n\n constructor(tableName: string, indexName: string, columns: readonly string[]) {\n super();\n this.tableName = tableName;\n this.indexName = indexName;\n this.columns = columns;\n this.label = `Create index ${indexName} on ${tableName}`;\n this.freeze();\n }\n\n async toOp(lowerer?: ExecuteRequestLowerer): Promise<Op> {\n if (lowerer === undefined) {\n throw new Error(\n `CreateIndexCall.toOp: a lowerer is required on the SQLite planner path (index \"${this.indexName}\" on table \"${this.tableName}\"). Pass the control adapter to createSqliteMigrationPlanner.`,\n );\n }\n const checks = indexExistsAst(this.indexName);\n const absent = await lowerer.lowerToExecuteRequest(checks.indexAbsent());\n const present = await lowerer.lowerToExecuteRequest(checks.indexPresent());\n return {\n id: `index.${this.tableName}.${this.indexName}`,\n label: `Create index ${this.indexName} on ${this.tableName}`,\n summary: `Creates index ${this.indexName} on ${this.tableName}`,\n operationClass: 'additive',\n target: {\n id: 'sqlite',\n details: buildTargetDetails('index', this.indexName, this.tableName),\n },\n precheck: [step(`ensure index \"${this.indexName}\" is missing`, absent.sql, absent.params)],\n execute: [\n step(\n `create index \"${this.indexName}\"`,\n buildCreateIndexSql(this.tableName, this.indexName, this.columns),\n ),\n ],\n postcheck: [step(`verify index \"${this.indexName}\" exists`, present.sql, present.params)],\n };\n }\n\n renderTypeScript(): string {\n return `this.createIndex({ table: ${jsonToTsSource(this.tableName)}, index: ${jsonToTsSource(this.indexName)}, columns: ${jsonToTsSource(this.columns)} })`;\n }\n\n override importRequirements(): readonly ImportRequirement[] {\n return [];\n }\n}\n\nexport class DropIndexCall extends SqliteOpFactoryCallNode {\n readonly factoryName = 'dropIndex' as const;\n readonly operationClass = 'destructive' as const;\n readonly tableName: string;\n readonly indexName: string;\n readonly label: string;\n\n constructor(tableName: string, indexName: string) {\n super();\n this.tableName = tableName;\n this.indexName = indexName;\n this.label = `Drop index ${indexName} on ${tableName}`;\n this.freeze();\n }\n\n async toOp(lowerer?: ExecuteRequestLowerer): Promise<Op> {\n if (lowerer === undefined) {\n throw new Error(\n `DropIndexCall.toOp: a lowerer is required on the SQLite planner path (index \"${this.indexName}\" on table \"${this.tableName}\"). Pass the control adapter to createSqliteMigrationPlanner.`,\n );\n }\n const checks = indexExistsAst(this.indexName);\n const present = await lowerer.lowerToExecuteRequest(checks.indexPresent());\n const absent = await lowerer.lowerToExecuteRequest(checks.indexAbsent());\n return {\n id: `dropIndex.${this.tableName}.${this.indexName}`,\n label: `Drop index ${this.indexName} on ${this.tableName}`,\n summary: `Drops index ${this.indexName} on ${this.tableName} which is not in the contract`,\n operationClass: 'destructive',\n target: {\n id: 'sqlite',\n details: buildTargetDetails('index', this.indexName, this.tableName),\n },\n precheck: [step(`ensure index \"${this.indexName}\" exists`, present.sql, present.params)],\n execute: [step(`drop index \"${this.indexName}\"`, buildDropIndexSql(this.indexName))],\n postcheck: [step(`verify index \"${this.indexName}\" is gone`, absent.sql, absent.params)],\n };\n }\n\n renderTypeScript(): string {\n return `this.dropIndex({ table: ${jsonToTsSource(this.tableName)}, index: ${jsonToTsSource(this.indexName)} })`;\n }\n\n override importRequirements(): readonly ImportRequirement[] {\n return [];\n }\n}\n\n// ============================================================================\n// Data transform\n// ============================================================================\n\n/**\n * A planner-generated data-transform stub. The current default strategy\n * (`nullabilityTighteningBackfillStrategy`) emits one of these with a\n * backfill-flavored `id`/`label` when the policy allows `'data'` and the\n * contract tightens a column's nullability, but the op itself is generic —\n * any future strategy that needs a placeholder data step can construct one\n * with its own id/label.\n *\n * `toOp()` always throws `PN-MIG-2001`: the planner cannot lower a stubbed\n * transform to a runtime op — the user must edit the rendered\n * `migration.ts` and re-emit.\n */\nexport class DataTransformCall extends SqliteOpFactoryCallNode {\n readonly factoryName = 'dataTransform' as const;\n readonly operationClass = 'data' as const;\n readonly id: string;\n readonly label: string;\n readonly tableName: string;\n readonly columnName: string;\n\n constructor(id: string, label: string, tableName: string, columnName: string) {\n super();\n this.id = id;\n this.label = label;\n this.tableName = tableName;\n this.columnName = columnName;\n this.freeze();\n }\n\n toOp(_lowerer?: Lowerer): Op {\n throw errorUnfilledPlaceholder(this.label);\n }\n\n renderTypeScript(): string {\n const slot = `${this.tableName}-${this.columnName}-backfill-sql`;\n return [\n 'dataTransform({',\n ` id: ${jsonToTsSource(this.id)},`,\n ` label: ${jsonToTsSource(this.label)},`,\n ` table: ${jsonToTsSource(this.tableName)},`,\n ` description: ${jsonToTsSource(`Backfill NULL ${this.columnName} values in ${this.tableName}`)},`,\n ` run: () => placeholder(${jsonToTsSource(slot)}),`,\n '})',\n ].join('\\n');\n }\n\n override importRequirements(): readonly ImportRequirement[] {\n return [\n { moduleSpecifier: TARGET_MIGRATION_MODULE, symbol: this.factoryName },\n { moduleSpecifier: TARGET_MIGRATION_MODULE, symbol: 'placeholder' },\n ];\n }\n}\n\n// ============================================================================\n// Raw SQL\n// ============================================================================\n\n/**\n * Laundered pre-built operation. Mirrors Postgres's `RawSqlCall`: wraps an\n * already-materialized `SqlMigrationPlanOperation` (typically produced by a\n * SQL-family helper or a codec lifecycle hook) so the planner can carry it\n * alongside structured call IR. `toOp()` returns the stored op unchanged;\n * `renderTypeScript()` emits `rawSql({...})` with the op serialized as a\n * JSON literal — round-tripping requires every field on the op to be\n * JSON-serializable (no closures).\n */\nexport class RawSqlCall extends SqliteOpFactoryCallNode {\n readonly factoryName = 'rawSql' as const;\n readonly operationClass: MigrationOperationClass;\n readonly label: string;\n readonly op: Op;\n\n constructor(op: Op) {\n super();\n this.op = op;\n this.label = op.label;\n this.operationClass = op.operationClass;\n this.freeze();\n }\n\n toOp(_lowerer?: Lowerer): Op {\n return this.op;\n }\n\n renderTypeScript(): string {\n return `rawSql(${jsonToTsSource(this.op)})`;\n }\n}\n\n// ============================================================================\n// Union\n// ============================================================================\n\nexport type SqliteOpFactoryCall =\n | CreateTableCall\n | DropTableCall\n | RecreateTableCall\n | AddColumnCall\n | DropColumnCall\n | CreateIndexCall\n | DropIndexCall\n | DataTransformCall\n | RawSqlCall;\n"],"mappings":"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"}
|