@prisma-next/target-sqlite 0.13.0-dev.28 → 0.13.0-dev.29

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 CHANGED
@@ -2,8 +2,8 @@ import { t as sqliteTargetDescriptorMeta } from "./descriptor-meta-Dxx2A6PT.mjs"
2
2
  import { t as parseSqliteDefault } from "./default-normalizer-DuoHj9-O.mjs";
3
3
  import { t as normalizeSqliteNativeType } from "./native-type-normalizer-CiSyVmMP.mjs";
4
4
  import { r as MARKER_TABLE_NAME } from "./control-tables-7KwMyJ6i.mjs";
5
- import { y as renderDefaultLiteral } from "./op-factory-call-BX69rHxs.mjs";
6
- import { n as createSqliteMigrationPlanner } from "./planner-DOZWouPl.mjs";
5
+ import { y as renderDefaultLiteral } from "./op-factory-call-z4TT72k3.mjs";
6
+ import { n as createSqliteMigrationPlanner } from "./planner-jMHqfl1A.mjs";
7
7
  import { n as SqliteUnboundDatabase, r as sqliteCreateNamespace, t as SqliteContractSerializer } from "./sqlite-contract-serializer-B_Cu0o3G.mjs";
8
8
  import { contractToSchemaIR, runnerFailure, runnerSuccess } from "@prisma-next/family-sql/control";
9
9
  import { SqlStorage } from "@prisma-next/sql-contract/types";
@@ -1,6 +1,6 @@
1
1
  import { t as buildTargetDetails } from "./planner-target-details-H8z9TFDg.mjs";
2
- import { C as step, S as dropColumn, f as dropTable, h as dropIndex, m as createIndex, p as recreateTable, x as addColumn } from "./op-factory-call-BX69rHxs.mjs";
3
- import { t as SqliteMigration } from "./sqlite-migration-CCYnBXZp.mjs";
2
+ import { C as step, S as dropColumn, f as dropTable, h as dropIndex, m as createIndex, p as recreateTable, x as addColumn } from "./op-factory-call-z4TT72k3.mjs";
3
+ import { t as SqliteMigration } from "./sqlite-migration-DhW4ycZV.mjs";
4
4
  import { placeholder } from "@prisma-next/errors/migration";
5
5
  import { col, fn, foreignKey, lit, primaryKey, unique } from "@prisma-next/sql-relational-core/contract-free";
6
6
  import { MigrationCLI } from "@prisma-next/cli/migration-cli";
@@ -2,7 +2,6 @@ import { n as stripOuterParens } from "./default-normalizer-DuoHj9-O.mjs";
2
2
  import { t as createTable } from "./ddl-CH8V_qcd.mjs";
3
3
  import { n as escapeLiteral, r as quoteIdentifier } from "./sql-utils-CV8Bdgtc.mjs";
4
4
  import { t as buildTargetDetails } from "./planner-target-details-H8z9TFDg.mjs";
5
- import { isPostgresEnumStorageEntry } from "@prisma-next/sql-contract/types";
6
5
  import { ifDefined } from "@prisma-next/utils/defined";
7
6
  import { errorUnfilledPlaceholder } from "@prisma-next/errors/migration";
8
7
  import { TsExpression, jsonToTsSource } from "@prisma-next/ts-render";
@@ -82,15 +81,6 @@ function dropColumn(tableName, columnName) {
82
81
  }
83
82
  //#endregion
84
83
  //#region src/core/migrations/planner-ddl-builders.ts
85
- /**
86
- * Low-level DDL fragment builders for SQLite migrations.
87
- *
88
- * These helpers consume `StorageColumn` (the contract shape, possibly with
89
- * `typeRef`) and produce string fragments. They are called once per column
90
- * at the call-construction boundary in `issue-planner.ts` / strategies to
91
- * build flat `SqliteColumnSpec`s; the operation factories themselves never
92
- * see `StorageColumn` or `storageTypes`.
93
- */
94
84
  const SAFE_NATIVE_TYPE_PATTERN = /^[a-zA-Z][a-zA-Z0-9_ ]*$/;
95
85
  function assertSafeNativeType(nativeType) {
96
86
  if (!SAFE_NATIVE_TYPE_PATTERN.test(nativeType)) throw new Error(`Unsafe native type name in contract: "${nativeType}". Native type names must match /^[a-zA-Z][a-zA-Z0-9_ ]*\$/`);
@@ -156,11 +146,6 @@ function resolveColumnTypeMetadata(column, storageTypes) {
156
146
  if (!column.typeRef) return column;
157
147
  const referencedType = storageTypes[column.typeRef];
158
148
  if (!referencedType) throw new Error(`Storage type "${column.typeRef}" referenced by column is not defined in storage.types.`);
159
- if (isPostgresEnumStorageEntry(referencedType)) return {
160
- codecId: referencedType.codecId,
161
- nativeType: referencedType.nativeType,
162
- typeParams: { values: referencedType.values }
163
- };
164
149
  return {
165
150
  codecId: referencedType.codecId,
166
151
  nativeType: referencedType.nativeType,
@@ -767,4 +752,4 @@ var RawSqlCall = class extends SqliteOpFactoryCallNode {
767
752
  //#endregion
768
753
  export { step as C, dropColumn as S, buildColumnTypeSql as _, DropColumnCall as a, resolveColumnTypeMetadata as b, RawSqlCall as c, buildRecreateSummary as d, dropTable as f, buildColumnDefaultSql as g, dropIndex as h, DataTransformCall as i, RecreateTableCall as l, createIndex as m, CreateIndexCall as n, DropIndexCall as o, recreateTable as p, CreateTableCall as r, DropTableCall as s, AddColumnCall as t, buildRecreatePostchecks as u, isInlineAutoincrementPrimaryKey as v, addColumn as x, renderDefaultLiteral as y };
769
754
 
770
- //# sourceMappingURL=op-factory-call-BX69rHxs.mjs.map
755
+ //# sourceMappingURL=op-factory-call-z4TT72k3.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"op-factory-call-z4TT72k3.mjs","names":["contractFreeDdl.createTable"],"sources":["../src/core/migrations/operations/shared.ts","../src/core/migrations/operations/columns.ts","../src/core/migrations/planner-ddl-builders.ts","../src/core/migrations/operations/indexes.ts","../src/core/migrations/operations/tables.ts","../src/core/migrations/op-factory-call.ts"],"sourcesContent":["import type { SqlMigrationPlanOperation } 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 { quoteIdentifier } from '../../sql-utils';\nimport type { SqlitePlanTargetDetails } from '../planner-target-details';\n\nexport type Op = SqlMigrationPlanOperation<SqlitePlanTargetDetails>;\n\nexport function step(description: string, sql: string): { description: string; sql: string } {\n return { description, sql };\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 readonly constraint: boolean;\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. Returns the empty string when `constraint` is false (the FK is\n * tracked at the contract level for index-creation purposes only and must\n * not produce DDL).\n */\nexport function renderForeignKeyClause(fk: SqliteForeignKeySpec): string {\n if (!fk.constraint) return '';\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 { escapeLiteral, quoteIdentifier } from '../../sql-utils';\nimport { buildTargetDetails } from '../planner-target-details';\nimport { type Op, type SqliteColumnSpec, step } from './shared';\n\nexport function addColumn(tableName: string, column: SqliteColumnSpec): Op {\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 const addSql = parts.join(' ');\n\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: [\n step(\n `ensure column \"${column.name}\" is missing`,\n `SELECT COUNT(*) = 0 FROM pragma_table_info('${escapeLiteral(tableName)}') WHERE name = '${escapeLiteral(column.name)}'`,\n ),\n ],\n execute: [step(`add column \"${column.name}\"`, addSql)],\n postcheck: [\n step(\n `verify column \"${column.name}\" exists`,\n `SELECT COUNT(*) > 0 FROM pragma_table_info('${escapeLiteral(tableName)}') WHERE name = '${escapeLiteral(column.name)}'`,\n ),\n ],\n };\n}\n\nexport function dropColumn(tableName: string, columnName: string): Op {\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(\n `ensure column \"${columnName}\" exists on \"${tableName}\"`,\n `SELECT COUNT(*) > 0 FROM pragma_table_info('${escapeLiteral(tableName)}') WHERE name = '${escapeLiteral(columnName)}'`,\n ),\n ],\n execute: [\n step(\n `drop column \"${columnName}\" from \"${tableName}\"`,\n `ALTER TABLE ${quoteIdentifier(tableName)} DROP COLUMN ${quoteIdentifier(columnName)}`,\n ),\n ],\n postcheck: [\n step(\n `verify column \"${columnName}\" is gone from \"${tableName}\"`,\n `SELECT COUNT(*) = 0 FROM pragma_table_info('${escapeLiteral(tableName)}') WHERE name = '${escapeLiteral(columnName)}'`,\n ),\n ],\n };\n}\n","/**\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 { escapeLiteral } from '../../sql-utils';\nimport { buildCreateIndexSql, buildDropIndexSql } from '../planner-ddl-builders';\nimport { buildTargetDetails } from '../planner-target-details';\nimport { type Op, step } from './shared';\n\nexport function createIndex(tableName: string, indexName: string, columns: readonly string[]): Op {\n return {\n id: `index.${tableName}.${indexName}`,\n label: `Create index ${indexName} on ${tableName}`,\n summary: `Creates index ${indexName} on ${tableName}`,\n operationClass: 'additive',\n target: { id: 'sqlite', details: buildTargetDetails('index', indexName, tableName) },\n precheck: [\n step(\n `ensure index \"${indexName}\" is missing`,\n `SELECT COUNT(*) = 0 FROM sqlite_master WHERE type = 'index' AND name = '${escapeLiteral(indexName)}'`,\n ),\n ],\n execute: [\n step(`create index \"${indexName}\"`, buildCreateIndexSql(tableName, indexName, columns)),\n ],\n postcheck: [\n step(\n `verify index \"${indexName}\" exists`,\n `SELECT COUNT(*) > 0 FROM sqlite_master WHERE type = 'index' AND name = '${escapeLiteral(indexName)}'`,\n ),\n ],\n };\n}\n\nexport function dropIndex(tableName: string, indexName: string): Op {\n return {\n id: `dropIndex.${tableName}.${indexName}`,\n label: `Drop index ${indexName} on ${tableName}`,\n summary: `Drops index ${indexName} on ${tableName} which is not in the contract`,\n operationClass: 'destructive',\n target: { id: 'sqlite', details: buildTargetDetails('index', indexName, tableName) },\n precheck: [\n step(\n `ensure index \"${indexName}\" exists`,\n `SELECT COUNT(*) > 0 FROM sqlite_master WHERE type = 'index' AND name = '${escapeLiteral(indexName)}'`,\n ),\n ],\n execute: [step(`drop index \"${indexName}\"`, buildDropIndexSql(indexName))],\n postcheck: [\n step(\n `verify index \"${indexName}\" is gone`,\n `SELECT COUNT(*) = 0 FROM sqlite_master WHERE type = 'index' AND name = '${escapeLiteral(indexName)}'`,\n ),\n ],\n };\n}\n","import type { MigrationOperationClass } from '@prisma-next/family-sql/control';\nimport type { SchemaIssue } from '@prisma-next/framework-components/control';\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\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 function createTable(tableName: string, spec: SqliteTableSpec): Op {\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: [\n step(\n `ensure table \"${tableName}\" does not exist`,\n `SELECT COUNT(*) = 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapeLiteral(tableName)}'`,\n ),\n ],\n execute: [step(`create table \"${tableName}\"`, renderCreateTableSql(tableName, spec))],\n postcheck: [\n step(\n `verify table \"${tableName}\" exists`,\n `SELECT COUNT(*) > 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapeLiteral(tableName)}'`,\n ),\n ],\n };\n}\n\nexport function dropTable(tableName: string): Op {\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: [\n step(\n `ensure table \"${tableName}\" exists`,\n `SELECT COUNT(*) > 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapeLiteral(tableName)}'`,\n ),\n ],\n execute: [step(`drop table \"${tableName}\"`, `DROP TABLE ${quoteIdentifier(tableName)}`)],\n postcheck: [\n step(\n `verify table \"${tableName}\" is gone`,\n `SELECT COUNT(*) = 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapeLiteral(tableName)}'`,\n ),\n ],\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 `SchemaIssue` references.\n */\n readonly postchecks: readonly { readonly description: string; readonly sql: string }[];\n readonly operationClass: MigrationOperationClass;\n}\n\nexport function recreateTable(args: RecreateTableArgs): 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 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(\n `ensure table \"${tableName}\" exists`,\n `SELECT COUNT(*) > 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapeLiteral(tableName)}'`,\n ),\n step(\n `ensure temp table \"${tempName}\" does not exist`,\n `SELECT COUNT(*) = 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapeLiteral(tempName)}'`,\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(\n `verify table \"${tableName}\" exists`,\n `SELECT COUNT(*) > 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapeLiteral(tableName)}'`,\n ),\n step(\n `verify temp table \"${tempName}\" is gone`,\n `SELECT COUNT(*) = 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapeLiteral(tempName)}'`,\n ),\n ...postchecks,\n ],\n };\n}\n\n/**\n * Build a one-line summary of a recreate-table operation from the schema\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.\n */\nexport function buildRecreateSummary(tableName: string, issues: readonly SchemaIssue[]): string {\n const messages = issues.map((i) => i.message).join('; ');\n return `Recreates table ${tableName} to apply schema changes: ${messages}`;\n}\n\nconst COLUMN_LEVEL_ISSUE_KINDS = new Set<SchemaIssue['kind']>([\n 'nullability_mismatch',\n 'default_mismatch',\n 'default_missing',\n 'extra_default',\n 'type_mismatch',\n]);\n\nconst PK_ISSUE_KINDS = new Set<SchemaIssue['kind']>(['primary_key_mismatch', 'extra_primary_key']);\n\nconst UNIQUE_ISSUE_KINDS = new Set<SchemaIssue['kind']>([\n 'unique_constraint_mismatch',\n 'extra_unique_constraint',\n]);\n\nconst FK_ISSUE_KINDS = new Set<SchemaIssue['kind']>(['foreign_key_mismatch', 'extra_foreign_key']);\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\n/**\n * Per-issue postchecks verifying the recreated table's shape against the\n * contract spec. Column-level issues (`nullability_mismatch`,\n * `default_mismatch`, …) emit one targeted check each; constraint-level\n * issues (`primary_key_mismatch`, `unique_constraint_mismatch`,\n * `foreign_key_mismatch`, plus their `extra_*` siblings) emit one\n * `pragma_*`-driven check per declared constraint in the contract spec, so\n * a recreated table with the right columns but the wrong PK / unique / FK\n * shape fails the postcheck instead of passing silently. Exported so the\n * planner can pre-build the list at construction time and\n * `RecreateTableCall` doesn't have to carry `SchemaIssue` objects through\n * to render time.\n */\nexport function buildRecreatePostchecks(\n tableName: string,\n issues: readonly SchemaIssue[],\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 for (const issue of issues) {\n if (issue.kind === 'enum_values_changed') continue;\n if (!COLUMN_LEVEL_ISSUE_KINDS.has(issue.kind)) continue;\n if (!issue.column) continue;\n const c = escapeLiteral(issue.column);\n if (issue.kind === 'nullability_mismatch') {\n // `expected` carries the contract's nullable flag as a string. We only\n // emit a postcheck when the value is recognized — anything else\n // (case-folded, numeric coding, etc.) is left to the structural\n // verifier so a typo here can't silently invert the meaning.\n let wantNotNull: boolean | undefined;\n if (issue.expected === 'false') wantNotNull = true;\n else if (issue.expected === 'true') wantNotNull = false;\n if (wantNotNull !== undefined) {\n checks.push({\n description: `verify \"${issue.column}\" nullability on \"${tableName}\"`,\n sql: `SELECT COUNT(*) > 0 FROM pragma_table_info('${t}') WHERE name = '${c}' AND \"notnull\" = ${wantNotNull ? 1 : 0}`,\n });\n }\n }\n if (issue.kind === 'default_mismatch' || issue.kind === 'default_missing') {\n const colSpec = byName.get(issue.column);\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 \"${issue.column}\" default on \"${tableName}\"`,\n sql: `SELECT COUNT(*) > 0 FROM pragma_table_info('${t}') WHERE name = '${c}' AND dflt_value = '${escapeLiteral(expectedRaw)}'`,\n });\n }\n }\n if (issue.kind === 'type_mismatch') {\n const colSpec = byName.get(issue.column);\n if (colSpec) {\n checks.push({\n description: `verify \"${issue.column}\" 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 if (issue.kind === 'extra_default') {\n checks.push({\n description: `verify \"${issue.column}\" 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 }\n }\n\n // Constraint-level issues — emit one postcheck per declared constraint in\n // the contract spec when *any* issue of that kind fires, since recreate\n // rebuilds the entire table at once.\n const hasPkIssue = issues.some((i) => PK_ISSUE_KINDS.has(i.kind));\n const hasUniqueIssue = issues.some((i) => UNIQUE_ISSUE_KINDS.has(i.kind));\n const hasFkIssue = issues.some((i) => FK_ISSUE_KINDS.has(i.kind));\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 * as contractFreeDdl from '../../contract-free/ddl';\nimport { escapeLiteral } from '../sql-utils';\nimport { addColumn, dropColumn } from './operations/columns';\nimport { createIndex, dropIndex } from './operations/indexes';\nimport type { SqliteColumnSpec, SqliteIndexSpec, SqliteTableSpec } from './operations/shared';\nimport { step } from './operations/shared';\nimport { dropTable, recreateTable } from './operations/tables';\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 }\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 escapedName = escapeLiteral(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: [\n step(\n `ensure table \"${tableName}\" does not exist`,\n `SELECT COUNT(*) = 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapedName}'`,\n ),\n ],\n execute: [\n {\n description: `create table \"${tableName}\"`,\n sql: statement.sql,\n params: statement.params ?? [],\n },\n ],\n postcheck: [\n step(\n `verify table \"${tableName}\" exists`,\n `SELECT COUNT(*) > 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapedName}'`,\n ),\n ],\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 toOp(_lowerer?: Lowerer): Op {\n return dropTable(this.tableName);\n }\n\n renderTypeScript(): string {\n return `dropTable(${jsonToTsSource(this.tableName)})`;\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 toOp(_lowerer?: Lowerer): Op {\n return recreateTable({\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 }\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 `recreateTable(${jsonToTsSource(args)})`;\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 toOp(_lowerer?: Lowerer): Op {\n return addColumn(this.tableName, this.column);\n }\n\n renderTypeScript(): string {\n return `addColumn(${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.column)})`;\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 toOp(_lowerer?: Lowerer): Op {\n return dropColumn(this.tableName, this.columnName);\n }\n\n renderTypeScript(): string {\n return `dropColumn(${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.columnName)})`;\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 toOp(_lowerer?: Lowerer): Op {\n return createIndex(this.tableName, this.indexName, this.columns);\n }\n\n renderTypeScript(): string {\n return `createIndex(${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.indexName)}, ${jsonToTsSource(this.columns)})`;\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 toOp(_lowerer?: Lowerer): Op {\n return dropIndex(this.tableName, this.indexName);\n }\n\n renderTypeScript(): string {\n return `dropIndex(${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.indexName)})`;\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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"}
@@ -1,2 +1,2 @@
1
- import { a as DropColumnCall, c as RawSqlCall, i as DataTransformCall, l as RecreateTableCall, n as CreateIndexCall, o as DropIndexCall, r as CreateTableCall, s as DropTableCall, t as AddColumnCall } from "./op-factory-call-BX69rHxs.mjs";
1
+ import { a as DropColumnCall, c as RawSqlCall, i as DataTransformCall, l as RecreateTableCall, n as CreateIndexCall, o as DropIndexCall, r as CreateTableCall, s as DropTableCall, t as AddColumnCall } from "./op-factory-call-z4TT72k3.mjs";
2
2
  export { AddColumnCall, CreateIndexCall, CreateTableCall, DataTransformCall, DropColumnCall, DropIndexCall, DropTableCall, RawSqlCall, RecreateTableCall };
@@ -1,8 +1,8 @@
1
1
  import { t as parseSqliteDefault } from "./default-normalizer-DuoHj9-O.mjs";
2
2
  import { t as normalizeSqliteNativeType } from "./native-type-normalizer-CiSyVmMP.mjs";
3
3
  import { t as CONTROL_TABLE_NAMES } from "./control-tables-7KwMyJ6i.mjs";
4
- import { _ as buildColumnTypeSql, a as DropColumnCall, b as resolveColumnTypeMetadata, d as buildRecreateSummary, g as buildColumnDefaultSql, i as DataTransformCall, l as RecreateTableCall, n as CreateIndexCall, o as DropIndexCall, r as CreateTableCall, s as DropTableCall, t as AddColumnCall, u as buildRecreatePostchecks, v as isInlineAutoincrementPrimaryKey } from "./op-factory-call-BX69rHxs.mjs";
5
- import { t as TypeScriptRenderableSqliteMigration } from "./planner-produced-sqlite-migration-DwQSUgSk.mjs";
4
+ import { _ as buildColumnTypeSql, a as DropColumnCall, b as resolveColumnTypeMetadata, d as buildRecreateSummary, g as buildColumnDefaultSql, i as DataTransformCall, l as RecreateTableCall, n as CreateIndexCall, o as DropIndexCall, r as CreateTableCall, s as DropTableCall, t as AddColumnCall, u as buildRecreatePostchecks, v as isInlineAutoincrementPrimaryKey } from "./op-factory-call-z4TT72k3.mjs";
5
+ import { t as TypeScriptRenderableSqliteMigration } from "./planner-produced-sqlite-migration-CyyvoPmm.mjs";
6
6
  import { DdlColumn, ForeignKeyConstraint, FunctionColumnDefault, LiteralColumnDefault, PrimaryKeyConstraint, UniqueConstraint } from "@prisma-next/sql-relational-core/ast";
7
7
  import { extractCodecControlHooks, planFieldEventOperations, plannerFailure } from "@prisma-next/family-sql/control";
8
8
  import { UNBOUND_NAMESPACE_ID } from "@prisma-next/framework-components/ir";
@@ -619,4 +619,4 @@ var SqliteMigrationPlanner = class {
619
619
  //#endregion
620
620
  export { createSqliteMigrationPlanner as n, SqliteMigrationPlanner as t };
621
621
 
622
- //# sourceMappingURL=planner-DOZWouPl.mjs.map
622
+ //# sourceMappingURL=planner-jMHqfl1A.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planner-jMHqfl1A.mjs","names":["exhaustive","#lowerer"],"sources":["../src/core/migrations/planner-strategies.ts","../src/core/migrations/issue-planner.ts","../src/core/migrations/planner.ts"],"sourcesContent":["/**\n * SQLite migration strategies.\n *\n * Each strategy examines the issue list, consumes issues it handles, and\n * returns the `SqliteOpFactoryCall[]` to address them. The issue planner\n * runs each strategy in order and routes whatever's left through\n * `mapIssueToCall`.\n *\n * SQLite has no enums, no data-safe backfill, and no component-declared\n * database dependencies. The only recipe that needs strategy-level\n * multi-issue consumption is `recreateTable` (added in a later phase), which\n * absorbs type/nullability/default/constraint mismatches for a given table\n * into a single recreate operation.\n */\n\nimport type { Contract } from '@prisma-next/contract/types';\nimport type {\n CodecControlHooks,\n MigrationOperationClass,\n MigrationOperationPolicy,\n} from '@prisma-next/family-sql/control';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type { SchemaIssue } from '@prisma-next/framework-components/control';\nimport { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';\nimport type {\n SqlStorage,\n StorageTable,\n StorageTypeInstance,\n} from '@prisma-next/sql-contract/types';\nimport { defaultIndexName } from '@prisma-next/sql-schema-ir/naming';\nimport type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';\nimport { toTableSpec } from './issue-planner';\nimport { DataTransformCall, RecreateTableCall, type SqliteOpFactoryCall } from './op-factory-call';\nimport type { SqliteIndexSpec } from './operations/shared';\nimport { buildRecreatePostchecks, buildRecreateSummary } from './operations/tables';\n\nexport interface StrategyContext {\n readonly toContract: Contract<SqlStorage>;\n readonly fromContract: Contract<SqlStorage> | null;\n readonly codecHooks: ReadonlyMap<string, CodecControlHooks>;\n readonly storageTypes: Readonly<Record<string, StorageTypeInstance>>;\n readonly schema: SqlSchemaIR;\n readonly policy: MigrationOperationPolicy;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;\n}\n\n/**\n * Look up a storage table by its explicit namespace coordinate. Returns\n * `undefined` when the namespace has no table by that name (or no such\n * namespace exists). Callers that get `undefined` MUST treat it as an\n * explicit conflict rather than silently falling back to a name-only\n * walk across namespaces — the SQLite target currently has a single\n * namespace, but this helper enforces the explicit-coordinate\n * discipline so a future multi-namespace SQLite shape inherits the\n * conflict-on-stale-coordinate behaviour the Postgres planner already\n * has.\n */\nexport function tableAt(\n storage: SqlStorage,\n namespaceId: string,\n tableName: string,\n): StorageTable | undefined {\n const ns = storage.namespaces[namespaceId];\n return ns !== undefined ? ns.entries.table?.[tableName] : undefined;\n}\n\n/**\n * Default namespace coordinate for an issue that does not carry one\n * explicitly. Hand-crafted unit-test issues fall back to `__unbound__`,\n * the only namespace any single-namespace contract carries —\n * verifier-emitted issues for legacy single-namespace contracts already\n * stamp this id explicitly. Typed structurally so issue variants\n * without a `namespaceId` slot flow through to the same fallback.\n */\nexport function resolveNamespaceIdForIssue(issue: { readonly namespaceId?: string }): string {\n return issue.namespaceId ?? UNBOUND_NAMESPACE_ID;\n}\n\nexport type CallMigrationStrategy = (\n issues: readonly SchemaIssue[],\n context: StrategyContext,\n) =>\n | {\n kind: 'match';\n issues: readonly SchemaIssue[];\n calls: readonly SqliteOpFactoryCall[];\n recipe?: boolean;\n }\n | { kind: 'no_match' };\n\n// ============================================================================\n// Recreate-table strategy\n// ============================================================================\n\nconst WIDENING_ISSUE_KINDS = new Set<SchemaIssue['kind']>(['default_mismatch', 'default_missing']);\n\nconst DESTRUCTIVE_ISSUE_KINDS = new Set<SchemaIssue['kind']>([\n 'extra_default',\n 'type_mismatch',\n 'primary_key_mismatch',\n 'foreign_key_mismatch',\n 'unique_constraint_mismatch',\n 'extra_foreign_key',\n 'extra_unique_constraint',\n 'extra_primary_key',\n]);\n\nfunction classifyIssue(issue: SchemaIssue): 'widening' | 'destructive' | null {\n if (issue.kind === 'enum_values_changed') return null;\n if (!issue.table) return null;\n if (issue.kind === 'nullability_mismatch') {\n // Relaxing (NOT NULL → nullable) is widening; tightening is destructive.\n return issue.expected === 'true' ? 'widening' : 'destructive';\n }\n if (WIDENING_ISSUE_KINDS.has(issue.kind)) return 'widening';\n if (DESTRUCTIVE_ISSUE_KINDS.has(issue.kind)) return 'destructive';\n return null;\n}\n\n/**\n * Groups recreate-eligible issues by table, decides per-table operation class\n * (destructive wins over widening), and emits one `RecreateTableCall` per\n * table. Returns unchanged-or-smaller issue list — issues the strategy\n * consumed are removed so `mapIssueToCall` doesn't double-handle them.\n */\nexport const recreateTableStrategy: CallMigrationStrategy = (issues, ctx) => {\n const byTable = new Map<\n string,\n { issues: SchemaIssue[]; hasDestructive: boolean; namespaceId: string }\n >();\n const consumed = new Set<SchemaIssue>();\n\n for (const issue of issues) {\n const cls = classifyIssue(issue);\n if (!cls) continue;\n if (issue.kind === 'enum_values_changed') continue;\n if (!issue.table) continue;\n const table = issue.table;\n const entry = byTable.get(table);\n if (entry) {\n entry.issues.push(issue);\n if (cls === 'destructive') entry.hasDestructive = true;\n } else {\n byTable.set(table, {\n issues: [issue],\n hasDestructive: cls === 'destructive',\n namespaceId: resolveNamespaceIdForIssue(issue),\n });\n }\n consumed.add(issue);\n }\n\n if (byTable.size === 0) return { kind: 'no_match' };\n\n const calls: SqliteOpFactoryCall[] = [];\n for (const [tableName, entry] of byTable) {\n const contractTable = tableAt(ctx.toContract.storage, entry.namespaceId, tableName);\n const schemaTable = ctx.schema.tables[tableName];\n if (!contractTable || !schemaTable) continue;\n const operationClass: MigrationOperationClass = entry.hasDestructive\n ? 'destructive'\n : 'widening';\n\n // Flatten the contract table to a self-contained spec — the Call holds\n // pre-rendered SQL fragments only, no `StorageColumn` or `storageTypes`.\n const tableSpec = toTableSpec(contractTable, ctx.storageTypes);\n\n const seenIndexColumnKeys = new Set<string>();\n const indexes: SqliteIndexSpec[] = [];\n for (const idx of contractTable.indexes) {\n const key = idx.columns.join(',');\n if (seenIndexColumnKeys.has(key)) continue;\n seenIndexColumnKeys.add(key);\n indexes.push({\n name: idx.name ?? defaultIndexName(tableName, idx.columns),\n columns: idx.columns,\n });\n }\n for (const fk of contractTable.foreignKeys) {\n if (fk.index === false) continue;\n const key = fk.source.columns.join(',');\n if (seenIndexColumnKeys.has(key)) continue;\n seenIndexColumnKeys.add(key);\n indexes.push({\n name: defaultIndexName(tableName, fk.source.columns),\n columns: fk.source.columns,\n });\n }\n\n calls.push(\n new RecreateTableCall({\n tableName,\n contractTable: tableSpec,\n schemaColumnNames: Object.keys(schemaTable.columns),\n indexes,\n summary: buildRecreateSummary(tableName, entry.issues),\n postchecks: buildRecreatePostchecks(tableName, entry.issues, tableSpec),\n operationClass,\n }),\n );\n }\n\n return {\n kind: 'match',\n issues: issues.filter((i) => !consumed.has(i)),\n calls,\n recipe: true,\n };\n};\n\n// ============================================================================\n// Nullability-tightening backfill strategy\n// ============================================================================\n\n/**\n * When the policy allows `'data'` and the contract tightens one or more\n * columns from nullable to NOT NULL, emit a `DataTransformCall` stub per\n * tightened column. The user fills the backfill `UPDATE` in the rendered\n * `migration.ts` before the subsequent `RecreateTableCall` copies data into\n * the tightened schema (whose `INSERT INTO temp SELECT … FROM old` would\n * otherwise fail at runtime if any `NULL`s remain).\n *\n * Does NOT consume the tightening issue — `recreateTableStrategy` still\n * needs it to produce the actual recreate that enforces the NOT NULL at\n * the schema level. The backfill op and the recreate op end up in the\n * recipe slot in strategy order (backfill first, recreate second), which\n * matches the required execution order.\n *\n * Mirrors Postgres's `nullableTighteningCallStrategy` / `'data'`-class\n * gating. When `'data'` is not in the policy (the default `db update` /\n * `db init` path), the strategy short-circuits and the recreate alone\n * runs with its current destructive-class gating — preserving today's\n * behavior where a tightening blows up at runtime if NULLs are present.\n */\nexport const nullabilityTighteningBackfillStrategy: CallMigrationStrategy = (issues, ctx) => {\n if (!ctx.policy.allowedOperationClasses.includes('data')) {\n return { kind: 'no_match' };\n }\n\n const calls: SqliteOpFactoryCall[] = [];\n for (const issue of issues) {\n if (issue.kind !== 'nullability_mismatch') continue;\n if (!issue.table || !issue.column) continue;\n // Tightening only: `expected === 'true'` means the contract wants the\n // column nullable (relaxing from NOT NULL → nullable), which is safe and\n // needs no backfill.\n if (issue.expected === 'true') continue;\n\n const namespaceId = resolveNamespaceIdForIssue(issue);\n const column = tableAt(ctx.toContract.storage, namespaceId, issue.table)?.columns[issue.column];\n if (!column || column.nullable === true) continue;\n\n calls.push(\n new DataTransformCall(\n `data_migration.backfill-${issue.table}-${issue.column}`,\n `Backfill NULLs in \"${issue.table}\".\"${issue.column}\" before NOT NULL tightening`,\n issue.table,\n issue.column,\n ),\n );\n }\n\n if (calls.length === 0) return { kind: 'no_match' };\n\n return {\n kind: 'match',\n issues,\n calls,\n recipe: true,\n };\n};\n\nexport const sqlitePlannerStrategies: readonly CallMigrationStrategy[] = [\n nullabilityTighteningBackfillStrategy,\n recreateTableStrategy,\n];\n","/**\n * SQLite migration issue planner.\n *\n * Takes schema issues (from `verifySqlSchema`) and emits migration IR\n * (`SqliteOpFactoryCall[]`). Strategies consume issues they recognize and\n * produce specialized call sequences (e.g. recreateTableStrategy absorbs\n * type/nullability/default/constraint mismatches into a single recreate op);\n * remaining issues flow through `mapIssueToCall` for the default case.\n */\n\nimport type { Contract, JsonValue } from '@prisma-next/contract/types';\nimport type {\n CodecControlHooks,\n MigrationOperationPolicy,\n SqlPlannerConflict,\n SqlPlannerConflictLocation,\n} from '@prisma-next/family-sql/control';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type { SchemaIssue } from '@prisma-next/framework-components/control';\nimport type {\n SqlStorage,\n StorageColumn,\n StorageTable,\n StorageTypeInstance,\n} from '@prisma-next/sql-contract/types';\nimport type { CodecRef, DdlTableConstraint } from '@prisma-next/sql-relational-core/ast';\nimport {\n DdlColumn,\n ForeignKeyConstraint,\n FunctionColumnDefault,\n LiteralColumnDefault,\n PrimaryKeyConstraint,\n UniqueConstraint,\n} from '@prisma-next/sql-relational-core/ast';\nimport { defaultIndexName } from '@prisma-next/sql-schema-ir/naming';\nimport type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { Result } from '@prisma-next/utils/result';\nimport { notOk, ok } from '@prisma-next/utils/result';\nimport { CONTROL_TABLE_NAMES } from '../control-tables';\nimport {\n AddColumnCall,\n CreateIndexCall,\n CreateTableCall,\n DropColumnCall,\n DropIndexCall,\n DropTableCall,\n type SqliteOpFactoryCall,\n} from './op-factory-call';\nimport type {\n SqliteColumnSpec,\n SqliteForeignKeySpec,\n SqliteTableSpec,\n SqliteUniqueSpec,\n} from './operations/shared';\nimport {\n buildColumnDefaultSql,\n buildColumnTypeSql,\n isInlineAutoincrementPrimaryKey,\n resolveColumnTypeMetadata,\n} from './planner-ddl-builders';\nimport {\n type CallMigrationStrategy,\n resolveNamespaceIdForIssue,\n type StrategyContext,\n sqlitePlannerStrategies,\n tableAt,\n} from './planner-strategies';\n\nexport type { CallMigrationStrategy, StrategyContext };\n\n// ============================================================================\n// Issue kind ordering (dependency order)\n// ============================================================================\n\nconst ISSUE_KIND_ORDER: Record<string, number> = {\n // Drops (reconciliation — clear the way for creates)\n extra_foreign_key: 10,\n extra_unique_constraint: 11,\n extra_primary_key: 12,\n extra_index: 13,\n extra_default: 14,\n extra_column: 15,\n extra_table: 16,\n\n // Tables before columns\n missing_table: 20,\n\n // Columns before constraints\n missing_column: 30,\n\n // Reconciliation alters (on existing objects)\n type_mismatch: 40,\n nullability_mismatch: 41,\n default_missing: 42,\n default_mismatch: 43,\n\n // Constraints after columns exist\n primary_key_mismatch: 50,\n unique_constraint_mismatch: 51,\n index_mismatch: 52,\n foreign_key_mismatch: 60,\n};\n\nfunction issueOrder(issue: SchemaIssue): number {\n return ISSUE_KIND_ORDER[issue.kind] ?? 99;\n}\n\nfunction issueKey(issue: SchemaIssue): string {\n const table = 'table' in issue && typeof issue.table === 'string' ? issue.table : '';\n const column = 'column' in issue && typeof issue.column === 'string' ? issue.column : '';\n const name =\n 'indexOrConstraint' in issue && typeof issue.indexOrConstraint === 'string'\n ? issue.indexOrConstraint\n : '';\n return `${table}\\u0000${column}\\u0000${name}`;\n}\n\n// ============================================================================\n// Conflict helpers\n// ============================================================================\n\nfunction issueConflict(\n kind: SqlPlannerConflict['kind'],\n summary: string,\n location?: SqlPlannerConflict['location'],\n): SqlPlannerConflict {\n return {\n kind,\n summary,\n why: 'Use `migration new` to author a custom migration for this change.',\n ...(location ? { location } : {}),\n };\n}\n\nfunction conflictKindForIssue(issue: SchemaIssue): SqlPlannerConflict['kind'] {\n switch (issue.kind) {\n case 'type_mismatch':\n return 'typeMismatch';\n case 'nullability_mismatch':\n return 'nullabilityConflict';\n case 'primary_key_mismatch':\n case 'unique_constraint_mismatch':\n case 'index_mismatch':\n case 'extra_primary_key':\n case 'extra_unique_constraint':\n return 'indexIncompatible';\n case 'foreign_key_mismatch':\n case 'extra_foreign_key':\n return 'foreignKeyConflict';\n default:\n return 'missingButNonAdditive';\n }\n}\n\nfunction issueLocation(issue: SchemaIssue): SqlPlannerConflictLocation | undefined {\n if (issue.kind === 'enum_values_changed') return undefined;\n const location: {\n table?: string;\n column?: string;\n constraint?: string;\n } = {};\n if (issue.table) location.table = issue.table;\n if (issue.column) location.column = issue.column;\n if (issue.indexOrConstraint) location.constraint = issue.indexOrConstraint;\n return Object.keys(location).length > 0 ? (location as SqlPlannerConflictLocation) : undefined;\n}\n\nfunction conflictForDisallowedCall(\n call: SqliteOpFactoryCall,\n allowed: readonly string[],\n): SqlPlannerConflict {\n const summary = `Operation \"${call.label}\" requires class \"${call.operationClass}\", but policy allows only: ${allowed.join(', ')}`;\n const location = locationForCall(call);\n return {\n kind: conflictKindForCall(call),\n summary,\n why: 'Use `migration new` to author a custom migration for this change.',\n ...(location ? { location } : {}),\n };\n}\n\nfunction conflictKindForCall(call: SqliteOpFactoryCall): SqlPlannerConflict['kind'] {\n switch (call.factoryName) {\n case 'createIndex':\n case 'dropIndex':\n return 'indexIncompatible';\n default:\n return 'missingButNonAdditive';\n }\n}\n\nfunction locationForCall(call: SqliteOpFactoryCall): SqlPlannerConflictLocation | undefined {\n const location: { table?: string; column?: string; index?: string } = {};\n if ('tableName' in call) location.table = call.tableName;\n if ('columnName' in call) location.column = call.columnName;\n if ('indexName' in call) location.index = call.indexName;\n return Object.keys(location).length > 0 ? (location as SqlPlannerConflictLocation) : undefined;\n}\n\nfunction isMissing(issue: SchemaIssue): boolean {\n if (issue.kind === 'enum_values_changed') return false;\n return issue.actual === undefined;\n}\n\n// ============================================================================\n// StorageTable / StorageColumn → flat SqliteTableSpec\n// ============================================================================\n\n/**\n * Resolves codec / `typeRef` / default rendering into a flat\n * `SqliteColumnSpec`. Mirrors Postgres's `toColumnSpec`. Once a column is\n * flattened, downstream Calls and operation factories never see\n * `StorageColumn` again — they deal in pre-rendered SQL fragments.\n */\nexport function toColumnSpec(\n name: string,\n column: StorageColumn,\n storageTypes: Readonly<Record<string, StorageTypeInstance>>,\n inlineAutoincrementPrimaryKey = false,\n): SqliteColumnSpec {\n const typeSql = buildColumnTypeSql(\n column,\n blindCast<\n Record<string, StorageTypeInstance>,\n 'buildColumnTypeSql declares its storageTypes parameter as mutable Record while the planner stores it readonly; the helper does not mutate, so the readonly→mutable narrowing is sound'\n >(storageTypes),\n );\n const defaultSql = buildColumnDefaultSql(column.default);\n return {\n name,\n typeSql,\n defaultSql,\n nullable: column.nullable,\n ...(inlineAutoincrementPrimaryKey ? { inlineAutoincrementPrimaryKey: true } : {}),\n };\n}\n\n/**\n * Flattens a `StorageTable` into a `SqliteTableSpec` ready for\n * `CreateTableCall` / `RecreateTableCall`. Sole-column AUTOINCREMENT\n * primary keys are detected here and marked on the column spec so the\n * renderer emits `INTEGER PRIMARY KEY AUTOINCREMENT` inline.\n */\nexport function toTableSpec(\n table: StorageTable,\n storageTypes: Readonly<Record<string, StorageTypeInstance>>,\n): SqliteTableSpec {\n const columns: SqliteColumnSpec[] = Object.entries(table.columns).map(([name, column]) =>\n toColumnSpec(name, column, storageTypes, isInlineAutoincrementPrimaryKey(table, name)),\n );\n const uniques: SqliteUniqueSpec[] = table.uniques.map((u) => ({\n columns: u.columns,\n ...(u.name !== undefined ? { name: u.name } : {}),\n }));\n const foreignKeys: SqliteForeignKeySpec[] = table.foreignKeys.map((fk) => ({\n columns: fk.source.columns,\n references: { table: fk.target.tableName, columns: fk.target.columns },\n constraint: fk.constraint !== false,\n ...(fk.name !== undefined ? { name: fk.name } : {}),\n ...(fk.onDelete !== undefined ? { onDelete: fk.onDelete } : {}),\n ...(fk.onUpdate !== undefined ? { onUpdate: fk.onUpdate } : {}),\n }));\n return {\n columns,\n ...(table.primaryKey ? { primaryKey: { columns: table.primaryKey.columns } } : {}),\n uniques,\n foreignKeys,\n };\n}\n\n// ============================================================================\n// StorageTable / StorageColumn → DdlColumn[] + DdlTableConstraint[] (for CreateTableCall)\n// ============================================================================\n\nfunction sqliteDefaultToDdlColumnDefault(\n columnDefault: StorageColumn['default'],\n): DdlColumn['default'] {\n if (!columnDefault) return undefined;\n switch (columnDefault.kind) {\n case 'literal':\n return new LiteralColumnDefault(columnDefault.value);\n case 'function':\n // `autoincrement()` is not a DEFAULT clause — SQLite encodes it as\n // `INTEGER PRIMARY KEY AUTOINCREMENT` inline on the column. Skip it\n // here; the renderer also has a defensive guard for the same case.\n if (columnDefault.expression === 'autoincrement()') return undefined;\n return new FunctionColumnDefault(columnDefault.expression);\n default: {\n const exhaustive: never = columnDefault;\n throw new Error(\n `sqliteDefaultToDdlColumnDefault: unhandled kind \"${blindCast<{ kind: string }, 'exhaustiveness: surface the unhandled default kind'>(exhaustive).kind}\"`,\n );\n }\n }\n}\n\n/**\n * Converts a `StorageTable` to the `DdlColumn[]` + `DdlTableConstraint[]`\n * pair used by `CreateTableCall`. This is the structured form consumed by\n * the DDL lowering path; `toTableSpec` / `toColumnSpec` remain in use for\n * `RecreateTableCall` and `AddColumnCall` (Phase 2).\n */\nexport function tableToDdlParts(\n table: StorageTable,\n storageTypes: Record<string, StorageTypeInstance>,\n): { columns: DdlColumn[]; constraints: DdlTableConstraint[] } {\n const columns: DdlColumn[] = Object.entries(table.columns).map(([name, column]) => {\n const inlineAutoincrement = isInlineAutoincrementPrimaryKey(table, name);\n const typeSql = buildColumnTypeSql(\n column,\n blindCast<\n Record<string, StorageTypeInstance>,\n 'buildColumnTypeSql declares its storageTypes parameter as mutable Record while the planner stores it readonly; the helper does not mutate, so the readonly→mutable narrowing is sound'\n >(storageTypes),\n );\n\n if (inlineAutoincrement) {\n // `DdlColumn` has no SQLite-specific autoincrement flag, so the full\n // `PRIMARY KEY AUTOINCREMENT` clause is embedded in the `type` string.\n // The DDL renderer (`ddl-renderer.ts`) substring-detects `AUTOINCREMENT`\n // to suppress the normal NOT NULL / PRIMARY KEY / DEFAULT clause rendering\n // and emit the entire type string verbatim. Both sites must stay in sync.\n // The structural fix (a SQLite-specific column option) is tracked in TML-2866.\n return new DdlColumn({ name, type: `${typeSql} PRIMARY KEY AUTOINCREMENT` });\n }\n const colDefault = sqliteDefaultToDdlColumnDefault(column.default);\n const resolved = resolveColumnTypeMetadata(\n column,\n blindCast<\n Record<string, StorageTypeInstance>,\n 'resolveColumnTypeMetadata declares its storageTypes parameter as mutable Record while the planner stores it readonly; the helper does not mutate, so the readonly→mutable narrowing is sound'\n >(storageTypes),\n );\n const codecRef: CodecRef | undefined = resolved.codecId\n ? {\n codecId: resolved.codecId,\n ...(resolved.typeParams !== undefined\n ? {\n typeParams: blindCast<\n JsonValue,\n 'resolved.typeParams is JsonValue-shaped storage metadata; the narrowed (non-undefined) value lands in CodecRef.typeParams which is JsonValue'\n >(resolved.typeParams),\n }\n : {}),\n }\n : undefined;\n return new DdlColumn({\n name,\n type: typeSql,\n ...(!column.nullable ? { notNull: true } : {}),\n ...(colDefault !== undefined ? { default: colDefault } : {}),\n ...(codecRef !== undefined ? { codecRef } : {}),\n });\n });\n\n const constraints: DdlTableConstraint[] = [];\n\n const hasInlinePk = Object.entries(table.columns).some(([name]) =>\n isInlineAutoincrementPrimaryKey(table, name),\n );\n if (table.primaryKey && !hasInlinePk) {\n constraints.push(new PrimaryKeyConstraint({ columns: table.primaryKey.columns }));\n }\n\n for (const u of table.uniques) {\n constraints.push(\n new UniqueConstraint({\n columns: u.columns,\n ...(u.name !== undefined ? { name: u.name } : {}),\n }),\n );\n }\n\n for (const fk of table.foreignKeys) {\n if (fk.constraint === false) continue;\n constraints.push(\n new ForeignKeyConstraint({\n columns: fk.source.columns,\n refTable: fk.target.tableName,\n refColumns: fk.target.columns,\n ...ifDefined('name', fk.name),\n ...ifDefined('onDelete', fk.onDelete),\n ...ifDefined('onUpdate', fk.onUpdate),\n }),\n );\n }\n\n return { columns, constraints };\n}\n\n// ============================================================================\n// Issue planner\n// ============================================================================\n\nexport interface IssuePlannerOptions {\n readonly issues: readonly SchemaIssue[];\n readonly toContract: Contract<SqlStorage>;\n readonly fromContract: Contract<SqlStorage> | null;\n readonly codecHooks: ReadonlyMap<string, CodecControlHooks>;\n readonly storageTypes: Readonly<Record<string, StorageTypeInstance>>;\n readonly schema?: SqlSchemaIR;\n readonly policy?: MigrationOperationPolicy;\n readonly frameworkComponents?: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;\n readonly strategies?: readonly CallMigrationStrategy[];\n}\n\nexport interface IssuePlannerValue {\n readonly calls: readonly SqliteOpFactoryCall[];\n}\n\nconst DEFAULT_POLICY: MigrationOperationPolicy = {\n allowedOperationClasses: ['additive', 'widening', 'destructive', 'data'],\n};\n\nfunction emptySchemaIR(): SqlSchemaIR {\n return { tables: {} };\n}\n\n// ============================================================================\n// Issue → Call mapping (per-issue default path)\n// ============================================================================\n\nfunction mapIssueToCall(\n issue: SchemaIssue,\n ctx: StrategyContext,\n): Result<readonly SqliteOpFactoryCall[], SqlPlannerConflict> {\n switch (issue.kind) {\n case 'missing_table': {\n if (!issue.table) {\n return notOk(\n issueConflict('unsupportedOperation', 'Missing table issue has no table name'),\n );\n }\n const namespaceId = resolveNamespaceIdForIssue(issue);\n const contractTable = tableAt(ctx.toContract.storage, namespaceId, issue.table);\n if (!contractTable) {\n return notOk(\n issueConflict(\n 'unsupportedOperation',\n `Table \"${issue.table}\" in namespace \"${namespaceId}\" reported missing but not found in destination contract`,\n ),\n );\n }\n const { columns: ddlColumns, constraints: ddlConstraints } = tableToDdlParts(\n contractTable,\n ctx.storageTypes,\n );\n const calls: SqliteOpFactoryCall[] = [\n new CreateTableCall(\n issue.table,\n ddlColumns,\n ddlConstraints.length > 0 ? ddlConstraints : undefined,\n ),\n ];\n const declaredIndexColumnKeys = new Set<string>();\n for (const index of contractTable.indexes) {\n const indexName = index.name ?? defaultIndexName(issue.table, index.columns);\n declaredIndexColumnKeys.add(index.columns.join(','));\n calls.push(new CreateIndexCall(issue.table, indexName, index.columns));\n }\n for (const fk of contractTable.foreignKeys) {\n if (fk.index === false) continue;\n if (declaredIndexColumnKeys.has(fk.source.columns.join(','))) continue;\n const indexName = defaultIndexName(issue.table, fk.source.columns);\n calls.push(new CreateIndexCall(issue.table, indexName, fk.source.columns));\n }\n return ok(calls);\n }\n\n case 'missing_column': {\n if (!issue.table || !issue.column) {\n return notOk(\n issueConflict('unsupportedOperation', 'Missing column issue has no table/column name'),\n );\n }\n const namespaceId = resolveNamespaceIdForIssue(issue);\n const contractTable2 = tableAt(ctx.toContract.storage, namespaceId, issue.table);\n const column = contractTable2?.columns[issue.column];\n if (!column) {\n return notOk(\n issueConflict(\n 'unsupportedOperation',\n `Column \"${issue.table}\".\"${issue.column}\" not in destination contract`,\n ),\n );\n }\n const contractTable = contractTable2;\n const columnSpec = toColumnSpec(\n issue.column,\n column,\n ctx.storageTypes,\n contractTable ? isInlineAutoincrementPrimaryKey(contractTable, issue.column) : false,\n );\n return ok([new AddColumnCall(issue.table, columnSpec)]);\n }\n\n case 'index_mismatch': {\n if (!issue.table) {\n return notOk(issueConflict('indexIncompatible', 'Index issue has no table name'));\n }\n if (!isMissing(issue) || !issue.expected) {\n return notOk(\n issueConflict(\n 'indexIncompatible',\n `Index on \"${issue.table}\" differs (expected: ${issue.expected}, actual: ${issue.actual})`,\n { table: issue.table },\n ),\n );\n }\n const namespaceId = resolveNamespaceIdForIssue(issue);\n const columns = issue.expected.split(', ');\n const contractTable = tableAt(ctx.toContract.storage, namespaceId, issue.table);\n if (!contractTable) {\n return notOk(\n issueConflict(\n 'unsupportedOperation',\n `Table \"${issue.table}\" not found in destination contract`,\n ),\n );\n }\n const explicitIndex = contractTable.indexes.find(\n (idx) => idx.columns.join(',') === columns.join(','),\n );\n const indexName = explicitIndex?.name ?? defaultIndexName(issue.table, columns);\n return ok([new CreateIndexCall(issue.table, indexName, columns)]);\n }\n\n case 'extra_table': {\n if (!issue.table) {\n return notOk(issueConflict('unsupportedOperation', 'Extra table issue has no table name'));\n }\n // Runner-owned control tables must never be dropped.\n if (CONTROL_TABLE_NAMES.has(issue.table)) return ok([]);\n return ok([new DropTableCall(issue.table)]);\n }\n\n case 'extra_column': {\n if (!issue.table || !issue.column) {\n return notOk(\n issueConflict('unsupportedOperation', 'Extra column issue has no table/column name'),\n );\n }\n return ok([new DropColumnCall(issue.table, issue.column)]);\n }\n\n case 'extra_index': {\n if (!issue.table || !issue.indexOrConstraint) {\n return notOk(\n issueConflict('unsupportedOperation', 'Extra index issue has no table/index name'),\n );\n }\n return ok([new DropIndexCall(issue.table, issue.indexOrConstraint)]);\n }\n\n // SQLite has no enum types (capability `sql.enums: false`). The verifier\n // should never emit `enum_values_changed` against a SQLite schema, so if\n // we receive one it is a verifier bug — surface it as an explicit\n // conflict rather than silently dropping it.\n case 'enum_values_changed':\n return notOk(\n issueConflict(\n 'unsupportedOperation',\n 'Received enum_values_changed against a SQLite schema (sql.enums: false) — verifier bug',\n ),\n );\n\n // Everything below is absorbed by recreateTableStrategy. If it falls\n // through here, policy or context didn't allow the recreate — surface as\n // a conflict.\n case 'type_mismatch':\n case 'nullability_mismatch':\n case 'default_mismatch':\n case 'default_missing':\n case 'extra_default':\n case 'primary_key_mismatch':\n case 'unique_constraint_mismatch':\n case 'foreign_key_mismatch':\n case 'extra_foreign_key':\n case 'extra_unique_constraint':\n case 'extra_primary_key':\n return notOk(issueConflict(conflictKindForIssue(issue), issue.message, issueLocation(issue)));\n\n default:\n return notOk(\n issueConflict(\n 'unsupportedOperation',\n `Unhandled issue kind: ${(issue as SchemaIssue).kind}`,\n ),\n );\n }\n}\n\n// ============================================================================\n// Call categorization for final emission order\n// ============================================================================\n\ntype CallCategory =\n | 'drop-column'\n | 'drop-index'\n | 'drop-table'\n | 'create-table'\n | 'add-column'\n | 'create-index';\n\nfunction classifyCall(call: SqliteOpFactoryCall): CallCategory | null {\n switch (call.factoryName) {\n case 'createTable':\n return 'create-table';\n case 'addColumn':\n return 'add-column';\n case 'createIndex':\n return 'create-index';\n case 'dropColumn':\n return 'drop-column';\n case 'dropIndex':\n return 'drop-index';\n case 'dropTable':\n return 'drop-table';\n // recreateTable goes into the recipe slot; return null for bucketable.\n case 'recreateTable':\n return null;\n default:\n return null;\n }\n}\n\n// ============================================================================\n// Top-level planIssues\n// ============================================================================\n\nexport function planIssues(\n options: IssuePlannerOptions,\n): Result<IssuePlannerValue, readonly SqlPlannerConflict[]> {\n const policyProvided = options.policy !== undefined;\n const policy = options.policy ?? DEFAULT_POLICY;\n const schema = options.schema ?? emptySchemaIR();\n const frameworkComponents = options.frameworkComponents ?? [];\n\n const context: StrategyContext = {\n toContract: options.toContract,\n fromContract: options.fromContract,\n codecHooks: options.codecHooks,\n storageTypes: options.storageTypes,\n schema,\n policy,\n frameworkComponents,\n };\n\n const strategies = options.strategies ?? sqlitePlannerStrategies;\n\n let remaining = options.issues;\n const recipeCalls: SqliteOpFactoryCall[] = [];\n const bucketableCalls: SqliteOpFactoryCall[] = [];\n\n for (const strategy of strategies) {\n const result = strategy(remaining, context);\n if (result.kind === 'match') {\n remaining = result.issues;\n if (result.recipe) {\n recipeCalls.push(...result.calls);\n } else {\n bucketableCalls.push(...result.calls);\n }\n }\n }\n\n const sorted = [...remaining].sort((a, b) => {\n const kindDelta = issueOrder(a) - issueOrder(b);\n if (kindDelta !== 0) return kindDelta;\n const keyA = issueKey(a);\n const keyB = issueKey(b);\n return keyA < keyB ? -1 : keyA > keyB ? 1 : 0;\n });\n\n const defaultCalls: SqliteOpFactoryCall[] = [];\n const conflicts: SqlPlannerConflict[] = [];\n\n for (const issue of sorted) {\n const result = mapIssueToCall(issue, context);\n if (result.ok) {\n defaultCalls.push(...result.value);\n } else {\n conflicts.push(result.failure);\n }\n }\n\n // Policy gating for recipe + bucketable. Default-mapped calls for disallowed\n // classes never get here (they're surfaced as per-issue conflicts above).\n const allowed = policy.allowedOperationClasses;\n let gatedRecipe = recipeCalls;\n let gatedBucketable = bucketableCalls;\n let gatedDefault = defaultCalls;\n if (policyProvided) {\n const sink = (acc: SqliteOpFactoryCall[]) => (call: SqliteOpFactoryCall) => {\n if (allowed.includes(call.operationClass)) {\n acc.push(call);\n return;\n }\n conflicts.push(conflictForDisallowedCall(call, allowed));\n };\n const gatedRecipeBucket: SqliteOpFactoryCall[] = [];\n const gatedBucketableBucket: SqliteOpFactoryCall[] = [];\n const gatedDefaultBucket: SqliteOpFactoryCall[] = [];\n recipeCalls.forEach(sink(gatedRecipeBucket));\n bucketableCalls.forEach(sink(gatedBucketableBucket));\n defaultCalls.forEach(sink(gatedDefaultBucket));\n gatedRecipe = gatedRecipeBucket;\n gatedBucketable = gatedBucketableBucket;\n gatedDefault = gatedDefaultBucket;\n }\n\n if (conflicts.length > 0) {\n return notOk(conflicts);\n }\n\n // Final emission order matches the current monolithic planner:\n // create-table → add-column → create-index → recreate → drop-column → drop-index → drop-table\n const combined = [...gatedDefault, ...gatedBucketable];\n const byCategory = (cat: CallCategory) => combined.filter((c) => classifyCall(c) === cat);\n\n const calls: SqliteOpFactoryCall[] = [\n ...byCategory('create-table'),\n ...byCategory('add-column'),\n ...byCategory('create-index'),\n ...gatedRecipe,\n ...byCategory('drop-column'),\n ...byCategory('drop-index'),\n ...byCategory('drop-table'),\n ];\n\n return ok({ calls });\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport type {\n MigrationOperationPolicy,\n SqlMigrationPlanner,\n SqlMigrationPlannerPlanOptions,\n SqlPlannerFailureResult,\n} from '@prisma-next/family-sql/control';\nimport {\n extractCodecControlHooks,\n planFieldEventOperations,\n plannerFailure,\n} from '@prisma-next/family-sql/control';\nimport type { ExecuteRequestLowerer } from '@prisma-next/family-sql/control-adapter';\nimport { verifySqlSchema } from '@prisma-next/family-sql/schema-verify';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n MigrationPlanner,\n MigrationScaffoldContext,\n SchemaIssue,\n} from '@prisma-next/framework-components/control';\nimport { parseSqliteDefault } from '../default-normalizer';\nimport { normalizeSqliteNativeType } from '../native-type-normalizer';\nimport { planIssues } from './issue-planner';\nimport {\n type SqliteMigrationDestinationInfo,\n TypeScriptRenderableSqliteMigration,\n} from './planner-produced-sqlite-migration';\nimport { sqlitePlannerStrategies } from './planner-strategies';\nimport type { SqlitePlanTargetDetails } from './planner-target-details';\n\nexport function createSqliteMigrationPlanner(\n lowerer: ExecuteRequestLowerer,\n): SqliteMigrationPlanner {\n return new SqliteMigrationPlanner(lowerer);\n}\n\nexport type SqlitePlanResult =\n | { readonly kind: 'success'; readonly plan: TypeScriptRenderableSqliteMigration }\n | SqlPlannerFailureResult;\n\n/**\n * SQLite migration planner — a thin wrapper over `planIssues`.\n *\n * `plan()` verifies the live schema against the target contract (producing\n * `SchemaIssue[]`) and delegates to `planIssues` with the registered\n * strategies. Strategies absorb groups of related issues into composite\n * recipes (e.g. recreating a table to apply type/nullability/default/\n * constraint changes at once); anything not absorbed by a strategy flows\n * through `mapIssueToCall` in the issue planner as a one-off call.\n *\n * FK-backing indexes are surfaced by `verifySqlSchema`'s index expansion\n * (see `verify-sql-schema.ts:459-469`), so `mapIssueToCall` handles them\n * uniformly alongside user-declared indexes.\n */\nexport class SqliteMigrationPlanner\n implements SqlMigrationPlanner<SqlitePlanTargetDetails>, MigrationPlanner<'sql', 'sqlite'>\n{\n readonly #lowerer: ExecuteRequestLowerer;\n\n constructor(lowerer: ExecuteRequestLowerer) {\n this.#lowerer = lowerer;\n }\n\n plan(options: {\n readonly contract: unknown;\n readonly schema: unknown;\n readonly policy: MigrationOperationPolicy;\n /**\n * The \"from\" contract (state the planner assumes the database starts at),\n * or `null` for reconciliation flows.\n *\n * Typed as the framework `Contract | null` to satisfy the\n * `MigrationPlanner` interface contract; `planSql` narrows to the SQL\n * shape via `SqlMigrationPlannerPlanOptions`. Used to populate\n * `describe().from` on the produced plan as\n * `fromContract?.storage.storageHash ?? null`.\n */\n readonly fromContract: Contract | null;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;\n /**\n * Contract space this plan applies to. Stamped onto the produced\n * {@link TypeScriptRenderableSqliteMigration.spaceId} so the runner keys\n * the marker row by the right space.\n */\n readonly spaceId: string;\n }): SqlitePlanResult {\n return this.planSql(options as SqlMigrationPlannerPlanOptions);\n }\n\n emptyMigration(\n context: MigrationScaffoldContext,\n spaceId: string,\n ): TypeScriptRenderableSqliteMigration {\n return new TypeScriptRenderableSqliteMigration(\n [],\n {\n from: context.fromHash,\n to: context.toHash,\n },\n spaceId,\n undefined,\n this.#lowerer,\n );\n }\n\n private planSql(options: SqlMigrationPlannerPlanOptions): SqlitePlanResult {\n const policyResult = this.ensureAdditivePolicy(options.policy);\n if (policyResult) return policyResult;\n\n const schemaIssues = this.collectSchemaIssues(options);\n const codecHooks = extractCodecControlHooks(options.frameworkComponents);\n const storageTypes = options.contract.storage.types ?? {};\n\n const result = planIssues({\n issues: schemaIssues,\n toContract: options.contract,\n fromContract: options.fromContract,\n codecHooks,\n storageTypes,\n schema: options.schema,\n policy: options.policy,\n frameworkComponents: options.frameworkComponents,\n strategies: sqlitePlannerStrategies,\n });\n\n if (!result.ok) {\n return plannerFailure(result.failure);\n }\n\n // Codec lifecycle hook (T2.2): inline `onFieldEvent`-emitted ops after\n // structural DDL. Sub-spec § 5 fixes the ordering as\n // `structural → added → dropped → altered`, with within-group sorting by\n // `(tableName, fieldName)` deterministic for byte-stable re-emits.\n // Hook fires only at the application emitter — extension-space planning\n // (M2 R2) never reaches this helper.\n const fieldEventOps = planFieldEventOperations({\n priorContract: options.fromContract,\n newContract: options.contract,\n codecHooks,\n });\n // Codec-emitted calls already conform to `OpFactoryCall` — render +\n // toOp + importRequirements ride directly through the same emit path\n // as structural ops, no `RawSqlCall` wrap.\n const calls = [...result.value.calls, ...fieldEventOps];\n\n const destination: SqliteMigrationDestinationInfo = {\n storageHash: options.contract.storage.storageHash,\n ...(options.contract.profileHash !== undefined\n ? { profileHash: options.contract.profileHash }\n : {}),\n };\n\n return {\n kind: 'success' as const,\n plan: new TypeScriptRenderableSqliteMigration(\n calls,\n {\n from: options.fromContract?.storage.storageHash ?? null,\n to: options.contract.storage.storageHash,\n },\n options.spaceId,\n destination,\n this.#lowerer,\n ),\n };\n }\n\n private ensureAdditivePolicy(policy: MigrationOperationPolicy): SqlPlannerFailureResult | null {\n if (!policy.allowedOperationClasses.includes('additive')) {\n return plannerFailure([\n {\n kind: 'unsupportedOperation',\n summary: 'Migration planner requires additive operations be allowed',\n why: 'The planner requires the \"additive\" operation class to be allowed in the policy.',\n },\n ]);\n }\n return null;\n }\n\n private collectSchemaIssues(options: SqlMigrationPlannerPlanOptions): readonly SchemaIssue[] {\n const allowed = options.policy.allowedOperationClasses;\n const strict = allowed.includes('widening') || allowed.includes('destructive');\n const verifyResult = verifySqlSchema({\n contract: options.contract,\n schema: options.schema,\n strict,\n typeMetadataRegistry: new Map(),\n frameworkComponents: options.frameworkComponents,\n normalizeDefault: parseSqliteDefault,\n normalizeNativeType: normalizeSqliteNativeType,\n });\n return verifyResult.schema.issues;\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { t as renderOps } from "./render-ops-BDW2tUeR.mjs";
2
- import { t as SqliteMigration } from "./sqlite-migration-CCYnBXZp.mjs";
2
+ import { t as SqliteMigration } from "./sqlite-migration-DhW4ycZV.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
@@ -108,4 +108,4 @@ var TypeScriptRenderableSqliteMigration = class extends SqliteMigration {
108
108
  //#endregion
109
109
  export { TypeScriptRenderableSqliteMigration as t };
110
110
 
111
- //# sourceMappingURL=planner-produced-sqlite-migration-DwQSUgSk.mjs.map
111
+ //# sourceMappingURL=planner-produced-sqlite-migration-CyyvoPmm.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"planner-produced-sqlite-migration-DwQSUgSk.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);\n const operationsBody = calls.map((c) => c.renderTypeScript()).join(',\\n');\n\n return [\n shebangLineFor(detectScaffoldRuntime()),\n imports,\n '',\n 'export default class M extends Migration {',\n buildDescribeMethod(meta),\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>): string {\n const requirements: ImportRequirement[] = [...BASE_IMPORTS];\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\nfunction buildDescribeMethod(meta: RenderMigrationMeta): string {\n const lines: string[] = [];\n lines.push(' override describe() {');\n lines.push(' return {');\n lines.push(` from: ${JSON.stringify(meta.from)},`);\n lines.push(` to: ${JSON.stringify(meta.to)},`);\n lines.push(' };');\n lines.push(' }');\n lines.push('');\n return lines.join('\\n');\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,KAAK;CAClC,MAAM,iBAAiB,MAAM,KAAK,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,KAAK;CAExE,OAAO;EACL,eAAe,sBAAsB,CAAC;EACtC;EACA;EACA;EACA,oBAAoB,IAAI;EACxB;EACA;EACA,OAAO,gBAAgB,CAAC;EACxB;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;AACb;AAEA,SAAS,aAAa,OAA6C;CACjE,MAAM,eAAoC,CAAC,GAAG,YAAY;CAC1D,KAAK,MAAM,QAAQ,OACjB,KAAK,MAAM,OAAO,KAAK,mBAAmB,GACxC,aAAa,KAAK,GAAG;CAGzB,OAAO,cAAc,YAAY;AACnC;AAEA,SAAS,oBAAoB,MAAmC;CAC9D,MAAM,QAAkB,CAAC;CACzB,MAAM,KAAK,yBAAyB;CACpC,MAAM,KAAK,cAAc;CACzB,MAAM,KAAK,eAAe,KAAK,UAAU,KAAK,IAAI,EAAE,EAAE;CACtD,MAAM,KAAK,aAAa,KAAK,UAAU,KAAK,EAAE,EAAE,EAAE;CAClD,MAAM,KAAK,QAAQ;CACnB,MAAM,KAAK,KAAK;CAChB,MAAM,KAAK,EAAE;CACb,OAAO,MAAM,KAAK,IAAI;AACxB;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;;;ACnEA,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
+ {"version":3,"file":"planner-produced-sqlite-migration-CyyvoPmm.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);\n const operationsBody = calls.map((c) => c.renderTypeScript()).join(',\\n');\n\n return [\n shebangLineFor(detectScaffoldRuntime()),\n imports,\n '',\n 'export default class M extends Migration {',\n buildDescribeMethod(meta),\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>): string {\n const requirements: ImportRequirement[] = [...BASE_IMPORTS];\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\nfunction buildDescribeMethod(meta: RenderMigrationMeta): string {\n const lines: string[] = [];\n lines.push(' override describe() {');\n lines.push(' return {');\n lines.push(` from: ${JSON.stringify(meta.from)},`);\n lines.push(` to: ${JSON.stringify(meta.to)},`);\n lines.push(' };');\n lines.push(' }');\n lines.push('');\n return lines.join('\\n');\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,KAAK;CAClC,MAAM,iBAAiB,MAAM,KAAK,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,KAAK;CAExE,OAAO;EACL,eAAe,sBAAsB,CAAC;EACtC;EACA;EACA;EACA,oBAAoB,IAAI;EACxB;EACA;EACA,OAAO,gBAAgB,CAAC;EACxB;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;AACb;AAEA,SAAS,aAAa,OAA6C;CACjE,MAAM,eAAoC,CAAC,GAAG,YAAY;CAC1D,KAAK,MAAM,QAAQ,OACjB,KAAK,MAAM,OAAO,KAAK,mBAAmB,GACxC,aAAa,KAAK,GAAG;CAGzB,OAAO,cAAc,YAAY;AACnC;AAEA,SAAS,oBAAoB,MAAmC;CAC9D,MAAM,QAAkB,CAAC;CACzB,MAAM,KAAK,yBAAyB;CACpC,MAAM,KAAK,cAAc;CACzB,MAAM,KAAK,eAAe,KAAK,UAAU,KAAK,IAAI,EAAE,EAAE;CACtD,MAAM,KAAK,aAAa,KAAK,UAAU,KAAK,EAAE,EAAE,EAAE;CAClD,MAAM,KAAK,QAAQ;CACnB,MAAM,KAAK,KAAK;CAChB,MAAM,KAAK,EAAE;CACb,OAAO,MAAM,KAAK,IAAI;AACxB;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;;;ACnEA,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-DwQSUgSk.mjs";
1
+ import { t as TypeScriptRenderableSqliteMigration } from "./planner-produced-sqlite-migration-CyyvoPmm.mjs";
2
2
  export { TypeScriptRenderableSqliteMigration };
package/dist/planner.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { n as createSqliteMigrationPlanner, t as SqliteMigrationPlanner } from "./planner-DOZWouPl.mjs";
1
+ import { n as createSqliteMigrationPlanner, t as SqliteMigrationPlanner } from "./planner-jMHqfl1A.mjs";
2
2
  export { SqliteMigrationPlanner, createSqliteMigrationPlanner };
@@ -1,4 +1,4 @@
1
- import { r as CreateTableCall } from "./op-factory-call-BX69rHxs.mjs";
1
+ import { r as CreateTableCall } from "./op-factory-call-z4TT72k3.mjs";
2
2
  import { blindCast } from "@prisma-next/utils/casts";
3
3
  import { Migration } from "@prisma-next/family-sql/migration";
4
4
  import { CliStructuredError } from "@prisma-next/errors/control";
@@ -70,4 +70,4 @@ var SqliteMigration = class extends Migration {
70
70
  //#endregion
71
71
  export { SqliteMigration as t };
72
72
 
73
- //# sourceMappingURL=sqlite-migration-CCYnBXZp.mjs.map
73
+ //# sourceMappingURL=sqlite-migration-DhW4ycZV.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite-migration-CCYnBXZp.mjs","names":["SqlMigration"],"sources":["../src/core/errors.ts","../src/core/migrations/sqlite-migration.ts"],"sourcesContent":["import { CliStructuredError } from '@prisma-next/errors/control';\n\n/**\n * A `SqliteMigration` instance method that needs the materialized control\n * adapter (currently only `this.createTable(...)`) was invoked, but the\n * migration was constructed without a `ControlStack`. Concrete authoring\n * usage always goes through the migration CLI entrypoint, which assembles\n * a stack from the loaded `prisma-next.config.ts`; reaching this error\n * means a test fixture or ad-hoc consumer instantiated `SqliteMigration`\n * with the no-arg form (legal for `operations` / `describe` introspection\n * only).\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(): CliStructuredError {\n return new CliStructuredError('2008', 'SqliteMigration.createTable requires a control adapter', {\n domain: 'MIG',\n why: 'SqliteMigration.createTable was invoked on an instance constructed without a ControlStack. The stored controlAdapter is undefined, so createTable 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: {},\n });\n}\n","import type { SqlMigrationPlanOperation } 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 type { DdlColumn, DdlTableConstraint } from '@prisma-next/sql-relational-core/ast';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { errorSqliteMigrationStackMissing } from '../errors';\nimport { CreateTableCall } from './op-factory-call';\nimport type { SqlitePlanTargetDetails } from './planner-target-details';\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 `createTable`\n * instance method forwards to `CreateTableCall` with that stored adapter,\n * so user migrations can write `this.createTable({...})` without threading\n * the adapter through every call.\n */\nexport abstract class SqliteMigration extends SqlMigration<SqlitePlanTargetDetails, 'sqlite'> {\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); `createTable`\n * throws in that case to surface the misuse.\n */\n protected readonly controlAdapter: SqlControlAdapter<'sqlite'> | undefined;\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 * Emit a `CREATE TABLE` migration operation. Builds a typed DDL node from\n * the supplied options and lowers it through the stored control adapter.\n * Throws if no adapter is present (i.e. migration instantiated without a stack).\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<SqlMigrationPlanOperation<SqlitePlanTargetDetails>> {\n if (!this.controlAdapter) {\n throw errorSqliteMigrationStackMissing();\n }\n return new CreateTableCall(options.table, options.columns, options.constraints).toOp(\n this.controlAdapter,\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,mCAAuD;CACrE,OAAO,IAAI,mBAAmB,QAAQ,0DAA0D;EAC9F,QAAQ;EACR,KAAK;EACL,KAAK;EACL,MAAM,CAAC;CACT,CAAC;AACH;;;;;;;;;;;;;;;;ACJA,IAAsB,kBAAtB,cAA8CA,UAAgD;CAC5F,WAAoB;;;;;;;CAQpB;CAEA,YAAY,OAAuC;EACjD,MAAM,KAAK;EACX,KAAK,iBAAiB,OAAO,UACzB,UAGE,MAAM,QAAQ,OAAO,KAAK,CAAC,IAC7B,KAAA;CACN;;;;;;CAOA,YAAsB,SAK0C;EAC9D,IAAI,CAAC,KAAK,gBACR,MAAM,iCAAiC;EAEzC,OAAO,IAAI,gBAAgB,QAAQ,OAAO,QAAQ,SAAS,QAAQ,WAAW,CAAC,CAAC,KAC9E,KAAK,cACP;CACF;AACF"}
1
+ {"version":3,"file":"sqlite-migration-DhW4ycZV.mjs","names":["SqlMigration"],"sources":["../src/core/errors.ts","../src/core/migrations/sqlite-migration.ts"],"sourcesContent":["import { CliStructuredError } from '@prisma-next/errors/control';\n\n/**\n * A `SqliteMigration` instance method that needs the materialized control\n * adapter (currently only `this.createTable(...)`) was invoked, but the\n * migration was constructed without a `ControlStack`. Concrete authoring\n * usage always goes through the migration CLI entrypoint, which assembles\n * a stack from the loaded `prisma-next.config.ts`; reaching this error\n * means a test fixture or ad-hoc consumer instantiated `SqliteMigration`\n * with the no-arg form (legal for `operations` / `describe` introspection\n * only).\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(): CliStructuredError {\n return new CliStructuredError('2008', 'SqliteMigration.createTable requires a control adapter', {\n domain: 'MIG',\n why: 'SqliteMigration.createTable was invoked on an instance constructed without a ControlStack. The stored controlAdapter is undefined, so createTable 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: {},\n });\n}\n","import type { SqlMigrationPlanOperation } 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 type { DdlColumn, DdlTableConstraint } from '@prisma-next/sql-relational-core/ast';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { errorSqliteMigrationStackMissing } from '../errors';\nimport { CreateTableCall } from './op-factory-call';\nimport type { SqlitePlanTargetDetails } from './planner-target-details';\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 `createTable`\n * instance method forwards to `CreateTableCall` with that stored adapter,\n * so user migrations can write `this.createTable({...})` without threading\n * the adapter through every call.\n */\nexport abstract class SqliteMigration extends SqlMigration<SqlitePlanTargetDetails, 'sqlite'> {\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); `createTable`\n * throws in that case to surface the misuse.\n */\n protected readonly controlAdapter: SqlControlAdapter<'sqlite'> | undefined;\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 * Emit a `CREATE TABLE` migration operation. Builds a typed DDL node from\n * the supplied options and lowers it through the stored control adapter.\n * Throws if no adapter is present (i.e. migration instantiated without a stack).\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<SqlMigrationPlanOperation<SqlitePlanTargetDetails>> {\n if (!this.controlAdapter) {\n throw errorSqliteMigrationStackMissing();\n }\n return new CreateTableCall(options.table, options.columns, options.constraints).toOp(\n this.controlAdapter,\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,mCAAuD;CACrE,OAAO,IAAI,mBAAmB,QAAQ,0DAA0D;EAC9F,QAAQ;EACR,KAAK;EACL,KAAK;EACL,MAAM,CAAC;CACT,CAAC;AACH;;;;;;;;;;;;;;;;ACJA,IAAsB,kBAAtB,cAA8CA,UAAgD;CAC5F,WAAoB;;;;;;;CAQpB;CAEA,YAAY,OAAuC;EACjD,MAAM,KAAK;EACX,KAAK,iBAAiB,OAAO,UACzB,UAGE,MAAM,QAAQ,OAAO,KAAK,CAAC,IAC7B,KAAA;CACN;;;;;;CAOA,YAAsB,SAK0C;EAC9D,IAAI,CAAC,KAAK,gBACR,MAAM,iCAAiC;EAEzC,OAAO,IAAI,gBAAgB,QAAQ,OAAO,QAAQ,SAAS,QAAQ,WAAW,CAAC,CAAC,KAC9E,KAAK,cACP;CACF;AACF"}
package/package.json CHANGED
@@ -1,30 +1,30 @@
1
1
  {
2
2
  "name": "@prisma-next/target-sqlite",
3
- "version": "0.13.0-dev.28",
3
+ "version": "0.13.0-dev.29",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "dependencies": {
8
- "@prisma-next/cli": "0.13.0-dev.28",
9
- "@prisma-next/contract": "0.13.0-dev.28",
10
- "@prisma-next/errors": "0.13.0-dev.28",
11
- "@prisma-next/family-sql": "0.13.0-dev.28",
12
- "@prisma-next/framework-components": "0.13.0-dev.28",
13
- "@prisma-next/migration-tools": "0.13.0-dev.28",
14
- "@prisma-next/sql-contract": "0.13.0-dev.28",
15
- "@prisma-next/sql-errors": "0.13.0-dev.28",
16
- "@prisma-next/sql-relational-core": "0.13.0-dev.28",
17
- "@prisma-next/sql-runtime": "0.13.0-dev.28",
18
- "@prisma-next/sql-schema-ir": "0.13.0-dev.28",
19
- "@prisma-next/ts-render": "0.13.0-dev.28",
20
- "@prisma-next/utils": "0.13.0-dev.28",
8
+ "@prisma-next/cli": "0.13.0-dev.29",
9
+ "@prisma-next/contract": "0.13.0-dev.29",
10
+ "@prisma-next/errors": "0.13.0-dev.29",
11
+ "@prisma-next/family-sql": "0.13.0-dev.29",
12
+ "@prisma-next/framework-components": "0.13.0-dev.29",
13
+ "@prisma-next/migration-tools": "0.13.0-dev.29",
14
+ "@prisma-next/sql-contract": "0.13.0-dev.29",
15
+ "@prisma-next/sql-errors": "0.13.0-dev.29",
16
+ "@prisma-next/sql-relational-core": "0.13.0-dev.29",
17
+ "@prisma-next/sql-runtime": "0.13.0-dev.29",
18
+ "@prisma-next/sql-schema-ir": "0.13.0-dev.29",
19
+ "@prisma-next/ts-render": "0.13.0-dev.29",
20
+ "@prisma-next/utils": "0.13.0-dev.29",
21
21
  "@standard-schema/spec": "1.1.0"
22
22
  },
23
23
  "devDependencies": {
24
- "@prisma-next/driver-sqlite": "0.13.0-dev.28",
25
- "@prisma-next/test-utils": "0.13.0-dev.28",
26
- "@prisma-next/tsconfig": "0.13.0-dev.28",
27
- "@prisma-next/tsdown": "0.13.0-dev.28",
24
+ "@prisma-next/driver-sqlite": "0.13.0-dev.29",
25
+ "@prisma-next/test-utils": "0.13.0-dev.29",
26
+ "@prisma-next/tsconfig": "0.13.0-dev.29",
27
+ "@prisma-next/tsdown": "0.13.0-dev.29",
28
28
  "tsdown": "0.22.1",
29
29
  "typescript": "5.9.3",
30
30
  "vitest": "4.1.8"
@@ -18,7 +18,6 @@ import type {
18
18
  import type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';
19
19
  import type { SchemaIssue } from '@prisma-next/framework-components/control';
20
20
  import type {
21
- PostgresEnumStorageEntry,
22
21
  SqlStorage,
23
22
  StorageColumn,
24
23
  StorageTable,
@@ -218,13 +217,13 @@ function isMissing(issue: SchemaIssue): boolean {
218
217
  export function toColumnSpec(
219
218
  name: string,
220
219
  column: StorageColumn,
221
- storageTypes: Readonly<Record<string, StorageTypeInstance | PostgresEnumStorageEntry>>,
220
+ storageTypes: Readonly<Record<string, StorageTypeInstance>>,
222
221
  inlineAutoincrementPrimaryKey = false,
223
222
  ): SqliteColumnSpec {
224
223
  const typeSql = buildColumnTypeSql(
225
224
  column,
226
225
  blindCast<
227
- Record<string, StorageTypeInstance | PostgresEnumStorageEntry>,
226
+ Record<string, StorageTypeInstance>,
228
227
  'buildColumnTypeSql declares its storageTypes parameter as mutable Record while the planner stores it readonly; the helper does not mutate, so the readonly→mutable narrowing is sound'
229
228
  >(storageTypes),
230
229
  );
@@ -246,7 +245,7 @@ export function toColumnSpec(
246
245
  */
247
246
  export function toTableSpec(
248
247
  table: StorageTable,
249
- storageTypes: Readonly<Record<string, StorageTypeInstance | PostgresEnumStorageEntry>>,
248
+ storageTypes: Readonly<Record<string, StorageTypeInstance>>,
250
249
  ): SqliteTableSpec {
251
250
  const columns: SqliteColumnSpec[] = Object.entries(table.columns).map(([name, column]) =>
252
251
  toColumnSpec(name, column, storageTypes, isInlineAutoincrementPrimaryKey(table, name)),
@@ -305,14 +304,14 @@ function sqliteDefaultToDdlColumnDefault(
305
304
  */
306
305
  export function tableToDdlParts(
307
306
  table: StorageTable,
308
- storageTypes: Record<string, StorageTypeInstance | PostgresEnumStorageEntry>,
307
+ storageTypes: Record<string, StorageTypeInstance>,
309
308
  ): { columns: DdlColumn[]; constraints: DdlTableConstraint[] } {
310
309
  const columns: DdlColumn[] = Object.entries(table.columns).map(([name, column]) => {
311
310
  const inlineAutoincrement = isInlineAutoincrementPrimaryKey(table, name);
312
311
  const typeSql = buildColumnTypeSql(
313
312
  column,
314
313
  blindCast<
315
- Record<string, StorageTypeInstance | PostgresEnumStorageEntry>,
314
+ Record<string, StorageTypeInstance>,
316
315
  'buildColumnTypeSql declares its storageTypes parameter as mutable Record while the planner stores it readonly; the helper does not mutate, so the readonly→mutable narrowing is sound'
317
316
  >(storageTypes),
318
317
  );
@@ -330,7 +329,7 @@ export function tableToDdlParts(
330
329
  const resolved = resolveColumnTypeMetadata(
331
330
  column,
332
331
  blindCast<
333
- Record<string, StorageTypeInstance | PostgresEnumStorageEntry>,
332
+ Record<string, StorageTypeInstance>,
334
333
  'resolveColumnTypeMetadata declares its storageTypes parameter as mutable Record while the planner stores it readonly; the helper does not mutate, so the readonly→mutable narrowing is sound'
335
334
  >(storageTypes),
336
335
  );
@@ -400,7 +399,7 @@ export interface IssuePlannerOptions {
400
399
  readonly toContract: Contract<SqlStorage>;
401
400
  readonly fromContract: Contract<SqlStorage> | null;
402
401
  readonly codecHooks: ReadonlyMap<string, CodecControlHooks>;
403
- readonly storageTypes: Readonly<Record<string, StorageTypeInstance | PostgresEnumStorageEntry>>;
402
+ readonly storageTypes: Readonly<Record<string, StorageTypeInstance>>;
404
403
  readonly schema?: SqlSchemaIR;
405
404
  readonly policy?: MigrationOperationPolicy;
406
405
  readonly frameworkComponents?: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;
@@ -8,12 +8,10 @@
8
8
  * see `StorageColumn` or `storageTypes`.
9
9
  */
10
10
 
11
- import {
12
- isPostgresEnumStorageEntry,
13
- type PostgresEnumStorageEntry,
14
- type StorageColumn,
15
- type StorageTable,
16
- type StorageTypeInstance,
11
+ import type {
12
+ StorageColumn,
13
+ StorageTable,
14
+ StorageTypeInstance,
17
15
  } from '@prisma-next/sql-contract/types';
18
16
  import { escapeLiteral, quoteIdentifier } from '../sql-utils';
19
17
 
@@ -46,7 +44,7 @@ function assertSafeDefaultExpression(expression: string): void {
46
44
  */
47
45
  export function buildColumnTypeSql(
48
46
  column: StorageColumn,
49
- storageTypes: Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = {},
47
+ storageTypes: Record<string, StorageTypeInstance> = {},
50
48
  ): string {
51
49
  const resolved = resolveColumnTypeMetadata(column, storageTypes);
52
50
  assertSafeNativeType(resolved.nativeType);
@@ -125,7 +123,7 @@ type ResolvedColumnTypeMetadata = Pick<StorageColumn, 'nativeType' | 'codecId' |
125
123
 
126
124
  export function resolveColumnTypeMetadata(
127
125
  column: StorageColumn,
128
- storageTypes: Record<string, StorageTypeInstance | PostgresEnumStorageEntry>,
126
+ storageTypes: Record<string, StorageTypeInstance>,
129
127
  ): ResolvedColumnTypeMetadata {
130
128
  if (!column.typeRef) {
131
129
  return column;
@@ -136,13 +134,6 @@ export function resolveColumnTypeMetadata(
136
134
  `Storage type "${column.typeRef}" referenced by column is not defined in storage.types.`,
137
135
  );
138
136
  }
139
- if (isPostgresEnumStorageEntry(referencedType)) {
140
- return {
141
- codecId: referencedType.codecId,
142
- nativeType: referencedType.nativeType,
143
- typeParams: { values: referencedType.values } as Record<string, unknown>,
144
- };
145
- }
146
137
  return {
147
138
  codecId: referencedType.codecId,
148
139
  nativeType: referencedType.nativeType,
@@ -23,7 +23,6 @@ import type { TargetBoundComponentDescriptor } from '@prisma-next/framework-comp
23
23
  import type { SchemaIssue } from '@prisma-next/framework-components/control';
24
24
  import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
25
25
  import type {
26
- PostgresEnumStorageEntry,
27
26
  SqlStorage,
28
27
  StorageTable,
29
28
  StorageTypeInstance,
@@ -39,7 +38,7 @@ export interface StrategyContext {
39
38
  readonly toContract: Contract<SqlStorage>;
40
39
  readonly fromContract: Contract<SqlStorage> | null;
41
40
  readonly codecHooks: ReadonlyMap<string, CodecControlHooks>;
42
- readonly storageTypes: Readonly<Record<string, StorageTypeInstance | PostgresEnumStorageEntry>>;
41
+ readonly storageTypes: Readonly<Record<string, StorageTypeInstance>>;
43
42
  readonly schema: SqlSchemaIR;
44
43
  readonly policy: MigrationOperationPolicy;
45
44
  readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;
@@ -1 +0,0 @@
1
- {"version":3,"file":"op-factory-call-BX69rHxs.mjs","names":["contractFreeDdl.createTable"],"sources":["../src/core/migrations/operations/shared.ts","../src/core/migrations/operations/columns.ts","../src/core/migrations/planner-ddl-builders.ts","../src/core/migrations/operations/indexes.ts","../src/core/migrations/operations/tables.ts","../src/core/migrations/op-factory-call.ts"],"sourcesContent":["import type { SqlMigrationPlanOperation } 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 { quoteIdentifier } from '../../sql-utils';\nimport type { SqlitePlanTargetDetails } from '../planner-target-details';\n\nexport type Op = SqlMigrationPlanOperation<SqlitePlanTargetDetails>;\n\nexport function step(description: string, sql: string): { description: string; sql: string } {\n return { description, sql };\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 readonly constraint: boolean;\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. Returns the empty string when `constraint` is false (the FK is\n * tracked at the contract level for index-creation purposes only and must\n * not produce DDL).\n */\nexport function renderForeignKeyClause(fk: SqliteForeignKeySpec): string {\n if (!fk.constraint) return '';\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 { escapeLiteral, quoteIdentifier } from '../../sql-utils';\nimport { buildTargetDetails } from '../planner-target-details';\nimport { type Op, type SqliteColumnSpec, step } from './shared';\n\nexport function addColumn(tableName: string, column: SqliteColumnSpec): Op {\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 const addSql = parts.join(' ');\n\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: [\n step(\n `ensure column \"${column.name}\" is missing`,\n `SELECT COUNT(*) = 0 FROM pragma_table_info('${escapeLiteral(tableName)}') WHERE name = '${escapeLiteral(column.name)}'`,\n ),\n ],\n execute: [step(`add column \"${column.name}\"`, addSql)],\n postcheck: [\n step(\n `verify column \"${column.name}\" exists`,\n `SELECT COUNT(*) > 0 FROM pragma_table_info('${escapeLiteral(tableName)}') WHERE name = '${escapeLiteral(column.name)}'`,\n ),\n ],\n };\n}\n\nexport function dropColumn(tableName: string, columnName: string): Op {\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(\n `ensure column \"${columnName}\" exists on \"${tableName}\"`,\n `SELECT COUNT(*) > 0 FROM pragma_table_info('${escapeLiteral(tableName)}') WHERE name = '${escapeLiteral(columnName)}'`,\n ),\n ],\n execute: [\n step(\n `drop column \"${columnName}\" from \"${tableName}\"`,\n `ALTER TABLE ${quoteIdentifier(tableName)} DROP COLUMN ${quoteIdentifier(columnName)}`,\n ),\n ],\n postcheck: [\n step(\n `verify column \"${columnName}\" is gone from \"${tableName}\"`,\n `SELECT COUNT(*) = 0 FROM pragma_table_info('${escapeLiteral(tableName)}') WHERE name = '${escapeLiteral(columnName)}'`,\n ),\n ],\n };\n}\n","/**\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 {\n isPostgresEnumStorageEntry,\n type PostgresEnumStorageEntry,\n type StorageColumn,\n type StorageTable,\n type 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 | PostgresEnumStorageEntry> = {},\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 | PostgresEnumStorageEntry>,\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 if (isPostgresEnumStorageEntry(referencedType)) {\n return {\n codecId: referencedType.codecId,\n nativeType: referencedType.nativeType,\n typeParams: { values: referencedType.values } as Record<string, unknown>,\n };\n }\n return {\n codecId: referencedType.codecId,\n nativeType: referencedType.nativeType,\n typeParams: referencedType.typeParams,\n };\n}\n","import { escapeLiteral } from '../../sql-utils';\nimport { buildCreateIndexSql, buildDropIndexSql } from '../planner-ddl-builders';\nimport { buildTargetDetails } from '../planner-target-details';\nimport { type Op, step } from './shared';\n\nexport function createIndex(tableName: string, indexName: string, columns: readonly string[]): Op {\n return {\n id: `index.${tableName}.${indexName}`,\n label: `Create index ${indexName} on ${tableName}`,\n summary: `Creates index ${indexName} on ${tableName}`,\n operationClass: 'additive',\n target: { id: 'sqlite', details: buildTargetDetails('index', indexName, tableName) },\n precheck: [\n step(\n `ensure index \"${indexName}\" is missing`,\n `SELECT COUNT(*) = 0 FROM sqlite_master WHERE type = 'index' AND name = '${escapeLiteral(indexName)}'`,\n ),\n ],\n execute: [\n step(`create index \"${indexName}\"`, buildCreateIndexSql(tableName, indexName, columns)),\n ],\n postcheck: [\n step(\n `verify index \"${indexName}\" exists`,\n `SELECT COUNT(*) > 0 FROM sqlite_master WHERE type = 'index' AND name = '${escapeLiteral(indexName)}'`,\n ),\n ],\n };\n}\n\nexport function dropIndex(tableName: string, indexName: string): Op {\n return {\n id: `dropIndex.${tableName}.${indexName}`,\n label: `Drop index ${indexName} on ${tableName}`,\n summary: `Drops index ${indexName} on ${tableName} which is not in the contract`,\n operationClass: 'destructive',\n target: { id: 'sqlite', details: buildTargetDetails('index', indexName, tableName) },\n precheck: [\n step(\n `ensure index \"${indexName}\" exists`,\n `SELECT COUNT(*) > 0 FROM sqlite_master WHERE type = 'index' AND name = '${escapeLiteral(indexName)}'`,\n ),\n ],\n execute: [step(`drop index \"${indexName}\"`, buildDropIndexSql(indexName))],\n postcheck: [\n step(\n `verify index \"${indexName}\" is gone`,\n `SELECT COUNT(*) = 0 FROM sqlite_master WHERE type = 'index' AND name = '${escapeLiteral(indexName)}'`,\n ),\n ],\n };\n}\n","import type { MigrationOperationClass } from '@prisma-next/family-sql/control';\nimport type { SchemaIssue } from '@prisma-next/framework-components/control';\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\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 function createTable(tableName: string, spec: SqliteTableSpec): Op {\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: [\n step(\n `ensure table \"${tableName}\" does not exist`,\n `SELECT COUNT(*) = 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapeLiteral(tableName)}'`,\n ),\n ],\n execute: [step(`create table \"${tableName}\"`, renderCreateTableSql(tableName, spec))],\n postcheck: [\n step(\n `verify table \"${tableName}\" exists`,\n `SELECT COUNT(*) > 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapeLiteral(tableName)}'`,\n ),\n ],\n };\n}\n\nexport function dropTable(tableName: string): Op {\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: [\n step(\n `ensure table \"${tableName}\" exists`,\n `SELECT COUNT(*) > 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapeLiteral(tableName)}'`,\n ),\n ],\n execute: [step(`drop table \"${tableName}\"`, `DROP TABLE ${quoteIdentifier(tableName)}`)],\n postcheck: [\n step(\n `verify table \"${tableName}\" is gone`,\n `SELECT COUNT(*) = 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapeLiteral(tableName)}'`,\n ),\n ],\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 `SchemaIssue` references.\n */\n readonly postchecks: readonly { readonly description: string; readonly sql: string }[];\n readonly operationClass: MigrationOperationClass;\n}\n\nexport function recreateTable(args: RecreateTableArgs): 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 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(\n `ensure table \"${tableName}\" exists`,\n `SELECT COUNT(*) > 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapeLiteral(tableName)}'`,\n ),\n step(\n `ensure temp table \"${tempName}\" does not exist`,\n `SELECT COUNT(*) = 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapeLiteral(tempName)}'`,\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(\n `verify table \"${tableName}\" exists`,\n `SELECT COUNT(*) > 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapeLiteral(tableName)}'`,\n ),\n step(\n `verify temp table \"${tempName}\" is gone`,\n `SELECT COUNT(*) = 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapeLiteral(tempName)}'`,\n ),\n ...postchecks,\n ],\n };\n}\n\n/**\n * Build a one-line summary of a recreate-table operation from the schema\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.\n */\nexport function buildRecreateSummary(tableName: string, issues: readonly SchemaIssue[]): string {\n const messages = issues.map((i) => i.message).join('; ');\n return `Recreates table ${tableName} to apply schema changes: ${messages}`;\n}\n\nconst COLUMN_LEVEL_ISSUE_KINDS = new Set<SchemaIssue['kind']>([\n 'nullability_mismatch',\n 'default_mismatch',\n 'default_missing',\n 'extra_default',\n 'type_mismatch',\n]);\n\nconst PK_ISSUE_KINDS = new Set<SchemaIssue['kind']>(['primary_key_mismatch', 'extra_primary_key']);\n\nconst UNIQUE_ISSUE_KINDS = new Set<SchemaIssue['kind']>([\n 'unique_constraint_mismatch',\n 'extra_unique_constraint',\n]);\n\nconst FK_ISSUE_KINDS = new Set<SchemaIssue['kind']>(['foreign_key_mismatch', 'extra_foreign_key']);\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\n/**\n * Per-issue postchecks verifying the recreated table's shape against the\n * contract spec. Column-level issues (`nullability_mismatch`,\n * `default_mismatch`, …) emit one targeted check each; constraint-level\n * issues (`primary_key_mismatch`, `unique_constraint_mismatch`,\n * `foreign_key_mismatch`, plus their `extra_*` siblings) emit one\n * `pragma_*`-driven check per declared constraint in the contract spec, so\n * a recreated table with the right columns but the wrong PK / unique / FK\n * shape fails the postcheck instead of passing silently. Exported so the\n * planner can pre-build the list at construction time and\n * `RecreateTableCall` doesn't have to carry `SchemaIssue` objects through\n * to render time.\n */\nexport function buildRecreatePostchecks(\n tableName: string,\n issues: readonly SchemaIssue[],\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 for (const issue of issues) {\n if (issue.kind === 'enum_values_changed') continue;\n if (!COLUMN_LEVEL_ISSUE_KINDS.has(issue.kind)) continue;\n if (!issue.column) continue;\n const c = escapeLiteral(issue.column);\n if (issue.kind === 'nullability_mismatch') {\n // `expected` carries the contract's nullable flag as a string. We only\n // emit a postcheck when the value is recognized — anything else\n // (case-folded, numeric coding, etc.) is left to the structural\n // verifier so a typo here can't silently invert the meaning.\n let wantNotNull: boolean | undefined;\n if (issue.expected === 'false') wantNotNull = true;\n else if (issue.expected === 'true') wantNotNull = false;\n if (wantNotNull !== undefined) {\n checks.push({\n description: `verify \"${issue.column}\" nullability on \"${tableName}\"`,\n sql: `SELECT COUNT(*) > 0 FROM pragma_table_info('${t}') WHERE name = '${c}' AND \"notnull\" = ${wantNotNull ? 1 : 0}`,\n });\n }\n }\n if (issue.kind === 'default_mismatch' || issue.kind === 'default_missing') {\n const colSpec = byName.get(issue.column);\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 \"${issue.column}\" default on \"${tableName}\"`,\n sql: `SELECT COUNT(*) > 0 FROM pragma_table_info('${t}') WHERE name = '${c}' AND dflt_value = '${escapeLiteral(expectedRaw)}'`,\n });\n }\n }\n if (issue.kind === 'type_mismatch') {\n const colSpec = byName.get(issue.column);\n if (colSpec) {\n checks.push({\n description: `verify \"${issue.column}\" 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 if (issue.kind === 'extra_default') {\n checks.push({\n description: `verify \"${issue.column}\" 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 }\n }\n\n // Constraint-level issues — emit one postcheck per declared constraint in\n // the contract spec when *any* issue of that kind fires, since recreate\n // rebuilds the entire table at once.\n const hasPkIssue = issues.some((i) => PK_ISSUE_KINDS.has(i.kind));\n const hasUniqueIssue = issues.some((i) => UNIQUE_ISSUE_KINDS.has(i.kind));\n const hasFkIssue = issues.some((i) => FK_ISSUE_KINDS.has(i.kind));\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 * as contractFreeDdl from '../../contract-free/ddl';\nimport { escapeLiteral } from '../sql-utils';\nimport { addColumn, dropColumn } from './operations/columns';\nimport { createIndex, dropIndex } from './operations/indexes';\nimport type { SqliteColumnSpec, SqliteIndexSpec, SqliteTableSpec } from './operations/shared';\nimport { step } from './operations/shared';\nimport { dropTable, recreateTable } from './operations/tables';\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 }\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 escapedName = escapeLiteral(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: [\n step(\n `ensure table \"${tableName}\" does not exist`,\n `SELECT COUNT(*) = 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapedName}'`,\n ),\n ],\n execute: [\n {\n description: `create table \"${tableName}\"`,\n sql: statement.sql,\n params: statement.params ?? [],\n },\n ],\n postcheck: [\n step(\n `verify table \"${tableName}\" exists`,\n `SELECT COUNT(*) > 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapedName}'`,\n ),\n ],\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 toOp(_lowerer?: Lowerer): Op {\n return dropTable(this.tableName);\n }\n\n renderTypeScript(): string {\n return `dropTable(${jsonToTsSource(this.tableName)})`;\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 toOp(_lowerer?: Lowerer): Op {\n return recreateTable({\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 }\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 `recreateTable(${jsonToTsSource(args)})`;\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 toOp(_lowerer?: Lowerer): Op {\n return addColumn(this.tableName, this.column);\n }\n\n renderTypeScript(): string {\n return `addColumn(${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.column)})`;\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 toOp(_lowerer?: Lowerer): Op {\n return dropColumn(this.tableName, this.columnName);\n }\n\n renderTypeScript(): string {\n return `dropColumn(${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.columnName)})`;\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 toOp(_lowerer?: Lowerer): Op {\n return createIndex(this.tableName, this.indexName, this.columns);\n }\n\n renderTypeScript(): string {\n return `createIndex(${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.indexName)}, ${jsonToTsSource(this.columns)})`;\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 toOp(_lowerer?: Lowerer): Op {\n return dropIndex(this.tableName, this.indexName);\n }\n\n renderTypeScript(): string {\n return `dropIndex(${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.indexName)})`;\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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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"planner-DOZWouPl.mjs","names":["exhaustive","#lowerer"],"sources":["../src/core/migrations/planner-strategies.ts","../src/core/migrations/issue-planner.ts","../src/core/migrations/planner.ts"],"sourcesContent":["/**\n * SQLite migration strategies.\n *\n * Each strategy examines the issue list, consumes issues it handles, and\n * returns the `SqliteOpFactoryCall[]` to address them. The issue planner\n * runs each strategy in order and routes whatever's left through\n * `mapIssueToCall`.\n *\n * SQLite has no enums, no data-safe backfill, and no component-declared\n * database dependencies. The only recipe that needs strategy-level\n * multi-issue consumption is `recreateTable` (added in a later phase), which\n * absorbs type/nullability/default/constraint mismatches for a given table\n * into a single recreate operation.\n */\n\nimport type { Contract } from '@prisma-next/contract/types';\nimport type {\n CodecControlHooks,\n MigrationOperationClass,\n MigrationOperationPolicy,\n} from '@prisma-next/family-sql/control';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type { SchemaIssue } from '@prisma-next/framework-components/control';\nimport { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';\nimport type {\n PostgresEnumStorageEntry,\n SqlStorage,\n StorageTable,\n StorageTypeInstance,\n} from '@prisma-next/sql-contract/types';\nimport { defaultIndexName } from '@prisma-next/sql-schema-ir/naming';\nimport type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';\nimport { toTableSpec } from './issue-planner';\nimport { DataTransformCall, RecreateTableCall, type SqliteOpFactoryCall } from './op-factory-call';\nimport type { SqliteIndexSpec } from './operations/shared';\nimport { buildRecreatePostchecks, buildRecreateSummary } from './operations/tables';\n\nexport interface StrategyContext {\n readonly toContract: Contract<SqlStorage>;\n readonly fromContract: Contract<SqlStorage> | null;\n readonly codecHooks: ReadonlyMap<string, CodecControlHooks>;\n readonly storageTypes: Readonly<Record<string, StorageTypeInstance | PostgresEnumStorageEntry>>;\n readonly schema: SqlSchemaIR;\n readonly policy: MigrationOperationPolicy;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;\n}\n\n/**\n * Look up a storage table by its explicit namespace coordinate. Returns\n * `undefined` when the namespace has no table by that name (or no such\n * namespace exists). Callers that get `undefined` MUST treat it as an\n * explicit conflict rather than silently falling back to a name-only\n * walk across namespaces — the SQLite target currently has a single\n * namespace, but this helper enforces the explicit-coordinate\n * discipline so a future multi-namespace SQLite shape inherits the\n * conflict-on-stale-coordinate behaviour the Postgres planner already\n * has.\n */\nexport function tableAt(\n storage: SqlStorage,\n namespaceId: string,\n tableName: string,\n): StorageTable | undefined {\n const ns = storage.namespaces[namespaceId];\n return ns !== undefined ? ns.entries.table?.[tableName] : undefined;\n}\n\n/**\n * Default namespace coordinate for an issue that does not carry one\n * explicitly. Hand-crafted unit-test issues fall back to `__unbound__`,\n * the only namespace any single-namespace contract carries —\n * verifier-emitted issues for legacy single-namespace contracts already\n * stamp this id explicitly. Typed structurally so issue variants\n * without a `namespaceId` slot flow through to the same fallback.\n */\nexport function resolveNamespaceIdForIssue(issue: { readonly namespaceId?: string }): string {\n return issue.namespaceId ?? UNBOUND_NAMESPACE_ID;\n}\n\nexport type CallMigrationStrategy = (\n issues: readonly SchemaIssue[],\n context: StrategyContext,\n) =>\n | {\n kind: 'match';\n issues: readonly SchemaIssue[];\n calls: readonly SqliteOpFactoryCall[];\n recipe?: boolean;\n }\n | { kind: 'no_match' };\n\n// ============================================================================\n// Recreate-table strategy\n// ============================================================================\n\nconst WIDENING_ISSUE_KINDS = new Set<SchemaIssue['kind']>(['default_mismatch', 'default_missing']);\n\nconst DESTRUCTIVE_ISSUE_KINDS = new Set<SchemaIssue['kind']>([\n 'extra_default',\n 'type_mismatch',\n 'primary_key_mismatch',\n 'foreign_key_mismatch',\n 'unique_constraint_mismatch',\n 'extra_foreign_key',\n 'extra_unique_constraint',\n 'extra_primary_key',\n]);\n\nfunction classifyIssue(issue: SchemaIssue): 'widening' | 'destructive' | null {\n if (issue.kind === 'enum_values_changed') return null;\n if (!issue.table) return null;\n if (issue.kind === 'nullability_mismatch') {\n // Relaxing (NOT NULL → nullable) is widening; tightening is destructive.\n return issue.expected === 'true' ? 'widening' : 'destructive';\n }\n if (WIDENING_ISSUE_KINDS.has(issue.kind)) return 'widening';\n if (DESTRUCTIVE_ISSUE_KINDS.has(issue.kind)) return 'destructive';\n return null;\n}\n\n/**\n * Groups recreate-eligible issues by table, decides per-table operation class\n * (destructive wins over widening), and emits one `RecreateTableCall` per\n * table. Returns unchanged-or-smaller issue list — issues the strategy\n * consumed are removed so `mapIssueToCall` doesn't double-handle them.\n */\nexport const recreateTableStrategy: CallMigrationStrategy = (issues, ctx) => {\n const byTable = new Map<\n string,\n { issues: SchemaIssue[]; hasDestructive: boolean; namespaceId: string }\n >();\n const consumed = new Set<SchemaIssue>();\n\n for (const issue of issues) {\n const cls = classifyIssue(issue);\n if (!cls) continue;\n if (issue.kind === 'enum_values_changed') continue;\n if (!issue.table) continue;\n const table = issue.table;\n const entry = byTable.get(table);\n if (entry) {\n entry.issues.push(issue);\n if (cls === 'destructive') entry.hasDestructive = true;\n } else {\n byTable.set(table, {\n issues: [issue],\n hasDestructive: cls === 'destructive',\n namespaceId: resolveNamespaceIdForIssue(issue),\n });\n }\n consumed.add(issue);\n }\n\n if (byTable.size === 0) return { kind: 'no_match' };\n\n const calls: SqliteOpFactoryCall[] = [];\n for (const [tableName, entry] of byTable) {\n const contractTable = tableAt(ctx.toContract.storage, entry.namespaceId, tableName);\n const schemaTable = ctx.schema.tables[tableName];\n if (!contractTable || !schemaTable) continue;\n const operationClass: MigrationOperationClass = entry.hasDestructive\n ? 'destructive'\n : 'widening';\n\n // Flatten the contract table to a self-contained spec — the Call holds\n // pre-rendered SQL fragments only, no `StorageColumn` or `storageTypes`.\n const tableSpec = toTableSpec(contractTable, ctx.storageTypes);\n\n const seenIndexColumnKeys = new Set<string>();\n const indexes: SqliteIndexSpec[] = [];\n for (const idx of contractTable.indexes) {\n const key = idx.columns.join(',');\n if (seenIndexColumnKeys.has(key)) continue;\n seenIndexColumnKeys.add(key);\n indexes.push({\n name: idx.name ?? defaultIndexName(tableName, idx.columns),\n columns: idx.columns,\n });\n }\n for (const fk of contractTable.foreignKeys) {\n if (fk.index === false) continue;\n const key = fk.source.columns.join(',');\n if (seenIndexColumnKeys.has(key)) continue;\n seenIndexColumnKeys.add(key);\n indexes.push({\n name: defaultIndexName(tableName, fk.source.columns),\n columns: fk.source.columns,\n });\n }\n\n calls.push(\n new RecreateTableCall({\n tableName,\n contractTable: tableSpec,\n schemaColumnNames: Object.keys(schemaTable.columns),\n indexes,\n summary: buildRecreateSummary(tableName, entry.issues),\n postchecks: buildRecreatePostchecks(tableName, entry.issues, tableSpec),\n operationClass,\n }),\n );\n }\n\n return {\n kind: 'match',\n issues: issues.filter((i) => !consumed.has(i)),\n calls,\n recipe: true,\n };\n};\n\n// ============================================================================\n// Nullability-tightening backfill strategy\n// ============================================================================\n\n/**\n * When the policy allows `'data'` and the contract tightens one or more\n * columns from nullable to NOT NULL, emit a `DataTransformCall` stub per\n * tightened column. The user fills the backfill `UPDATE` in the rendered\n * `migration.ts` before the subsequent `RecreateTableCall` copies data into\n * the tightened schema (whose `INSERT INTO temp SELECT … FROM old` would\n * otherwise fail at runtime if any `NULL`s remain).\n *\n * Does NOT consume the tightening issue — `recreateTableStrategy` still\n * needs it to produce the actual recreate that enforces the NOT NULL at\n * the schema level. The backfill op and the recreate op end up in the\n * recipe slot in strategy order (backfill first, recreate second), which\n * matches the required execution order.\n *\n * Mirrors Postgres's `nullableTighteningCallStrategy` / `'data'`-class\n * gating. When `'data'` is not in the policy (the default `db update` /\n * `db init` path), the strategy short-circuits and the recreate alone\n * runs with its current destructive-class gating — preserving today's\n * behavior where a tightening blows up at runtime if NULLs are present.\n */\nexport const nullabilityTighteningBackfillStrategy: CallMigrationStrategy = (issues, ctx) => {\n if (!ctx.policy.allowedOperationClasses.includes('data')) {\n return { kind: 'no_match' };\n }\n\n const calls: SqliteOpFactoryCall[] = [];\n for (const issue of issues) {\n if (issue.kind !== 'nullability_mismatch') continue;\n if (!issue.table || !issue.column) continue;\n // Tightening only: `expected === 'true'` means the contract wants the\n // column nullable (relaxing from NOT NULL → nullable), which is safe and\n // needs no backfill.\n if (issue.expected === 'true') continue;\n\n const namespaceId = resolveNamespaceIdForIssue(issue);\n const column = tableAt(ctx.toContract.storage, namespaceId, issue.table)?.columns[issue.column];\n if (!column || column.nullable === true) continue;\n\n calls.push(\n new DataTransformCall(\n `data_migration.backfill-${issue.table}-${issue.column}`,\n `Backfill NULLs in \"${issue.table}\".\"${issue.column}\" before NOT NULL tightening`,\n issue.table,\n issue.column,\n ),\n );\n }\n\n if (calls.length === 0) return { kind: 'no_match' };\n\n return {\n kind: 'match',\n issues,\n calls,\n recipe: true,\n };\n};\n\nexport const sqlitePlannerStrategies: readonly CallMigrationStrategy[] = [\n nullabilityTighteningBackfillStrategy,\n recreateTableStrategy,\n];\n","/**\n * SQLite migration issue planner.\n *\n * Takes schema issues (from `verifySqlSchema`) and emits migration IR\n * (`SqliteOpFactoryCall[]`). Strategies consume issues they recognize and\n * produce specialized call sequences (e.g. recreateTableStrategy absorbs\n * type/nullability/default/constraint mismatches into a single recreate op);\n * remaining issues flow through `mapIssueToCall` for the default case.\n */\n\nimport type { Contract, JsonValue } from '@prisma-next/contract/types';\nimport type {\n CodecControlHooks,\n MigrationOperationPolicy,\n SqlPlannerConflict,\n SqlPlannerConflictLocation,\n} from '@prisma-next/family-sql/control';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type { SchemaIssue } from '@prisma-next/framework-components/control';\nimport type {\n PostgresEnumStorageEntry,\n SqlStorage,\n StorageColumn,\n StorageTable,\n StorageTypeInstance,\n} from '@prisma-next/sql-contract/types';\nimport type { CodecRef, DdlTableConstraint } from '@prisma-next/sql-relational-core/ast';\nimport {\n DdlColumn,\n ForeignKeyConstraint,\n FunctionColumnDefault,\n LiteralColumnDefault,\n PrimaryKeyConstraint,\n UniqueConstraint,\n} from '@prisma-next/sql-relational-core/ast';\nimport { defaultIndexName } from '@prisma-next/sql-schema-ir/naming';\nimport type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { Result } from '@prisma-next/utils/result';\nimport { notOk, ok } from '@prisma-next/utils/result';\nimport { CONTROL_TABLE_NAMES } from '../control-tables';\nimport {\n AddColumnCall,\n CreateIndexCall,\n CreateTableCall,\n DropColumnCall,\n DropIndexCall,\n DropTableCall,\n type SqliteOpFactoryCall,\n} from './op-factory-call';\nimport type {\n SqliteColumnSpec,\n SqliteForeignKeySpec,\n SqliteTableSpec,\n SqliteUniqueSpec,\n} from './operations/shared';\nimport {\n buildColumnDefaultSql,\n buildColumnTypeSql,\n isInlineAutoincrementPrimaryKey,\n resolveColumnTypeMetadata,\n} from './planner-ddl-builders';\nimport {\n type CallMigrationStrategy,\n resolveNamespaceIdForIssue,\n type StrategyContext,\n sqlitePlannerStrategies,\n tableAt,\n} from './planner-strategies';\n\nexport type { CallMigrationStrategy, StrategyContext };\n\n// ============================================================================\n// Issue kind ordering (dependency order)\n// ============================================================================\n\nconst ISSUE_KIND_ORDER: Record<string, number> = {\n // Drops (reconciliation — clear the way for creates)\n extra_foreign_key: 10,\n extra_unique_constraint: 11,\n extra_primary_key: 12,\n extra_index: 13,\n extra_default: 14,\n extra_column: 15,\n extra_table: 16,\n\n // Tables before columns\n missing_table: 20,\n\n // Columns before constraints\n missing_column: 30,\n\n // Reconciliation alters (on existing objects)\n type_mismatch: 40,\n nullability_mismatch: 41,\n default_missing: 42,\n default_mismatch: 43,\n\n // Constraints after columns exist\n primary_key_mismatch: 50,\n unique_constraint_mismatch: 51,\n index_mismatch: 52,\n foreign_key_mismatch: 60,\n};\n\nfunction issueOrder(issue: SchemaIssue): number {\n return ISSUE_KIND_ORDER[issue.kind] ?? 99;\n}\n\nfunction issueKey(issue: SchemaIssue): string {\n const table = 'table' in issue && typeof issue.table === 'string' ? issue.table : '';\n const column = 'column' in issue && typeof issue.column === 'string' ? issue.column : '';\n const name =\n 'indexOrConstraint' in issue && typeof issue.indexOrConstraint === 'string'\n ? issue.indexOrConstraint\n : '';\n return `${table}\\u0000${column}\\u0000${name}`;\n}\n\n// ============================================================================\n// Conflict helpers\n// ============================================================================\n\nfunction issueConflict(\n kind: SqlPlannerConflict['kind'],\n summary: string,\n location?: SqlPlannerConflict['location'],\n): SqlPlannerConflict {\n return {\n kind,\n summary,\n why: 'Use `migration new` to author a custom migration for this change.',\n ...(location ? { location } : {}),\n };\n}\n\nfunction conflictKindForIssue(issue: SchemaIssue): SqlPlannerConflict['kind'] {\n switch (issue.kind) {\n case 'type_mismatch':\n return 'typeMismatch';\n case 'nullability_mismatch':\n return 'nullabilityConflict';\n case 'primary_key_mismatch':\n case 'unique_constraint_mismatch':\n case 'index_mismatch':\n case 'extra_primary_key':\n case 'extra_unique_constraint':\n return 'indexIncompatible';\n case 'foreign_key_mismatch':\n case 'extra_foreign_key':\n return 'foreignKeyConflict';\n default:\n return 'missingButNonAdditive';\n }\n}\n\nfunction issueLocation(issue: SchemaIssue): SqlPlannerConflictLocation | undefined {\n if (issue.kind === 'enum_values_changed') return undefined;\n const location: {\n table?: string;\n column?: string;\n constraint?: string;\n } = {};\n if (issue.table) location.table = issue.table;\n if (issue.column) location.column = issue.column;\n if (issue.indexOrConstraint) location.constraint = issue.indexOrConstraint;\n return Object.keys(location).length > 0 ? (location as SqlPlannerConflictLocation) : undefined;\n}\n\nfunction conflictForDisallowedCall(\n call: SqliteOpFactoryCall,\n allowed: readonly string[],\n): SqlPlannerConflict {\n const summary = `Operation \"${call.label}\" requires class \"${call.operationClass}\", but policy allows only: ${allowed.join(', ')}`;\n const location = locationForCall(call);\n return {\n kind: conflictKindForCall(call),\n summary,\n why: 'Use `migration new` to author a custom migration for this change.',\n ...(location ? { location } : {}),\n };\n}\n\nfunction conflictKindForCall(call: SqliteOpFactoryCall): SqlPlannerConflict['kind'] {\n switch (call.factoryName) {\n case 'createIndex':\n case 'dropIndex':\n return 'indexIncompatible';\n default:\n return 'missingButNonAdditive';\n }\n}\n\nfunction locationForCall(call: SqliteOpFactoryCall): SqlPlannerConflictLocation | undefined {\n const location: { table?: string; column?: string; index?: string } = {};\n if ('tableName' in call) location.table = call.tableName;\n if ('columnName' in call) location.column = call.columnName;\n if ('indexName' in call) location.index = call.indexName;\n return Object.keys(location).length > 0 ? (location as SqlPlannerConflictLocation) : undefined;\n}\n\nfunction isMissing(issue: SchemaIssue): boolean {\n if (issue.kind === 'enum_values_changed') return false;\n return issue.actual === undefined;\n}\n\n// ============================================================================\n// StorageTable / StorageColumn → flat SqliteTableSpec\n// ============================================================================\n\n/**\n * Resolves codec / `typeRef` / default rendering into a flat\n * `SqliteColumnSpec`. Mirrors Postgres's `toColumnSpec`. Once a column is\n * flattened, downstream Calls and operation factories never see\n * `StorageColumn` again — they deal in pre-rendered SQL fragments.\n */\nexport function toColumnSpec(\n name: string,\n column: StorageColumn,\n storageTypes: Readonly<Record<string, StorageTypeInstance | PostgresEnumStorageEntry>>,\n inlineAutoincrementPrimaryKey = false,\n): SqliteColumnSpec {\n const typeSql = buildColumnTypeSql(\n column,\n blindCast<\n Record<string, StorageTypeInstance | PostgresEnumStorageEntry>,\n 'buildColumnTypeSql declares its storageTypes parameter as mutable Record while the planner stores it readonly; the helper does not mutate, so the readonly→mutable narrowing is sound'\n >(storageTypes),\n );\n const defaultSql = buildColumnDefaultSql(column.default);\n return {\n name,\n typeSql,\n defaultSql,\n nullable: column.nullable,\n ...(inlineAutoincrementPrimaryKey ? { inlineAutoincrementPrimaryKey: true } : {}),\n };\n}\n\n/**\n * Flattens a `StorageTable` into a `SqliteTableSpec` ready for\n * `CreateTableCall` / `RecreateTableCall`. Sole-column AUTOINCREMENT\n * primary keys are detected here and marked on the column spec so the\n * renderer emits `INTEGER PRIMARY KEY AUTOINCREMENT` inline.\n */\nexport function toTableSpec(\n table: StorageTable,\n storageTypes: Readonly<Record<string, StorageTypeInstance | PostgresEnumStorageEntry>>,\n): SqliteTableSpec {\n const columns: SqliteColumnSpec[] = Object.entries(table.columns).map(([name, column]) =>\n toColumnSpec(name, column, storageTypes, isInlineAutoincrementPrimaryKey(table, name)),\n );\n const uniques: SqliteUniqueSpec[] = table.uniques.map((u) => ({\n columns: u.columns,\n ...(u.name !== undefined ? { name: u.name } : {}),\n }));\n const foreignKeys: SqliteForeignKeySpec[] = table.foreignKeys.map((fk) => ({\n columns: fk.source.columns,\n references: { table: fk.target.tableName, columns: fk.target.columns },\n constraint: fk.constraint !== false,\n ...(fk.name !== undefined ? { name: fk.name } : {}),\n ...(fk.onDelete !== undefined ? { onDelete: fk.onDelete } : {}),\n ...(fk.onUpdate !== undefined ? { onUpdate: fk.onUpdate } : {}),\n }));\n return {\n columns,\n ...(table.primaryKey ? { primaryKey: { columns: table.primaryKey.columns } } : {}),\n uniques,\n foreignKeys,\n };\n}\n\n// ============================================================================\n// StorageTable / StorageColumn → DdlColumn[] + DdlTableConstraint[] (for CreateTableCall)\n// ============================================================================\n\nfunction sqliteDefaultToDdlColumnDefault(\n columnDefault: StorageColumn['default'],\n): DdlColumn['default'] {\n if (!columnDefault) return undefined;\n switch (columnDefault.kind) {\n case 'literal':\n return new LiteralColumnDefault(columnDefault.value);\n case 'function':\n // `autoincrement()` is not a DEFAULT clause — SQLite encodes it as\n // `INTEGER PRIMARY KEY AUTOINCREMENT` inline on the column. Skip it\n // here; the renderer also has a defensive guard for the same case.\n if (columnDefault.expression === 'autoincrement()') return undefined;\n return new FunctionColumnDefault(columnDefault.expression);\n default: {\n const exhaustive: never = columnDefault;\n throw new Error(\n `sqliteDefaultToDdlColumnDefault: unhandled kind \"${blindCast<{ kind: string }, 'exhaustiveness: surface the unhandled default kind'>(exhaustive).kind}\"`,\n );\n }\n }\n}\n\n/**\n * Converts a `StorageTable` to the `DdlColumn[]` + `DdlTableConstraint[]`\n * pair used by `CreateTableCall`. This is the structured form consumed by\n * the DDL lowering path; `toTableSpec` / `toColumnSpec` remain in use for\n * `RecreateTableCall` and `AddColumnCall` (Phase 2).\n */\nexport function tableToDdlParts(\n table: StorageTable,\n storageTypes: Record<string, StorageTypeInstance | PostgresEnumStorageEntry>,\n): { columns: DdlColumn[]; constraints: DdlTableConstraint[] } {\n const columns: DdlColumn[] = Object.entries(table.columns).map(([name, column]) => {\n const inlineAutoincrement = isInlineAutoincrementPrimaryKey(table, name);\n const typeSql = buildColumnTypeSql(\n column,\n blindCast<\n Record<string, StorageTypeInstance | PostgresEnumStorageEntry>,\n 'buildColumnTypeSql declares its storageTypes parameter as mutable Record while the planner stores it readonly; the helper does not mutate, so the readonly→mutable narrowing is sound'\n >(storageTypes),\n );\n\n if (inlineAutoincrement) {\n // `DdlColumn` has no SQLite-specific autoincrement flag, so the full\n // `PRIMARY KEY AUTOINCREMENT` clause is embedded in the `type` string.\n // The DDL renderer (`ddl-renderer.ts`) substring-detects `AUTOINCREMENT`\n // to suppress the normal NOT NULL / PRIMARY KEY / DEFAULT clause rendering\n // and emit the entire type string verbatim. Both sites must stay in sync.\n // The structural fix (a SQLite-specific column option) is tracked in TML-2866.\n return new DdlColumn({ name, type: `${typeSql} PRIMARY KEY AUTOINCREMENT` });\n }\n const colDefault = sqliteDefaultToDdlColumnDefault(column.default);\n const resolved = resolveColumnTypeMetadata(\n column,\n blindCast<\n Record<string, StorageTypeInstance | PostgresEnumStorageEntry>,\n 'resolveColumnTypeMetadata declares its storageTypes parameter as mutable Record while the planner stores it readonly; the helper does not mutate, so the readonly→mutable narrowing is sound'\n >(storageTypes),\n );\n const codecRef: CodecRef | undefined = resolved.codecId\n ? {\n codecId: resolved.codecId,\n ...(resolved.typeParams !== undefined\n ? {\n typeParams: blindCast<\n JsonValue,\n 'resolved.typeParams is JsonValue-shaped storage metadata; the narrowed (non-undefined) value lands in CodecRef.typeParams which is JsonValue'\n >(resolved.typeParams),\n }\n : {}),\n }\n : undefined;\n return new DdlColumn({\n name,\n type: typeSql,\n ...(!column.nullable ? { notNull: true } : {}),\n ...(colDefault !== undefined ? { default: colDefault } : {}),\n ...(codecRef !== undefined ? { codecRef } : {}),\n });\n });\n\n const constraints: DdlTableConstraint[] = [];\n\n const hasInlinePk = Object.entries(table.columns).some(([name]) =>\n isInlineAutoincrementPrimaryKey(table, name),\n );\n if (table.primaryKey && !hasInlinePk) {\n constraints.push(new PrimaryKeyConstraint({ columns: table.primaryKey.columns }));\n }\n\n for (const u of table.uniques) {\n constraints.push(\n new UniqueConstraint({\n columns: u.columns,\n ...(u.name !== undefined ? { name: u.name } : {}),\n }),\n );\n }\n\n for (const fk of table.foreignKeys) {\n if (fk.constraint === false) continue;\n constraints.push(\n new ForeignKeyConstraint({\n columns: fk.source.columns,\n refTable: fk.target.tableName,\n refColumns: fk.target.columns,\n ...ifDefined('name', fk.name),\n ...ifDefined('onDelete', fk.onDelete),\n ...ifDefined('onUpdate', fk.onUpdate),\n }),\n );\n }\n\n return { columns, constraints };\n}\n\n// ============================================================================\n// Issue planner\n// ============================================================================\n\nexport interface IssuePlannerOptions {\n readonly issues: readonly SchemaIssue[];\n readonly toContract: Contract<SqlStorage>;\n readonly fromContract: Contract<SqlStorage> | null;\n readonly codecHooks: ReadonlyMap<string, CodecControlHooks>;\n readonly storageTypes: Readonly<Record<string, StorageTypeInstance | PostgresEnumStorageEntry>>;\n readonly schema?: SqlSchemaIR;\n readonly policy?: MigrationOperationPolicy;\n readonly frameworkComponents?: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;\n readonly strategies?: readonly CallMigrationStrategy[];\n}\n\nexport interface IssuePlannerValue {\n readonly calls: readonly SqliteOpFactoryCall[];\n}\n\nconst DEFAULT_POLICY: MigrationOperationPolicy = {\n allowedOperationClasses: ['additive', 'widening', 'destructive', 'data'],\n};\n\nfunction emptySchemaIR(): SqlSchemaIR {\n return { tables: {} };\n}\n\n// ============================================================================\n// Issue → Call mapping (per-issue default path)\n// ============================================================================\n\nfunction mapIssueToCall(\n issue: SchemaIssue,\n ctx: StrategyContext,\n): Result<readonly SqliteOpFactoryCall[], SqlPlannerConflict> {\n switch (issue.kind) {\n case 'missing_table': {\n if (!issue.table) {\n return notOk(\n issueConflict('unsupportedOperation', 'Missing table issue has no table name'),\n );\n }\n const namespaceId = resolveNamespaceIdForIssue(issue);\n const contractTable = tableAt(ctx.toContract.storage, namespaceId, issue.table);\n if (!contractTable) {\n return notOk(\n issueConflict(\n 'unsupportedOperation',\n `Table \"${issue.table}\" in namespace \"${namespaceId}\" reported missing but not found in destination contract`,\n ),\n );\n }\n const { columns: ddlColumns, constraints: ddlConstraints } = tableToDdlParts(\n contractTable,\n ctx.storageTypes,\n );\n const calls: SqliteOpFactoryCall[] = [\n new CreateTableCall(\n issue.table,\n ddlColumns,\n ddlConstraints.length > 0 ? ddlConstraints : undefined,\n ),\n ];\n const declaredIndexColumnKeys = new Set<string>();\n for (const index of contractTable.indexes) {\n const indexName = index.name ?? defaultIndexName(issue.table, index.columns);\n declaredIndexColumnKeys.add(index.columns.join(','));\n calls.push(new CreateIndexCall(issue.table, indexName, index.columns));\n }\n for (const fk of contractTable.foreignKeys) {\n if (fk.index === false) continue;\n if (declaredIndexColumnKeys.has(fk.source.columns.join(','))) continue;\n const indexName = defaultIndexName(issue.table, fk.source.columns);\n calls.push(new CreateIndexCall(issue.table, indexName, fk.source.columns));\n }\n return ok(calls);\n }\n\n case 'missing_column': {\n if (!issue.table || !issue.column) {\n return notOk(\n issueConflict('unsupportedOperation', 'Missing column issue has no table/column name'),\n );\n }\n const namespaceId = resolveNamespaceIdForIssue(issue);\n const contractTable2 = tableAt(ctx.toContract.storage, namespaceId, issue.table);\n const column = contractTable2?.columns[issue.column];\n if (!column) {\n return notOk(\n issueConflict(\n 'unsupportedOperation',\n `Column \"${issue.table}\".\"${issue.column}\" not in destination contract`,\n ),\n );\n }\n const contractTable = contractTable2;\n const columnSpec = toColumnSpec(\n issue.column,\n column,\n ctx.storageTypes,\n contractTable ? isInlineAutoincrementPrimaryKey(contractTable, issue.column) : false,\n );\n return ok([new AddColumnCall(issue.table, columnSpec)]);\n }\n\n case 'index_mismatch': {\n if (!issue.table) {\n return notOk(issueConflict('indexIncompatible', 'Index issue has no table name'));\n }\n if (!isMissing(issue) || !issue.expected) {\n return notOk(\n issueConflict(\n 'indexIncompatible',\n `Index on \"${issue.table}\" differs (expected: ${issue.expected}, actual: ${issue.actual})`,\n { table: issue.table },\n ),\n );\n }\n const namespaceId = resolveNamespaceIdForIssue(issue);\n const columns = issue.expected.split(', ');\n const contractTable = tableAt(ctx.toContract.storage, namespaceId, issue.table);\n if (!contractTable) {\n return notOk(\n issueConflict(\n 'unsupportedOperation',\n `Table \"${issue.table}\" not found in destination contract`,\n ),\n );\n }\n const explicitIndex = contractTable.indexes.find(\n (idx) => idx.columns.join(',') === columns.join(','),\n );\n const indexName = explicitIndex?.name ?? defaultIndexName(issue.table, columns);\n return ok([new CreateIndexCall(issue.table, indexName, columns)]);\n }\n\n case 'extra_table': {\n if (!issue.table) {\n return notOk(issueConflict('unsupportedOperation', 'Extra table issue has no table name'));\n }\n // Runner-owned control tables must never be dropped.\n if (CONTROL_TABLE_NAMES.has(issue.table)) return ok([]);\n return ok([new DropTableCall(issue.table)]);\n }\n\n case 'extra_column': {\n if (!issue.table || !issue.column) {\n return notOk(\n issueConflict('unsupportedOperation', 'Extra column issue has no table/column name'),\n );\n }\n return ok([new DropColumnCall(issue.table, issue.column)]);\n }\n\n case 'extra_index': {\n if (!issue.table || !issue.indexOrConstraint) {\n return notOk(\n issueConflict('unsupportedOperation', 'Extra index issue has no table/index name'),\n );\n }\n return ok([new DropIndexCall(issue.table, issue.indexOrConstraint)]);\n }\n\n // SQLite has no enum types (capability `sql.enums: false`). The verifier\n // should never emit `enum_values_changed` against a SQLite schema, so if\n // we receive one it is a verifier bug — surface it as an explicit\n // conflict rather than silently dropping it.\n case 'enum_values_changed':\n return notOk(\n issueConflict(\n 'unsupportedOperation',\n 'Received enum_values_changed against a SQLite schema (sql.enums: false) — verifier bug',\n ),\n );\n\n // Everything below is absorbed by recreateTableStrategy. If it falls\n // through here, policy or context didn't allow the recreate — surface as\n // a conflict.\n case 'type_mismatch':\n case 'nullability_mismatch':\n case 'default_mismatch':\n case 'default_missing':\n case 'extra_default':\n case 'primary_key_mismatch':\n case 'unique_constraint_mismatch':\n case 'foreign_key_mismatch':\n case 'extra_foreign_key':\n case 'extra_unique_constraint':\n case 'extra_primary_key':\n return notOk(issueConflict(conflictKindForIssue(issue), issue.message, issueLocation(issue)));\n\n default:\n return notOk(\n issueConflict(\n 'unsupportedOperation',\n `Unhandled issue kind: ${(issue as SchemaIssue).kind}`,\n ),\n );\n }\n}\n\n// ============================================================================\n// Call categorization for final emission order\n// ============================================================================\n\ntype CallCategory =\n | 'drop-column'\n | 'drop-index'\n | 'drop-table'\n | 'create-table'\n | 'add-column'\n | 'create-index';\n\nfunction classifyCall(call: SqliteOpFactoryCall): CallCategory | null {\n switch (call.factoryName) {\n case 'createTable':\n return 'create-table';\n case 'addColumn':\n return 'add-column';\n case 'createIndex':\n return 'create-index';\n case 'dropColumn':\n return 'drop-column';\n case 'dropIndex':\n return 'drop-index';\n case 'dropTable':\n return 'drop-table';\n // recreateTable goes into the recipe slot; return null for bucketable.\n case 'recreateTable':\n return null;\n default:\n return null;\n }\n}\n\n// ============================================================================\n// Top-level planIssues\n// ============================================================================\n\nexport function planIssues(\n options: IssuePlannerOptions,\n): Result<IssuePlannerValue, readonly SqlPlannerConflict[]> {\n const policyProvided = options.policy !== undefined;\n const policy = options.policy ?? DEFAULT_POLICY;\n const schema = options.schema ?? emptySchemaIR();\n const frameworkComponents = options.frameworkComponents ?? [];\n\n const context: StrategyContext = {\n toContract: options.toContract,\n fromContract: options.fromContract,\n codecHooks: options.codecHooks,\n storageTypes: options.storageTypes,\n schema,\n policy,\n frameworkComponents,\n };\n\n const strategies = options.strategies ?? sqlitePlannerStrategies;\n\n let remaining = options.issues;\n const recipeCalls: SqliteOpFactoryCall[] = [];\n const bucketableCalls: SqliteOpFactoryCall[] = [];\n\n for (const strategy of strategies) {\n const result = strategy(remaining, context);\n if (result.kind === 'match') {\n remaining = result.issues;\n if (result.recipe) {\n recipeCalls.push(...result.calls);\n } else {\n bucketableCalls.push(...result.calls);\n }\n }\n }\n\n const sorted = [...remaining].sort((a, b) => {\n const kindDelta = issueOrder(a) - issueOrder(b);\n if (kindDelta !== 0) return kindDelta;\n const keyA = issueKey(a);\n const keyB = issueKey(b);\n return keyA < keyB ? -1 : keyA > keyB ? 1 : 0;\n });\n\n const defaultCalls: SqliteOpFactoryCall[] = [];\n const conflicts: SqlPlannerConflict[] = [];\n\n for (const issue of sorted) {\n const result = mapIssueToCall(issue, context);\n if (result.ok) {\n defaultCalls.push(...result.value);\n } else {\n conflicts.push(result.failure);\n }\n }\n\n // Policy gating for recipe + bucketable. Default-mapped calls for disallowed\n // classes never get here (they're surfaced as per-issue conflicts above).\n const allowed = policy.allowedOperationClasses;\n let gatedRecipe = recipeCalls;\n let gatedBucketable = bucketableCalls;\n let gatedDefault = defaultCalls;\n if (policyProvided) {\n const sink = (acc: SqliteOpFactoryCall[]) => (call: SqliteOpFactoryCall) => {\n if (allowed.includes(call.operationClass)) {\n acc.push(call);\n return;\n }\n conflicts.push(conflictForDisallowedCall(call, allowed));\n };\n const gatedRecipeBucket: SqliteOpFactoryCall[] = [];\n const gatedBucketableBucket: SqliteOpFactoryCall[] = [];\n const gatedDefaultBucket: SqliteOpFactoryCall[] = [];\n recipeCalls.forEach(sink(gatedRecipeBucket));\n bucketableCalls.forEach(sink(gatedBucketableBucket));\n defaultCalls.forEach(sink(gatedDefaultBucket));\n gatedRecipe = gatedRecipeBucket;\n gatedBucketable = gatedBucketableBucket;\n gatedDefault = gatedDefaultBucket;\n }\n\n if (conflicts.length > 0) {\n return notOk(conflicts);\n }\n\n // Final emission order matches the current monolithic planner:\n // create-table → add-column → create-index → recreate → drop-column → drop-index → drop-table\n const combined = [...gatedDefault, ...gatedBucketable];\n const byCategory = (cat: CallCategory) => combined.filter((c) => classifyCall(c) === cat);\n\n const calls: SqliteOpFactoryCall[] = [\n ...byCategory('create-table'),\n ...byCategory('add-column'),\n ...byCategory('create-index'),\n ...gatedRecipe,\n ...byCategory('drop-column'),\n ...byCategory('drop-index'),\n ...byCategory('drop-table'),\n ];\n\n return ok({ calls });\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport type {\n MigrationOperationPolicy,\n SqlMigrationPlanner,\n SqlMigrationPlannerPlanOptions,\n SqlPlannerFailureResult,\n} from '@prisma-next/family-sql/control';\nimport {\n extractCodecControlHooks,\n planFieldEventOperations,\n plannerFailure,\n} from '@prisma-next/family-sql/control';\nimport type { ExecuteRequestLowerer } from '@prisma-next/family-sql/control-adapter';\nimport { verifySqlSchema } from '@prisma-next/family-sql/schema-verify';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n MigrationPlanner,\n MigrationScaffoldContext,\n SchemaIssue,\n} from '@prisma-next/framework-components/control';\nimport { parseSqliteDefault } from '../default-normalizer';\nimport { normalizeSqliteNativeType } from '../native-type-normalizer';\nimport { planIssues } from './issue-planner';\nimport {\n type SqliteMigrationDestinationInfo,\n TypeScriptRenderableSqliteMigration,\n} from './planner-produced-sqlite-migration';\nimport { sqlitePlannerStrategies } from './planner-strategies';\nimport type { SqlitePlanTargetDetails } from './planner-target-details';\n\nexport function createSqliteMigrationPlanner(\n lowerer: ExecuteRequestLowerer,\n): SqliteMigrationPlanner {\n return new SqliteMigrationPlanner(lowerer);\n}\n\nexport type SqlitePlanResult =\n | { readonly kind: 'success'; readonly plan: TypeScriptRenderableSqliteMigration }\n | SqlPlannerFailureResult;\n\n/**\n * SQLite migration planner — a thin wrapper over `planIssues`.\n *\n * `plan()` verifies the live schema against the target contract (producing\n * `SchemaIssue[]`) and delegates to `planIssues` with the registered\n * strategies. Strategies absorb groups of related issues into composite\n * recipes (e.g. recreating a table to apply type/nullability/default/\n * constraint changes at once); anything not absorbed by a strategy flows\n * through `mapIssueToCall` in the issue planner as a one-off call.\n *\n * FK-backing indexes are surfaced by `verifySqlSchema`'s index expansion\n * (see `verify-sql-schema.ts:459-469`), so `mapIssueToCall` handles them\n * uniformly alongside user-declared indexes.\n */\nexport class SqliteMigrationPlanner\n implements SqlMigrationPlanner<SqlitePlanTargetDetails>, MigrationPlanner<'sql', 'sqlite'>\n{\n readonly #lowerer: ExecuteRequestLowerer;\n\n constructor(lowerer: ExecuteRequestLowerer) {\n this.#lowerer = lowerer;\n }\n\n plan(options: {\n readonly contract: unknown;\n readonly schema: unknown;\n readonly policy: MigrationOperationPolicy;\n /**\n * The \"from\" contract (state the planner assumes the database starts at),\n * or `null` for reconciliation flows.\n *\n * Typed as the framework `Contract | null` to satisfy the\n * `MigrationPlanner` interface contract; `planSql` narrows to the SQL\n * shape via `SqlMigrationPlannerPlanOptions`. Used to populate\n * `describe().from` on the produced plan as\n * `fromContract?.storage.storageHash ?? null`.\n */\n readonly fromContract: Contract | null;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;\n /**\n * Contract space this plan applies to. Stamped onto the produced\n * {@link TypeScriptRenderableSqliteMigration.spaceId} so the runner keys\n * the marker row by the right space.\n */\n readonly spaceId: string;\n }): SqlitePlanResult {\n return this.planSql(options as SqlMigrationPlannerPlanOptions);\n }\n\n emptyMigration(\n context: MigrationScaffoldContext,\n spaceId: string,\n ): TypeScriptRenderableSqliteMigration {\n return new TypeScriptRenderableSqliteMigration(\n [],\n {\n from: context.fromHash,\n to: context.toHash,\n },\n spaceId,\n undefined,\n this.#lowerer,\n );\n }\n\n private planSql(options: SqlMigrationPlannerPlanOptions): SqlitePlanResult {\n const policyResult = this.ensureAdditivePolicy(options.policy);\n if (policyResult) return policyResult;\n\n const schemaIssues = this.collectSchemaIssues(options);\n const codecHooks = extractCodecControlHooks(options.frameworkComponents);\n const storageTypes = options.contract.storage.types ?? {};\n\n const result = planIssues({\n issues: schemaIssues,\n toContract: options.contract,\n fromContract: options.fromContract,\n codecHooks,\n storageTypes,\n schema: options.schema,\n policy: options.policy,\n frameworkComponents: options.frameworkComponents,\n strategies: sqlitePlannerStrategies,\n });\n\n if (!result.ok) {\n return plannerFailure(result.failure);\n }\n\n // Codec lifecycle hook (T2.2): inline `onFieldEvent`-emitted ops after\n // structural DDL. Sub-spec § 5 fixes the ordering as\n // `structural → added → dropped → altered`, with within-group sorting by\n // `(tableName, fieldName)` deterministic for byte-stable re-emits.\n // Hook fires only at the application emitter — extension-space planning\n // (M2 R2) never reaches this helper.\n const fieldEventOps = planFieldEventOperations({\n priorContract: options.fromContract,\n newContract: options.contract,\n codecHooks,\n });\n // Codec-emitted calls already conform to `OpFactoryCall` — render +\n // toOp + importRequirements ride directly through the same emit path\n // as structural ops, no `RawSqlCall` wrap.\n const calls = [...result.value.calls, ...fieldEventOps];\n\n const destination: SqliteMigrationDestinationInfo = {\n storageHash: options.contract.storage.storageHash,\n ...(options.contract.profileHash !== undefined\n ? { profileHash: options.contract.profileHash }\n : {}),\n };\n\n return {\n kind: 'success' as const,\n plan: new TypeScriptRenderableSqliteMigration(\n calls,\n {\n from: options.fromContract?.storage.storageHash ?? null,\n to: options.contract.storage.storageHash,\n },\n options.spaceId,\n destination,\n this.#lowerer,\n ),\n };\n }\n\n private ensureAdditivePolicy(policy: MigrationOperationPolicy): SqlPlannerFailureResult | null {\n if (!policy.allowedOperationClasses.includes('additive')) {\n return plannerFailure([\n {\n kind: 'unsupportedOperation',\n summary: 'Migration planner requires additive operations be allowed',\n why: 'The planner requires the \"additive\" operation class to be allowed in the policy.',\n },\n ]);\n }\n return null;\n }\n\n private collectSchemaIssues(options: SqlMigrationPlannerPlanOptions): readonly SchemaIssue[] {\n const allowed = options.policy.allowedOperationClasses;\n const strict = allowed.includes('widening') || allowed.includes('destructive');\n const verifyResult = verifySqlSchema({\n contract: options.contract,\n schema: options.schema,\n strict,\n typeMetadataRegistry: new Map(),\n frameworkComponents: options.frameworkComponents,\n normalizeDefault: parseSqliteDefault,\n normalizeNativeType: normalizeSqliteNativeType,\n });\n return verifyResult.schema.issues;\n }\n}\n"],"mappings":"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"}