@metaobjectsdev/migrate-ts 0.15.21-rc.1 → 0.16.0-rc.1

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 (51) hide show
  1. package/dist/diff/index.d.ts.map +1 -1
  2. package/dist/diff/index.js +141 -16
  3. package/dist/diff/index.js.map +1 -1
  4. package/dist/diff/status.js +28 -2
  5. package/dist/diff/status.js.map +1 -1
  6. package/dist/drift/drift.d.ts +2 -2
  7. package/dist/drift/drift.d.ts.map +1 -1
  8. package/dist/emit/postgres.d.ts.map +1 -1
  9. package/dist/emit/postgres.js +94 -4
  10. package/dist/emit/postgres.js.map +1 -1
  11. package/dist/expected-schema.d.ts +19 -2
  12. package/dist/expected-schema.d.ts.map +1 -1
  13. package/dist/expected-schema.js +26 -2
  14. package/dist/expected-schema.js.map +1 -1
  15. package/dist/introspect/postgres.d.ts +15 -1
  16. package/dist/introspect/postgres.d.ts.map +1 -1
  17. package/dist/introspect/postgres.js +132 -11
  18. package/dist/introspect/postgres.js.map +1 -1
  19. package/dist/snapshot/plan.d.ts +4 -3
  20. package/dist/snapshot/plan.d.ts.map +1 -1
  21. package/dist/snapshot/plan.js.map +1 -1
  22. package/dist/snapshot/serialize.d.ts +15 -1
  23. package/dist/snapshot/serialize.d.ts.map +1 -1
  24. package/dist/snapshot/serialize.js +15 -1
  25. package/dist/snapshot/serialize.js.map +1 -1
  26. package/dist/types.d.ts +95 -7
  27. package/dist/types.d.ts.map +1 -1
  28. package/dist/view-column-types.d.ts +40 -0
  29. package/dist/view-column-types.d.ts.map +1 -0
  30. package/dist/view-column-types.js +100 -0
  31. package/dist/view-column-types.js.map +1 -0
  32. package/dist/view-fingerprint.d.ts +40 -0
  33. package/dist/view-fingerprint.d.ts.map +1 -0
  34. package/dist/view-fingerprint.js +88 -0
  35. package/dist/view-fingerprint.js.map +1 -0
  36. package/dist/view-sql-compare.d.ts.map +1 -1
  37. package/dist/view-sql-compare.js +24 -19
  38. package/dist/view-sql-compare.js.map +1 -1
  39. package/package.json +2 -2
  40. package/src/diff/index.ts +151 -19
  41. package/src/diff/status.ts +29 -2
  42. package/src/drift/drift.ts +2 -2
  43. package/src/emit/postgres.ts +102 -4
  44. package/src/expected-schema.ts +44 -3
  45. package/src/introspect/postgres.ts +148 -10
  46. package/src/snapshot/plan.ts +4 -3
  47. package/src/snapshot/serialize.ts +15 -1
  48. package/src/types.ts +109 -9
  49. package/src/view-column-types.ts +110 -0
  50. package/src/view-fingerprint.ts +97 -0
  51. package/src/view-sql-compare.ts +24 -19
@@ -2,8 +2,22 @@
2
2
  * On-disk format version for the committed schema snapshot. Bump when the
3
3
  * SchemaSnapshot descriptor gains a field (a DDL-coverage feature); add the
4
4
  * matching upgrade branch in parseSnapshot at the same time.
5
+ *
6
+ * v3 — ViewDescriptor gained `fingerprint`, `columns` and `dependents`. The
7
+ * fingerprint is how Postgres decides whether a view is up to date (Postgres deparses
8
+ * view SQL, so the emitted text can never be compared against what it stores). A
9
+ * toolchain that does not understand these fields would silently fall back to the old
10
+ * text comparison and re-propose every view on every migrate — so a v3 snapshot must
11
+ * hard-fail on an older reader rather than be quietly misread. Reading an OLDER (v2)
12
+ * snapshot stays fine: the missing fields read as `undefined`, which every consumer
13
+ * treats as "unknown" and fails safe on.
14
+ *
15
+ * NOTE for anyone touching canonicalize(): a view's `columns` array is ORDER-SENSITIVE.
16
+ * Postgres allows a non-destructive CREATE OR REPLACE only when the old column list is
17
+ * a PREFIX of the new one, so sorting that array would destroy the very information the
18
+ * decision rests on.
5
19
  */
6
- export const SNAPSHOT_FORMAT_VERSION = 2;
20
+ export const SNAPSHOT_FORMAT_VERSION = 3;
7
21
  function sortByName(arr) {
8
22
  return [...arr].sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
9
23
  }
@@ -1 +1 @@
1
- {"version":3,"file":"serialize.js","sourceRoot":"","sources":["../../src/snapshot/serialize.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"serialize.js","sourceRoot":"","sources":["../../src/snapshot/serialize.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -96,6 +96,25 @@ export interface FkDescriptor {
96
96
  onUpdate?: FkAction;
97
97
  }
98
98
  export type FkAction = "cascade" | "set-null" | "restrict" | "no-action";
99
+ /** One output column of a view, in SELECT order. */
100
+ export interface ViewColumnDescriptor {
101
+ name: string;
102
+ sqlType: SqlType;
103
+ }
104
+ /** A relation that depends on a view — i.e. what a `DROP ... CASCADE` would destroy. */
105
+ export interface DependentRelation {
106
+ schema: string;
107
+ name: string;
108
+ /** 'v' = view, 'm' = materialized view. */
109
+ relkind: "v" | "m";
110
+ /**
111
+ * True when this dependent is a view MetaObjects manages (it carries our
112
+ * fingerprint). A managed dependent that the same migration recreates is
113
+ * harmless; an UNMANAGED one is somebody else's object and a CASCADE destroys
114
+ * it irrecoverably.
115
+ */
116
+ managed: boolean;
117
+ }
99
118
  export interface ViewDescriptor {
100
119
  name: string;
101
120
  /** Same semantics as TableDescriptor.schema. */
@@ -104,16 +123,49 @@ export interface ViewDescriptor {
104
123
  * View definition SQL.
105
124
  *
106
125
  * On the EXPECTED side (`buildExpectedSchema` / `buildExpectedViews`) this is
107
- * the view body — the SELECT clause through the FROM/WHERE/GROUP-BY tail.
126
+ * the view body — the SELECT clause through the FROM/WHERE/GROUP-BY tail. It is
127
+ * the input to `viewFingerprint()`.
128
+ *
129
+ * On the ACTUAL side (`introspect`) this is whatever the DB catalog stores.
130
+ * Its role is DIALECT-DEPENDENT, and this is load-bearing:
131
+ *
132
+ * - SQLite/D1 store `sqlite_master.sql` VERBATIM — the exact text we wrote —
133
+ * so there the body is a sound basis for comparison (`viewSqlEquals`).
108
134
  *
109
- * On the ACTUAL side (`introspect`) this is whatever the DB catalog stores:
110
- * sqlite's `sqlite_master.sql` is the full `CREATE VIEW <name> AS <body>`
111
- * statement, while Postgres' `information_schema.views.view_definition` is the
112
- * body only. `diff`'s view-body comparator normalizes both sides (strips any
113
- * leading `CREATE VIEW ... AS`, collapses whitespace) before comparing, so a
114
- * body change triggers a `replace-view`.
135
+ * - Postgres does NOT store view SQL. It stores the parse tree, and
136
+ * `pg_get_viewdef()` DEPARSES it back into Postgres's own canonical style
137
+ * (lowercased functions, `LEFT OUTER JOIN``LEFT JOIN`, parenthesized FROM
138
+ * items and ON predicates, dropped redundant aliases). It can never equal
139
+ * what we emitted, so on Postgres the body is NOT used for comparison —
140
+ * `fingerprint` is. The deparsed body is still carried, as the RESTORE
141
+ * payload for a down migration (it is valid SQL that reproduces the view).
115
142
  */
116
143
  sql?: string;
144
+ /**
145
+ * Content hash of the generated body — `metaobjects:v1:sha256:<hex>` — stamped
146
+ * into the view's `COMMENT ON VIEW` at emit time and read back at introspect
147
+ * time. This, not the body text, is how Postgres decides whether a view is
148
+ * up to date (see view-fingerprint.ts).
149
+ *
150
+ * Absent on the actual side means the view carries NO MetaObjects stamp: either
151
+ * it is hand-written, or it predates fingerprinting. The two are
152
+ * indistinguishable on Postgres, so the diff fails CLOSED and blocks pending
153
+ * `allow.adoptView`.
154
+ */
155
+ fingerprint?: string;
156
+ /**
157
+ * The view's output columns, in SELECT order. Drives the replace-vs-drop
158
+ * decision: Postgres permits `CREATE OR REPLACE VIEW` only when the existing
159
+ * columns are a PREFIX of the new ones (same names, same types, same order,
160
+ * additions at the end only). Undefined = unknown → fail safe to drop+create.
161
+ */
162
+ columns?: readonly ViewColumnDescriptor[];
163
+ /**
164
+ * Relations that depend on this view (transitively). Populated on the ACTUAL
165
+ * side by introspection. A `DROP VIEW` with dependents needs CASCADE, which
166
+ * destroys every one of them — including views owned by other applications.
167
+ */
168
+ dependents?: readonly DependentRelation[];
117
169
  /**
118
170
  * Physical tables this view reads (base + joined tables). Populated on the
119
171
  * EXPECTED side only (the view producer knows the join graph; introspection
@@ -244,11 +296,29 @@ export type Change = {
244
296
  view: string;
245
297
  schema?: string;
246
298
  status: ChangeStatus;
299
+ /** The view as it exists in the DB — lets the down migration recreate it. */
300
+ restore?: ViewDescriptor;
301
+ /**
302
+ * Relations a CASCADE would destroy. EXTERNAL dependents only: a managed view
303
+ * this same migration recreates is filtered out (it comes back). Non-empty ⇒
304
+ * a plain DROP VIEW would fail at apply, and CASCADE would destroy objects we
305
+ * do not manage — so this is blocked pending `allow.dropViewCascade`.
306
+ */
307
+ dependents?: readonly DependentRelation[];
247
308
  } | {
248
309
  kind: "replace-view";
249
310
  view: ViewDescriptor;
250
311
  schema?: string;
251
312
  status: ChangeStatus;
313
+ /** The view as it exists in the DB — lets the down migration restore the old body. */
314
+ restore?: ViewDescriptor;
315
+ /**
316
+ * The DB view carries no MetaObjects fingerprint — hand-written, or created
317
+ * before fingerprinting existed. We cannot tell which (Postgres deparses away
318
+ * the text evidence), and overwriting a hand-written view destroys SQL no down
319
+ * migration can recover. Blocked pending `allow.adoptView`.
320
+ */
321
+ unmanagedActual?: boolean;
252
322
  };
253
323
  export type ChangeKind = Change["kind"];
254
324
  export interface ChangeStatus {
@@ -270,6 +340,24 @@ export interface AllowOptions {
270
340
  * view is re-created in the same migration).
271
341
  */
272
342
  dropView?: boolean;
343
+ /**
344
+ * Gates `DROP VIEW ... CASCADE`. A view with dependents cannot be dropped plainly
345
+ * (Postgres refuses), and CASCADE destroys every dependent — including views and
346
+ * materialized views owned by OTHER applications, which this tool does not manage
347
+ * and cannot restore. Strictly ADDITIONAL to `dropView`: `--allow drop-view` alone
348
+ * never cascades, and a plain non-cascading DROP VIEW stays the emitted form
349
+ * whenever there are no dependents, so Postgres itself backstops a stale
350
+ * dependents snapshot rather than silently cascading.
351
+ */
352
+ dropViewCascade?: boolean;
353
+ /**
354
+ * Gates overwriting an existing view that carries NO MetaObjects fingerprint —
355
+ * i.e. taking ownership of it. It is either hand-written or predates
356
+ * fingerprinting, and on Postgres those are indistinguishable. Every environment
357
+ * upgrading from an older toolchain needs exactly one `--allow adopt-view` run to
358
+ * stamp its existing views; after that they are fingerprinted and silent.
359
+ */
360
+ adoptView?: boolean;
273
361
  /** Existing data must satisfy NOT NULL; diff cannot verify this. */
274
362
  nullableToNotNull?: boolean;
275
363
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import type { TableDescriptor, ViewColumnDescriptor } from "./types.js";
2
+ /** The codegen-side description of a view column: physical, but untyped. */
3
+ export type ExpectedViewColumnInput = {
4
+ kind: "passthrough";
5
+ name: string;
6
+ sourceTable: string;
7
+ sourceColumn: string;
8
+ } | {
9
+ kind: "aggregate";
10
+ name: string;
11
+ sourceTable: string;
12
+ sourceColumn: string;
13
+ agg: string;
14
+ };
15
+ /**
16
+ * Can `existing` be turned into `target` with a `CREATE OR REPLACE VIEW`?
17
+ *
18
+ * Postgres permits it only when the new query produces the same columns as the existing
19
+ * view — same names, same types, same order — with additions allowed at the END.
20
+ * Formally: `existing` must be a PREFIX of `target`.
21
+ * https://www.postgresql.org/docs/current/sql-createview.html
22
+ *
23
+ * Used in BOTH directions. Forward (target = expected, existing = live) it decides
24
+ * replace-vs-drop. Backward, in a down migration (target = the old view, existing = the
25
+ * one we just created), it decides the same thing — and usually says NO, because undoing
26
+ * an append means REMOVING a column, which OR REPLACE cannot do.
27
+ *
28
+ * Fails SAFE: unknown columns on either side → false → the caller uses drop+create.
29
+ * A wrong "yes" is not a failed check, it is a statement Postgres rejects at APPLY time,
30
+ * aborting the migration with no plan-time warning.
31
+ */
32
+ export declare function viewReplaceIsLegal(target: readonly ViewColumnDescriptor[] | undefined, existing: readonly ViewColumnDescriptor[] | undefined): boolean;
33
+ /**
34
+ * Resolve every view column against the expected TABLE descriptors.
35
+ *
36
+ * Returns undefined if ANY column cannot be resolved — a partial list is worse than
37
+ * none, because the prefix comparison would silently compare the wrong positions.
38
+ */
39
+ export declare function resolveViewColumns(inputs: readonly ExpectedViewColumnInput[] | undefined, tables: readonly TableDescriptor[]): ViewColumnDescriptor[] | undefined;
40
+ //# sourceMappingURL=view-column-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view-column-types.d.ts","sourceRoot":"","sources":["../src/view-column-types.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAExE,4EAA4E;AAC5E,MAAM,MAAM,uBAAuB,GAC/B;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAChF;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhG;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,oBAAoB,EAAE,GAAG,SAAS,EACnD,QAAQ,EAAE,SAAS,oBAAoB,EAAE,GAAG,SAAS,GACpD,OAAO,CAOT;AAoCD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,uBAAuB,EAAE,GAAG,SAAS,EACtD,MAAM,EAAE,SAAS,eAAe,EAAE,GACjC,oBAAoB,EAAE,GAAG,SAAS,CAiBpC"}
@@ -0,0 +1,100 @@
1
+ // view-column-types.ts — resolve a view's output columns to SqlTypes.
2
+ //
3
+ // Needed to decide whether a view change is non-destructively REPLACEABLE. Postgres
4
+ // permits `CREATE OR REPLACE VIEW` only when the existing output columns are a prefix
5
+ // of the new ones on (name, type, position); getting the types wrong would make the
6
+ // diff propose an OR REPLACE that Postgres rejects at APPLY time
7
+ // ("cannot change data type of view column ..."), aborting the migration mid-flight
8
+ // with no plan-time warning. So every resolution failure here degrades to `undefined`
9
+ // — "unknown" — which the diff treats as not-replaceable and routes through a gated,
10
+ // loud drop+create. Wrong-but-confident is the only outcome we must never produce.
11
+ import { sqlTypeEquals } from "./sql-type.js";
12
+ /**
13
+ * Can `existing` be turned into `target` with a `CREATE OR REPLACE VIEW`?
14
+ *
15
+ * Postgres permits it only when the new query produces the same columns as the existing
16
+ * view — same names, same types, same order — with additions allowed at the END.
17
+ * Formally: `existing` must be a PREFIX of `target`.
18
+ * https://www.postgresql.org/docs/current/sql-createview.html
19
+ *
20
+ * Used in BOTH directions. Forward (target = expected, existing = live) it decides
21
+ * replace-vs-drop. Backward, in a down migration (target = the old view, existing = the
22
+ * one we just created), it decides the same thing — and usually says NO, because undoing
23
+ * an append means REMOVING a column, which OR REPLACE cannot do.
24
+ *
25
+ * Fails SAFE: unknown columns on either side → false → the caller uses drop+create.
26
+ * A wrong "yes" is not a failed check, it is a statement Postgres rejects at APPLY time,
27
+ * aborting the migration with no plan-time warning.
28
+ */
29
+ export function viewReplaceIsLegal(target, existing) {
30
+ if (target === undefined || existing === undefined)
31
+ return false;
32
+ if (existing.length > target.length)
33
+ return false;
34
+ return existing.every((ec, i) => {
35
+ const tc = target[i];
36
+ return ec.name === tc.name && sqlTypeEquals(ec.sqlType, tc.sqlType);
37
+ });
38
+ }
39
+ /**
40
+ * Postgres aggregate result types. Not the argument type — `count(int)` is bigint and
41
+ * `avg(int)` is numeric — so a naive "same as input" rule would mis-type the column and
42
+ * mis-plan the replace.
43
+ *
44
+ * https://www.postgresql.org/docs/current/functions-aggregate.html
45
+ */
46
+ function aggregateResultType(agg, arg) {
47
+ switch (agg) {
48
+ // count() is bigint regardless of its argument — it need not even resolve.
49
+ case "count":
50
+ return { kind: "integer", bits: 64 };
51
+ case "min":
52
+ case "max":
53
+ return arg; // same as the argument type
54
+ case "sum":
55
+ if (arg === undefined)
56
+ return undefined;
57
+ if (arg.kind === "integer") {
58
+ // smallint/integer → bigint; bigint → numeric (sum can overflow).
59
+ return arg.bits === 64 ? { kind: "numeric" } : { kind: "integer", bits: 64 };
60
+ }
61
+ // numeric → numeric, real → real, double → double.
62
+ if (arg.kind === "numeric" || arg.kind === "real" || arg.kind === "real4")
63
+ return arg;
64
+ return undefined;
65
+ case "avg":
66
+ if (arg === undefined)
67
+ return undefined;
68
+ if (arg.kind === "integer" || arg.kind === "numeric")
69
+ return { kind: "numeric" };
70
+ if (arg.kind === "real" || arg.kind === "real4")
71
+ return { kind: "real" };
72
+ return undefined;
73
+ default:
74
+ return undefined;
75
+ }
76
+ }
77
+ /**
78
+ * Resolve every view column against the expected TABLE descriptors.
79
+ *
80
+ * Returns undefined if ANY column cannot be resolved — a partial list is worse than
81
+ * none, because the prefix comparison would silently compare the wrong positions.
82
+ */
83
+ export function resolveViewColumns(inputs, tables) {
84
+ if (inputs === undefined || inputs.length === 0)
85
+ return undefined;
86
+ const byTable = new Map(tables.map((t) => [t.name, t]));
87
+ const columnType = (table, column) => byTable.get(table)?.columns.find((c) => c.name === column)?.sqlType;
88
+ const out = [];
89
+ for (const input of inputs) {
90
+ const arg = columnType(input.sourceTable, input.sourceColumn);
91
+ const sqlType = input.kind === "aggregate"
92
+ ? aggregateResultType(input.agg, arg)
93
+ : arg;
94
+ if (sqlType === undefined)
95
+ return undefined;
96
+ out.push({ name: input.name, sqlType });
97
+ }
98
+ return out;
99
+ }
100
+ //# sourceMappingURL=view-column-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view-column-types.js","sourceRoot":"","sources":["../src/view-column-types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Marker format version. Bump ONLY if the normalization rules or the marker grammar
3
+ * change — i.e. if the same body would hash differently. The algorithm is tagged
4
+ * separately (`sha256:`), so swapping algorithms does not need a version bump.
5
+ */
6
+ export declare const FINGERPRINT_FORMAT_VERSION = 1;
7
+ /**
8
+ * Canonicalize a view body for hashing.
9
+ *
10
+ * Collapses whitespace (so reindenting the emitter does not re-stamp every deployed
11
+ * view) and strips an optional CREATE VIEW wrapper and trailing semicolon — and
12
+ * NOTHING else.
13
+ *
14
+ * Deliberately does NOT lowercase, unlike `normalizeViewSql`. That lowercasing exists
15
+ * only to chase Postgres's deparser, and it masks drift inside case-sensitive string
16
+ * literals — which `origin.aggregate @filter` predicates now carry (`status = 'Active'`
17
+ * and `status = 'active'` are different views). We never chase the deparser here, so
18
+ * there is nothing to buy and real drift to lose.
19
+ */
20
+ export declare function normalizeForFingerprint(body: string): string;
21
+ /** sha256 of the normalized body, lowercase hex. */
22
+ export declare function viewFingerprint(body: string): string;
23
+ /** The marker line stamped into `COMMENT ON VIEW`. */
24
+ export declare function renderFingerprintMarker(fingerprint: string): string;
25
+ /**
26
+ * Read a fingerprint marker out of a view's comment.
27
+ *
28
+ * Returns null when there is no marker — meaning the view carries no MetaObjects
29
+ * stamp and is therefore either hand-written or older than fingerprinting. Callers
30
+ * MUST fail closed on null: on Postgres those two cases are indistinguishable, and
31
+ * overwriting the first destroys hand-written SQL nothing can restore.
32
+ *
33
+ * An unknown VERSION still parses (the view is ours, stamped by a different
34
+ * toolchain) — the caller re-stamps it, which makes format migration self-healing.
35
+ */
36
+ export declare function parseFingerprintMarker(comment: string | null | undefined): {
37
+ version: number;
38
+ fingerprint: string;
39
+ } | null;
40
+ //# sourceMappingURL=view-fingerprint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view-fingerprint.d.ts","sourceRoot":"","sources":["../src/view-fingerprint.ts"],"names":[],"mappings":"AAgCA;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAU5C;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM5D;AAED,oDAAoD;AACpD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,sDAAsD;AACtD,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACjC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAKjD"}
@@ -0,0 +1,88 @@
1
+ // view-fingerprint.ts — how Postgres decides whether a managed view is up to date.
2
+ //
3
+ // WHY THIS EXISTS
4
+ //
5
+ // Postgres does not store view SQL. It stores the parse tree (as the view's `_RETURN`
6
+ // rewrite rule), and `pg_get_viewdef()` DEPARSES that back into Postgres's own
7
+ // canonical style. For one of our generated projection views, live PG 16 returns:
8
+ //
9
+ // we emit : SELECT p.id AS "programId", COUNT(DISTINCT w.id) AS "weekCount"
10
+ // FROM programs p LEFT OUTER JOIN weeks w ON w."programId" = p.id
11
+ // PG says : SELECT p.id AS "programId", count(DISTINCT w.id) AS "weekCount"
12
+ // FROM (programs p LEFT JOIN weeks w ON ((w."programId" = p.id)))
13
+ //
14
+ // — lowercased functions, LEFT OUTER JOIN rewritten, FROM item and ON predicate
15
+ // parenthesized. No textual normalizer can bridge that without reimplementing the
16
+ // deparser, so comparing our text against PG's text ALWAYS reports a difference. That
17
+ // is what made `replace-view` fire on every migrate for every view, forever, and kept
18
+ // `verify --db` permanently red for any project with a projection.
19
+ //
20
+ // THE FIX: never compare against the deparser. Hash the body WE generate, stamp the
21
+ // hash into the view's COMMENT at emit time, and read the stamp back at introspect
22
+ // time. Both sides of the comparison then come from the same emitter, and the
23
+ // deparsed body is never an input.
24
+ //
25
+ // The deparsed body is still useful — it is valid SQL that reproduces the view — so it
26
+ // is carried as the RESTORE payload for down migrations.
27
+ //
28
+ // SQLite/D1 need none of this: `sqlite_master.sql` is the verbatim text we wrote, so
29
+ // the body comparator (view-sql-compare.ts) is exact there.
30
+ import { createHash } from "node:crypto";
31
+ /**
32
+ * Marker format version. Bump ONLY if the normalization rules or the marker grammar
33
+ * change — i.e. if the same body would hash differently. The algorithm is tagged
34
+ * separately (`sha256:`), so swapping algorithms does not need a version bump.
35
+ */
36
+ export const FINGERPRINT_FORMAT_VERSION = 1;
37
+ const MARKER_PREFIX = "metaobjects";
38
+ /** Trailing-line marker: any human comment text may sit ABOVE it. */
39
+ const MARKER_RE = /(?:^|\n)metaobjects:v(\d+):sha256:([0-9a-f]{64})\s*$/;
40
+ const CREATE_VIEW_PREFIX = /^\s*create\s+(?:or\s+replace\s+)?(?:temp(?:orary)?\s+)?view\s+(?:if\s+not\s+exists\s+)?[^\s(]+(?:\s*\([^)]*\))?\s+as\s+/i;
41
+ /**
42
+ * Canonicalize a view body for hashing.
43
+ *
44
+ * Collapses whitespace (so reindenting the emitter does not re-stamp every deployed
45
+ * view) and strips an optional CREATE VIEW wrapper and trailing semicolon — and
46
+ * NOTHING else.
47
+ *
48
+ * Deliberately does NOT lowercase, unlike `normalizeViewSql`. That lowercasing exists
49
+ * only to chase Postgres's deparser, and it masks drift inside case-sensitive string
50
+ * literals — which `origin.aggregate @filter` predicates now carry (`status = 'Active'`
51
+ * and `status = 'active'` are different views). We never chase the deparser here, so
52
+ * there is nothing to buy and real drift to lose.
53
+ */
54
+ export function normalizeForFingerprint(body) {
55
+ return body
56
+ .replace(CREATE_VIEW_PREFIX, "")
57
+ .replace(/\s+/g, " ")
58
+ .replace(/;\s*$/, "")
59
+ .trim();
60
+ }
61
+ /** sha256 of the normalized body, lowercase hex. */
62
+ export function viewFingerprint(body) {
63
+ return createHash("sha256").update(normalizeForFingerprint(body), "utf8").digest("hex");
64
+ }
65
+ /** The marker line stamped into `COMMENT ON VIEW`. */
66
+ export function renderFingerprintMarker(fingerprint) {
67
+ return `${MARKER_PREFIX}:v${FINGERPRINT_FORMAT_VERSION}:sha256:${fingerprint}`;
68
+ }
69
+ /**
70
+ * Read a fingerprint marker out of a view's comment.
71
+ *
72
+ * Returns null when there is no marker — meaning the view carries no MetaObjects
73
+ * stamp and is therefore either hand-written or older than fingerprinting. Callers
74
+ * MUST fail closed on null: on Postgres those two cases are indistinguishable, and
75
+ * overwriting the first destroys hand-written SQL nothing can restore.
76
+ *
77
+ * An unknown VERSION still parses (the view is ours, stamped by a different
78
+ * toolchain) — the caller re-stamps it, which makes format migration self-healing.
79
+ */
80
+ export function parseFingerprintMarker(comment) {
81
+ if (typeof comment !== "string" || comment.length === 0)
82
+ return null;
83
+ const m = MARKER_RE.exec(comment.trim());
84
+ if (m === null)
85
+ return null;
86
+ return { version: parseInt(m[1], 10), fingerprint: m[2] };
87
+ }
88
+ //# sourceMappingURL=view-fingerprint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view-fingerprint.js","sourceRoot":"","sources":["../src/view-fingerprint.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,EAAE;AACF,kBAAkB;AAClB,EAAE;AACF,sFAAsF;AACtF,+EAA+E;AAC/E,kFAAkF;AAClF,EAAE;AACF,+EAA+E;AAC/E,iFAAiF;AACjF,+EAA+E;AAC/E,iFAAiF;AACjF,EAAE;AACF,gFAAgF;AAChF,kFAAkF;AAClF,sFAAsF;AACtF,sFAAsF;AACtF,mEAAmE;AACnE,EAAE;AACF,oFAAoF;AACpF,mFAAmF;AACnF,8EAA8E;AAC9E,mCAAmC;AACnC,EAAE;AACF,uFAAuF;AACvF,yDAAyD;AACzD,EAAE;AACF,qFAAqF;AACrF,4DAA4D;AAE5D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC;AAE5C,MAAM,aAAa,GAAG,aAAa,CAAC;AAEpC,qEAAqE;AACrE,MAAM,SAAS,GAAG,sDAAsD,CAAC;AAEzE,MAAM,kBAAkB,GACtB,0HAA0H,CAAC;AAE7H;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,OAAO,IAAI;SACR,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;SAC/B,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;SACpB,IAAI,EAAE,CAAC;AACZ,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,uBAAuB,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1F,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,uBAAuB,CAAC,WAAmB;IACzD,OAAO,GAAG,aAAa,KAAK,0BAA0B,WAAW,WAAW,EAAE,CAAC;AACjF,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,sBAAsB,CACpC,OAAkC;IAElC,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACrE,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACzC,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC5B,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC;AAC9D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"view-sql-compare.d.ts","sourceRoot":"","sources":["../src/view-sql-compare.ts"],"names":[],"mappings":"AA0BA;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAOpD;AAED,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAGnF"}
1
+ {"version":3,"file":"view-sql-compare.d.ts","sourceRoot":"","sources":["../src/view-sql-compare.ts"],"names":[],"mappings":"AA+BA;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAOpD;AAED,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAGnF"}
@@ -1,25 +1,30 @@
1
- // view-sql-compare.ts — the single shared comparator for view definition SQL.
1
+ // view-sql-compare.ts — the SQLITE/D1 comparator for view definition SQL.
2
2
  //
3
- // View definition SQL arrives in two shapes across the pipeline:
4
- // - EXPECTED (buildProjectionViews): the body only `SELECT ... FROM ...`.
5
- // - ACTUAL (introspect): sqlite's/D1's sqlite_master.sql is the full
6
- // `CREATE VIEW <name> AS <body>`; Postgres' view_definition is body-only.
3
+ // SCOPE read this before reusing it. This comparator is sound ONLY on engines that
4
+ // store view SQL VERBATIM. SQLite and D1 do: `sqlite_master.sql` hands back the exact
5
+ // `CREATE VIEW <name> AS <body>` text we wrote, so normalizing away whitespace and the
6
+ // CREATE wrapper leaves two strings that genuinely can be equal.
7
7
  //
8
- // normalizeViewSql reduces either of these to a comparable canonical form so the
9
- // diff (expected vs introspected) uses ONE comparison. It strips a leading
10
- // `CREATE [OR REPLACE] VIEW <name> AS`,
11
- // collapses runs of whitespace to a single space, drops a trailing `;`, and
12
- // lower-cases view-body drift should be classified by structure, not by
13
- // incidental whitespace/case/wrapper differences.
8
+ // It is NOT usable on Postgres, and used to be. Postgres does not store view SQL — it
9
+ // stores the parse tree, and `pg_get_viewdef()` DEPARSES it back in Postgres's own
10
+ // style (lowercased functions, `LEFT OUTER JOIN` rewritten to `LEFT JOIN`,
11
+ // parenthesized FROM items and ON predicates, redundant aliases dropped). The text we
12
+ // emitted therefore NEVER comes back, this comparator returned false every single
13
+ // time, and `replace-view` fired on every migrate for every view, forever — while
14
+ // `verify --db` stayed permanently red for any project with a projection. Postgres now
15
+ // compares FINGERPRINTS instead (see view-fingerprint.ts), which never consults the
16
+ // deparser at all. Do not point this function at Postgres again.
14
17
  //
15
- // CAVEAT (accepted tradeoff): lower-casing makes keyword/identifier comparison
16
- // case-insensitive but can mask a difference that lives ONLY in a case-sensitive
17
- // string literal in the body (e.g. `WHERE status = 'Active'` vs `'active'`) —
18
- // such a change would NOT be flagged as drift. Acceptable for generated
19
- // aggregate/passthrough projections (no literals); revisit if hand-authored
20
- // views with case-sensitive literals become a drift concern. The name regex
21
- // matches one whitespace/`(`-free token, so a quoted view name containing a
22
- // space would not strip cleanly also a non-issue for generated identifiers.
18
+ // normalizeViewSql strips a leading `CREATE [OR REPLACE] VIEW <name> AS`, collapses
19
+ // whitespace runs, drops a trailing `;`, and lower-cases.
20
+ //
21
+ // CAVEAT (accepted tradeoff): lower-casing can mask a difference living ONLY in a
22
+ // case-sensitive string literal (e.g. `WHERE status = 'Active'` vs `'active'`), which
23
+ // an `origin.aggregate @filter` predicate can now carry. The fingerprint path
24
+ // deliberately does NOT lowercase for exactly this reason; this SQLite path keeps it
25
+ // for backwards-compatible behavior. The name regex matches one whitespace/`(`-free
26
+ // token, so a quoted view name containing a space would not strip cleanly — a non-issue
27
+ // for generated identifiers.
23
28
  const CREATE_VIEW_PREFIX = /^\s*create\s+(?:or\s+replace\s+)?(?:temp(?:orary)?\s+)?view\s+(?:if\s+not\s+exists\s+)?[^\s(]+(?:\s*\([^)]*\))?\s+as\s+/i;
24
29
  /**
25
30
  * Collapse a view definition (full `CREATE VIEW ... AS body` OR a bare body)
@@ -1 +1 @@
1
- {"version":3,"file":"view-sql-compare.js","sourceRoot":"","sources":["../src/view-sql-compare.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,EAAE;AACF,iEAAiE;AACjE,8EAA8E;AAC9E,uEAAuE;AACvE,8EAA8E;AAC9E,EAAE;AACF,iFAAiF;AACjF,2EAA2E;AAC3E,wCAAwC;AACxC,4EAA4E;AAC5E,0EAA0E;AAC1E,kDAAkD;AAClD,EAAE;AACF,+EAA+E;AAC/E,iFAAiF;AACjF,8EAA8E;AAC9E,wEAAwE;AACxE,4EAA4E;AAC5E,4EAA4E;AAC5E,4EAA4E;AAC5E,8EAA8E;AAE9E,MAAM,kBAAkB,GACtB,0HAA0H,CAAC;AAE7H;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,OAAO,GAAG;SACP,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;SAC/B,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;SACpB,IAAI,EAAE;SACN,WAAW,EAAE,CAAC;AACnB,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,aAAa,CAAC,CAAqB,EAAE,CAAqB;IACxE,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACrD,OAAO,gBAAgB,CAAC,CAAC,CAAC,KAAK,gBAAgB,CAAC,CAAC,CAAC,CAAC;AACrD,CAAC"}
1
+ {"version":3,"file":"view-sql-compare.js","sourceRoot":"","sources":["../src/view-sql-compare.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,EAAE;AACF,qFAAqF;AACrF,sFAAsF;AACtF,uFAAuF;AACvF,iEAAiE;AACjE,EAAE;AACF,sFAAsF;AACtF,mFAAmF;AACnF,2EAA2E;AAC3E,sFAAsF;AACtF,kFAAkF;AAClF,kFAAkF;AAClF,uFAAuF;AACvF,oFAAoF;AACpF,iEAAiE;AACjE,EAAE;AACF,oFAAoF;AACpF,0DAA0D;AAC1D,EAAE;AACF,kFAAkF;AAClF,sFAAsF;AACtF,8EAA8E;AAC9E,qFAAqF;AACrF,oFAAoF;AACpF,wFAAwF;AACxF,6BAA6B;AAE7B,MAAM,kBAAkB,GACtB,0HAA0H,CAAC;AAE7H;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,OAAO,GAAG;SACP,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;SAC/B,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;SACpB,IAAI,EAAE;SACN,WAAW,EAAE,CAAC;AACnB,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,aAAa,CAAC,CAAqB,EAAE,CAAqB;IACxE,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACrD,OAAO,gBAAgB,CAAC,CAAC,CAAC,KAAK,gBAAgB,CAAC,CAAC,CAAC,CAAC;AACrD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metaobjectsdev/migrate-ts",
3
- "version": "0.15.21-rc.1",
3
+ "version": "0.16.0-rc.1",
4
4
  "description": "Schema migration tooling for MetaObjects: diff metadata vs DB and emit SQL for Postgres and SQLite.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -45,7 +45,7 @@
45
45
  },
46
46
  "dependencies": {
47
47
  "@iarna/toml": "^2.2.5",
48
- "@metaobjectsdev/metadata": "0.15.21-rc.1"
48
+ "@metaobjectsdev/metadata": "0.16.0-rc.1"
49
49
  },
50
50
  "peerDependencies": {
51
51
  "kysely": ">=0.27.0"