@prisma-next/target-sqlite 0.5.0-dev.66 → 0.5.0-dev.68

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/dist/{codec-ids-DyLO2Rfx.d.mts → codec-ids-CYwMu3-4.d.mts} +1 -1
  2. package/dist/codec-ids-CYwMu3-4.d.mts.map +1 -0
  3. package/dist/{codec-ids-B1-OiN8Q.mjs → codec-ids-CuUxYcd0.mjs} +2 -3
  4. package/dist/{codec-ids-B1-OiN8Q.mjs.map → codec-ids-CuUxYcd0.mjs.map} +1 -1
  5. package/dist/codec-ids.d.mts +1 -1
  6. package/dist/codec-ids.mjs +2 -3
  7. package/dist/{codec-types-Bbzv7qCW.d.mts → codec-types-DNauB5UT.d.mts} +7 -8
  8. package/dist/codec-types-DNauB5UT.d.mts.map +1 -0
  9. package/dist/codec-types.d.mts +2 -3
  10. package/dist/codec-types.mjs +2 -3
  11. package/dist/{codecs-BqDitp2X.d.mts → codecs-BAlEiSeP.d.mts} +18 -19
  12. package/dist/codecs-BAlEiSeP.d.mts.map +1 -0
  13. package/dist/{codecs-CDcidsHL.mjs → codecs-DVnHtVWW.mjs} +3 -4
  14. package/dist/codecs-DVnHtVWW.mjs.map +1 -0
  15. package/dist/codecs.d.mts +1 -2
  16. package/dist/codecs.mjs +2 -3
  17. package/dist/codecs.mjs.map +1 -1
  18. package/dist/control.d.mts +1 -1
  19. package/dist/control.d.mts.map +1 -1
  20. package/dist/control.mjs +127 -61
  21. package/dist/control.mjs.map +1 -1
  22. package/dist/{default-normalizer-R-sQXAYt.mjs → default-normalizer-3Fccw7yw.mjs} +2 -2
  23. package/dist/{default-normalizer-R-sQXAYt.mjs.map → default-normalizer-3Fccw7yw.mjs.map} +1 -1
  24. package/dist/default-normalizer.d.mts +0 -1
  25. package/dist/default-normalizer.d.mts.map +1 -1
  26. package/dist/default-normalizer.mjs +2 -3
  27. package/dist/descriptor-meta-CE2Kbn9b.mjs +17 -0
  28. package/dist/descriptor-meta-CE2Kbn9b.mjs.map +1 -0
  29. package/dist/migration.d.mts +13 -4
  30. package/dist/migration.d.mts.map +1 -1
  31. package/dist/migration.mjs +17 -6
  32. package/dist/migration.mjs.map +1 -1
  33. package/dist/{native-type-normalizer-BMovohPm.mjs → native-type-normalizer-BlN5XfD-.mjs} +2 -2
  34. package/dist/{native-type-normalizer-BMovohPm.mjs.map → native-type-normalizer-BlN5XfD-.mjs.map} +1 -1
  35. package/dist/native-type-normalizer.d.mts.map +1 -1
  36. package/dist/native-type-normalizer.mjs +2 -3
  37. package/dist/{op-factory-call-BUVV-W9F.mjs → op-factory-call-DRKKURAO.mjs} +32 -5
  38. package/dist/{op-factory-call-BUVV-W9F.mjs.map → op-factory-call-DRKKURAO.mjs.map} +1 -1
  39. package/dist/{op-factory-call-dUIOao68.d.mts → op-factory-call-FrU2vXqw.d.mts} +23 -6
  40. package/dist/op-factory-call-FrU2vXqw.d.mts.map +1 -0
  41. package/dist/op-factory-call.d.mts +2 -3
  42. package/dist/op-factory-call.mjs +2 -3
  43. package/dist/pack.d.mts +1 -3
  44. package/dist/pack.d.mts.map +1 -1
  45. package/dist/pack.mjs +2 -3
  46. package/dist/{planner-DmOFOhoq.mjs → planner-C94LJeIM.mjs} +16 -13
  47. package/dist/planner-C94LJeIM.mjs.map +1 -0
  48. package/dist/{planner-produced-sqlite-migration-CJr8ATRH.d.mts → planner-produced-sqlite-migration-BblR19lI.d.mts} +4 -4
  49. package/dist/planner-produced-sqlite-migration-BblR19lI.d.mts.map +1 -0
  50. package/dist/{planner-produced-sqlite-migration-BANB82Pw.mjs → planner-produced-sqlite-migration-CH7YGZf6.mjs} +4 -6
  51. package/dist/planner-produced-sqlite-migration-CH7YGZf6.mjs.map +1 -0
  52. package/dist/planner-produced-sqlite-migration.d.mts +1 -4
  53. package/dist/planner-produced-sqlite-migration.mjs +2 -3
  54. package/dist/{planner-target-details-BQIWQlBu.mjs → planner-target-details-Bm71XPKb.mjs} +2 -3
  55. package/dist/{planner-target-details-BQIWQlBu.mjs.map → planner-target-details-Bm71XPKb.mjs.map} +1 -1
  56. package/dist/{planner-target-details-CtWRvse0.d.mts → planner-target-details-vhvZDWK1.d.mts} +1 -1
  57. package/dist/planner-target-details-vhvZDWK1.d.mts.map +1 -0
  58. package/dist/planner-target-details.d.mts +1 -1
  59. package/dist/planner-target-details.mjs +2 -3
  60. package/dist/planner.d.mts +2 -5
  61. package/dist/planner.d.mts.map +1 -1
  62. package/dist/planner.mjs +2 -3
  63. package/dist/{render-ops-CXOv7SRC.mjs → render-ops-CSRDT4YL.mjs} +2 -2
  64. package/dist/{render-ops-CXOv7SRC.mjs.map → render-ops-CSRDT4YL.mjs.map} +1 -1
  65. package/dist/render-ops.d.mts +2 -3
  66. package/dist/render-ops.d.mts.map +1 -1
  67. package/dist/render-ops.mjs +2 -3
  68. package/dist/runtime.d.mts.map +1 -1
  69. package/dist/runtime.mjs +3 -5
  70. package/dist/runtime.mjs.map +1 -1
  71. package/dist/{shared-D_1fFqLf.d.mts → shared-qLsgTOZs.d.mts} +2 -2
  72. package/dist/shared-qLsgTOZs.d.mts.map +1 -0
  73. package/dist/{sql-utils-D3SMPFDD.mjs → sql-utils-DhevMgef.mjs} +4 -2
  74. package/dist/sql-utils-DhevMgef.mjs.map +1 -0
  75. package/dist/sql-utils.d.mts.map +1 -1
  76. package/dist/sql-utils.mjs +2 -3
  77. package/dist/{sqlite-migration-CnLhIrJF.mjs → sqlite-migration-BBJktVVw.mjs} +2 -3
  78. package/dist/{sqlite-migration-CnLhIrJF.mjs.map → sqlite-migration-BBJktVVw.mjs.map} +1 -1
  79. package/dist/{sqlite-migration-BeR1cikr.d.mts → sqlite-migration-DAb2NEX6.d.mts} +2 -3
  80. package/dist/sqlite-migration-DAb2NEX6.d.mts.map +1 -0
  81. package/dist/{statement-builders-DobaAWnW.mjs → statement-builders-Dne-LkAV.mjs} +5 -6
  82. package/dist/statement-builders-Dne-LkAV.mjs.map +1 -0
  83. package/dist/statement-builders.d.mts.map +1 -1
  84. package/dist/statement-builders.mjs +2 -3
  85. package/dist/{tables-sKIg_lWE.mjs → tables-D84zfPZI.mjs} +5 -10
  86. package/dist/tables-D84zfPZI.mjs.map +1 -0
  87. package/package.json +19 -19
  88. package/src/core/migrations/op-factory-call.ts +38 -1
  89. package/src/core/migrations/operations/raw.ts +12 -0
  90. package/src/core/migrations/planner.ts +30 -2
  91. package/src/core/migrations/runner.ts +164 -75
  92. package/src/exports/migration.ts +1 -0
  93. package/src/exports/op-factory-call.ts +1 -0
  94. package/dist/codec-ids-DyLO2Rfx.d.mts.map +0 -1
  95. package/dist/codec-types-Bbzv7qCW.d.mts.map +0 -1
  96. package/dist/codecs-BqDitp2X.d.mts.map +0 -1
  97. package/dist/codecs-CDcidsHL.mjs.map +0 -1
  98. package/dist/descriptor-meta-BA2YAFQq.mjs +0 -24
  99. package/dist/descriptor-meta-BA2YAFQq.mjs.map +0 -1
  100. package/dist/op-factory-call-dUIOao68.d.mts.map +0 -1
  101. package/dist/planner-DmOFOhoq.mjs.map +0 -1
  102. package/dist/planner-produced-sqlite-migration-BANB82Pw.mjs.map +0 -1
  103. package/dist/planner-produced-sqlite-migration-CJr8ATRH.d.mts.map +0 -1
  104. package/dist/planner-target-details-CtWRvse0.d.mts.map +0 -1
  105. package/dist/shared-D_1fFqLf.d.mts.map +0 -1
  106. package/dist/sql-utils-D3SMPFDD.mjs.map +0 -1
  107. package/dist/sqlite-migration-BeR1cikr.d.mts.map +0 -1
  108. package/dist/statement-builders-DobaAWnW.mjs.map +0 -1
  109. package/dist/tables-sKIg_lWE.mjs.map +0 -1
@@ -1,6 +1,7 @@
1
1
  import type { ContractMarkerRecord } from '@prisma-next/contract/types';
2
2
  import type {
3
3
  MigrationOperationPolicy,
4
+ MultiSpaceRunnerResult,
4
5
  SqlControlFamilyInstance,
5
6
  SqlMigrationPlanContractInfo,
6
7
  SqlMigrationPlanOperation,
@@ -9,13 +10,16 @@ import type {
9
10
  SqlMigrationRunnerExecuteOptions,
10
11
  SqlMigrationRunnerFailure,
11
12
  SqlMigrationRunnerResult,
13
+ SqlMigrationRunnerSuccessValue,
12
14
  } from '@prisma-next/family-sql/control';
13
15
  import { runnerFailure, runnerSuccess } from '@prisma-next/family-sql/control';
14
16
  import { verifySqlSchema } from '@prisma-next/family-sql/schema-verify';
15
17
  import { type ContractMarkerRow, parseContractMarkerRow } from '@prisma-next/family-sql/verify';
18
+ import type { ControlDriverInstance } from '@prisma-next/framework-components/control';
19
+ import { APP_SPACE_ID } from '@prisma-next/framework-components/control';
16
20
  import { ifDefined } from '@prisma-next/utils/defined';
17
21
  import type { Result } from '@prisma-next/utils/result';
18
- import { ok, okVoid } from '@prisma-next/utils/result';
22
+ import { notOk, ok, okVoid } from '@prisma-next/utils/result';
19
23
  import { parseSqliteDefault } from '../default-normalizer';
20
24
  import { normalizeSqliteNativeType } from '../native-type-normalizer';
21
25
  import type { SqlitePlanTargetDetails } from './planner-target-details';
@@ -47,14 +51,10 @@ class SqliteMigrationRunner implements SqlMigrationRunner<SqlitePlanTargetDetail
47
51
  options.plan.destination,
48
52
  options.destinationContract,
49
53
  );
50
- if (!destinationCheck.ok) {
51
- return destinationCheck;
52
- }
54
+ if (!destinationCheck.ok) return destinationCheck;
53
55
 
54
56
  const policyCheck = this.enforcePolicyCompatibility(options.policy, options.plan.operations);
55
- if (!policyCheck.ok) {
56
- return policyCheck;
57
- }
57
+ if (!policyCheck.ok) return policyCheck;
58
58
 
59
59
  // SQLite recreate-table drops and rebuilds the table. If foreign_keys is ON,
60
60
  // dropping a referenced parent cascade-deletes child rows; we must disable FK
@@ -70,92 +70,180 @@ class SqliteMigrationRunner implements SqlMigrationRunner<SqlitePlanTargetDetail
70
70
  await this.beginExclusiveTransaction(driver);
71
71
  let committed = false;
72
72
  try {
73
- const ensureResult = await this.ensureControlTables(driver);
74
- if (!ensureResult.ok) {
75
- return ensureResult;
76
- }
77
- const existingMarker = await this.readMarker(driver, options.plan.spaceId);
73
+ const result = await this.executeOnConnection(options);
74
+ if (!result.ok) return result;
78
75
 
79
- const markerCheck = this.ensureMarkerCompatibility(existingMarker, options.plan);
80
- if (!markerCheck.ok) {
81
- return markerCheck;
76
+ if (fkWasEnabled) {
77
+ const fkIntegrityCheck = await this.verifyForeignKeyIntegrity(driver);
78
+ if (!fkIntegrityCheck.ok) return fkIntegrityCheck;
82
79
  }
83
80
 
84
- const markerAtDestination = this.markerMatchesDestination(existingMarker, options.plan);
85
- const isSelfEdge =
86
- options.plan.origin?.storageHash === options.plan.destination.storageHash;
87
- const skipOperations = markerAtDestination && options.plan.origin != null && !isSelfEdge;
88
-
89
- let operationsExecuted: number;
90
- let executedOperations: readonly SqlMigrationPlanOperation<SqlitePlanTargetDetails>[];
91
-
92
- if (skipOperations) {
93
- operationsExecuted = 0;
94
- executedOperations = [];
95
- } else {
96
- const applyResult = await this.applyPlan(driver, options);
97
- if (!applyResult.ok) {
98
- return applyResult;
99
- }
100
- operationsExecuted = applyResult.value.operationsExecuted;
101
- executedOperations = applyResult.value.executedOperations;
81
+ await this.commitTransaction(driver);
82
+ committed = true;
83
+ return result;
84
+ } finally {
85
+ if (!committed) {
86
+ await this.rollbackTransaction(driver);
102
87
  }
88
+ }
89
+ } finally {
90
+ if (fkWasEnabled) {
91
+ await driver.query('PRAGMA foreign_keys = ON');
92
+ }
93
+ }
94
+ }
103
95
 
104
- const schemaIR = await this.family.introspect({
105
- driver,
106
- contract: options.destinationContract,
107
- });
96
+ /**
97
+ * Apply the plan against an already-open connection without managing
98
+ * the transaction lifecycle. The caller owns BEGIN/COMMIT/ROLLBACK
99
+ * and any connection-level setup (FK pragma toggle, FK integrity
100
+ * check). Used by the per-space runner orchestration to fan out
101
+ * across contract spaces inside one outer transaction.
102
+ */
103
+ async executeOnConnection(
104
+ options: SqlMigrationRunnerExecuteOptions<SqlitePlanTargetDetails>,
105
+ ): Promise<SqlMigrationRunnerResult> {
106
+ const driver = options.driver;
107
+ if (options.space !== undefined && options.space !== options.plan.spaceId) {
108
+ throw new Error(
109
+ `SqlMigrationRunner: options.space (${options.space}) does not match plan.spaceId (${options.plan.spaceId})`,
110
+ );
111
+ }
112
+ const space = options.plan.spaceId;
108
113
 
109
- const schemaVerifyResult = verifySqlSchema({
110
- contract: options.destinationContract,
111
- schema: schemaIR,
112
- strict: options.strictVerification ?? true,
113
- context: options.context ?? {},
114
- typeMetadataRegistry: this.family.typeMetadataRegistry,
115
- frameworkComponents: options.frameworkComponents,
116
- normalizeDefault: parseSqliteDefault,
117
- normalizeNativeType: normalizeSqliteNativeType,
114
+ const destinationCheck = this.ensurePlanMatchesDestinationContract(
115
+ options.plan.destination,
116
+ options.destinationContract,
117
+ );
118
+ if (!destinationCheck.ok) return destinationCheck;
119
+
120
+ const policyCheck = this.enforcePolicyCompatibility(options.policy, options.plan.operations);
121
+ if (!policyCheck.ok) return policyCheck;
122
+
123
+ const ensureResult = await this.ensureControlTables(driver);
124
+ if (!ensureResult.ok) return ensureResult;
125
+ const existingMarker = await this.readMarker(driver, space);
126
+
127
+ const markerCheck = this.ensureMarkerCompatibility(existingMarker, options.plan);
128
+ if (!markerCheck.ok) return markerCheck;
129
+
130
+ const markerAtDestination = this.markerMatchesDestination(existingMarker, options.plan);
131
+ const isSelfEdge = options.plan.origin?.storageHash === options.plan.destination.storageHash;
132
+ const skipOperations = markerAtDestination && options.plan.origin != null && !isSelfEdge;
133
+
134
+ let operationsExecuted: number;
135
+ let executedOperations: readonly SqlMigrationPlanOperation<SqlitePlanTargetDetails>[];
136
+
137
+ if (skipOperations) {
138
+ operationsExecuted = 0;
139
+ executedOperations = [];
140
+ } else {
141
+ const applyResult = await this.applyPlan(driver, options);
142
+ if (!applyResult.ok) return applyResult;
143
+ operationsExecuted = applyResult.value.operationsExecuted;
144
+ executedOperations = applyResult.value.executedOperations;
145
+ }
146
+
147
+ if (space === APP_SPACE_ID) {
148
+ const schemaIR = await this.family.introspect({
149
+ driver,
150
+ contract: options.destinationContract,
151
+ });
152
+
153
+ const schemaVerifyResult = verifySqlSchema({
154
+ contract: options.destinationContract,
155
+ schema: schemaIR,
156
+ strict: options.strictVerification ?? true,
157
+ context: options.context ?? {},
158
+ typeMetadataRegistry: this.family.typeMetadataRegistry,
159
+ frameworkComponents: options.frameworkComponents,
160
+ normalizeDefault: parseSqliteDefault,
161
+ normalizeNativeType: normalizeSqliteNativeType,
162
+ });
163
+ if (!schemaVerifyResult.ok) {
164
+ return runnerFailure('SCHEMA_VERIFY_FAILED', schemaVerifyResult.summary, {
165
+ why: 'The resulting database schema does not satisfy the destination contract.',
166
+ meta: { issues: schemaVerifyResult.schema.issues },
118
167
  });
119
- if (!schemaVerifyResult.ok) {
120
- return runnerFailure('SCHEMA_VERIFY_FAILED', schemaVerifyResult.summary, {
121
- why: 'The resulting database schema does not satisfy the destination contract.',
122
- meta: {
123
- issues: schemaVerifyResult.schema.issues,
124
- },
125
- });
126
- }
168
+ }
169
+ }
127
170
 
128
- // Self-edge no-op detection: a self-edge migration whose ops had no
129
- // ops to begin with and brings no new invariants produced no
130
- // observable change. Skip the marker + ledger writes so an idempotent
131
- // re-apply of a self-edge data transform doesn't churn updatedAt or
132
- // pile up empty ledger entries. db update no-ops still write a
133
- // ledger entry as audit trail.
134
- const incomingInvariants = options.plan.providedInvariants;
135
- const existingInvariants = new Set(existingMarker?.invariants ?? []);
136
- const incomingIsSubsetOfExisting = incomingInvariants.every((id) =>
137
- existingInvariants.has(id),
138
- );
139
- const isSelfEdgeNoOp = isSelfEdge && operationsExecuted === 0 && incomingIsSubsetOfExisting;
171
+ // Self-edge no-op detection: see Postgres runner for the rationale
172
+ // (kept symmetric across both targets).
173
+ const incomingInvariants = options.plan.providedInvariants;
174
+ const existingInvariants = new Set(existingMarker?.invariants ?? []);
175
+ const incomingIsSubsetOfExisting = incomingInvariants.every((id) => existingInvariants.has(id));
176
+ const isSelfEdgeNoOp = isSelfEdge && operationsExecuted === 0 && incomingIsSubsetOfExisting;
177
+
178
+ if (!isSelfEdgeNoOp) {
179
+ await this.upsertMarker(driver, options, existingMarker, space);
180
+ await this.recordLedgerEntry(driver, options, existingMarker, executedOperations);
181
+ }
182
+
183
+ return runnerSuccess({
184
+ operationsPlanned: options.plan.operations.length,
185
+ operationsExecuted,
186
+ });
187
+ }
188
+
189
+ async executeAcrossSpaces(options: {
190
+ readonly driver: ControlDriverInstance<'sql', string>;
191
+ readonly perSpaceOptions: ReadonlyArray<
192
+ SqlMigrationRunnerExecuteOptions<SqlitePlanTargetDetails>
193
+ >;
194
+ }): Promise<MultiSpaceRunnerResult> {
195
+ const driver = options.driver;
196
+ const perSpaceOptions = options.perSpaceOptions;
140
197
 
141
- if (!isSelfEdgeNoOp) {
142
- await this.upsertMarker(driver, options, existingMarker);
143
- await this.recordLedgerEntry(driver, options, existingMarker, executedOperations);
198
+ if (perSpaceOptions.length === 0) {
199
+ return ok({ perSpaceResults: [] });
200
+ }
201
+
202
+ // FK pragma toggle and the FK integrity check both span the outer
203
+ // transaction — see `execute(...)` for the full rationale.
204
+ const fkWasEnabled = await this.readForeignKeysEnabled(driver);
205
+ if (fkWasEnabled) {
206
+ await driver.query('PRAGMA foreign_keys = OFF');
207
+ }
208
+
209
+ try {
210
+ await this.beginExclusiveTransaction(driver);
211
+ let committed = false;
212
+ try {
213
+ const perSpaceResults: Array<{
214
+ space: string;
215
+ value: SqlMigrationRunnerSuccessValue;
216
+ }> = [];
217
+ let lastProcessedSpace: string | undefined;
218
+ for (const spaceOptions of perSpaceOptions) {
219
+ const space = spaceOptions.space ?? spaceOptions.plan.spaceId;
220
+ const result = await this.executeOnConnection({ ...spaceOptions, driver, space });
221
+ if (!result.ok) {
222
+ return notOk({ ...result.failure, failingSpace: space });
223
+ }
224
+ perSpaceResults.push({ space, value: result.value });
225
+ lastProcessedSpace = space;
144
226
  }
145
227
 
146
228
  if (fkWasEnabled) {
147
229
  const fkIntegrityCheck = await this.verifyForeignKeyIntegrity(driver);
148
230
  if (!fkIntegrityCheck.ok) {
149
- return fkIntegrityCheck;
231
+ // Post-loop integrity violations cannot be attributed to a
232
+ // single per-space step (the cumulative effect of all
233
+ // applied plans was needed to reveal the broken
234
+ // reference). Surface the last successfully-applied space
235
+ // so operators can investigate from the most recent
236
+ // migration first.
237
+ return notOk({
238
+ ...fkIntegrityCheck.failure,
239
+ failingSpace: lastProcessedSpace ?? APP_SPACE_ID,
240
+ });
150
241
  }
151
242
  }
152
243
 
153
244
  await this.commitTransaction(driver);
154
245
  committed = true;
155
- return runnerSuccess({
156
- operationsPlanned: options.plan.operations.length,
157
- operationsExecuted,
158
- });
246
+ return ok({ perSpaceResults });
159
247
  } finally {
160
248
  if (!committed) {
161
249
  await this.rollbackTransaction(driver);
@@ -560,6 +648,7 @@ class SqliteMigrationRunner implements SqlMigrationRunner<SqlitePlanTargetDetail
560
648
  driver: SqlMigrationRunnerExecuteOptions<SqlitePlanTargetDetails>['driver'],
561
649
  options: SqlMigrationRunnerExecuteOptions<SqlitePlanTargetDetails>,
562
650
  existingMarker: ContractMarkerRecord | null,
651
+ space: string,
563
652
  ): Promise<void> {
564
653
  // SQLite has no native array type, so we can't merge invariants in SQL
565
654
  // the way Postgres does. Merge client-side under the runner's
@@ -568,7 +657,7 @@ class SqliteMigrationRunner implements SqlMigrationRunner<SqlitePlanTargetDetail
568
657
  for (const inv of options.plan.providedInvariants) merged.add(inv);
569
658
  const invariants = Array.from(merged).sort();
570
659
  const writeStatements = buildWriteMarkerStatements({
571
- space: options.plan.spaceId,
660
+ space,
572
661
  storageHash: options.plan.destination.storageHash,
573
662
  profileHash:
574
663
  options.plan.destination.profileHash ??
@@ -15,6 +15,7 @@ export {
15
15
  dataTransform,
16
16
  } from '../core/migrations/operations/data-transform';
17
17
  export { createIndex, dropIndex } from '../core/migrations/operations/indexes';
18
+ export { rawSql } from '../core/migrations/operations/raw';
18
19
  export { createTable, dropTable, recreateTable } from '../core/migrations/operations/tables';
19
20
  // Target-owned base class for migrations. Aliased to `Migration` so
20
21
  // user-edited migration.ts files (and the renderer's scaffold) read as
@@ -6,6 +6,7 @@ export {
6
6
  DropColumnCall,
7
7
  DropIndexCall,
8
8
  DropTableCall,
9
+ RawSqlCall,
9
10
  RecreateTableCall,
10
11
  type SqliteOpFactoryCall,
11
12
  } from '../core/migrations/op-factory-call';
@@ -1 +0,0 @@
1
- {"version":3,"file":"codec-ids-DyLO2Rfx.d.mts","names":[],"sources":["../src/core/codec-ids.ts"],"sourcesContent":[],"mappings":";;;cAMa;cACA;AADA,cAEA,oBAF+C,EAAA,eAAA;AAC/C,cAEA,oBAFqD,EAAA,eAAA;AACrD,cAEA,wBAF+C,EAAA,mBAAA;AAC/C,cAEA,oBAF+C,EAAA,eAAA;AAC/C,cAEA,sBAFuD,EAAA,iBAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"codec-types-Bbzv7qCW.d.mts","names":[],"sources":["../src/exports/codec-types.ts"],"sourcesContent":[],"mappings":";;;;;;cAwBM;iBAYI,qCAAA,CAAA;;;;;;;;;;EAEL,SAAA,MAAO,wBAAA;CAA6B;KAApC,OAA+D,CAAA,CAAA,CAAA,GAAA,iBAAE,MAA7B,CAA6B,GAAA,iBAAK,MAAP,CAAO,CAAL,CAAK,CAAA,GAAA,CAAA,CAAE,CAAF,CAAA,CAAK,CAAL,CAAA,EAAE,EAAG;AAAC,KAErE,UAAA,GAAa,OAFwD,CAEhD,iBAFgD,CAAA,OAEvB,kBAFuB,CAAA,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"codecs-BqDitp2X.d.mts","names":[],"sources":["../src/core/codec-helpers.ts","../src/core/codecs.ts","../src/core/registry.ts"],"sourcesContent":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"codecs-CDcidsHL.mjs","names":["codecDescriptors: readonly AnyCodecDescriptor[]"],"sources":["../src/core/codecs.ts"],"sourcesContent":["/**\n * Native SQLite target codecs (TML-2357). Mirrors the Postgres codec class form in `packages/3-targets/3-targets/postgres/src/core/codecs.ts`.\n *\n * Each codec ships as three artifacts:\n *\n * 1. A `SqliteXCodec` class extending {@link CodecImpl} that wraps the encode/decode/encodeJson/decodeJson conversions inline. SQLite's runtime conversions are simple enough that there is no shared helper module; the class bodies are the single source of truth. 2. A `SqliteXDescriptor` class extending {@link CodecDescriptorImpl} declaring the codec id, traits, target types, and params schema. SQLite codecs do not carry\n * `meta` (no per-target native-type meta today) and are all non-parameterized. 3. A per-codec column helper (`sqliteXColumn`) that calls `descriptor.factory()` directly and packages the result into a {@link ColumnSpec} via the framework {@link column} packager. The helper is tied to its descriptor with `satisfies ColumnHelperFor` + `ColumnHelperForStrict` (every SQLite codec's resolved type is well-defined).\n *\n * After TML-2357 this is the canonical source of SQLite codec metadata and runtime behaviour — the legacy `mkCodec` / `defineCodec` carriers (and the parallel `byScalar` / `codecDescriptorDefinitions` collection exports) retired with the deletion sweep.\n *\n * Audit: every SQLite codec is non-parameterized and parameter-stateless; `factory()` takes no params (`P = void`) and returns a fresh codec constructed solely from `this`.\n */\n\nimport type { JsonValue } from '@prisma-next/contract/types';\nimport {\n type AnyCodecDescriptor,\n type CodecCallContext,\n CodecDescriptorImpl,\n CodecImpl,\n type CodecInstanceContext,\n type ColumnHelperFor,\n type ColumnHelperForStrict,\n column,\n voidParamsSchema,\n} from '@prisma-next/framework-components/codec';\nimport {\n sqlCharDescriptor,\n sqlFloatDescriptor,\n sqlIntDescriptor,\n sqlVarcharDescriptor,\n} from '@prisma-next/sql-relational-core/ast';\nimport {\n SQLITE_BIGINT_CODEC_ID,\n SQLITE_BLOB_CODEC_ID,\n SQLITE_DATETIME_CODEC_ID,\n SQLITE_INTEGER_CODEC_ID,\n SQLITE_JSON_CODEC_ID,\n SQLITE_REAL_CODEC_ID,\n SQLITE_TEXT_CODEC_ID,\n} from './codec-ids';\n\nexport class SqliteTextCodec extends CodecImpl<\n typeof SQLITE_TEXT_CODEC_ID,\n readonly ['equality', 'order', 'textual'],\n string,\n string\n> {\n async encode(value: string, _ctx: CodecCallContext): Promise<string> {\n return value;\n }\n async decode(wire: string, _ctx: CodecCallContext): Promise<string> {\n return wire;\n }\n encodeJson(value: string): JsonValue {\n return value;\n }\n decodeJson(json: JsonValue): string {\n return json as string;\n }\n}\n\nexport class SqliteTextDescriptor extends CodecDescriptorImpl<void> {\n override readonly codecId = SQLITE_TEXT_CODEC_ID;\n override readonly traits = ['equality', 'order', 'textual'] as const;\n override readonly targetTypes = ['text'] as const;\n override readonly paramsSchema = voidParamsSchema;\n override factory(): (ctx: CodecInstanceContext) => SqliteTextCodec {\n return () => new SqliteTextCodec(this);\n }\n}\n\nexport const sqliteTextDescriptor = new SqliteTextDescriptor();\n\nexport const sqliteTextColumn = () =>\n column(sqliteTextDescriptor.factory(), sqliteTextDescriptor.codecId, undefined, 'text');\n\nsqliteTextColumn satisfies ColumnHelperFor<SqliteTextDescriptor>;\nsqliteTextColumn satisfies ColumnHelperForStrict<SqliteTextDescriptor>;\n\nexport class SqliteIntegerCodec extends CodecImpl<\n typeof SQLITE_INTEGER_CODEC_ID,\n readonly ['equality', 'order', 'numeric'],\n number,\n number\n> {\n async encode(value: number, _ctx: CodecCallContext): Promise<number> {\n return value;\n }\n async decode(wire: number, _ctx: CodecCallContext): Promise<number> {\n return wire;\n }\n encodeJson(value: number): JsonValue {\n return value;\n }\n decodeJson(json: JsonValue): number {\n return json as number;\n }\n}\n\nexport class SqliteIntegerDescriptor extends CodecDescriptorImpl<void> {\n override readonly codecId = SQLITE_INTEGER_CODEC_ID;\n override readonly traits = ['equality', 'order', 'numeric'] as const;\n override readonly targetTypes = ['integer'] as const;\n override readonly paramsSchema = voidParamsSchema;\n override factory(): (ctx: CodecInstanceContext) => SqliteIntegerCodec {\n return () => new SqliteIntegerCodec(this);\n }\n}\n\nexport const sqliteIntegerDescriptor = new SqliteIntegerDescriptor();\n\nexport const sqliteIntegerColumn = () =>\n column(sqliteIntegerDescriptor.factory(), sqliteIntegerDescriptor.codecId, undefined, 'integer');\n\nsqliteIntegerColumn satisfies ColumnHelperFor<SqliteIntegerDescriptor>;\nsqliteIntegerColumn satisfies ColumnHelperForStrict<SqliteIntegerDescriptor>;\n\nexport class SqliteRealCodec extends CodecImpl<\n typeof SQLITE_REAL_CODEC_ID,\n readonly ['equality', 'order', 'numeric'],\n number,\n number\n> {\n async encode(value: number, _ctx: CodecCallContext): Promise<number> {\n return value;\n }\n async decode(wire: number, _ctx: CodecCallContext): Promise<number> {\n return wire;\n }\n encodeJson(value: number): JsonValue {\n return value;\n }\n decodeJson(json: JsonValue): number {\n return json as number;\n }\n}\n\nexport class SqliteRealDescriptor extends CodecDescriptorImpl<void> {\n override readonly codecId = SQLITE_REAL_CODEC_ID;\n override readonly traits = ['equality', 'order', 'numeric'] as const;\n override readonly targetTypes = ['real'] as const;\n override readonly paramsSchema = voidParamsSchema;\n override factory(): (ctx: CodecInstanceContext) => SqliteRealCodec {\n return () => new SqliteRealCodec(this);\n }\n}\n\nexport const sqliteRealDescriptor = new SqliteRealDescriptor();\n\nexport const sqliteRealColumn = () =>\n column(sqliteRealDescriptor.factory(), sqliteRealDescriptor.codecId, undefined, 'real');\n\nsqliteRealColumn satisfies ColumnHelperFor<SqliteRealDescriptor>;\nsqliteRealColumn satisfies ColumnHelperForStrict<SqliteRealDescriptor>;\n\nexport class SqliteBlobCodec extends CodecImpl<\n typeof SQLITE_BLOB_CODEC_ID,\n readonly ['equality'],\n Uint8Array,\n Uint8Array\n> {\n async encode(value: Uint8Array, _ctx: CodecCallContext): Promise<Uint8Array> {\n return value;\n }\n async decode(wire: Uint8Array, _ctx: CodecCallContext): Promise<Uint8Array> {\n return wire;\n }\n encodeJson(value: Uint8Array): JsonValue {\n return Buffer.from(value).toString('base64');\n }\n decodeJson(json: JsonValue): Uint8Array {\n if (typeof json !== 'string') {\n throw new TypeError('sqlite/blob@1 contract value must be a base64 string');\n }\n return new Uint8Array(Buffer.from(json, 'base64'));\n }\n}\n\nexport class SqliteBlobDescriptor extends CodecDescriptorImpl<void> {\n override readonly codecId = SQLITE_BLOB_CODEC_ID;\n override readonly traits = ['equality'] as const;\n override readonly targetTypes = ['blob'] as const;\n override readonly paramsSchema = voidParamsSchema;\n override factory(): (ctx: CodecInstanceContext) => SqliteBlobCodec {\n return () => new SqliteBlobCodec(this);\n }\n}\n\nexport const sqliteBlobDescriptor = new SqliteBlobDescriptor();\n\nexport const sqliteBlobColumn = () =>\n column(sqliteBlobDescriptor.factory(), sqliteBlobDescriptor.codecId, undefined, 'blob');\n\nsqliteBlobColumn satisfies ColumnHelperFor<SqliteBlobDescriptor>;\nsqliteBlobColumn satisfies ColumnHelperForStrict<SqliteBlobDescriptor>;\n\nexport class SqliteDatetimeCodec extends CodecImpl<\n typeof SQLITE_DATETIME_CODEC_ID,\n readonly ['equality', 'order'],\n string,\n Date\n> {\n // Reject `Invalid Date` (NaN-time) at every decode ingress so consumers never receive a Date object whose downstream operations silently produce NaN. Mirrors the stricter ISO-8601 validation on the postgres timestamp helpers.\n private parseDate(value: string): Date {\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) {\n throw new TypeError(`sqlite/datetime@1 value must be a valid ISO-8601 string: ${value}`);\n }\n return date;\n }\n async encode(value: Date, _ctx: CodecCallContext): Promise<string> {\n return value.toISOString();\n }\n async decode(wire: string, _ctx: CodecCallContext): Promise<Date> {\n return this.parseDate(wire);\n }\n encodeJson(value: Date): JsonValue {\n return value.toISOString();\n }\n decodeJson(json: JsonValue): Date {\n if (typeof json !== 'string') {\n throw new TypeError('sqlite/datetime@1 contract value must be an ISO-8601 string');\n }\n return this.parseDate(json);\n }\n}\n\nexport class SqliteDatetimeDescriptor extends CodecDescriptorImpl<void> {\n override readonly codecId = SQLITE_DATETIME_CODEC_ID;\n override readonly traits = ['equality', 'order'] as const;\n override readonly targetTypes = ['text'] as const;\n override readonly paramsSchema = voidParamsSchema;\n override factory(): (ctx: CodecInstanceContext) => SqliteDatetimeCodec {\n return () => new SqliteDatetimeCodec(this);\n }\n}\n\nexport const sqliteDatetimeDescriptor = new SqliteDatetimeDescriptor();\n\nexport const sqliteDatetimeColumn = () =>\n column(sqliteDatetimeDescriptor.factory(), sqliteDatetimeDescriptor.codecId, undefined, 'text');\n\nsqliteDatetimeColumn satisfies ColumnHelperFor<SqliteDatetimeDescriptor>;\nsqliteDatetimeColumn satisfies ColumnHelperForStrict<SqliteDatetimeDescriptor>;\n\nexport class SqliteJsonCodec extends CodecImpl<\n typeof SQLITE_JSON_CODEC_ID,\n readonly ['equality'],\n string | JsonValue,\n JsonValue\n> {\n async encode(value: JsonValue, _ctx: CodecCallContext): Promise<string> {\n return JSON.stringify(value);\n }\n async decode(wire: string | JsonValue, _ctx: CodecCallContext): Promise<JsonValue> {\n return typeof wire === 'string' ? (JSON.parse(wire) as JsonValue) : wire;\n }\n encodeJson(value: JsonValue): JsonValue {\n return value;\n }\n decodeJson(json: JsonValue): JsonValue {\n return json;\n }\n}\n\nexport class SqliteJsonDescriptor extends CodecDescriptorImpl<void> {\n override readonly codecId = SQLITE_JSON_CODEC_ID;\n override readonly traits = ['equality'] as const;\n override readonly targetTypes = ['text'] as const;\n override readonly paramsSchema = voidParamsSchema;\n override factory(): (ctx: CodecInstanceContext) => SqliteJsonCodec {\n return () => new SqliteJsonCodec(this);\n }\n}\n\nexport const sqliteJsonDescriptor = new SqliteJsonDescriptor();\n\nexport const sqliteJsonColumn = () =>\n column(sqliteJsonDescriptor.factory(), sqliteJsonDescriptor.codecId, undefined, 'text');\n\nsqliteJsonColumn satisfies ColumnHelperFor<SqliteJsonDescriptor>;\nsqliteJsonColumn satisfies ColumnHelperForStrict<SqliteJsonDescriptor>;\n\nexport class SqliteBigintCodec extends CodecImpl<\n typeof SQLITE_BIGINT_CODEC_ID,\n readonly ['equality', 'order', 'numeric'],\n number | bigint,\n bigint\n> {\n async encode(value: bigint, _ctx: CodecCallContext): Promise<number | bigint> {\n return value;\n }\n async decode(wire: number | bigint, _ctx: CodecCallContext): Promise<bigint> {\n return BigInt(wire);\n }\n encodeJson(value: bigint): JsonValue {\n return value.toString();\n }\n decodeJson(json: JsonValue): bigint {\n if (typeof json !== 'string' && typeof json !== 'number') {\n throw new TypeError('sqlite/bigint@1 contract value must be a string or number');\n }\n return BigInt(json);\n }\n}\n\nexport class SqliteBigintDescriptor extends CodecDescriptorImpl<void> {\n override readonly codecId = SQLITE_BIGINT_CODEC_ID;\n override readonly traits = ['equality', 'order', 'numeric'] as const;\n override readonly targetTypes = ['integer'] as const;\n override readonly paramsSchema = voidParamsSchema;\n override factory(): (ctx: CodecInstanceContext) => SqliteBigintCodec {\n return () => new SqliteBigintCodec(this);\n }\n}\n\nexport const sqliteBigintDescriptor = new SqliteBigintDescriptor();\n\nexport const sqliteBigintColumn = () =>\n column(sqliteBigintDescriptor.factory(), sqliteBigintDescriptor.codecId, undefined, 'integer');\n\nsqliteBigintColumn satisfies ColumnHelperFor<SqliteBigintDescriptor>;\nsqliteBigintColumn satisfies ColumnHelperForStrict<SqliteBigintDescriptor>;\n\nexport const codecDescriptors: readonly AnyCodecDescriptor[] = [\n sqlCharDescriptor,\n sqlVarcharDescriptor,\n sqlIntDescriptor,\n sqlFloatDescriptor,\n sqliteTextDescriptor,\n sqliteIntegerDescriptor,\n sqliteRealDescriptor,\n sqliteBlobDescriptor,\n sqliteDatetimeDescriptor,\n sqliteJsonDescriptor,\n sqliteBigintDescriptor,\n];\n"],"mappings":"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"}
@@ -1,24 +0,0 @@
1
- import { temporalAuthoringPresets } from "@prisma-next/family-sql/control";
2
-
3
- //#region src/core/authoring.ts
4
- const sqliteAuthoringFieldPresets = { temporal: temporalAuthoringPresets({
5
- codecId: "sqlite/datetime@1",
6
- nativeType: "text"
7
- }) };
8
-
9
- //#endregion
10
- //#region src/core/descriptor-meta.ts
11
- const sqliteTargetDescriptorMetaBase = {
12
- kind: "target",
13
- familyId: "sql",
14
- targetId: "sqlite",
15
- id: "sqlite",
16
- version: "0.0.1",
17
- capabilities: {},
18
- authoring: { field: sqliteAuthoringFieldPresets }
19
- };
20
- const sqliteTargetDescriptorMeta = sqliteTargetDescriptorMetaBase;
21
-
22
- //#endregion
23
- export { sqliteTargetDescriptorMeta as t };
24
- //# sourceMappingURL=descriptor-meta-BA2YAFQq.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"descriptor-meta-BA2YAFQq.mjs","names":["sqliteTargetDescriptorMeta: typeof sqliteTargetDescriptorMetaBase & {\n readonly __codecTypes?: CodecTypes;\n}"],"sources":["../src/core/authoring.ts","../src/core/descriptor-meta.ts"],"sourcesContent":["import { temporalAuthoringPresets } from '@prisma-next/family-sql/control';\nimport type { AuthoringFieldNamespace } from '@prisma-next/framework-components/authoring';\n\nexport const sqliteAuthoringFieldPresets = {\n temporal: temporalAuthoringPresets({\n codecId: 'sqlite/datetime@1',\n nativeType: 'text',\n }),\n} as const satisfies AuthoringFieldNamespace;\n","import type { CodecTypes } from '../exports/codec-types';\nimport { sqliteAuthoringFieldPresets } from './authoring';\n\nconst sqliteTargetDescriptorMetaBase = {\n kind: 'target',\n familyId: 'sql',\n targetId: 'sqlite',\n id: 'sqlite',\n version: '0.0.1',\n capabilities: {},\n authoring: {\n field: sqliteAuthoringFieldPresets,\n },\n} as const;\n\nexport const sqliteTargetDescriptorMeta: typeof sqliteTargetDescriptorMetaBase & {\n readonly __codecTypes?: CodecTypes;\n} = sqliteTargetDescriptorMetaBase;\n"],"mappings":";;;AAGA,MAAa,8BAA8B,EACzC,UAAU,yBAAyB;CACjC,SAAS;CACT,YAAY;CACb,CAAC,EACH;;;;ACLD,MAAM,iCAAiC;CACrC,MAAM;CACN,UAAU;CACV,UAAU;CACV,IAAI;CACJ,SAAS;CACT,cAAc,EAAE;CAChB,WAAW,EACT,OAAO,6BACR;CACF;AAED,MAAaA,6BAET"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"op-factory-call-dUIOao68.d.mts","names":[],"sources":["../src/core/migrations/op-factory-call.ts"],"sourcesContent":[],"mappings":";;;;;;;;KA0BK,EAAA,GAAK,yBA8B6B,CA9BH,uBA8BG,CAAA;uBA1BxB,uBAAA,SAAgC,YAAA,YAAwB,aAkC7D,CAAA;EAf2B,kBAAA,WAAA,EAAA,MAAA;EAAuB,kBAAA,cAAA,EAjBxB,uBAiBwB;EAwB/C,kBAAc,KAAA,EAAA,MAajB;EASG,SAAA,IAAA,CAAA,CAAA,EA7DM,EA6DN;EAEc,kBAAA,CAAA,CAAA,EAAA,SA7DM,iBA6DN,EAAA;EAED,UAAA,MAAA,CAAA,CAAA,EAAA,IAAA;;AASP,cA3DN,eAAA,SAAwB,uBAAA,CA2DlB;EAEG,SAAA,WAAA,EAAA,aAAA;EAGF,SAAA,cAAA,EAAA,UAAA;EAcV,SAAA,SAAA,EAAA,MAAA;EAhC6B,SAAA,IAAA,EA1CtB,eA0CsB;EAAuB,SAAA,KAAA,EAAA,MAAA;EA8DjD,WAAA,CAAA,SAAc,EAAA,MAAA,EAAA,IAAA,EArGY,eAqGZ;EAKR,IAAA,CAAA,CAAA,EAlGT,EAkGS;EAGsB,gBAAA,CAAA,CAAA,EAAA,MAAA;;AARN,cApFtB,aAAA,SAAsB,uBAAA,CAoFA;EAAuB,SAAA,WAAA,EAAA,WAAA;EA0B7C,SAAA,cAAe,EAAA,aAAQ;EA4BvB,SAAA,SAAgB,EAAA,MAAA;EA0BhB,SAAA,KAAA,EAAc,MAAA;EAwCd,WAAA,CAAA,SAAkB,EAAA,MAAA;EAiBrB,IAAA,CAAA,CAAA,EAhNA,EAgNA;EAiBgC,gBAAA,CAAA,CAAA,EAAA,MAAA;;AAlCoB,cAtLjD,iBAAA,SAA0B,uBAAA,CAsLuB;EA8ClD,SAAA,WAAA,EAAmB,eAAA;EAC3B,SAAA,cAAA,EAnOuB,uBAmOvB;EACA,SAAA,SAAA,EAAA,MAAA;EACA,SAAA,aAAA,EAnOsB,eAmOtB;EACA,SAAA,iBAAA,EAAA,SAAA,MAAA,EAAA;EACA,SAAA,OAAA,EAAA,SAnOyB,eAmOzB,EAAA;EACA,SAAA,OAAA,EAAA,MAAA;EACA,SAAA,UAAA,EAAA,SAAA;IACA,SAAA,WAAA,EAAA,MAAA;IAAiB,SAAA,GAAA,EAAA,MAAA;;;;;mBA/NF;;sBAEG;;;;;;oBAGF;;UAcV;;;cA8BG,aAAA,SAAsB,uBAAA;;;;;mBAKhB;;yCAGsB;UAS/B;;;cASG,cAAA,SAAuB,uBAAA;;;;;;;UAe1B;;;cAaG,eAAA,SAAwB,uBAAA;;;;;;;;UAiB3B;;;cASG,aAAA,SAAsB,uBAAA;;;;;;;UAezB;;;;;;;;;;;;;;;cAyBG,iBAAA,SAA0B,uBAAA;;;;;;;;UAiB7B;;iCAiBgC;;KAY9B,mBAAA,GACR,kBACA,gBACA,oBACA,gBACA,iBACA,kBACA,gBACA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"planner-DmOFOhoq.mjs","names":["recreateTableStrategy: CallMigrationStrategy","calls: SqliteOpFactoryCall[]","operationClass: MigrationOperationClass","indexes: SqliteIndexSpec[]","nullabilityTighteningBackfillStrategy: CallMigrationStrategy","sqlitePlannerStrategies: readonly CallMigrationStrategy[]","ISSUE_KIND_ORDER: Record<string, number>","location: {\n table?: string;\n column?: string;\n constraint?: string;\n }","location: { table?: string; column?: string; index?: string }","columns: SqliteColumnSpec[]","uniques: SqliteUniqueSpec[]","foreignKeys: SqliteForeignKeySpec[]","DEFAULT_POLICY: MigrationOperationPolicy","calls: SqliteOpFactoryCall[]","context: StrategyContext","recipeCalls: SqliteOpFactoryCall[]","bucketableCalls: SqliteOpFactoryCall[]","defaultCalls: SqliteOpFactoryCall[]","conflicts: SqlPlannerConflict[]","gatedRecipeBucket: SqliteOpFactoryCall[]","gatedBucketableBucket: SqliteOpFactoryCall[]","gatedDefaultBucket: SqliteOpFactoryCall[]","destination: SqliteMigrationDestinationInfo"],"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 type { SqlStorage, StorageTypeInstance } 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\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<string, { issues: SchemaIssue[]; hasDestructive: boolean }>();\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, { issues: [issue], hasDestructive: cls === 'destructive' });\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 = ctx.toContract.storage.tables[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.columns.join(',');\n if (seenIndexColumnKeys.has(key)) continue;\n seenIndexColumnKeys.add(key);\n indexes.push({\n name: defaultIndexName(tableName, fk.columns),\n columns: fk.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 column = ctx.toContract.storage.tables[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 } 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 { defaultIndexName } from '@prisma-next/sql-schema-ir/naming';\nimport type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';\nimport type { Result } from '@prisma-next/utils/result';\nimport { notOk, ok } from '@prisma-next/utils/result';\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} from './planner-ddl-builders';\nimport {\n type CallMigrationStrategy,\n type StrategyContext,\n sqlitePlannerStrategies,\n} from './planner-strategies';\nimport { CONTROL_TABLE_NAMES } from './statement-builders';\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(column, storageTypes as Record<string, StorageTypeInstance>);\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.columns,\n references: { table: fk.references.table, columns: fk.references.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// 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: {}, dependencies: [] };\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 contractTable = ctx.toContract.storage.tables[issue.table];\n if (!contractTable) {\n return notOk(\n issueConflict(\n 'unsupportedOperation',\n `Table \"${issue.table}\" reported missing but not found in destination contract`,\n ),\n );\n }\n const tableSpec = toTableSpec(contractTable, ctx.storageTypes);\n const calls: SqliteOpFactoryCall[] = [new CreateTableCall(issue.table, tableSpec)];\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.columns.join(','))) continue;\n const indexName = defaultIndexName(issue.table, fk.columns);\n calls.push(new CreateIndexCall(issue.table, indexName, fk.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 column = ctx.toContract.storage.tables[issue.table]?.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 = ctx.toContract.storage.tables[issue.table];\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 columns = issue.expected.split(', ');\n const contractTable = ctx.toContract.storage.tables[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 // Use the explicit-index name if one is declared for these columns;\n // otherwise fall back to `defaultIndexName` (which is also what\n // `verifySqlSchema` synthesizes for FK-backing indexes). Whether the\n // missing index originates from `contractTable.indexes` or from an FK\n // with `index: true` doesn't change the emitted DDL.\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 { extractCodecControlHooks, plannerFailure } from '@prisma-next/family-sql/control';\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(): SqliteMigrationPlanner {\n return new SqliteMigrationPlanner();\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 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 );\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 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 result.value.calls,\n {\n from: options.fromContract?.storage.storageHash ?? null,\n to: options.contract.storage.storageHash,\n },\n options.spaceId,\n destination,\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 +0,0 @@
1
- {"version":3,"file":"planner-produced-sqlite-migration-BANB82Pw.mjs","names":["BASE_IMPORTS: readonly ImportRequirement[]","requirements: ImportRequirement[]","lines: string[]","#calls","#meta","#destination","#spaceId"],"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 { detectScaffoldRuntime, shebangLineFor } from '@prisma-next/migration-tools/migration-ts';\nimport { type ImportRequirement, jsonToTsSource, renderImports } from '@prisma-next/ts-render';\nimport type { SqliteOpFactoryCall } from './op-factory-call';\n\nexport interface RenderMigrationMeta {\n readonly from: string | null;\n readonly to: string;\n readonly labels?: readonly string[];\n}\n\n/**\n * Always-present base imports for the rendered scaffold. Both come from\n * `@prisma-next/target-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 target-owned 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/target-sqlite/migration', symbol: 'Migration' },\n { moduleSpecifier: '@prisma-next/target-sqlite/migration', symbol: 'MigrationCLI' },\n];\n\nexport function renderCallsToTypeScript(\n calls: ReadonlyArray<SqliteOpFactoryCall>,\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<SqliteOpFactoryCall>): 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 if (meta.labels && meta.labels.length > 0) {\n lines.push(` labels: ${jsonToTsSource(meta.labels)},`);\n }\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 { MigrationPlanWithAuthoringSurface } from '@prisma-next/framework-components/control';\nimport type { MigrationMeta } from '@prisma-next/migration-tools/migration';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { SqliteOpFactoryCall } from './op-factory-call';\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 SqliteOpFactoryCall[];\n readonly #meta: MigrationMeta;\n readonly #destination: SqliteMigrationDestinationInfo;\n readonly #spaceId: string;\n\n constructor(\n calls: readonly SqliteOpFactoryCall[],\n meta: MigrationMeta,\n spaceId: string,\n destination?: SqliteMigrationDestinationInfo,\n ) {\n super();\n this.#calls = calls;\n this.#meta = meta;\n this.#spaceId = spaceId;\n this.#destination = destination ?? { storageHash: meta.to };\n }\n\n override get operations(): readonly Op[] {\n return renderOps(this.#calls);\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 ...ifDefined('labels', this.#meta.labels),\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,MAAMA,eAA6C,CACjD;CAAE,iBAAiB;CAAwC,QAAQ;CAAa,EAChF;CAAE,iBAAiB;CAAwC,QAAQ;CAAgB,CACpF;AAED,SAAgB,wBACd,OACA,MACQ;CACR,MAAM,UAAU,aAAa,MAAM;CACnC,MAAM,iBAAiB,MAAM,KAAK,MAAM,EAAE,kBAAkB,CAAC,CAAC,KAAK,MAAM;AAEzE,QAAO;EACL,eAAe,uBAAuB,CAAC;EACvC;EACA;EACA;EACA,oBAAoB,KAAK;EACzB;EACA;EACA,OAAO,gBAAgB,EAAE;EACzB;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK;;AAGd,SAAS,aAAa,OAAmD;CACvE,MAAMC,eAAoC,CAAC,GAAG,aAAa;AAC3D,MAAK,MAAM,QAAQ,MACjB,MAAK,MAAM,OAAO,KAAK,oBAAoB,CACzC,cAAa,KAAK,IAAI;AAG1B,QAAO,cAAc,aAAa;;AAGpC,SAAS,oBAAoB,MAAmC;CAC9D,MAAMC,QAAkB,EAAE;AAC1B,OAAM,KAAK,0BAA0B;AACrC,OAAM,KAAK,eAAe;AAC1B,OAAM,KAAK,eAAe,KAAK,UAAU,KAAK,KAAK,CAAC,GAAG;AACvD,OAAM,KAAK,aAAa,KAAK,UAAU,KAAK,GAAG,CAAC,GAAG;AACnD,KAAI,KAAK,UAAU,KAAK,OAAO,SAAS,EACtC,OAAM,KAAK,iBAAiB,eAAe,KAAK,OAAO,CAAC,GAAG;AAE7D,OAAM,KAAK,SAAS;AACpB,OAAM,KAAK,MAAM;AACjB,OAAM,KAAK,GAAG;AACd,QAAO,MAAM,KAAK,KAAK;;AAGzB,SAAS,OAAO,MAAc,QAAwB;CACpD,MAAM,MAAM,IAAI,OAAO,OAAO;AAC9B,QAAO,KACJ,MAAM,KAAK,CACX,KAAK,SAAU,KAAK,MAAM,GAAG,GAAG,MAAM,SAAS,KAAM,CACrD,KAAK,KAAK;;;;;ACxEf,IAAa,sCAAb,cACU,gBAEV;CACE,CAASC;CACT,CAASC;CACT,CAASC;CACT,CAASC;CAET,YACE,OACA,MACA,SACA,aACA;AACA,SAAO;AACP,QAAKH,QAAS;AACd,QAAKC,OAAQ;AACb,QAAKE,UAAW;AAChB,QAAKD,cAAe,eAAe,EAAE,aAAa,KAAK,IAAI;;CAG7D,IAAa,aAA4B;AACvC,SAAO,UAAU,MAAKF,MAAO;;CAG/B,AAAS,WAA0B;AACjC,SAAO,MAAKC;;CAGd,IAAa,cAA8C;AACzD,SAAO,MAAKC;;;;;;;CAQd,IAAI,UAAkB;AACpB,SAAO,MAAKC;;CAGd,mBAA2B;AACzB,SAAO,wBAAwB,MAAKH,OAAQ;GAC1C,MAAM,MAAKC,KAAM;GACjB,IAAI,MAAKA,KAAM;GACf,GAAG,UAAU,UAAU,MAAKA,KAAM,OAAO;GAC1C,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"planner-produced-sqlite-migration-CJr8ATRH.d.mts","names":[],"sources":["../src/core/migrations/planner-produced-sqlite-migration.ts"],"sourcesContent":[],"mappings":";;;;;;;;KAUK,EAAA,GAAK,0BAA0B;UAEnB,8BAAA;EAFZ,SAAE,WAA6B,EAAA,MAAA;EAEnB,SAAA,WAAA,CAAA,EAAA,MAAA;AAKjB;AAUoB,cAVP,mCAAA,SACH,eAAA,YACG,iCAQO,CAAA;EACV,CAAA,OAAA;EAEQ,WAAA,CAAA,KAAA,EAAA,SAHE,mBAGF,EAAA,EAAA,IAAA,EAFR,aAEQ,EAAA,OAAA,EAAA,MAAA,EAAA,WAAA,CAAA,EAAA,8BAAA;EASoB,IAAA,UAAA,CAAA,CAAA,EAAA,SAAA,EAAA,EAAA;EAIf,QAAA,CAAA,CAAA,EAAA,aAAA;EAIO,IAAA,WAAA,CAAA,CAAA,EAAA,8BAAA;EA7BpB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"planner-target-details-CtWRvse0.d.mts","names":[],"sources":["../src/core/migrations/planner-target-details.ts"],"sourcesContent":[],"mappings":";KAEY,cAAA;AAAA,UAMK,uBAAA,CANS;EAMT,SAAA,MAAA,EAAA,MAAA;EAaD,SAAA,UAAA,EAXO,cAYT;;;;iBADE,kBAAA,aACF,+CAGX"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"shared-D_1fFqLf.d.mts","names":[],"sources":["../src/core/migrations/operations/shared.ts"],"sourcesContent":[],"mappings":";;;;;KAKY,EAAA,GAAK,0BAA0B;AAkC3C;AAKA;AAgBA;;;;;;AAYA;;;;;;;;UA7CiB,gBAAA;;;;;;;UAQA,oBAAA;;;UAIA,gBAAA;;;;UAKA,oBAAA;;;;;;;sBAOK;sBACA;;;;;;;UAQL,eAAA;6BACY;wBACL;8BACM;kCACI;;;;;;;UAQjB,eAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"sql-utils-D3SMPFDD.mjs","names":["value: string","kind: 'identifier' | 'literal'"],"sources":["../src/core/sql-utils.ts"],"sourcesContent":["/**\n * Shared SQL utility functions for the SQLite target.\n *\n * These functions handle safe SQL identifier and literal escaping. They\n * live in `target-sqlite` (mirroring `target-postgres/src/core/sql-utils.ts`)\n * so both the control adapter (used at emit time) and the runtime adapter\n * (used at execute time) can depend on them through a single one-way edge:\n * `adapter-sqlite → target-sqlite`. Hosting them target-side avoids the\n * cyclic workspace dependency that would arise if `target-sqlite` reached\n * back into `adapter-sqlite` for these primitives.\n */\n\nexport class SqlEscapeError extends Error {\n constructor(\n message: string,\n public readonly value: string,\n public readonly kind: 'identifier' | 'literal',\n ) {\n super(message);\n this.name = 'SqlEscapeError';\n }\n}\n\nexport function quoteIdentifier(identifier: string): string {\n if (identifier.length === 0) {\n throw new SqlEscapeError('Identifier cannot be empty', identifier, 'identifier');\n }\n if (identifier.includes('\\0')) {\n throw new SqlEscapeError(\n 'Identifier cannot contain null bytes',\n identifier.replace(/\\0/g, '\\\\0'),\n 'identifier',\n );\n }\n return `\"${identifier.replace(/\"/g, '\"\"')}\"`;\n}\n\nexport function escapeLiteral(value: string): string {\n if (value.includes('\\0')) {\n throw new SqlEscapeError(\n 'Literal value cannot contain null bytes',\n value.replace(/\\0/g, '\\\\0'),\n 'literal',\n );\n }\n return value.replace(/'/g, \"''\");\n}\n"],"mappings":";;;;;;;;;;;;AAYA,IAAa,iBAAb,cAAoC,MAAM;CACxC,YACE,SACA,AAAgBA,OAChB,AAAgBC,MAChB;AACA,QAAM,QAAQ;EAHE;EACA;AAGhB,OAAK,OAAO;;;AAIhB,SAAgB,gBAAgB,YAA4B;AAC1D,KAAI,WAAW,WAAW,EACxB,OAAM,IAAI,eAAe,8BAA8B,YAAY,aAAa;AAElF,KAAI,WAAW,SAAS,KAAK,CAC3B,OAAM,IAAI,eACR,wCACA,WAAW,QAAQ,OAAO,MAAM,EAChC,aACD;AAEH,QAAO,IAAI,WAAW,QAAQ,MAAM,OAAK,CAAC;;AAG5C,SAAgB,cAAc,OAAuB;AACnD,KAAI,MAAM,SAAS,KAAK,CACtB,OAAM,IAAI,eACR,2CACA,MAAM,QAAQ,OAAO,MAAM,EAC3B,UACD;AAEH,QAAO,MAAM,QAAQ,MAAM,KAAK"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"sqlite-migration-BeR1cikr.d.mts","names":[],"sources":["../src/core/migrations/sqlite-migration.ts"],"sourcesContent":[],"mappings":";;;;;;;AAUA;;;;;uBAAsB,eAAA,SAAwB,UAAa"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"statement-builders-DobaAWnW.mjs","names":["CONTROL_TABLE_NAMES: ReadonlySet<string>","ensureMarkerTableStatement: SqlStatement","ensureLedgerTableStatement: SqlStatement"],"sources":["../src/core/migrations/statement-builders.ts"],"sourcesContent":["import { APP_SPACE_ID } from '@prisma-next/framework-components/control';\n\nexport { APP_SPACE_ID };\n\nexport interface SqlStatement {\n readonly sql: string;\n readonly params: readonly unknown[];\n}\n\nexport const MARKER_TABLE_NAME = '_prisma_marker';\nexport const LEDGER_TABLE_NAME = '_prisma_ledger';\n\n/**\n * Control tables the runner creates/manages. The planner must not drop these\n * when reconciling \"extra\" tables against the contract.\n */\nexport const CONTROL_TABLE_NAMES: ReadonlySet<string> = new Set([\n MARKER_TABLE_NAME,\n LEDGER_TABLE_NAME,\n]);\n\n/**\n * Schema for `_prisma_marker`. The `space TEXT PRIMARY KEY` shape\n * supports one row per loaded contract space (`'app'`,\n * `'<extension-id>'`, …); brand-new databases create this shape\n * directly. The migration runner detects pre-1.0 single-row markers\n * (no `space` column) at boot and fails with a structured\n * `LEGACY_MARKER_SHAPE` error rather than auto-rebuilding the table —\n * see `specs/framework-mechanism.spec.md § 2`.\n */\nexport const ensureMarkerTableStatement: SqlStatement = {\n sql: `CREATE TABLE IF NOT EXISTS _prisma_marker (\n space TEXT NOT NULL PRIMARY KEY DEFAULT '${APP_SPACE_ID}',\n core_hash TEXT NOT NULL,\n profile_hash TEXT NOT NULL,\n contract_json TEXT,\n canonical_version INTEGER,\n updated_at TEXT NOT NULL DEFAULT (datetime('now')),\n app_tag TEXT,\n meta TEXT NOT NULL DEFAULT '{}',\n invariants TEXT NOT NULL DEFAULT '[]'\n )`,\n params: [],\n};\n\nexport const ensureLedgerTableStatement: SqlStatement = {\n sql: `CREATE TABLE IF NOT EXISTS _prisma_ledger (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n origin_core_hash TEXT,\n origin_profile_hash TEXT,\n destination_core_hash TEXT NOT NULL,\n destination_profile_hash TEXT,\n contract_json_before TEXT,\n contract_json_after TEXT,\n operations TEXT NOT NULL\n )`,\n params: [],\n};\n\nexport function readMarkerStatement(space: string): SqlStatement {\n return {\n sql: `SELECT\n core_hash,\n profile_hash,\n contract_json,\n canonical_version,\n updated_at,\n app_tag,\n meta,\n invariants\n FROM _prisma_marker\n WHERE space = ?`,\n params: [space],\n };\n}\n\nexport interface WriteMarkerInput {\n /**\n * Logical space identifier for this marker row. Required at every\n * call site so the type system surfaces every place that needs to\n * thread the value (rather than letting an `?? APP_SPACE_ID`\n * fall-through silently collapse multi-space markers onto the\n * `'app'` row). App-plan callers pass {@link APP_SPACE_ID}\n * (`'app'`); per-extension callers pass the extension's space id.\n */\n readonly space: string;\n readonly storageHash: string;\n readonly profileHash: string;\n readonly contractJson?: unknown;\n readonly canonicalVersion?: number | null;\n readonly appTag?: string | null;\n readonly meta?: Record<string, unknown>;\n /**\n * Invariants to write into `marker.invariants`. Stored as a JSON-encoded\n * TEXT array — SQLite has no native array type. The runner is responsible\n * for merging with the existing column (no SQL-side merge here, unlike\n * Postgres) before passing them in: BEGIN EXCLUSIVE on the migration\n * transaction makes the read-then-merge-then-write sequence safe.\n */\n readonly invariants: readonly string[];\n}\n\nexport function buildWriteMarkerStatements(input: WriteMarkerInput): {\n readonly insert: SqlStatement;\n readonly update: SqlStatement;\n} {\n const params: readonly unknown[] = [\n input.space,\n input.storageHash,\n input.profileHash,\n jsonParam(input.contractJson),\n input.canonicalVersion ?? null,\n input.appTag ?? null,\n jsonParam(input.meta ?? {}),\n jsonParam(input.invariants),\n ];\n\n return {\n insert: {\n sql: `INSERT INTO _prisma_marker (\n space,\n core_hash,\n profile_hash,\n contract_json,\n canonical_version,\n updated_at,\n app_tag,\n meta,\n invariants\n ) VALUES (\n ?,\n ?,\n ?,\n ?,\n ?,\n datetime('now'),\n ?,\n ?,\n ?\n )`,\n params,\n },\n update: {\n sql: `UPDATE _prisma_marker SET\n core_hash = ?,\n profile_hash = ?,\n contract_json = ?,\n canonical_version = ?,\n updated_at = datetime('now'),\n app_tag = ?,\n meta = ?,\n invariants = ?\n WHERE space = ?`,\n params: [\n input.storageHash,\n input.profileHash,\n jsonParam(input.contractJson),\n input.canonicalVersion ?? null,\n input.appTag ?? null,\n jsonParam(input.meta ?? {}),\n jsonParam(input.invariants),\n input.space,\n ],\n },\n };\n}\n\nexport interface LedgerInsertInput {\n readonly originStorageHash?: string | null;\n readonly originProfileHash?: string | null;\n readonly destinationStorageHash: string;\n readonly destinationProfileHash?: string | null;\n readonly contractJsonBefore?: unknown;\n readonly contractJsonAfter?: unknown;\n readonly operations: unknown;\n}\n\nexport function buildLedgerInsertStatement(input: LedgerInsertInput): SqlStatement {\n return {\n sql: `INSERT INTO _prisma_ledger (\n origin_core_hash,\n origin_profile_hash,\n destination_core_hash,\n destination_profile_hash,\n contract_json_before,\n contract_json_after,\n operations\n ) VALUES (\n ?,\n ?,\n ?,\n ?,\n ?,\n ?,\n ?\n )`,\n params: [\n input.originStorageHash ?? null,\n input.originProfileHash ?? null,\n input.destinationStorageHash,\n input.destinationProfileHash ?? null,\n jsonParam(input.contractJsonBefore),\n jsonParam(input.contractJsonAfter),\n jsonParam(input.operations),\n ],\n };\n}\n\nfunction jsonParam(value: unknown): string {\n return JSON.stringify(value ?? null);\n}\n"],"mappings":";;;AASA,MAAa,oBAAoB;AACjC,MAAa,oBAAoB;;;;;AAMjC,MAAaA,sBAA2C,IAAI,IAAI,CAC9D,mBACA,kBACD,CAAC;;;;;;;;;;AAWF,MAAaC,6BAA2C;CACtD,KAAK;+CACwC,aAAa;;;;;;;;;;CAU1D,QAAQ,EAAE;CACX;AAED,MAAaC,6BAA2C;CACtD,KAAK;;;;;;;;;;;CAWL,QAAQ,EAAE;CACX;AAED,SAAgB,oBAAoB,OAA6B;AAC/D,QAAO;EACL,KAAK;;;;;;;;;;;EAWL,QAAQ,CAAC,MAAM;EAChB;;AA6BH,SAAgB,2BAA2B,OAGzC;AAYA,QAAO;EACL,QAAQ;GACN,KAAK;;;;;;;;;;;;;;;;;;;;;GAqBL,QAlC+B;IACjC,MAAM;IACN,MAAM;IACN,MAAM;IACN,UAAU,MAAM,aAAa;IAC7B,MAAM,oBAAoB;IAC1B,MAAM,UAAU;IAChB,UAAU,MAAM,QAAQ,EAAE,CAAC;IAC3B,UAAU,MAAM,WAAW;IAC5B;GA0BE;EACD,QAAQ;GACN,KAAK;;;;;;;;;;GAUL,QAAQ;IACN,MAAM;IACN,MAAM;IACN,UAAU,MAAM,aAAa;IAC7B,MAAM,oBAAoB;IAC1B,MAAM,UAAU;IAChB,UAAU,MAAM,QAAQ,EAAE,CAAC;IAC3B,UAAU,MAAM,WAAW;IAC3B,MAAM;IACP;GACF;EACF;;AAaH,SAAgB,2BAA2B,OAAwC;AACjF,QAAO;EACL,KAAK;;;;;;;;;;;;;;;;;EAiBL,QAAQ;GACN,MAAM,qBAAqB;GAC3B,MAAM,qBAAqB;GAC3B,MAAM;GACN,MAAM,0BAA0B;GAChC,UAAU,MAAM,mBAAmB;GACnC,UAAU,MAAM,kBAAkB;GAClC,UAAU,MAAM,WAAW;GAC5B;EACF;;AAGH,SAAS,UAAU,OAAwB;AACzC,QAAO,KAAK,UAAU,SAAS,KAAK"}