@prisma-next/target-sqlite 0.14.0-dev.6 → 0.14.0-dev.60

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 (72) hide show
  1. package/dist/contract-free.mjs +1 -1
  2. package/dist/control.d.mts +3 -4
  3. package/dist/control.d.mts.map +1 -1
  4. package/dist/control.mjs +16 -27
  5. package/dist/control.mjs.map +1 -1
  6. package/dist/{descriptor-meta-DxmEeTJ-.mjs → descriptor-meta-D1fap-5t.mjs} +4 -11
  7. package/dist/descriptor-meta-D1fap-5t.mjs.map +1 -0
  8. package/dist/descriptor-meta-runtime-BkXK3OjD.mjs +12 -0
  9. package/dist/descriptor-meta-runtime-BkXK3OjD.mjs.map +1 -0
  10. package/dist/migration.d.mts +2 -2
  11. package/dist/migration.mjs +2 -2
  12. package/dist/native-type-normalizer.mjs +13 -1
  13. package/dist/native-type-normalizer.mjs.map +1 -0
  14. package/dist/{op-factory-call-DmdfD1yd.mjs → op-factory-call-Do03QgD9.mjs} +134 -117
  15. package/dist/op-factory-call-Do03QgD9.mjs.map +1 -0
  16. package/dist/op-factory-call.d.mts +2 -2
  17. package/dist/op-factory-call.d.mts.map +1 -1
  18. package/dist/op-factory-call.mjs +1 -1
  19. package/dist/pack.mjs +1 -1
  20. package/dist/planner-DGhzXuGh.mjs +848 -0
  21. package/dist/planner-DGhzXuGh.mjs.map +1 -0
  22. package/dist/{planner-produced-sqlite-migration-0xPEm3R1.mjs → planner-produced-sqlite-migration-BDzhFAoW.mjs} +46 -17
  23. package/dist/planner-produced-sqlite-migration-BDzhFAoW.mjs.map +1 -0
  24. package/dist/{planner-produced-sqlite-migration-CpgsY-M9.d.mts → planner-produced-sqlite-migration-o1qUzwLk.d.mts} +3 -3
  25. package/dist/{planner-produced-sqlite-migration-CpgsY-M9.d.mts.map → planner-produced-sqlite-migration-o1qUzwLk.d.mts.map} +1 -1
  26. package/dist/planner-produced-sqlite-migration.d.mts +1 -1
  27. package/dist/planner-produced-sqlite-migration.mjs +1 -1
  28. package/dist/planner.d.mts +47 -11
  29. package/dist/planner.d.mts.map +1 -1
  30. package/dist/planner.mjs +1 -1
  31. package/dist/runtime.d.mts +6 -4
  32. package/dist/runtime.d.mts.map +1 -1
  33. package/dist/runtime.mjs +3 -3
  34. package/dist/{shared-Dhc8mLK1.d.mts → shared-C6sM-wel.d.mts} +2 -2
  35. package/dist/{shared-Dhc8mLK1.d.mts.map → shared-C6sM-wel.d.mts.map} +1 -1
  36. package/dist/{sqlite-contract-serializer--iaDgC8e.mjs → sqlite-contract-view-BEwi0mUC.mjs} +34 -9
  37. package/dist/sqlite-contract-view-BEwi0mUC.mjs.map +1 -0
  38. package/dist/sqlite-contract-view-J32K82Gi.d.mts +29 -0
  39. package/dist/sqlite-contract-view-J32K82Gi.d.mts.map +1 -0
  40. package/dist/sqlite-migration-BNiSiP0z.mjs +123 -0
  41. package/dist/sqlite-migration-BNiSiP0z.mjs.map +1 -0
  42. package/dist/{sqlite-migration-DVfhQwN_.d.mts → sqlite-migration-BYbzskpE.d.mts} +35 -6
  43. package/dist/sqlite-migration-BYbzskpE.d.mts.map +1 -0
  44. package/package.json +18 -18
  45. package/src/core/control-target.ts +13 -18
  46. package/src/core/errors.ts +14 -12
  47. package/src/core/migrations/column-ddl-rendering.ts +177 -0
  48. package/src/core/migrations/diff-database-schema.ts +230 -0
  49. package/src/core/migrations/issue-planner.ts +361 -488
  50. package/src/core/migrations/op-factory-call.ts +5 -0
  51. package/src/core/migrations/operations/tables.ts +107 -68
  52. package/src/core/migrations/planner-strategies.ts +118 -137
  53. package/src/core/migrations/planner.ts +117 -30
  54. package/src/core/migrations/render-typescript.ts +42 -15
  55. package/src/core/migrations/runner.ts +4 -10
  56. package/src/core/migrations/sqlite-migration.ts +69 -31
  57. package/src/core/sqlite-contract-serializer.ts +29 -14
  58. package/src/core/sqlite-contract-view.ts +41 -0
  59. package/src/core/sqlite-schema-verifier.ts +6 -3
  60. package/src/core/sqlite-unbound-database.ts +8 -8
  61. package/src/exports/runtime.ts +1 -0
  62. package/dist/descriptor-meta-DxmEeTJ-.mjs.map +0 -1
  63. package/dist/native-type-normalizer-CiSyVmMP.mjs +0 -14
  64. package/dist/native-type-normalizer-CiSyVmMP.mjs.map +0 -1
  65. package/dist/op-factory-call-DmdfD1yd.mjs.map +0 -1
  66. package/dist/planner-Ciq8p_dL.mjs +0 -622
  67. package/dist/planner-Ciq8p_dL.mjs.map +0 -1
  68. package/dist/planner-produced-sqlite-migration-0xPEm3R1.mjs.map +0 -1
  69. package/dist/sqlite-contract-serializer--iaDgC8e.mjs.map +0 -1
  70. package/dist/sqlite-migration-A0rwqPOG.mjs +0 -92
  71. package/dist/sqlite-migration-A0rwqPOG.mjs.map +0 -1
  72. package/dist/sqlite-migration-DVfhQwN_.d.mts.map +0 -1
@@ -0,0 +1,230 @@
1
+ import type { ColumnDefault, Contract, ControlPolicy } from '@prisma-next/contract/types';
2
+ import type { NativeTypeExpander, SqlSchemaDiffResult } from '@prisma-next/family-sql/control';
3
+ import { buildNativeTypeExpander, contractToSchemaIR } from '@prisma-next/family-sql/control';
4
+ import { verifySqlSchemaByDiff } from '@prisma-next/family-sql/diff';
5
+ import type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';
6
+ import type {
7
+ SchemaDiffIssue,
8
+ VerifyDatabaseSchemaResult,
9
+ } from '@prisma-next/framework-components/control';
10
+ import { diffSchemas } from '@prisma-next/framework-components/control';
11
+ import { entityAt } from '@prisma-next/framework-components/ir';
12
+ import type { SqlStorage, StorageColumn, StorageTable } from '@prisma-next/sql-contract/types';
13
+ import type {
14
+ SqlColumnIRInput,
15
+ SqlSchemaIRInput,
16
+ SqlSchemaIRNode,
17
+ SqlTableIRInput,
18
+ } from '@prisma-next/sql-schema-ir/types';
19
+ import { relationalNodeGranularity, SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';
20
+ import { blindCast } from '@prisma-next/utils/casts';
21
+ import { ifDefined } from '@prisma-next/utils/defined';
22
+ import { renderDefaultLiteral } from './planner-ddl-builders';
23
+
24
+ interface SqliteDiffDatabaseSchemaInput {
25
+ readonly contract: Contract<SqlStorage>;
26
+ readonly actualSchema: SqlSchemaIRNode;
27
+ readonly strict: boolean;
28
+ readonly typeMetadataRegistry: ReadonlyMap<string, { readonly nativeType?: string }>;
29
+ readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;
30
+ }
31
+
32
+ /** Renders a column default for the SQLite dialect. */
33
+ export function sqliteRenderDefault(def: ColumnDefault, _column: StorageColumn): string {
34
+ if (def.kind === 'function') {
35
+ if (def.expression === 'now()') {
36
+ return "datetime('now')";
37
+ }
38
+ return def.expression;
39
+ }
40
+ return renderDefaultLiteral(def.value);
41
+ }
42
+
43
+ /**
44
+ * The SQLite expected-side projection: contract → flat relational schema IR.
45
+ *
46
+ * `extras` thread the plan-time derivation input: the native-type expander,
47
+ * so the expected side carries resolved native types (like the verify
48
+ * side). Every expected column also carries its `codecRef` unconditionally
49
+ * (Decision 5) — the planner's op-builders resolve DDL rendering from it at
50
+ * plan time, so no separate render stamper is threaded here.
51
+ */
52
+ export function sqliteContractToSchema(
53
+ contract: Contract<SqlStorage> | null,
54
+ extras?: {
55
+ readonly expandNativeType?: NativeTypeExpander;
56
+ },
57
+ ): SqlSchemaIR {
58
+ // SQLite is single-schema: every contract FK targets the unbound namespace
59
+ // node, so derivation stamps no referenced namespace — the same absence
60
+ // flat introspection produces — and the derived expected FK pairs with its
61
+ // introspected counterpart by construction. No pre-diff pass, no flag.
62
+ return contractToSchemaIR(contract, {
63
+ annotationNamespace: 'sqlite',
64
+ renderDefault: sqliteRenderDefault,
65
+ ...ifDefined('expandNativeType', extras?.expandNativeType),
66
+ });
67
+ }
68
+
69
+ /**
70
+ * The SQLite schema verify: the full-tree node-diff verdict wrapped in the
71
+ * issue-based result envelope. Used by the runner's post-apply check; the
72
+ * family `verifySchema` runs the same composition via the descriptor hook.
73
+ */
74
+ export function verifySqliteDatabaseSchema(
75
+ input: SqliteDiffDatabaseSchemaInput,
76
+ ): VerifyDatabaseSchemaResult {
77
+ return verifySqlSchemaByDiff({
78
+ contract: input.contract,
79
+ schema: input.actualSchema,
80
+ strict: input.strict,
81
+ frameworkComponents: input.frameworkComponents,
82
+ diffSchema: diffSqliteSchema,
83
+ granularityOf: relationalNodeGranularity,
84
+ });
85
+ }
86
+
87
+ /**
88
+ * Resolves a verdict-diff issue's subject table's declared control policy
89
+ * directly from the contract. SQLite's expected tree is flat, so the issue
90
+ * path carries no namespace segment — `path[1]` is the table name (`path[0]`
91
+ * is the tree root's own id); every contract namespace is searched for that
92
+ * table name (table names are globally unique in the flat tree — duplicates
93
+ * across namespaces are rejected earlier, at `contractToSchemaIR`).
94
+ */
95
+ function resolveControlPolicy(
96
+ issue: SchemaDiffIssue,
97
+ contract: Contract<SqlStorage>,
98
+ ): ControlPolicy | undefined {
99
+ const tableName = issue.path[1];
100
+ if (tableName === undefined) return undefined;
101
+ for (const namespaceId of Object.keys(contract.storage.namespaces)) {
102
+ const table = entityAt<StorageTable>(contract.storage, {
103
+ namespaceId,
104
+ entityKind: 'table',
105
+ entityName: tableName,
106
+ });
107
+ if (table !== undefined) return table.control;
108
+ }
109
+ return undefined;
110
+ }
111
+
112
+ /**
113
+ * The SQLite full-tree node diff for the family verify verdict: derive the
114
+ * expected flat tree with resolved leaf values (expander threaded so
115
+ * parameterized types compare expanded; FK nodes born with the flat empty
116
+ * `resolvedReferencedNamespace`), and run the generic differ over the trees
117
+ * as derived. Flat targets need no ownership scoping. The codec `verifyType`
118
+ * hooks run once per contract namespace with tables, each against the sole
119
+ * flat actual root — exactly the legacy per-namespace pairing.
120
+ */
121
+ export function diffSqliteSchema(input: {
122
+ readonly contract: Contract<SqlStorage>;
123
+ readonly schema: SqlSchemaIRNode;
124
+ readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;
125
+ }): SqlSchemaDiffResult {
126
+ const expandNativeType = buildNativeTypeExpander(input.frameworkComponents);
127
+ const expected = sqliteContractToSchema(input.contract, {
128
+ ...ifDefined('expandNativeType', expandNativeType),
129
+ });
130
+ const actual =
131
+ input.schema instanceof SqlSchemaIR
132
+ ? input.schema
133
+ : blindCast<
134
+ SqlSchemaIR,
135
+ 'the SQLite introspection adapter always produces a flat SqlSchemaIR root'
136
+ >(input.schema);
137
+ const issues = diffSchemas(expected, actual);
138
+ const namespacesWithTables = Object.values(input.contract.storage.namespaces).filter(
139
+ (ns) => Object.keys(ns.entries.table ?? {}).length > 0,
140
+ );
141
+ return {
142
+ issues,
143
+ resolveControlPolicy: (issue) => resolveControlPolicy(issue, input.contract),
144
+ namespacePairs: namespacesWithTables.map(() => ({ actual })),
145
+ };
146
+ }
147
+
148
+ export interface SqlitePlanDiff {
149
+ /** The desired ("end") tree — resolved leaf values, incl. `codecRef`, on every column. */
150
+ readonly expected: SqlSchemaIR;
151
+ /** The live ("start") tree. */
152
+ readonly actual: SqlSchemaIR;
153
+ readonly issues: readonly SchemaDiffIssue[];
154
+ }
155
+
156
+ /**
157
+ * The SQLite planner's diff input: the same tree-building
158
+ * `diffSqliteSchema` uses (expander threaded, FK nodes born flat). One differ
159
+ * drives both verify and plan over the trees as derived; this is the plan-side
160
+ * derivation — column DDL resolves from each expected column's `codecRef` at
161
+ * plan time (`column-ddl-rendering.ts`), so no separate render stamping happens here.
162
+ */
163
+ export function buildSqlitePlanDiff(input: {
164
+ readonly contract: Contract<SqlStorage>;
165
+ readonly actualSchema: SqlSchemaIRNode;
166
+ readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;
167
+ }): SqlitePlanDiff {
168
+ const expandNativeType = buildNativeTypeExpander(input.frameworkComponents);
169
+ const expected = sqliteContractToSchema(input.contract, {
170
+ ...ifDefined('expandNativeType', expandNativeType),
171
+ });
172
+ // The differ dispatches polymorphically (`.isEqualTo()` / `.children()`), so
173
+ // the actual tree must be genuine `SqlSchemaIR`/`SqlTableIR`/`SqlColumnIR`
174
+ // instances, not plain data shaped like them. `new SqlSchemaIR(...)`
175
+ // normalizes either input uniformly (an already-real tree passes through
176
+ // untouched — its nested values are already instances) and is a no-op
177
+ // rebuild in the common (real-instance) case, so this is always safe to run.
178
+ const actual = new SqlSchemaIR(withRecordKeyNames(input.actualSchema));
179
+ const issues = diffSchemas(expected, actual);
180
+ return { expected, actual, issues };
181
+ }
182
+
183
+ /**
184
+ * Every schema-tree builder in this codebase derives a table's / column's
185
+ * `name` from the record key it's stored under (`contractToSchemaIR`,
186
+ * the SQLite introspection adapter) rather than trusting a redundant
187
+ * embedded field — the record key IS the identity. Mirrors that discipline
188
+ * for the actual/live tree before construction, so `SqlTableIR.id` /
189
+ * `SqlColumnIR.id` (both derived from `.name`) are always correct without
190
+ * requiring every caller to duplicate the key onto the value. A no-op for a
191
+ * tree that already carries matching names (the real introspection adapter
192
+ * always does).
193
+ */
194
+ function withRecordKeyNames(actualSchema: SqlSchemaIRNode): SqlSchemaIRInput {
195
+ const raw = blindCast<
196
+ { readonly tables?: Readonly<Record<string, unknown>> },
197
+ 'the SQLite introspection adapter always produces a flat, tables-keyed root'
198
+ >(actualSchema);
199
+ const tables: Record<string, SqlTableIRInput> = {};
200
+ for (const [tableName, table] of Object.entries(raw.tables ?? {})) {
201
+ const rawTable = blindCast<
202
+ Omit<SqlTableIRInput, 'name' | 'columns'>,
203
+ 'every table value in a tables record is SqlTableIR(Input)-shaped'
204
+ >(table);
205
+ const columns: Record<string, SqlColumnIRInput> = {};
206
+ for (const [columnName, column] of Object.entries(
207
+ blindCast<
208
+ { readonly columns?: Readonly<Record<string, unknown>> },
209
+ 'every SqlTableIR(Input) carries a columns record keyed by column name'
210
+ >(table).columns ?? {},
211
+ )) {
212
+ columns[columnName] = {
213
+ ...blindCast<
214
+ SqlColumnIRInput,
215
+ 'every column value in a columns record is SqlColumnIR(Input)-shaped'
216
+ >(column),
217
+ name: columnName,
218
+ };
219
+ }
220
+ tables[tableName] = {
221
+ ...rawTable,
222
+ name: tableName,
223
+ columns,
224
+ foreignKeys: rawTable.foreignKeys ?? [],
225
+ uniques: rawTable.uniques ?? [],
226
+ indexes: rawTable.indexes ?? [],
227
+ };
228
+ }
229
+ return { tables };
230
+ }