@substrat-run/model-emit 0.3.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -50,6 +50,9 @@ const sql = emitTables(entities);
50
50
  | declared | emitted |
51
51
  |---|---|
52
52
  | `id` | `id TEXT PRIMARY KEY NOT NULL` |
53
+ | `primaryKey: ['workorder_id']` | `workorder_id TEXT PRIMARY KEY NOT NULL` — the identity of a side table keyed by an engine's id |
54
+ | `primaryKey: ['customer_id','year']` | `PRIMARY KEY (customer_id, year)` as a table-level constraint, in declaration order |
55
+ | neither an `id` field nor a `primaryKey` | **refused** — a table with no primary key accepts duplicate rows |
53
56
  | `z.string()` / `.nullable()` | `TEXT NOT NULL` / `TEXT` |
54
57
  | `z.number()` | `INTEGER` |
55
58
  | `z.boolean()` | **refused** — SQLite returns 0/1, so declare `z.number()` and keep the row type honest (`z.boolean()` stays right for an operation's *input*) |
@@ -60,10 +63,36 @@ const sql = emitTables(entities);
60
63
 
61
64
  Pass `{ ifNotExists: true }` to emit `CREATE TABLE IF NOT EXISTS`.
62
65
 
66
+ ## Not every table is keyed by `id`
67
+
68
+ `primaryKey` defaults to `['id']`, and is declared where the identity is something else:
69
+
70
+ ```ts
71
+ // the side table the design rules prescribe for extra data on an engine's entity.
72
+ // Its identity IS the work order's — an `id` of its own would permit two side
73
+ // rows for one work order, which is what the primary key exists to prevent.
74
+ ext: {
75
+ table: 'vertical_workorder_ext',
76
+ fields: z.object({ workorder_id: z.string(), route_note: z.string().nullable() }),
77
+ primaryKey: ['workorder_id'],
78
+ },
79
+ ```
80
+
81
+ It stays separate from `key` because SQL's own distinction is the useful one: `primaryKey`
82
+ is identity, `key` is an additional uniqueness rule, and a table legitimately has both.
83
+ Column order is preserved rather than sorted — a composite primary key is also the index its
84
+ columns are searched by, left to right.
85
+
86
+ An entity with neither an `id` field nor a `primaryKey` is **refused**. It used to emit a
87
+ table with no primary key at all, silently: a production vertical had that on 15 of 63
88
+ tables while its own column-by-column parity check reported 63/63, because it never compared
89
+ primary keys ([#804](https://github.com/substrat-run/substrat/issues/804)). `journalPrimaryKeys`
90
+ is the reader that closes that gap, next to `journalColumns` and `journalUniques`.
91
+
63
92
  ## It is stricter than a hand-written schema, in one way
64
93
 
65
- An `id` becomes `TEXT PRIMARY KEY **NOT NULL**`. In SQLite a non-INTEGER primary key does
66
- *not* imply `NOT NULL`, so `id TEXT PRIMARY KEY` accepts a NULL id:
94
+ The primary key becomes `TEXT PRIMARY KEY **NOT NULL**`. In SQLite a non-INTEGER primary key
95
+ does *not* imply `NOT NULL`, so `id TEXT PRIMARY KEY` accepts a NULL id:
67
96
 
68
97
  ```
69
98
  hand-written id TEXT PRIMARY KEY → ACCEPTED a NULL id
@@ -71,7 +100,7 @@ emitted id TEXT PRIMARY KEY NOT NULL → rejected
71
100
  ```
72
101
 
73
102
  Every hand-written `vertical_*` table in the Substrat repo had that hole. The emitter cannot
74
- produce it.
103
+ produce it, and it refuses a nullable key column for the same reason.
75
104
 
76
105
  ## It refuses rather than guesses
77
106
 
@@ -6,10 +6,14 @@ export interface EmitSqlOptions {
6
6
  /**
7
7
  * `CREATE TABLE` for every declared entity, in sorted order.
8
8
  *
9
- * - `id` becomes `TEXT PRIMARY KEY NOT NULL`. The `NOT NULL` is deliberate and
9
+ * - The primary key `primaryKey` if declared, else `id` becomes
10
+ * `TEXT PRIMARY KEY NOT NULL` inline when it is one column, and a table-level
11
+ * `PRIMARY KEY (a, b)` when it is several. The `NOT NULL` is deliberate and
10
12
  * stricter than most hand-written schemas: in SQLite a non-INTEGER primary key
11
13
  * does NOT imply it, so `id TEXT PRIMARY KEY` accepts a NULL id. Every
12
14
  * `vertical_*` table written by hand in this repo has that hole.
15
+ * - An entity with neither is an ERROR. A table emitted with no primary key
16
+ * accepts duplicate rows and a column-wise parity check cannot see it (#804).
13
17
  * - `key` becomes a `UNIQUE` constraint.
14
18
  * - `parents` becomes a `REFERENCES` clause per parent, on `<parent>_id` when the
15
19
  * entity declares such a column — never invented if it does not.
@@ -32,6 +36,18 @@ export interface EmittedColumn {
32
36
  * a schema subtly unlike the one a fresh `CREATE TABLE` would.
33
37
  */
34
38
  export declare function columnsOf<T extends Record<string, EntityDef>>(name: string, entity: EntityDef, entities: T): EmittedColumn[];
39
+ /**
40
+ * The table-level `PRIMARY KEY (a, b)`, for a composite key only.
41
+ *
42
+ * A single-column key is written inline by `columnsOf`, so this returns nothing
43
+ * for it — emitting both would declare the primary key twice and SQLite would
44
+ * refuse the table.
45
+ *
46
+ * Column order is preserved, not sorted: a composite primary key is also the
47
+ * index its columns are searched by, left to right, so `(customer_id, year,
48
+ * month)` and `(year, month, customer_id)` are different tables.
49
+ */
50
+ export declare function primaryKeyConstraint(name: string, entity: EntityDef): string[];
35
51
  /**
36
52
  * The natural key, as ONE constraint over all its fields.
37
53
  *
@@ -1 +1 @@
1
- {"version":3,"file":"emit-sql.d.ts","sourceRoot":"","sources":["../src/emit-sql.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,yBAAyB,CAAC;AA+HtE,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EAC5D,QAAQ,EAAE,CAAC,EACX,OAAO,GAAE,cAAmB,GAC3B,MAAM,CAeR;AAED,0FAA0F;AAC1F,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,iFAAiF;IACjF,QAAQ,CAAC,sBAAsB,EAAE,OAAO,CAAC;CAC1C;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EAC3D,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,CAAC,GACV,aAAa,EAAE,CAuBjB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,MAAM,EAAE,CAO3E"}
1
+ {"version":3,"file":"emit-sql.d.ts","sourceRoot":"","sources":["../src/emit-sql.ts"],"names":[],"mappings":"AAqBA,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,yBAAyB,CAAC;AA+HpF,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EAC5D,QAAQ,EAAE,CAAC,EACX,OAAO,GAAE,cAAmB,GAC3B,MAAM,CAgBR;AAED,0FAA0F;AAC1F,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,iFAAiF;IACjF,QAAQ,CAAC,sBAAsB,EAAE,OAAO,CAAC;CAC1C;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EAC3D,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,CAAC,GACV,aAAa,EAAE,CAmCjB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,MAAM,EAAE,CAG9E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,MAAM,EAAE,CAO3E"}
package/dist/emit-sql.js CHANGED
@@ -19,7 +19,7 @@
19
19
  * silently — for anything reaching a migration, absent must be loud.
20
20
  */
21
21
  import { z } from 'zod';
22
- import { JSON_COLUMN } from '@substrat-run/contracts';
22
+ import { JSON_COLUMN, primaryKeyOf } from '@substrat-run/contracts';
23
23
  /** Unwrap the wrappers Zod puts around a base type, recording nullability. */
24
24
  function peel(schema) {
25
25
  let s = schema;
@@ -127,10 +127,14 @@ function tableOrder(entities) {
127
127
  /**
128
128
  * `CREATE TABLE` for every declared entity, in sorted order.
129
129
  *
130
- * - `id` becomes `TEXT PRIMARY KEY NOT NULL`. The `NOT NULL` is deliberate and
130
+ * - The primary key `primaryKey` if declared, else `id` becomes
131
+ * `TEXT PRIMARY KEY NOT NULL` inline when it is one column, and a table-level
132
+ * `PRIMARY KEY (a, b)` when it is several. The `NOT NULL` is deliberate and
131
133
  * stricter than most hand-written schemas: in SQLite a non-INTEGER primary key
132
134
  * does NOT imply it, so `id TEXT PRIMARY KEY` accepts a NULL id. Every
133
135
  * `vertical_*` table written by hand in this repo has that hole.
136
+ * - An entity with neither is an ERROR. A table emitted with no primary key
137
+ * accepts duplicate rows and a column-wise parity check cannot see it (#804).
134
138
  * - `key` becomes a `UNIQUE` constraint.
135
139
  * - `parents` becomes a `REFERENCES` clause per parent, on `<parent>_id` when the
136
140
  * entity declares such a column — never invented if it does not.
@@ -144,6 +148,7 @@ export function emitTables(entities, options = {}) {
144
148
  continue;
145
149
  const cols = [
146
150
  ...columnsOf(name, entity, entities).map((c) => ` ${c.ddl}`),
151
+ ...primaryKeyConstraint(name, entity).map((k) => ` ${k}`),
147
152
  ...uniqueConstraints(name, entity).map((u) => ` ${u}`),
148
153
  ];
149
154
  out.push(`CREATE TABLE ${exists}${entity.table} (\n${cols.join(',\n')}\n);`);
@@ -161,14 +166,24 @@ export function emitTables(entities, options = {}) {
161
166
  export function columnsOf(name, entity, entities) {
162
167
  const shape = entity.fields.shape;
163
168
  const out = [];
169
+ const pk = primaryKeyOf(name, entity);
170
+ const inKey = new Set(pk);
164
171
  for (const [field, schema] of Object.entries(shape)) {
165
172
  const c = columnFor(field, schema, `${name}.${field}`);
166
- if (field === 'id') {
167
- out.push({ name: 'id', ddl: `id ${c.type} PRIMARY KEY NOT NULL`, requiredWithoutDefault: true });
168
- continue;
173
+ if (inKey.has(field) && c.nullable) {
174
+ // A nullable primary-key column is a contradiction the database would not
175
+ // catch: SQLite lets a NULL into a non-INTEGER primary key, which is the
176
+ // very hole this emitter exists to close.
177
+ throw new Error(`emit-sql: ${name}.${field} is part of the primary key but is nullable — ` +
178
+ 'a key column identifies a row, so it cannot be absent');
169
179
  }
170
180
  let ddl = `${c.name} ${c.type}`;
171
- if (!c.nullable)
181
+ // One column: inline, which is what a hand-written schema writes and what
182
+ // keeps `id TEXT PRIMARY KEY NOT NULL` byte-identical. Several: a
183
+ // table-level constraint, the only way SQL can express it.
184
+ if (inKey.has(field) && pk.length === 1)
185
+ ddl += ' PRIMARY KEY NOT NULL';
186
+ else if (!c.nullable)
172
187
  ddl += ' NOT NULL';
173
188
  if (c.check)
174
189
  ddl += ` ${c.check}`;
@@ -183,6 +198,21 @@ export function columnsOf(name, entity, entities) {
183
198
  }
184
199
  return out;
185
200
  }
201
+ /**
202
+ * The table-level `PRIMARY KEY (a, b)`, for a composite key only.
203
+ *
204
+ * A single-column key is written inline by `columnsOf`, so this returns nothing
205
+ * for it — emitting both would declare the primary key twice and SQLite would
206
+ * refuse the table.
207
+ *
208
+ * Column order is preserved, not sorted: a composite primary key is also the
209
+ * index its columns are searched by, left to right, so `(customer_id, year,
210
+ * month)` and `(year, month, customer_id)` are different tables.
211
+ */
212
+ export function primaryKeyConstraint(name, entity) {
213
+ const pk = primaryKeyOf(name, entity);
214
+ return pk.length > 1 ? [`PRIMARY KEY (${pk.join(', ')})`] : [];
215
+ }
186
216
  /**
187
217
  * The natural key, as ONE constraint over all its fields.
188
218
  *
@@ -1 +1 @@
1
- {"version":3,"file":"emit-sql.js","sourceRoot":"","sources":["../src/emit-sql.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAkB,MAAM,yBAAyB,CAAC;AAWtE,8EAA8E;AAC9E,SAAS,IAAI,CAAC,MAAoB;IAChC,IAAI,CAAC,GAAG,MAAM,CAAC;IACf,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,sEAAsE;IACtE,SAAS,CAAC;QACR,MAAM,GAAG,GAAI,CAAgE,CAAC,IAAI,CAAC;QACnF,MAAM,CAAC,GAAG,GAAG,EAAE,QAAQ,IAAK,CAAuB,CAAC,IAAI,CAAC;QACzD,IAAI,CAAC,CAAC,KAAK,aAAa,IAAI,CAAC,KAAK,aAAa,IAAI,CAAC,KAAK,UAAU,IAAI,CAAC,KAAK,UAAU,CAAC,IAAI,GAAG,EAAE,SAAS,EAAE,CAAC;YAC3G,QAAQ,GAAG,IAAI,CAAC;YAChB,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC;YAClB,SAAS;QACX,CAAC;QACD,2DAA2D;QAC3D,MAAM,MAAM,GAAI,CAAqC,CAAC,MAAM,CAAC;QAC7D,IAAI,OAAO,MAAM,KAAK,UAAU,IAAI,CAAC,CAAC,KAAK,aAAa,IAAI,CAAC,KAAK,aAAa,CAAC,EAAE,CAAC;YACjF,QAAQ,GAAG,IAAI,CAAC;YAChB,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACnB,SAAS;QACX,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC;IAChC,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,IAAY,EAAE,MAAoB,EAAE,KAAa;IAClE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,IAAI,GAAI,KAA2B,CAAC,IAAI,IAAK,KAA0C,CAAC,IAAI,EAAE,QAAQ,CAAC;IAE7G,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,WAAW;QAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IACvF,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;QAChD,2EAA2E;QAC3E,2EAA2E;QAC3E,uEAAuE;QACvE,gDAAgD;QAChD,EAAE;QACF,yEAAyE;QACzE,wEAAwE;QACxE,wEAAwE;QACxE,MAAM,IAAI,KAAK,CACb,aAAa,KAAK,sEAAsE;YACtF,8EAA8E;YAC9E,yCAAyC,CAC5C,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;QAC9C,sEAAsE;QACtE,qEAAqE;QACrE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;IAC7C,CAAC;IACD,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QAC1C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CACzB,KAAgF,CAAC,OAAO;YACtF,KAAmD,CAAC,IAAI,EAAE,MAAM;YACjE,EAAE,CACO,CAAC;QACd,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,aAAa,KAAK,4BAA4B,CAAC,CAAC;QACpF,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;IACjF,CAAC;IAED,6EAA6E;IAC7E,4EAA4E;IAC5E,4EAA4E;IAC5E,IAAK,KAAkC,CAAC,WAAW,EAAE,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7E,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAC1C,CAAC;IAED,wEAAwE;IACxE,qDAAqD;IACrD,MAAM,IAAI,KAAK,CACb,wBAAwB,KAAK,eAAe,MAAM,CAAC,IAAI,CAAC,mBAAmB;QACzE,+DAA+D,CAClE,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,UAAU,CAAsC,QAAW;IAClE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,MAAM,GAAG,GAAa,EAAE,CAAC;IAEzB,IAAI,QAAQ,GAAG,IAAI,CAAC;IACpB,OAAO,QAAQ,IAAI,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QAC7C,QAAQ,GAAG,KAAK,CAAC;QACjB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAS;YAC/B,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,IAAI,EAAE,CAAC;YAC9C,wEAAwE;YACxE,mDAAmD;YACnD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,QAAQ,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7E,IAAI,OAAO;gBAAE,SAAS;YACtB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACjB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACf,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC;IACH,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,IAAI,KAAK,CACb,gCAAgC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,4CAA4C,CAC9F,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAOD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,UAAU,CACxB,QAAW,EACX,OAAO,GAAmB,EAAE;IAE5B,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3D,MAAM,GAAG,GAAa,EAAE,CAAC;IAEzB,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxC,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,MAAM,IAAI,GAAG;YACX,GAAG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC;YAC7D,GAAG,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;SACxD,CAAC;QACF,GAAG,CAAC,IAAI,CAAC,gBAAgB,MAAM,GAAG,MAAM,CAAC,KAAK,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC/E,CAAC;IAED,OAAO,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC1B,CAAC;AAWD;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CACvB,IAAY,EACZ,MAAiB,EACjB,QAAW;IAEX,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,KAAqC,CAAC;IAClE,MAAM,GAAG,GAAoB,EAAE,CAAC;IAEhC,KAAK,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACpD,MAAM,CAAC,GAAG,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC;QACvD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,IAAI,uBAAuB,EAAE,sBAAsB,EAAE,IAAI,EAAE,CAAC,CAAC;YACjG,SAAS;QACX,CAAC;QACD,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,CAAC,CAAC,QAAQ;YAAE,GAAG,IAAI,WAAW,CAAC;QACpC,IAAI,CAAC,CAAC,KAAK;YAAE,GAAG,IAAI,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;QAClC,uEAAuE;QACvE,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;YAC1C,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAiB,CAAC,EAAE,KAAK,CAAC;YACvD,IAAI,WAAW,IAAI,CAAC,CAAC,IAAI,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC;gBAC1G,GAAG,IAAI,eAAe,WAAW,MAAM,CAAC;YAC1C,CAAC;QACH,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,sBAAsB,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,MAAiB;IAC/D,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,KAAqC,CAAC;IAClE,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IAC7B,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;QACpB,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,eAAe,CAAC,yBAAyB,CAAC,CAAC;IACjG,CAAC;IACD,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC9D,CAAC"}
1
+ {"version":3,"file":"emit-sql.js","sourceRoot":"","sources":["../src/emit-sql.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { emitTables, columnsOf, uniqueConstraints, type EmitSqlOptions, type EmittedColumn } from './emit-sql.js';
2
- export { journalColumns, journalUniques } from './journal.js';
1
+ export { emitTables, columnsOf, primaryKeyConstraint, uniqueConstraints, type EmitSqlOptions, type EmittedColumn, } from './emit-sql.js';
2
+ export { journalColumns, journalUniques, journalPrimaryKeys } from './journal.js';
3
3
  export { planMigration, parseJournal, type Journal, type JournalEntry, type MigrationPlan, } from './plan.js';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,iBAAiB,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAClH,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EACL,aAAa,EACb,YAAY,EACZ,KAAK,OAAO,EACZ,KAAK,YAAY,EACjB,KAAK,aAAa,GACnB,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,SAAS,EACT,oBAAoB,EACpB,iBAAiB,EACjB,KAAK,cAAc,EACnB,KAAK,aAAa,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClF,OAAO,EACL,aAAa,EACb,YAAY,EACZ,KAAK,OAAO,EACZ,KAAK,YAAY,EACjB,KAAK,aAAa,GACnB,MAAM,WAAW,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { emitTables, columnsOf, uniqueConstraints } from './emit-sql.js';
2
- export { journalColumns, journalUniques } from './journal.js';
1
+ export { emitTables, columnsOf, primaryKeyConstraint, uniqueConstraints, } from './emit-sql.js';
2
+ export { journalColumns, journalUniques, journalPrimaryKeys } from './journal.js';
3
3
  export { planMigration, parseJournal, } from './plan.js';
4
4
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,iBAAiB,EAA2C,MAAM,eAAe,CAAC;AAClH,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EACL,aAAa,EACb,YAAY,GAIb,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,SAAS,EACT,oBAAoB,EACpB,iBAAiB,GAGlB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClF,OAAO,EACL,aAAa,EACb,YAAY,GAIb,MAAM,WAAW,CAAC"}
package/dist/journal.d.ts CHANGED
@@ -34,4 +34,24 @@ export declare function journalColumns(sql: string): Map<string, Set<string>>;
34
34
  * constraint written two ways compares equal.
35
35
  */
36
36
  export declare function journalUniques(sql: string): Map<string, Set<string>>;
37
+ /**
38
+ * The primary key per table, read out of a journal.
39
+ *
40
+ * `journalColumns` answers "which columns exist" and `journalUniques` "which
41
+ * uniqueness rules"; neither says which columns *identify* a row, and that gap
42
+ * is what made #804 invisible. A production vertical's parity check compared
43
+ * names, types and nullability across 63 tables and reported 63/63 while 15 of
44
+ * the emitted tables had no primary key at all.
45
+ *
46
+ * Both spellings are read, because journals use both: inline
47
+ * (`id TEXT PRIMARY KEY NOT NULL`) for one column, and a table-level
48
+ * `PRIMARY KEY (a, b)` for several. A table with no primary key maps to an
49
+ * EMPTY array rather than being absent — "the journal never built this table"
50
+ * and "the journal built it without a key" are different answers, and only one
51
+ * of them is a bug.
52
+ *
53
+ * Order is preserved: a composite primary key is the index its columns are
54
+ * searched by, so `(a, b)` and `(b, a)` are not the same key.
55
+ */
56
+ export declare function journalPrimaryKeys(sql: string): Map<string, string[]>;
37
57
  //# sourceMappingURL=journal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"journal.d.ts","sourceRoot":"","sources":["../src/journal.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CA4CpE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAwDpE"}
1
+ {"version":3,"file":"journal.d.ts","sourceRoot":"","sources":["../src/journal.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CA4CpE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAwDpE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAyDrE"}
package/dist/journal.js CHANGED
@@ -126,4 +126,80 @@ export function journalUniques(sql) {
126
126
  }
127
127
  return tables;
128
128
  }
129
+ /**
130
+ * The primary key per table, read out of a journal.
131
+ *
132
+ * `journalColumns` answers "which columns exist" and `journalUniques` "which
133
+ * uniqueness rules"; neither says which columns *identify* a row, and that gap
134
+ * is what made #804 invisible. A production vertical's parity check compared
135
+ * names, types and nullability across 63 tables and reported 63/63 while 15 of
136
+ * the emitted tables had no primary key at all.
137
+ *
138
+ * Both spellings are read, because journals use both: inline
139
+ * (`id TEXT PRIMARY KEY NOT NULL`) for one column, and a table-level
140
+ * `PRIMARY KEY (a, b)` for several. A table with no primary key maps to an
141
+ * EMPTY array rather than being absent — "the journal never built this table"
142
+ * and "the journal built it without a key" are different answers, and only one
143
+ * of them is a bug.
144
+ *
145
+ * Order is preserved: a composite primary key is the index its columns are
146
+ * searched by, so `(a, b)` and `(b, a)` are not the same key.
147
+ */
148
+ export function journalPrimaryKeys(sql) {
149
+ const tables = new Map();
150
+ for (const [, table, body] of sql.matchAll(/CREATE TABLE (?:IF NOT EXISTS )?([a-z_][a-z0-9_]*)\s*\(([\s\S]*?)\n\s*\);/gi)) {
151
+ if (!table || !body)
152
+ continue;
153
+ let key = [];
154
+ let depth = 0;
155
+ for (const raw of body.split('\n')) {
156
+ const line = raw.trim();
157
+ const atTop = depth === 0;
158
+ depth += (line.match(/\(/g) ?? []).length - (line.match(/\)/g) ?? []).length;
159
+ if (!atTop || !line || line.startsWith('--'))
160
+ continue;
161
+ // Table-level. Written as its own clause, so it wins over any inline
162
+ // spelling — a table cannot legally have both, and if one somehow did,
163
+ // the explicit list is the one a reader would believe.
164
+ const composite = /^(?:CONSTRAINT\s+[a-z_][a-z0-9_]*\s+)?PRIMARY\s+KEY\s*\(([^)]*)\)/i.exec(line);
165
+ if (composite?.[1]) {
166
+ key = composite[1]
167
+ .split(',')
168
+ // `PRIMARY KEY (a DESC, b COLLATE NOCASE)` — the column is the first word.
169
+ .map((c) => /^([a-z_][a-z0-9_]*)/i.exec(c.trim())?.[1] ?? '')
170
+ .filter(Boolean);
171
+ continue;
172
+ }
173
+ if (/^(PRIMARY|FOREIGN|UNIQUE|CHECK|CONSTRAINT)\b/i.test(line))
174
+ continue;
175
+ // Inline, on the column that carries it.
176
+ const name = /^([a-z_][a-z0-9_]*)\b/i.exec(line)?.[1];
177
+ if (name && /\bPRIMARY\s+KEY\b/i.test(line) && key.length === 0)
178
+ key = [name];
179
+ }
180
+ tables.set(table, key);
181
+ }
182
+ // Replayed in statement order, like `journalColumns`. A rebuild renames a
183
+ // table onto another's name and the key travels with it; `ADD COLUMN` cannot
184
+ // introduce one, because SQLite refuses to add a PRIMARY KEY column.
185
+ for (const m of sql.matchAll(/(?:ALTER TABLE ([a-z_][a-z0-9_]*)\s+RENAME COLUMN\s+([a-z_][a-z0-9_]*)\s+TO\s+([a-z_][a-z0-9_]*))|(?:ALTER TABLE ([a-z_][a-z0-9_]*)\s+RENAME TO\s+([a-z_][a-z0-9_]*))|(?:DROP TABLE (?:IF EXISTS )?([a-z_][a-z0-9_]*))/gi)) {
186
+ const [, renTable, renFrom, renTo, fromTable, toTable, dropped] = m;
187
+ if (dropped) {
188
+ tables.delete(dropped);
189
+ }
190
+ else if (renTable && renFrom && renTo) {
191
+ const key = tables.get(renTable);
192
+ if (key)
193
+ tables.set(renTable, key.map((c) => (c === renFrom ? renTo : c)));
194
+ }
195
+ else if (fromTable && toTable) {
196
+ const key = tables.get(fromTable);
197
+ if (key) {
198
+ tables.delete(fromTable);
199
+ tables.set(toTable, key);
200
+ }
201
+ }
202
+ }
203
+ return tables;
204
+ }
129
205
  //# sourceMappingURL=journal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"journal.js","sourceRoot":"","sources":["../src/journal.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"journal.js","sourceRoot":"","sources":["../src/journal.ts"],"names":[],"mappings":"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"}
package/dist/plan.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { EntityDef } from '@substrat-run/contracts';
1
+ import { type EntityDef } from '@substrat-run/contracts';
2
2
  export interface JournalEntry {
3
3
  /** Derived, monotonic, zero-padded: `0001`. Never authored. */
4
4
  readonly version: string;
@@ -1 +1 @@
1
- {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAGzD,MAAM,WAAW,YAAY;IAC3B,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;CAC3C;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;CAAE,GAC/B;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAA;CAAE,GACzD;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAItE;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EAC/D,QAAQ,EAAE,CAAC,EACX,OAAO,EAAE,OAAO,GACf,aAAa,CA6If;AAED,oFAAoF;AACpF,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAkBlD"}
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAgB,KAAK,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAGvE,MAAM,WAAW,YAAY;IAC3B,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;CAC3C;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;CAAE,GAC/B;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAA;CAAE,GACzD;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAItE;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EAC/D,QAAQ,EAAE,CAAC,EACX,OAAO,EAAE,OAAO,GACf,aAAa,CAwKf;AAED,oFAAoF;AACpF,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAkBlD"}
package/dist/plan.js CHANGED
@@ -18,14 +18,15 @@
18
18
  * the model, re-run, it renumbers.
19
19
  *
20
20
  * **What this refuses.** Anything that would rewrite history or lose data: a
21
- * dropped table or column, a retyped column, or a required column added to a
22
- * table that may already hold rows. Those are real decisions (expand/contract,
23
- * a backfill, a `renamedFrom` declaration) and a generator that guessed at them
24
- * would be guessing with somebody's data.
21
+ * dropped table or column, a retyped column, a moved primary key, or a required
22
+ * column added to a table that may already hold rows. Those are real decisions
23
+ * (expand/contract, a rebuild, a backfill, a `renamedFrom` declaration) and a
24
+ * generator that guessed at them would be guessing with somebody's data.
25
25
  */
26
26
  import { z } from 'zod';
27
- import { columnsOf, emitTables, uniqueConstraints } from './emit-sql.js';
28
- import { journalColumns, journalUniques } from './journal.js';
27
+ import { columnsOf, emitTables, primaryKeyConstraint, uniqueConstraints } from './emit-sql.js';
28
+ import { primaryKeyOf } from '@substrat-run/contracts';
29
+ import { journalColumns, journalPrimaryKeys, journalUniques } from './journal.js';
29
30
  const pad = (n) => String(n).padStart(4, '0');
30
31
  /**
31
32
  * What one entry would have to say to bring the journal up to the model.
@@ -38,6 +39,7 @@ export function planMigration(entities, journal) {
38
39
  const applied = journalColumns(journalSql);
39
40
  const desired = journalColumns(emitTables(entities));
40
41
  const appliedUniques = journalUniques(journalSql);
42
+ const appliedKeys = journalPrimaryKeys(journalSql);
41
43
  // table name → the entity that owns it, so a diff can be reported in the
42
44
  // vocabulary the model uses rather than in raw table names.
43
45
  const owner = new Map();
@@ -65,6 +67,7 @@ export function planMigration(entities, journal) {
65
67
  // the REFERENCES clause of every foreign key pointing outside it.
66
68
  const cols = [
67
69
  ...columnsOf(o.name, o.entity, entities).map((c) => ` ${c.ddl}`),
70
+ ...primaryKeyConstraint(o.name, o.entity).map((k) => ` ${k}`),
68
71
  ...uniqueConstraints(o.name, o.entity).map((u) => ` ${u}`),
69
72
  ];
70
73
  statements.push(`CREATE TABLE ${table} (\n${cols.join(',\n')}\n);`);
@@ -122,6 +125,33 @@ export function planMigration(entities, journal) {
122
125
  'rename from a drop-plus-add, and guessing wrong loses the data. Declare it with ' +
123
126
  `\`renamedFrom: { <newName>: '${name}' }\` on the entity, or retire the column deliberately`);
124
127
  }
128
+ // -- the primary key moved -------------------------------------------------
129
+ // SQLite cannot alter a primary key at all: it needs the table rebuilt,
130
+ // copied and renamed, which is a decision about live data rather than a
131
+ // diff. Refused LOUDLY for the same reason as a late UNIQUE — a schema that
132
+ // silently identifies rows differently than the journal does is how a
133
+ // duplicate gets in, and #804 is exactly that failure going unseen.
134
+ //
135
+ // Both comparisons below translate the journal's column names through any
136
+ // rename THIS plan is about to emit: the journal still names the old column,
137
+ // and SQLite rewrites keys and constraints along with it. Comparing
138
+ // untranslated makes a renamed key look like one the journal never had, and
139
+ // refuses the very change that would fix it. Built from `renames`, not from
140
+ // `renamedFrom`, so a spent declaration cannot translate a name the journal
141
+ // is not actually renaming.
142
+ const previousToCurrent = new Map([...renames].map(([current, previous]) => [previous, current]));
143
+ const wantKey = primaryKeyOf(o.name, o.entity).join(', ');
144
+ const haveKey = (appliedKeys.get(table) ?? []).map((c) => previousToCurrent.get(c) ?? c).join(', ');
145
+ if (haveKey !== wantKey) {
146
+ refusals.push(haveKey === ''
147
+ ? `'${table}' exists in the journal with NO primary key, and the model identifies a row ` +
148
+ `by (${wantKey}) — SQLite cannot add a primary key to an existing table. Rebuild it in ` +
149
+ 'a hand-written entry (create, copy, drop, rename), after deciding what to do with any ' +
150
+ 'duplicate rows it already holds'
151
+ : `'${table}' is keyed by (${haveKey}) in the journal and by (${wantKey}) in the model — ` +
152
+ 'SQLite cannot change a primary key in place. Rebuild the table in a hand-written ' +
153
+ 'entry, or restore the declared key');
154
+ }
125
155
  // -- a key declared after the table already exists ------------------------
126
156
  // SQLite cannot ADD a UNIQUE constraint in place; it needs the table
127
157
  // rebuilt, copied and renamed. That is a decision about live data, not a
@@ -133,14 +163,9 @@ export function planMigration(entities, journal) {
133
163
  .map((c) => c.trim())
134
164
  .filter(Boolean)
135
165
  .join(', '));
136
- // Translated through any rename THIS plan is about to emit: the journal
137
- // still names the old column, and SQLite rewrites the constraint along with
138
- // it. Comparing untranslated makes a renamed key look like one the journal
139
- // never had, and refuses the very change that would fix it.
140
- const toCurrent = new Map([...renames].map(([current, previous]) => [previous, current]));
141
166
  const haveUniques = new Set([...(appliedUniques.get(table) ?? new Set())].map((c) => c
142
167
  .split(', ')
143
- .map((col) => toCurrent.get(col) ?? col)
168
+ .map((col) => previousToCurrent.get(col) ?? col)
144
169
  .join(', ')));
145
170
  for (const want of wantUniques) {
146
171
  if (haveUniques.has(want))
package/dist/plan.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"plan.js","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plan.js","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC/F,OAAO,EAAE,YAAY,EAAkB,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAwBlF,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAEtD;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAC3B,QAAW,EACX,OAAgB;IAEhB,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChE,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;IACrD,MAAM,cAAc,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;IAClD,MAAM,WAAW,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAEnD,yEAAyE;IACzE,4DAA4D;IAC5D,MAAM,KAAK,GAAG,IAAI,GAAG,EAA+C,CAAC;IACrE,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;QAAE,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IAEjG,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,8EAA8E;IAC9E,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QACnC,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,SAAS;QACjC,QAAQ,CAAC,IAAI,CACX,UAAU,KAAK,uEAAuE;YACpF,4EAA4E,CAC/E,CAAC;IACJ,CAAC;IAED,KAAK,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAEhC,4EAA4E;QAC5E,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC3B,IAAI,CAAC,CAAC;gBAAE,SAAS;YACjB,sEAAsE;YACtE,yEAAyE;YACzE,kEAAkE;YAClE,MAAM,IAAI,GAAG;gBACX,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC;gBACjE,GAAG,oBAAoB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9D,GAAG,iBAAiB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;aAC5D,CAAC;YACF,UAAU,CAAC,IAAI,CAAC,gBAAgB,KAAK,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACpE,OAAO,CAAC,IAAI,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC;YAC7B,SAAS;QACX,CAAC;QAED,4EAA4E;QAC5E,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAEtD,0EAA0E;QAC1E,wEAAwE;QACxE,0EAA0E;QAC1E,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC1C,KAAK,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,EAAE,CAAC;YAC7E,IAAI,OAAO,QAAQ,KAAK,QAAQ;gBAAE,SAAS;YAC3C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,EAAE,CAAC;gBAC7C,QAAQ,CAAC,IAAI,CACX,IAAI,KAAK,IAAI,OAAO,kCAAkC,QAAQ,uBAAuB;oBACnF,8DAA8D,CACjE,CAAC;gBACF,SAAS;YACX,CAAC;YACD,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;gBAAE,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC/E,CAAC;QAED,KAAK,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,OAAO,EAAE,CAAC;YAC1C,UAAU,CAAC,IAAI,CAAC,eAAe,KAAK,kBAAkB,QAAQ,OAAO,OAAO,GAAG,CAAC,CAAC;YACjF,OAAO,CAAC,IAAI,CAAC,UAAU,KAAK,IAAI,QAAQ,OAAO,OAAO,EAAE,CAAC,CAAC;QAC5D,CAAC;QAED,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAS;YACjC,wEAAwE;YACxE,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAS;YACpC,IAAI,GAAG,CAAC,sBAAsB,EAAE,CAAC;gBAC/B,QAAQ,CAAC,IAAI,CACX,IAAI,KAAK,IAAI,GAAG,CAAC,IAAI,0CAA0C,KAAK,qBAAqB;oBACvF,gFAAgF;oBAChF,qEAAqE,CACxE,CAAC;gBACF,SAAS;YACX,CAAC;YACD,UAAU,CAAC,IAAI,CAAC,eAAe,KAAK,eAAe,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;YAC/D,OAAO,CAAC,IAAI,CAAC,OAAO,KAAK,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3C,CAAC;QAED,4EAA4E;QAC5E,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9C,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;YACxB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC;gBAAE,SAAS;YACnD,wDAAwD;YACxD,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAS;YACpC,QAAQ,CAAC,IAAI,CACX,IAAI,KAAK,IAAI,IAAI,wEAAwE;gBACvF,kFAAkF;gBAClF,gCAAgC,IAAI,wDAAwD,CAC/F,CAAC;QACJ,CAAC;QAED,6EAA6E;QAC7E,wEAAwE;QACxE,wEAAwE;QACxE,4EAA4E;QAC5E,sEAAsE;QACtE,oEAAoE;QACpE,EAAE;QACF,0EAA0E;QAC1E,6EAA6E;QAC7E,oEAAoE;QACpE,4EAA4E;QAC5E,4EAA4E;QAC5E,4EAA4E;QAC5E,4BAA4B;QAC5B,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;QAClG,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpG,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;YACxB,QAAQ,CAAC,IAAI,CACX,OAAO,KAAK,EAAE;gBACZ,CAAC,CAAC,IAAI,KAAK,8EAA8E;oBACvF,OAAO,OAAO,0EAA0E;oBACxF,wFAAwF;oBACxF,iCAAiC;gBACnC,CAAC,CAAC,IAAI,KAAK,kBAAkB,OAAO,4BAA4B,OAAO,mBAAmB;oBACxF,mFAAmF;oBACnF,oCAAoC,CACzC,CAAC;QACJ,CAAC;QAED,4EAA4E;QAC5E,qEAAqE;QACrE,yEAAyE;QACzE,2EAA2E;QAC3E,yEAAyE;QACzE,2BAA2B;QAC3B,MAAM,WAAW,GAAG,iBAAiB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAChE,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACzC,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACpB,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,IAAI,CAAC,CACd,CAAC;QACF,MAAM,WAAW,GAAG,IAAI,GAAG,CACzB,CAAC,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,GAAG,EAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAC9D,CAAC;aACE,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC;aAC/C,IAAI,CAAC,IAAI,CAAC,CACd,CACF,CAAC;QACF,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAS;YACpC,QAAQ,CAAC,IAAI,CACX,IAAI,KAAK,0BAA0B,IAAI,4CAA4C;gBACjF,qFAAqF;gBACrF,6CAA6C,CAChD,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IACvE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IAE3D,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAChD,4EAA4E;IAC5E,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAE,OAAO,CAAC,CAAC,CAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,QAAQ,OAAO,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC;IAC5G,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;AACpF,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC;QACrB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,yCAAyC,CAAC;QAC/E,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACvB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACtB,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;KACjC,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAEhE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC9B,IAAI,CAAC,CAAC,OAAO,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CACb,kBAAkB,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,OAAO,kCAAkC;gBACjF,wEAAwE,CAC3E,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@substrat-run/model-emit",
3
- "version": "0.3.3",
3
+ "version": "0.4.0",
4
4
  "description": "Build-time tooling over a Substrat model — DDL emitted from the entity registry, and the journal reader that holds it honest",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -22,7 +22,7 @@
22
22
  "dist"
23
23
  ],
24
24
  "dependencies": {
25
- "@substrat-run/contracts": "0.76.0"
25
+ "@substrat-run/contracts": "0.77.0"
26
26
  },
27
27
  "devDependencies": {
28
28
  "typescript": "^7.0.0",