@metaobjectsdev/migrate-ts 1.0.0-rc.4 → 1.0.0-rc.6

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.
@@ -20,6 +20,30 @@ export interface ApplyPendingResult {
20
20
  /** Migration names that were applied this run, in order. Empty on dryRun. */
21
21
  applied: string[];
22
22
  }
23
+ /**
24
+ * A committed migration's SQL failed. Carries WHICH one, because the driver's error says
25
+ * only what the database refused ("no such table: purchases") and never which file asked.
26
+ *
27
+ * The position matters to callers, not just the name: `--replay` prescribes a different
28
+ * remedy at the HEAD of the chain, where nothing earlier in this chain could have created
29
+ * what the migration needs, so the base schema must come from outside it.
30
+ */
31
+ export declare class MigrationApplyError extends Error {
32
+ /** `<timestamp>-<slug>` directory name of the migration that failed. */
33
+ readonly migration: string;
34
+ /** 0-based position among the PENDING migrations this run attempted. */
35
+ readonly index: number;
36
+ /** How many migrations were pending when the run started. */
37
+ readonly pendingCount: number;
38
+ readonly cause: unknown;
39
+ constructor(
40
+ /** `<timestamp>-<slug>` directory name of the migration that failed. */
41
+ migration: string,
42
+ /** 0-based position among the PENDING migrations this run attempted. */
43
+ index: number,
44
+ /** How many migrations were pending when the run started. */
45
+ pendingCount: number, cause: unknown);
46
+ }
23
47
  /**
24
48
  * Apply pending committed migration files in order, tracked by the
25
49
  * migration-history ledger, transactionally.
@@ -1 +1 @@
1
- {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/apply/apply.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,MAAM,EAAyB,MAAM,QAAQ,CAAC;AAC5D,OAAO,EAKL,KAAK,aAAa,EAClB,KAAK,aAAa,EAGnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAMhE,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAO9B,MAAM,WAAW,mBAAmB;IAClC,8DAA8D;IAC9D,MAAM,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,6FAA6F;IAC7F,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,2EAA2E;IAC3E,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,6EAA6E;IAC7E,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAWD;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAChC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACnC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,kBAAkB,CAAC,CAgD7B;AAED,MAAM,WAAW,iBAAiB;IAChC,iGAAiG;IACjG,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,6FAA6F;IAC7F,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,+EAA+E;IAC/E,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,UAAU,CAC9B,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACnC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,IAAI,GAAE,iBAAsB,GAC3B,OAAO,CAAC,gBAAgB,CAAC,CAyC3B"}
1
+ {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/apply/apply.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,MAAM,EAAyB,MAAM,QAAQ,CAAC;AAC5D,OAAO,EAKL,KAAK,aAAa,EAClB,KAAK,aAAa,EAGnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAMhE,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAO9B,MAAM,WAAW,mBAAmB;IAClC,8DAA8D;IAC9D,MAAM,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,6FAA6F;IAC7F,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,2EAA2E;IAC3E,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,6EAA6E;IAC7E,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAE1C,wEAAwE;IACxE,QAAQ,CAAC,SAAS,EAAE,MAAM;IAC1B,wEAAwE;IACxE,QAAQ,CAAC,KAAK,EAAE,MAAM;IACtB,6DAA6D;IAC7D,QAAQ,CAAC,YAAY,EAAE,MAAM;aACX,KAAK,EAAE,OAAO;;IANhC,wEAAwE;IAC/D,SAAS,EAAE,MAAM;IAC1B,wEAAwE;IAC/D,KAAK,EAAE,MAAM;IACtB,6DAA6D;IACpD,YAAY,EAAE,MAAM,EACX,KAAK,EAAE,OAAO;CAKnC;AAWD;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAChC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACnC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,kBAAkB,CAAC,CA0D7B;AAED,MAAM,WAAW,iBAAiB;IAChC,iGAAiG;IACjG,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,6FAA6F;IAC7F,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,+EAA+E;IAC/E,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,UAAU,CAC9B,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACnC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,IAAI,GAAE,iBAAsB,GAC3B,OAAO,CAAC,gBAAgB,CAAC,CAyC3B"}
@@ -13,6 +13,34 @@ export { splitSqlStatements };
13
13
  const UP_SQL = "up.sql";
14
14
  /** The per-migration down-SQL filename, shared with writeMigration's layout. */
15
15
  const DOWN_SQL = "down.sql";
16
+ /**
17
+ * A committed migration's SQL failed. Carries WHICH one, because the driver's error says
18
+ * only what the database refused ("no such table: purchases") and never which file asked.
19
+ *
20
+ * The position matters to callers, not just the name: `--replay` prescribes a different
21
+ * remedy at the HEAD of the chain, where nothing earlier in this chain could have created
22
+ * what the migration needs, so the base schema must come from outside it.
23
+ */
24
+ export class MigrationApplyError extends Error {
25
+ migration;
26
+ index;
27
+ pendingCount;
28
+ cause;
29
+ constructor(
30
+ /** `<timestamp>-<slug>` directory name of the migration that failed. */
31
+ migration,
32
+ /** 0-based position among the PENDING migrations this run attempted. */
33
+ index,
34
+ /** How many migrations were pending when the run started. */
35
+ pendingCount, cause) {
36
+ super(`migration '${migration}' failed to apply: ${cause?.message ?? String(cause)}`);
37
+ this.migration = migration;
38
+ this.index = index;
39
+ this.pendingCount = pendingCount;
40
+ this.cause = cause;
41
+ this.name = "MigrationApplyError";
42
+ }
43
+ }
16
44
  /**
17
45
  * Apply pending committed migration files in order, tracked by the
18
46
  * migration-history ledger, transactionally.
@@ -54,12 +82,23 @@ export async function applyPending(db, dir, opts) {
54
82
  return { pending: pendingNames, applied: [] };
55
83
  }
56
84
  const applied = [];
57
- for (const m of pending) {
85
+ for (const [i, m] of pending.entries()) {
58
86
  const text = await readFile(m.upPath, "utf8");
59
87
  const checksum = checksumOf(text);
60
88
  // Run the file's SQL + the ledger insert in ONE transaction. A failure
61
89
  // rolls the whole file back (unrecorded) and propagates — stopping the run.
62
- await runSqlFileWithLedgerMutation(db, text, (trx) => recordApplied(trx, m.name, checksum, dialect, ledger));
90
+ //
91
+ // Wrapped so the failure names the FILE. The driver reports what the database
92
+ // refused and nothing about who asked, which left every caller — `apply-pending`
93
+ // and `verify --replay` alike — printing "no such table: purchases" over a
94
+ // directory of migrations, and `--replay` guessing at a remedy it could not
95
+ // have chosen correctly without knowing the position.
96
+ try {
97
+ await runSqlFileWithLedgerMutation(db, text, (trx) => recordApplied(trx, m.name, checksum, dialect, ledger));
98
+ }
99
+ catch (err) {
100
+ throw new MigrationApplyError(m.name, i, pending.length, err);
101
+ }
63
102
  applied.push(m.name);
64
103
  }
65
104
  return { pending: pendingNames, applied };
@@ -1 +1 @@
1
- {"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/apply/apply.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/apply/apply.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,8 @@
1
- /** Canonical form: drop casts/brackets/parens, fold `= ANY (ARRAY[…])` back to `IN`, lower-case, collapse whitespace. */
1
+ /**
2
+ * Canonical form: drop casts/brackets/parens, fold `= ANY (ARRAY[…])` back to `IN`,
3
+ * lower-case, collapse whitespace, canonicalize cast target types, and collapse spacing
4
+ * around commas, casts and SYMBOLIC operators (outside single-quoted literals).
5
+ */
2
6
  export declare function normalizeCheckExpr(expr: string): string;
3
7
  /** True when two CHECK expressions are equivalent after normalization. */
4
8
  export declare function checkExprEquals(a: string | undefined, b: string | undefined): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"check-expr-compare.d.ts","sourceRoot":"","sources":["../src/check-expr-compare.ts"],"names":[],"mappings":"AAcA,yHAAyH;AACzH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA+BvD;AAqCD,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAGrF;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGrD"}
1
+ {"version":3,"file":"check-expr-compare.d.ts","sourceRoot":"","sources":["../src/check-expr-compare.ts"],"names":[],"mappings":"AA8BA;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAkDvD;AA+KD,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAGrF;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGrD"}
@@ -2,16 +2,36 @@
2
2
  //
3
3
  // CHECK-expression comparison. Postgres rewrites a stored CHECK body so the raw
4
4
  // text we generate and the introspected text differ textually but mean the same
5
- // thing. This reduces both to ONE canonical form for comparison. Reliable here
6
- // because every check expression we emit is machine-derived with a simple, known
7
- // shape (comparison / IN / length / regex) there is no arbitrary author SQL to
8
- // mis-normalize. The rewrites PG applies (verified against a live server):
5
+ // thing. This reduces both to ONE canonical form for comparison.
6
+ //
7
+ // It was written when every expression reaching it was machine-derived with a simple,
8
+ // known shape (comparison / IN / length / regex), and the header said there was "no
9
+ // arbitrary author SQL to mis-normalize". That stopped being true when `index.lookup`'s
10
+ // `@expr` and `@where` began using the same canonicalizer: those are AUTHOR-written SQL.
11
+ // Each rewrite below is therefore justified on the stronger ground it now needs — that
12
+ // the difference it erases is not semantic in ANY valid SQL, not merely in the shapes we
13
+ // emit. The rewrites PG applies (verified against a live server):
9
14
  // - parenthesizes terms: `col >= 0 AND col <= 100` → `(col >= 0) AND (col <= 100)`
10
15
  // - rewrites IN-lists: `status IN ('A','B')` → `status = ANY (ARRAY['A'::text, 'B'::text])`
11
16
  // - appends type casts: string literals gain `::text`
12
- // All three are canonicalized below so an enum/range CHECK introspected from PG
17
+ // - parenthesizes a cast OPERAND: `x::integer` → `(x)::integer`
18
+ // - respells a cast TARGET canonically: `x::int` → `(x)::integer`
19
+ // All five are canonicalized below so an enum/range CHECK introspected from PG
13
20
  // compares equal to the one we generate (idempotency on the --from-db / verify paths).
14
- /** Canonical form: drop casts/brackets/parens, fold `= ANY (ARRAY[…])` back to `IN`, lower-case, collapse whitespace. */
21
+ //
22
+ // The last two are why a cast-bearing `@expr` used to drift FOREVER. The paren-strip
23
+ // turns PG's added parens into a space, so `(x)::integer` reduced to `x ::integer` while
24
+ // the authored `x::integer` stayed tight — and `:` is not one of PG's operator characters,
25
+ // so the operator-run collapse never reached it. On top of that, PG re-emits the target
26
+ // type in its canonical spelling, so an authored `int`/`varchar`/`timestamptz` could not
27
+ // match the `integer`/`character varying`/`timestamp with time zone` it got back. Both
28
+ // are fixed in the quote-aware walker below, which is the only place that can tell a real
29
+ // cast from a `::` inside a regex literal.
30
+ /**
31
+ * Canonical form: drop casts/brackets/parens, fold `= ANY (ARRAY[…])` back to `IN`,
32
+ * lower-case, collapse whitespace, canonicalize cast target types, and collapse spacing
33
+ * around commas, casts and SYMBOLIC operators (outside single-quoted literals).
34
+ */
15
35
  export function normalizeCheckExpr(expr) {
16
36
  const stripped = expr
17
37
  .toLowerCase()
@@ -36,16 +56,142 @@ export function normalizeCheckExpr(expr) {
36
56
  // PG stores `col IN (…)` as `col = ANY (ARRAY[…])`; after the bracket strip above
37
57
  // that reads `col = any array …`. Fold it back to the `col in …` form we emit.
38
58
  const folded = stripped.replace(/=\s*any\s+array/g, "in").replace(/\s+/g, " ").trim();
39
- // Normalize spacing AROUND COMMAS so a generated IN-list (`'a', 'b'`) compares equal
40
- // to a hand-written one (`'a','b'`) — the separator commas are never semantically
41
- // meaningful, and a hand SQLite migration omits the space. This is done OUTSIDE
42
- // single-quoted literals only: a comma inside a string/regex literal (`'a, b'`, or a
43
- // quantifier `'{1, 3}'`) IS meaningful, so two checks that differ only there must
44
- // stay distinct (else a real regex/predicate change reads as clean drift).
45
- return collapseCommaSpacingOutsideQuotes(folded);
59
+ // Normalize spacing around COMMAS and SYMBOLIC OPERATORS, so the spelling a human
60
+ // writes compares equal to the one Postgres hands back.
61
+ //
62
+ // Commas: a generated IN-list (`'a', 'b'`) must equal a hand-written one (`'a','b'`)
63
+ // a hand SQLite migration omits the space.
64
+ //
65
+ // Operators: `pg_get_expr` re-emits every operator SPACED, and a person authoring an
66
+ // `index.lookup @expr` writes it tight. So `(request_context->>'device_id')` — the
67
+ // natural spelling — normalized to `request_context->>'device_id'` while the live index
68
+ // introspected to `request_context ->> 'device_id'`, and `verify --db` proposed DROP +
69
+ // CREATE against an index the database already held, exactly as declared. Casts and
70
+ // redundant parens were ALREADY canonicalized above, so the one difference left was the
71
+ // spacing — and it was the one difference a human actually produces.
72
+ //
73
+ // Safe because whitespace around a symbolic operator is not semantic in ANY valid SQL:
74
+ // where two spellings differ only there, at most one of them parses. Postgres lexes a
75
+ // maximal run of operator characters as a SINGLE token, so `a =- 1` is not `a = -1`
76
+ // spelled differently — it is a syntax error. Only SYMBOLIC operators are touched;
77
+ // collapsing around an alphabetic one would turn `a AND b` into `aANDb`.
78
+ //
79
+ // Both are done OUTSIDE single-quoted literals: a comma or an operator character inside
80
+ // a string/regex literal (`'a, b'`, a quantifier `'{1, 3}'`, a pattern `'a ->> b'`) IS
81
+ // meaningful, so two checks differing only there must stay distinct — else a real
82
+ // pattern change reads as clean drift, which is this file's failure in the other
83
+ // direction and the worse of the two.
84
+ return collapseSeparatorSpacingOutsideQuotes(folded);
85
+ }
86
+ /**
87
+ * Postgres' operator characters. A maximal run of these is ONE operator token — which is
88
+ * why `->>` and `!~*` survive intact rather than being split apart. Derived as the
89
+ * character SET rather than a list of known operators, so a spelling this file has never
90
+ * seen (`@>`, `?|`, a user-defined operator) normalizes by the same rule instead of
91
+ * needing an edit here.
92
+ */
93
+ const OPERATOR_CHARS = new Set([..."+-*/<>=~!@#%^&|?"]);
94
+ /**
95
+ * Cast target types PG respells, mapped to the spelling `pg_get_constraintdef` /
96
+ * `pg_get_expr` hand back. MEASURED against PostgreSQL 16.15 by creating one CHECK per
97
+ * alias and reading the definition back — not derived from the docs, because the two
98
+ * that would most easily have been missed (`timestamp` → `timestamp WITHOUT time zone`,
99
+ * `float` → `double precision`) only show up when you ask the server.
100
+ *
101
+ * The four `… time zone` forms map to THEMSELVES on purpose: they are already canonical,
102
+ * and they exist here to be matched BEFORE the shorter `timestamp` / `time` aliases would
103
+ * otherwise rewrite their leading word into `timestamp without time zone with time zone`.
104
+ * No other canonical form needs that guard — `\b` already stops `int` matching inside
105
+ * `integer`, `char` inside `character`, and `bool` inside `boolean`.
106
+ */
107
+ const CAST_TYPE_ALIASES = {
108
+ "timestamp with time zone": "timestamp with time zone",
109
+ "timestamp without time zone": "timestamp without time zone",
110
+ "time with time zone": "time with time zone",
111
+ "time without time zone": "time without time zone",
112
+ timestamptz: "timestamp with time zone",
113
+ timestamp: "timestamp without time zone",
114
+ timetz: "time with time zone",
115
+ time: "time without time zone",
116
+ varchar: "character varying",
117
+ varbit: "bit varying",
118
+ bpchar: "character",
119
+ char: "character",
120
+ int8: "bigint",
121
+ int4: "integer",
122
+ int2: "smallint",
123
+ int: "integer",
124
+ float8: "double precision",
125
+ float4: "real",
126
+ float: "double precision",
127
+ bool: "boolean",
128
+ decimal: "numeric",
129
+ };
130
+ /**
131
+ * Anchored alternation over the alias keys, LONGEST FIRST — JS alternation is
132
+ * first-match-wins, not longest-match, so the order is load-bearing and is derived here
133
+ * rather than trusted to the literal order above.
134
+ */
135
+ const CAST_TYPE_RE = new RegExp(`^(${Object.keys(CAST_TYPE_ALIASES)
136
+ .sort((a, b) => b.length - a.length)
137
+ .join("|")})\\b`);
138
+ /** Numeric target types, for the literal-cast rule in isElidableCast. */
139
+ const NUMERIC_CAST_TYPES = new Set([
140
+ "numeric", "integer", "bigint", "smallint", "real", "double precision",
141
+ ]);
142
+ /**
143
+ * Read the target type of a cast at `i`, canonicalized. Returns the canonical spelling and
144
+ * how many characters it consumed (0 for an unrecognizable target — `::` before something
145
+ * this walker should just copy through).
146
+ */
147
+ function readCastTarget(s, i) {
148
+ const alias = CAST_TYPE_RE.exec(s.slice(i));
149
+ if (alias)
150
+ return { type: CAST_TYPE_ALIASES[alias[1]], consumed: alias[1].length };
151
+ // Any other type name — `uuid`, `jsonb`, `text`, `public.mytype`. PG's spelling and ours
152
+ // already agree for these, so it passes through as written.
153
+ const plain = /^[a-z_][\w.]*/.exec(s.slice(i));
154
+ if (plain)
155
+ return { type: plain[0], consumed: plain[0].length };
156
+ return { type: "", consumed: 0 };
157
+ }
158
+ /**
159
+ * True when a cast is one Postgres ADDS or ELIDES on its own, so its presence on one side
160
+ * and absence on the other is not a difference in meaning. Two cases, both found by a
161
+ * differential against live PG 16.15 rather than by reading the SQL:
162
+ *
163
+ * 1. `::text` on a `->>` / `#>>` result. Those operators are DEFINED to return text, so
164
+ * PG drops the author's explicit cast; `(payload->>'k')::text` comes back as
165
+ * `(payload ->> 'k'::text)`, whose only cast belongs to the KEY literal.
166
+ * 2. A numeric cast on a NUMERIC LITERAL. PG coerces the literal to the column's type, so
167
+ * `amt > 0` on a numeric column comes back as `amt > (0)::numeric`.
168
+ *
169
+ * Case 2 is the rule this file has always applied to STRING literals — the post-quote
170
+ * `'open'::text` strip up in normalizeCheckExpr — extended to the numeric ones, where the
171
+ * same PG behaviour produces the same permanent drift. Both are deliberately narrow: a
172
+ * cast on anything that is not a literal or a text-returning operator is a REAL cast and
173
+ * survives, because erasing it would let a genuine change read as clean drift.
174
+ */
175
+ function isElidableCast(type, lhs) {
176
+ // `->>` / `#>>` yield text; a following `::text` cannot change anything.
177
+ if (type === "text" && /(?:->>|#>>)\s*(?:'(?:[^']|'')*'|[\w."]+)$/.test(lhs))
178
+ return true;
179
+ // A numeric literal cast to a numeric type.
180
+ if (NUMERIC_CAST_TYPES.has(type) && /(?:^|[^\w."'])\d+(?:\.\d+)?$/.test(lhs))
181
+ return true;
182
+ return false;
46
183
  }
47
- /** Collapse `\s*,\s*` → `,` OUTSIDE single-quoted literals (see normalizeCheckExpr). */
48
- function collapseCommaSpacingOutsideQuotes(s) {
184
+ /**
185
+ * Collapse whitespace around commas, casts and symbolic-operator runs, and canonicalize
186
+ * cast target types — all OUTSIDE single-quoted literals (see normalizeCheckExpr).
187
+ *
188
+ * The cast work lives in this walker rather than in a `.replace()` up in the pipeline
189
+ * because only a quote-aware pass can tell a real `x::int` cast from the `::int` inside
190
+ * a regex literal (`slug ~ 'a::int'`). A blind replace would rewrite the pattern, and two
191
+ * distinct regex CHECKs would compare equal — a real change reading as clean drift, which
192
+ * is this file's failure in the worse direction.
193
+ */
194
+ function collapseSeparatorSpacingOutsideQuotes(s) {
49
195
  let out = "";
50
196
  let i = 0;
51
197
  const n = s.length;
@@ -69,12 +215,41 @@ function collapseCommaSpacingOutsideQuotes(s) {
69
215
  out += s.slice(start, i);
70
216
  continue;
71
217
  }
218
+ // A separator token: a comma, a `::` cast, or a symbolic-operator run. All three bind
219
+ // tight to what PRECEDES them, so any whitespace already emitted before them is
220
+ // dropped. They differ only in whether what FOLLOWS binds tight too.
221
+ let token;
222
+ let tightAfter = true;
72
223
  if (ch === ",") {
73
- out = out.replace(/\s+$/, ""); // drop whitespace already emitted before it
74
- out += ",";
224
+ token = ",";
75
225
  i++;
226
+ }
227
+ else if (ch === ":" && s[i + 1] === ":") {
228
+ i += 2;
76
229
  while (i < n && /\s/.test(s[i]))
77
- i++; // skip whitespace after it
230
+ i++; // `:: integer` `::integer`
231
+ const target = readCastTarget(s, i);
232
+ i += target.consumed;
233
+ const lhs = out.replace(/\s+$/, "");
234
+ token = isElidableCast(target.type, lhs) ? "" : `::${target.type}`;
235
+ out = lhs;
236
+ // Whitespace AFTER the target type is load-bearing — `x::integer is not null` must
237
+ // not become `x::integeris not null` — so the cast, unlike a comma or an operator,
238
+ // binds tight on its left only.
239
+ tightAfter = false;
240
+ }
241
+ else if (OPERATOR_CHARS.has(ch)) {
242
+ const start = i;
243
+ // Take the WHOLE run, so `->>` stays one token rather than three.
244
+ while (i < n && OPERATOR_CHARS.has(s[i]))
245
+ i++;
246
+ token = s.slice(start, i);
247
+ }
248
+ if (token !== undefined) {
249
+ out = out.replace(/\s+$/, "") + token;
250
+ if (tightAfter)
251
+ while (i < n && /\s/.test(s[i]))
252
+ i++;
78
253
  continue;
79
254
  }
80
255
  out += ch;
@@ -1 +1 @@
1
- {"version":3,"file":"check-expr-compare.js","sourceRoot":"","sources":["../src/check-expr-compare.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"check-expr-compare.js","sourceRoot":"","sources":["../src/check-expr-compare.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -35,7 +35,7 @@ export { findReferencedRebuilds, D1ReferencedTableRebuildError, D1CyclicForeignK
35
35
  export type { D1RebuildRefusal } from "./emit/d1-fk-refuse.js";
36
36
  export { introspectD1, type D1Runner, type IntrospectD1Options } from "./introspect/d1.js";
37
37
  export { ensureLedger, recordApplied, deleteApplied, appliedNames, appliedRecords, recordBaseline, baselineRecord, BASELINE_NAME, MIGRATIONS_TABLE, DEFAULT_LEDGER_SCHEMA, type LedgerRow, type LedgerOptions, type LedgerDialect, } from "./apply/ledger.js";
38
- export { applyPending, rollbackTo, type ApplyPendingOptions, type ApplyPendingResult, type RollbackToOptions, type RollbackToResult, } from "./apply/apply.js";
38
+ export { applyPending, MigrationApplyError, rollbackTo, type ApplyPendingOptions, type ApplyPendingResult, type RollbackToOptions, type RollbackToResult, } from "./apply/apply.js";
39
39
  export { verifyReplay } from "./verify/replay.js";
40
40
  export type { VerifyReplayArgs, VerifyReplayResult } from "./verify/replay.js";
41
41
  export { openReplayEngine } from "./verify/replay-engine.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -49,7 +49,7 @@ export { findReferencedRebuilds, D1ReferencedTableRebuildError, D1CyclicForeignK
49
49
  export { introspectD1 } from "./introspect/d1.js";
50
50
  // Migration-history ledger + ordered transactional apply (postgres/sqlite)
51
51
  export { ensureLedger, recordApplied, deleteApplied, appliedNames, appliedRecords, recordBaseline, baselineRecord, BASELINE_NAME, MIGRATIONS_TABLE, DEFAULT_LEDGER_SCHEMA, } from "./apply/ledger.js";
52
- export { applyPending, rollbackTo, } from "./apply/apply.js";
52
+ export { applyPending, MigrationApplyError, rollbackTo, } from "./apply/apply.js";
53
53
  // Snapshot-integrity: replay migrations and assert == committed snapshot.
54
54
  export { verifyReplay } from "./verify/replay.js";
55
55
  // An empty in-process database to replay a committed chain into (#313).
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,EAAE;AACF,gEAAgE;AAChE,yEAAyE;AACzE,sEAAsE;AACtE,2BAA2B;AAC3B,EAAE;AACF,2DAA2D;AAE3D,qBAAqB;AACrB,OAAO,EAAE,mBAAmB,EAAE,iCAAiC,EAAE,MAAM,sBAAsB,CAAC;AAE9F,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzF,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,gFAAgF;AAChF,qEAAqE;AACrE,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAA8C,MAAM,kBAAkB,CAAC;AACpH,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE1E,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,kFAAkF;AAClF,yFAAyF;AACzF,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAEnE,0DAA0D;AAC1D,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAGvE,SAAS;AACT,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAElG,oEAAoE;AACpE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAkB1D,+EAA+E;AAC/E,gFAAgF;AAChF,mFAAmF;AACnF,4EAA4E;AAC5E,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAExE,oCAAoC;AACpC,wEAAwE;AACxE,yEAAyE;AACzE,8CAA8C;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAC1F,OAAO,EAAE,sBAAsB,EAAE,6BAA6B,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAGxH,mBAAmB;AACnB,OAAO,EAAE,YAAY,EAA2C,MAAM,oBAAoB,CAAC;AAE3F,2EAA2E;AAC3E,OAAO,EACL,YAAY,EACZ,aAAa,EACb,aAAa,EACb,YAAY,EACZ,cAAc,EACd,cAAc,EACd,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,qBAAqB,GAItB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,YAAY,EACZ,UAAU,GAKX,MAAM,kBAAkB,CAAC;AAE1B,0EAA0E;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,wEAAwE;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAG7D,0BAA0B;AAC1B,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,GAGjB,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metaobjectsdev/migrate-ts",
3
- "version": "1.0.0-rc.4",
3
+ "version": "1.0.0-rc.6",
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": "1.0.0-rc.4"
48
+ "@metaobjectsdev/metadata": "1.0.0-rc.6"
49
49
  },
50
50
  "peerDependencies": {
51
51
  "kysely": ">=0.27.0 <0.30.0",
@@ -45,6 +45,29 @@ export interface ApplyPendingResult {
45
45
  applied: string[];
46
46
  }
47
47
 
48
+ /**
49
+ * A committed migration's SQL failed. Carries WHICH one, because the driver's error says
50
+ * only what the database refused ("no such table: purchases") and never which file asked.
51
+ *
52
+ * The position matters to callers, not just the name: `--replay` prescribes a different
53
+ * remedy at the HEAD of the chain, where nothing earlier in this chain could have created
54
+ * what the migration needs, so the base schema must come from outside it.
55
+ */
56
+ export class MigrationApplyError extends Error {
57
+ constructor(
58
+ /** `<timestamp>-<slug>` directory name of the migration that failed. */
59
+ readonly migration: string,
60
+ /** 0-based position among the PENDING migrations this run attempted. */
61
+ readonly index: number,
62
+ /** How many migrations were pending when the run started. */
63
+ readonly pendingCount: number,
64
+ override readonly cause: unknown,
65
+ ) {
66
+ super(`migration '${migration}' failed to apply: ${(cause as Error)?.message ?? String(cause)}`);
67
+ this.name = "MigrationApplyError";
68
+ }
69
+ }
70
+
48
71
  interface DiscoveredMigration {
49
72
  /** `<timestamp>-<slug>` directory name — stable id + sort key. */
50
73
  name: string;
@@ -106,14 +129,24 @@ export async function applyPending(
106
129
  }
107
130
 
108
131
  const applied: string[] = [];
109
- for (const m of pending) {
132
+ for (const [i, m] of pending.entries()) {
110
133
  const text = await readFile(m.upPath, "utf8");
111
134
  const checksum = checksumOf(text);
112
135
  // Run the file's SQL + the ledger insert in ONE transaction. A failure
113
136
  // rolls the whole file back (unrecorded) and propagates — stopping the run.
114
- await runSqlFileWithLedgerMutation(db, text, (trx) =>
115
- recordApplied(trx, m.name, checksum, dialect, ledger),
116
- );
137
+ //
138
+ // Wrapped so the failure names the FILE. The driver reports what the database
139
+ // refused and nothing about who asked, which left every caller — `apply-pending`
140
+ // and `verify --replay` alike — printing "no such table: purchases" over a
141
+ // directory of migrations, and `--replay` guessing at a remedy it could not
142
+ // have chosen correctly without knowing the position.
143
+ try {
144
+ await runSqlFileWithLedgerMutation(db, text, (trx) =>
145
+ recordApplied(trx, m.name, checksum, dialect, ledger),
146
+ );
147
+ } catch (err) {
148
+ throw new MigrationApplyError(m.name, i, pending.length, err);
149
+ }
117
150
  applied.push(m.name);
118
151
  }
119
152
 
@@ -2,17 +2,37 @@
2
2
  //
3
3
  // CHECK-expression comparison. Postgres rewrites a stored CHECK body so the raw
4
4
  // text we generate and the introspected text differ textually but mean the same
5
- // thing. This reduces both to ONE canonical form for comparison. Reliable here
6
- // because every check expression we emit is machine-derived with a simple, known
7
- // shape (comparison / IN / length / regex) there is no arbitrary author SQL to
8
- // mis-normalize. The rewrites PG applies (verified against a live server):
5
+ // thing. This reduces both to ONE canonical form for comparison.
6
+ //
7
+ // It was written when every expression reaching it was machine-derived with a simple,
8
+ // known shape (comparison / IN / length / regex), and the header said there was "no
9
+ // arbitrary author SQL to mis-normalize". That stopped being true when `index.lookup`'s
10
+ // `@expr` and `@where` began using the same canonicalizer: those are AUTHOR-written SQL.
11
+ // Each rewrite below is therefore justified on the stronger ground it now needs — that
12
+ // the difference it erases is not semantic in ANY valid SQL, not merely in the shapes we
13
+ // emit. The rewrites PG applies (verified against a live server):
9
14
  // - parenthesizes terms: `col >= 0 AND col <= 100` → `(col >= 0) AND (col <= 100)`
10
15
  // - rewrites IN-lists: `status IN ('A','B')` → `status = ANY (ARRAY['A'::text, 'B'::text])`
11
16
  // - appends type casts: string literals gain `::text`
12
- // All three are canonicalized below so an enum/range CHECK introspected from PG
17
+ // - parenthesizes a cast OPERAND: `x::integer` → `(x)::integer`
18
+ // - respells a cast TARGET canonically: `x::int` → `(x)::integer`
19
+ // All five are canonicalized below so an enum/range CHECK introspected from PG
13
20
  // compares equal to the one we generate (idempotency on the --from-db / verify paths).
21
+ //
22
+ // The last two are why a cast-bearing `@expr` used to drift FOREVER. The paren-strip
23
+ // turns PG's added parens into a space, so `(x)::integer` reduced to `x ::integer` while
24
+ // the authored `x::integer` stayed tight — and `:` is not one of PG's operator characters,
25
+ // so the operator-run collapse never reached it. On top of that, PG re-emits the target
26
+ // type in its canonical spelling, so an authored `int`/`varchar`/`timestamptz` could not
27
+ // match the `integer`/`character varying`/`timestamp with time zone` it got back. Both
28
+ // are fixed in the quote-aware walker below, which is the only place that can tell a real
29
+ // cast from a `::` inside a regex literal.
14
30
 
15
- /** Canonical form: drop casts/brackets/parens, fold `= ANY (ARRAY[…])` back to `IN`, lower-case, collapse whitespace. */
31
+ /**
32
+ * Canonical form: drop casts/brackets/parens, fold `= ANY (ARRAY[…])` back to `IN`,
33
+ * lower-case, collapse whitespace, canonicalize cast target types, and collapse spacing
34
+ * around commas, casts and SYMBOLIC operators (outside single-quoted literals).
35
+ */
16
36
  export function normalizeCheckExpr(expr: string): string {
17
37
  const stripped = expr
18
38
  .toLowerCase()
@@ -37,17 +57,147 @@ export function normalizeCheckExpr(expr: string): string {
37
57
  // PG stores `col IN (…)` as `col = ANY (ARRAY[…])`; after the bracket strip above
38
58
  // that reads `col = any array …`. Fold it back to the `col in …` form we emit.
39
59
  const folded = stripped.replace(/=\s*any\s+array/g, "in").replace(/\s+/g, " ").trim();
40
- // Normalize spacing AROUND COMMAS so a generated IN-list (`'a', 'b'`) compares equal
41
- // to a hand-written one (`'a','b'`) — the separator commas are never semantically
42
- // meaningful, and a hand SQLite migration omits the space. This is done OUTSIDE
43
- // single-quoted literals only: a comma inside a string/regex literal (`'a, b'`, or a
44
- // quantifier `'{1, 3}'`) IS meaningful, so two checks that differ only there must
45
- // stay distinct (else a real regex/predicate change reads as clean drift).
46
- return collapseCommaSpacingOutsideQuotes(folded);
60
+ // Normalize spacing around COMMAS and SYMBOLIC OPERATORS, so the spelling a human
61
+ // writes compares equal to the one Postgres hands back.
62
+ //
63
+ // Commas: a generated IN-list (`'a', 'b'`) must equal a hand-written one (`'a','b'`)
64
+ // a hand SQLite migration omits the space.
65
+ //
66
+ // Operators: `pg_get_expr` re-emits every operator SPACED, and a person authoring an
67
+ // `index.lookup @expr` writes it tight. So `(request_context->>'device_id')` — the
68
+ // natural spelling — normalized to `request_context->>'device_id'` while the live index
69
+ // introspected to `request_context ->> 'device_id'`, and `verify --db` proposed DROP +
70
+ // CREATE against an index the database already held, exactly as declared. Casts and
71
+ // redundant parens were ALREADY canonicalized above, so the one difference left was the
72
+ // spacing — and it was the one difference a human actually produces.
73
+ //
74
+ // Safe because whitespace around a symbolic operator is not semantic in ANY valid SQL:
75
+ // where two spellings differ only there, at most one of them parses. Postgres lexes a
76
+ // maximal run of operator characters as a SINGLE token, so `a =- 1` is not `a = -1`
77
+ // spelled differently — it is a syntax error. Only SYMBOLIC operators are touched;
78
+ // collapsing around an alphabetic one would turn `a AND b` into `aANDb`.
79
+ //
80
+ // Both are done OUTSIDE single-quoted literals: a comma or an operator character inside
81
+ // a string/regex literal (`'a, b'`, a quantifier `'{1, 3}'`, a pattern `'a ->> b'`) IS
82
+ // meaningful, so two checks differing only there must stay distinct — else a real
83
+ // pattern change reads as clean drift, which is this file's failure in the other
84
+ // direction and the worse of the two.
85
+ return collapseSeparatorSpacingOutsideQuotes(folded);
47
86
  }
48
87
 
49
- /** Collapse `\s*,\s*` → `,` OUTSIDE single-quoted literals (see normalizeCheckExpr). */
50
- function collapseCommaSpacingOutsideQuotes(s: string): string {
88
+ /**
89
+ * Postgres' operator characters. A maximal run of these is ONE operator token — which is
90
+ * why `->>` and `!~*` survive intact rather than being split apart. Derived as the
91
+ * character SET rather than a list of known operators, so a spelling this file has never
92
+ * seen (`@>`, `?|`, a user-defined operator) normalizes by the same rule instead of
93
+ * needing an edit here.
94
+ */
95
+ const OPERATOR_CHARS = new Set([..."+-*/<>=~!@#%^&|?"]);
96
+
97
+ /**
98
+ * Cast target types PG respells, mapped to the spelling `pg_get_constraintdef` /
99
+ * `pg_get_expr` hand back. MEASURED against PostgreSQL 16.15 by creating one CHECK per
100
+ * alias and reading the definition back — not derived from the docs, because the two
101
+ * that would most easily have been missed (`timestamp` → `timestamp WITHOUT time zone`,
102
+ * `float` → `double precision`) only show up when you ask the server.
103
+ *
104
+ * The four `… time zone` forms map to THEMSELVES on purpose: they are already canonical,
105
+ * and they exist here to be matched BEFORE the shorter `timestamp` / `time` aliases would
106
+ * otherwise rewrite their leading word into `timestamp without time zone with time zone`.
107
+ * No other canonical form needs that guard — `\b` already stops `int` matching inside
108
+ * `integer`, `char` inside `character`, and `bool` inside `boolean`.
109
+ */
110
+ const CAST_TYPE_ALIASES: Record<string, string> = {
111
+ "timestamp with time zone": "timestamp with time zone",
112
+ "timestamp without time zone": "timestamp without time zone",
113
+ "time with time zone": "time with time zone",
114
+ "time without time zone": "time without time zone",
115
+ timestamptz: "timestamp with time zone",
116
+ timestamp: "timestamp without time zone",
117
+ timetz: "time with time zone",
118
+ time: "time without time zone",
119
+ varchar: "character varying",
120
+ varbit: "bit varying",
121
+ bpchar: "character",
122
+ char: "character",
123
+ int8: "bigint",
124
+ int4: "integer",
125
+ int2: "smallint",
126
+ int: "integer",
127
+ float8: "double precision",
128
+ float4: "real",
129
+ float: "double precision",
130
+ bool: "boolean",
131
+ decimal: "numeric",
132
+ };
133
+
134
+ /**
135
+ * Anchored alternation over the alias keys, LONGEST FIRST — JS alternation is
136
+ * first-match-wins, not longest-match, so the order is load-bearing and is derived here
137
+ * rather than trusted to the literal order above.
138
+ */
139
+ const CAST_TYPE_RE = new RegExp(
140
+ `^(${Object.keys(CAST_TYPE_ALIASES)
141
+ .sort((a, b) => b.length - a.length)
142
+ .join("|")})\\b`,
143
+ );
144
+
145
+ /** Numeric target types, for the literal-cast rule in isElidableCast. */
146
+ const NUMERIC_CAST_TYPES = new Set([
147
+ "numeric", "integer", "bigint", "smallint", "real", "double precision",
148
+ ]);
149
+
150
+ /**
151
+ * Read the target type of a cast at `i`, canonicalized. Returns the canonical spelling and
152
+ * how many characters it consumed (0 for an unrecognizable target — `::` before something
153
+ * this walker should just copy through).
154
+ */
155
+ function readCastTarget(s: string, i: number): { type: string; consumed: number } {
156
+ const alias = CAST_TYPE_RE.exec(s.slice(i));
157
+ if (alias) return { type: CAST_TYPE_ALIASES[alias[1]!]!, consumed: alias[1]!.length };
158
+ // Any other type name — `uuid`, `jsonb`, `text`, `public.mytype`. PG's spelling and ours
159
+ // already agree for these, so it passes through as written.
160
+ const plain = /^[a-z_][\w.]*/.exec(s.slice(i));
161
+ if (plain) return { type: plain[0], consumed: plain[0].length };
162
+ return { type: "", consumed: 0 };
163
+ }
164
+
165
+ /**
166
+ * True when a cast is one Postgres ADDS or ELIDES on its own, so its presence on one side
167
+ * and absence on the other is not a difference in meaning. Two cases, both found by a
168
+ * differential against live PG 16.15 rather than by reading the SQL:
169
+ *
170
+ * 1. `::text` on a `->>` / `#>>` result. Those operators are DEFINED to return text, so
171
+ * PG drops the author's explicit cast; `(payload->>'k')::text` comes back as
172
+ * `(payload ->> 'k'::text)`, whose only cast belongs to the KEY literal.
173
+ * 2. A numeric cast on a NUMERIC LITERAL. PG coerces the literal to the column's type, so
174
+ * `amt > 0` on a numeric column comes back as `amt > (0)::numeric`.
175
+ *
176
+ * Case 2 is the rule this file has always applied to STRING literals — the post-quote
177
+ * `'open'::text` strip up in normalizeCheckExpr — extended to the numeric ones, where the
178
+ * same PG behaviour produces the same permanent drift. Both are deliberately narrow: a
179
+ * cast on anything that is not a literal or a text-returning operator is a REAL cast and
180
+ * survives, because erasing it would let a genuine change read as clean drift.
181
+ */
182
+ function isElidableCast(type: string, lhs: string): boolean {
183
+ // `->>` / `#>>` yield text; a following `::text` cannot change anything.
184
+ if (type === "text" && /(?:->>|#>>)\s*(?:'(?:[^']|'')*'|[\w."]+)$/.test(lhs)) return true;
185
+ // A numeric literal cast to a numeric type.
186
+ if (NUMERIC_CAST_TYPES.has(type) && /(?:^|[^\w."'])\d+(?:\.\d+)?$/.test(lhs)) return true;
187
+ return false;
188
+ }
189
+
190
+ /**
191
+ * Collapse whitespace around commas, casts and symbolic-operator runs, and canonicalize
192
+ * cast target types — all OUTSIDE single-quoted literals (see normalizeCheckExpr).
193
+ *
194
+ * The cast work lives in this walker rather than in a `.replace()` up in the pipeline
195
+ * because only a quote-aware pass can tell a real `x::int` cast from the `::int` inside
196
+ * a regex literal (`slug ~ 'a::int'`). A blind replace would rewrite the pattern, and two
197
+ * distinct regex CHECKs would compare equal — a real change reading as clean drift, which
198
+ * is this file's failure in the worse direction.
199
+ */
200
+ function collapseSeparatorSpacingOutsideQuotes(s: string): string {
51
201
  let out = "";
52
202
  let i = 0;
53
203
  const n = s.length;
@@ -68,13 +218,40 @@ function collapseCommaSpacingOutsideQuotes(s: string): string {
68
218
  out += s.slice(start, i);
69
219
  continue;
70
220
  }
221
+
222
+ // A separator token: a comma, a `::` cast, or a symbolic-operator run. All three bind
223
+ // tight to what PRECEDES them, so any whitespace already emitted before them is
224
+ // dropped. They differ only in whether what FOLLOWS binds tight too.
225
+ let token: string | undefined;
226
+ let tightAfter = true;
71
227
  if (ch === ",") {
72
- out = out.replace(/\s+$/, ""); // drop whitespace already emitted before it
73
- out += ",";
228
+ token = ",";
74
229
  i++;
75
- while (i < n && /\s/.test(s[i]!)) i++; // skip whitespace after it
230
+ } else if (ch === ":" && s[i + 1] === ":") {
231
+ i += 2;
232
+ while (i < n && /\s/.test(s[i]!)) i++; // `:: integer` → `::integer`
233
+ const target = readCastTarget(s, i);
234
+ i += target.consumed;
235
+ const lhs = out.replace(/\s+$/, "");
236
+ token = isElidableCast(target.type, lhs) ? "" : `::${target.type}`;
237
+ out = lhs;
238
+ // Whitespace AFTER the target type is load-bearing — `x::integer is not null` must
239
+ // not become `x::integeris not null` — so the cast, unlike a comma or an operator,
240
+ // binds tight on its left only.
241
+ tightAfter = false;
242
+ } else if (OPERATOR_CHARS.has(ch)) {
243
+ const start = i;
244
+ // Take the WHOLE run, so `->>` stays one token rather than three.
245
+ while (i < n && OPERATOR_CHARS.has(s[i]!)) i++;
246
+ token = s.slice(start, i);
247
+ }
248
+
249
+ if (token !== undefined) {
250
+ out = out.replace(/\s+$/, "") + token;
251
+ if (tightAfter) while (i < n && /\s/.test(s[i]!)) i++;
76
252
  continue;
77
253
  }
254
+
78
255
  out += ch;
79
256
  i++;
80
257
  }
package/src/index.ts CHANGED
@@ -104,6 +104,7 @@ export {
104
104
  } from "./apply/ledger.js";
105
105
  export {
106
106
  applyPending,
107
+ MigrationApplyError,
107
108
  rollbackTo,
108
109
  type ApplyPendingOptions,
109
110
  type ApplyPendingResult,