@ingram-tech/nk-db 1.4.2 → 1.6.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
@@ -126,25 +126,38 @@ nk-pg-migrate --baseline # record the current file chain as applied, no DDL
126
126
  Unlike `drizzle-kit migrate` it surfaces the real Postgres error on failure,
127
127
  pre-flights journal drift (`MigrationDriftError` with a fix-it message instead
128
128
  of a confusing `relation already exists`), and serializes concurrent deploys
129
- with `pg_advisory_lock`. The same surface is available programmatically:
129
+ with `pg_advisory_lock`.
130
+
131
+ It also refuses to under-apply. drizzle's migrator picks what to run by
132
+ `when > max(created_at)`, so a migration whose journal timestamp lands below an
133
+ already-applied one is skipped **silently and permanently, reported as
134
+ success** — the shape two branches produce when they generate migrations and
135
+ merge in the other order. This runner computes pending as a set difference on
136
+ hash and throws `MigrationOrderError` naming the stranded migration and the
137
+ timestamp to clear; raising that entry's `when` in `meta/_journal.json` fixes it
138
+ without touching the `.sql`, so the hash every database recorded stays valid.
139
+ `--status` reports the same thing before you deploy.
140
+
141
+ The same surface is available programmatically:
130
142
  `runMigrations` / `inspectMigrations` / `baselineMigrations` from
131
143
  `@ingram-tech/nk-db/migrate`.
132
144
 
133
145
  ## Prefixed ids (`@ingram-tech/nk-db/id`)
134
146
 
135
- UUIDv7 minting (`uuidGenerateId`) plus a base58 "skin" for wire ids
136
- (`team_3nX…` ↔ stored UUID): `toPrefixedId` / `fromPrefixedId` / `base58Id`,
137
- and `createIdRegistry` for typed per-entity helpers.
147
+ The codec is the standalone [`id758`](https://github.com/ingram-technologies/id758)
148
+ package: `uuidv7()`, `encodeId` / `decodeId` / `mintId`, and `createIdRegistry`
149
+ for typed per-entity helpers. This subpath re-exports all of it, plus the
150
+ pre-extraction names (`uuidGenerateId`, `toPrefixedId`, `fromPrefixedId`,
151
+ `base58Id`) as deprecated aliases, so either import path works.
138
152
 
139
- **This module is isomorphic** zero imports, randomness from Web Crypto so a
153
+ **The module is isomorphic** (no imports, randomness from Web Crypto), so a
140
154
  Drizzle `schema.ts`, a client component or an edge runtime can all use it. Keep
141
155
  it that way: a single `node:crypto` import makes every module that touches an id
142
156
  node-only (a test enforces this).
143
157
 
144
- Store the raw `uuid` and skin at the edge. The prefixed id is presentation, not
158
+ Store the raw `uuid` and encode at the edge. The prefixed id is presentation, not
145
159
  identity: inside the DB, "which entity is this?" is already carried by the
146
- column, so storing the prefix duplicates schema metadata into every row and puts
147
- codec bugs permanently on disk.
160
+ column, so storing the prefix duplicates schema metadata into every row.
148
161
 
149
162
  **Ids are self-describing, uuids are not.** A prefix names its entity, so
150
163
  decoding needs no context — `entityOf(registry, id)` and `decodeAnyId(registry,
package/dist/id.d.ts CHANGED
@@ -1,134 +1,21 @@
1
1
  /**
2
- * The Ingram id codec a UUIDv7 and its base58 skin. It lives here in nk-db
3
- * (the lowest package in the graph) behind the `@ingram-tech/nk-db/id` subpath,
4
- * so it stays dependency-free no `pg` / `drizzle` — and any site can mint ids
5
- * without pulling a heavier slice.
2
+ * `@ingram-tech/nk-db/id`the fleet's id codec, now published standalone as
3
+ * [`id758`](https://github.com/ingram-technologies/id758). This subpath stays
4
+ * as the nextkit-facing entry point: it re-exports the whole `id758` surface
5
+ * plus the names nextkit sites adopted before the extraction, so nothing that
6
+ * imports from here needs to change. New code may import `id758` directly.
6
7
  *
7
- * **This module is isomorphic and must stay that way.** It has no imports at
8
- * all: randomness comes from Web Crypto (`crypto.getRandomValues`, a global on
9
- * Node 19+, Bun, Deno, edge runtimes and browsers), not `node:crypto`. That is
10
- * load-bearing, not incidental — a `node:crypto` import here makes every module
11
- * that touches an id node-only, which in practice means a Drizzle `schema.ts`
12
- * cannot encode/decode without dragging `node:crypto` into client bundles, and
13
- * sites end up dependency-injecting the codec to route around it. Keep the
14
- * import list empty.
15
- *
16
- * When a service has a non-JS twin of this codec (e.g. a Python API), keep its
17
- * byte string vectors identical to the ones in `id.test.ts`, so a stored
18
- * UUIDv7 and a prefixed base58 id are the same encoding of the same 16 bytes.
19
- * That cross-impl contract is the most important property of this file — keep
20
- * the vectors in lockstep.
21
- *
22
- * Store the hyphenated UUIDv7 at rest (uuid columns stay native and time-ordered
23
- * for index locality) and use {@link toPrefixedId} to skin it as a prefixed
24
- * base58 id for the wire / display, {@link fromPrefixedId} to recover it.
25
- * {@link base58Id} mints a fresh one directly; {@link createIdRegistry} builds a
26
- * typed, prefix-validated set of helpers for a project's entities.
27
- */
28
- /**
29
- * Mint a **UUIDv7** (RFC 9562): a 48-bit Unix-ms timestamp prefix + random tail,
30
- * version `7`, variant `10`. UUID-shaped (drops straight into a `uuid` column)
31
- * while staying time-ordered for index locality. Used as Better Auth's
32
- * `advanced.database.generateId`. Node/Bun's `randomUUID` is v4-only, so we lay
33
- * the bytes out by hand.
34
- */
35
- export declare const uuidGenerateId: () => Uuid;
36
- /** Skin a stored hyphenated UUIDv7 as a prefixed base58 id, e.g. `team_…`. */
37
- export declare function toPrefixedId(uuid: string, prefix: string): string;
38
- /** Inverse of {@link toPrefixedId}: recover the hyphenated UUIDv7. */
39
- export declare function fromPrefixedId(id: string): string;
40
- /** Mint a fresh prefixed base58 id (UUIDv7 core), for text-id sites / API parity. */
41
- export declare function base58Id(prefix: string): string;
42
- declare const ID_BRAND: unique symbol;
43
- declare const UUID_BRAND: unique symbol;
44
- /**
45
- * A prefixed base58 public id for entity `E` (e.g. `org_…`), branded by entity
46
- * so ids of different entities — and plain strings — can't be mixed silently. A
47
- * plain `string` at runtime; the brand is minted by a {@link createIdRegistry}
48
- * helper and erased on the wire.
49
- */
50
- export type Id<E extends string> = string & {
51
- readonly [ID_BRAND]: E;
52
- };
53
- /**
54
- * A hyphenated UUIDv7 at rest, branded distinct from a public {@link Id} so a
55
- * skinned id can't be fed into a uuid slot (or a uuid into an id slot) by
56
- * accident. Recovered from an {@link Id} by a registry helper's `decode`.
57
- */
58
- export type Uuid = string & {
59
- readonly [UUID_BRAND]: "Uuid";
60
- };
61
- /**
62
- * Whether `value` is a hyphenated uuid — the sanctioned string→{@link Uuid}
63
- * bless: narrowing through the shape check is never a blind cast. Use at trust
64
- * boundaries (env/config, external payloads, `crypto.randomUUID()`).
65
- */
66
- export declare const isUuid: (value: string | null | undefined) => value is Uuid;
67
- /** The throwing {@link isUuid}: bless a string you require to be a uuid. */
68
- export declare function asUuid(value: string): Uuid;
69
- /** Typed helpers for one entity's prefixed ids — built by {@link createIdRegistry}. */
70
- export interface IdHelper<E extends string = string> {
71
- /** This entity's prefix, e.g. `"agt"` (no trailing underscore). */
72
- readonly prefix: string;
73
- /** Mint a fresh prefixed id (new UUIDv7 core). */
74
- mint(): Id<E>;
75
- /** Skin a stored hyphenated UUIDv7 as this entity's prefixed id. */
76
- encode(uuid: string): Id<E>;
77
- /** Recover the hyphenated UUIDv7; throws if the prefix / shape doesn't match. */
78
- decode(id: string): Uuid;
79
- /**
80
- * Recover the hyphenated UUIDv7, or `null` if `id` isn't a well-formed
81
- * prefixed id for this entity. The throw-free {@link decode}, for validating
82
- * untrusted input (a path param, a query string) without a try/catch.
83
- */
84
- decodeOrNull(id: string): Uuid | null;
85
- /** Whether `id` is a well-formed prefixed id for this entity (narrows to {@link Id}). */
86
- is(id: string): id is Id<E>;
87
- }
88
- /** The map returned by {@link createIdRegistry}: one {@link IdHelper} per key. */
89
- export type IdRegistry<K extends string> = {
90
- [E in K]: IdHelper<E>;
91
- };
92
- /**
93
- * Build a typed, prefix-validated id registry for a project's entities — one
94
- * place to declare every prefix instead of hand-rolling encode/decode wrappers:
95
- *
96
- * ```ts
97
- * const ids = createIdRegistry({ org: "org", agent: "agt", session: "cs" });
98
- * ids.org.mint(); // "org_3k9…"
99
- * ids.org.encode(uuid); // "org_…"
100
- * ids.org.decode("org_…"); // uuid — throws on a wrong / missing prefix
101
- * ids.agent.is(someId); // boolean
102
- * ```
103
- */
104
- export declare function createIdRegistry<const T extends Record<string, string>>(prefixes: T): {
105
- [K in keyof T]: IdHelper;
106
- };
107
- /**
108
- * Which entity a prefixed id belongs to, or `null` if no helper in `registry`
109
- * recognises it (a raw uuid, a sentinel, a foreign prefix).
110
- *
111
- * A public id is **self-describing**: its prefix names its entity, so resolving
112
- * one needs no surrounding context. That is the property behind every
113
- * entity-agnostic decode — a polymorphic FK whose target is named by a sibling
114
- * `*_type` column, a raw-SQL binding that only has a value, a webhook payload.
115
- * The inverse does **not** hold: a bare uuid carries no entity, so encoding
116
- * always needs to know which entity you meant.
117
- *
118
- * Standalone rather than a registry method: the registry is keyed by entity
119
- * name, so a method would collide with an entity literally called `entityOf`.
120
- */
121
- export declare function entityOf<K extends string>(registry: Record<K, IdHelper>, value: string): K | null;
122
- /**
123
- * Decode a prefixed id belonging to **any** entity in `registry` (see
124
- * {@link entityOf}), for the boundaries that can't name one: polymorphic FKs,
125
- * raw-SQL id bindings, generic audit/event payloads.
126
- *
127
- * Tolerant by design — a value no helper recognises is returned unchanged, so an
128
- * already-decoded uuid passes straight through and this is safe to apply to a
129
- * value that may or may not be skinned. Use a helper's `decode`/`decodeOrNull`
130
- * when you know the entity and want a wrong prefix rejected.
131
- */
132
- export declare function decodeAnyId<K extends string>(registry: Record<K, IdHelper>, value: string): Uuid;
133
- export {};
8
+ * Like `id758` itself, this module must stay isomorphic (no node-only imports):
9
+ * it is pulled into Drizzle schemas, client components and edge runtimes.
10
+ */
11
+ export * from "id758";
12
+ import { decodeId, encodeId, mintId, uuidv7 } from "id758";
13
+ /** @deprecated Use `uuidv7` from `id758`. */
14
+ export declare const uuidGenerateId: typeof uuidv7;
15
+ /** @deprecated Use `encodeId` from `id758`. */
16
+ export declare const toPrefixedId: typeof encodeId;
17
+ /** @deprecated Use `decodeId` from `id758`. */
18
+ export declare const fromPrefixedId: typeof decodeId;
19
+ /** @deprecated Use `mintId` from `id758`. */
20
+ export declare const base58Id: typeof mintId;
134
21
  //# sourceMappingURL=id.d.ts.map
package/dist/id.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"id.d.ts","sourceRoot":"","sources":["../src/id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,QAAO,IAYjC,CAAC;AA0DF,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED,sEAAsE;AACtE,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAGjD;AAED,qFAAqF;AACrF,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,OAAO,CAAC,MAAM,QAAQ,EAAE,OAAO,MAAM,CAAC;AACtC,OAAO,CAAC,MAAM,UAAU,EAAE,OAAO,MAAM,CAAC;AAExC;;;;;GAKG;AACH,MAAM,MAAM,EAAE,CAAC,CAAC,SAAS,MAAM,IAAI,MAAM,GAAG;IAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;CAAE,CAAC;AAEvE;;;;GAIG;AACH,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAM9D;;;;GAIG;AACH,eAAO,MAAM,MAAM,UAAW,MAAM,GAAG,IAAI,GAAG,SAAS,KAAG,KAAK,IAAI,IAClB,CAAC;AAElD,4EAA4E;AAC5E,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAG1C;AAED,uFAAuF;AACvF,MAAM,WAAW,QAAQ,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IAClD,mEAAmE;IACnE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,kDAAkD;IAClD,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACd,oEAAoE;IACpE,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5B,iFAAiF;IACjF,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB;;;;OAIG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IACtC,yFAAyF;IACzF,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;CAC5B;AAED,kFAAkF;AAClF,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,MAAM,IAAI;KAAG,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC;CAAE,CAAC;AAmBrE;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACtE,QAAQ,EAAE,CAAC,GACT;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,QAAQ;CAAE,CAM9B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,MAAM,EACxC,QAAQ,EAAE,MAAM,CAAC,CAAC,EAAE,QAAQ,CAAC,EAC7B,KAAK,EAAE,MAAM,GACX,CAAC,GAAG,IAAI,CAOV;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAC3C,QAAQ,EAAE,MAAM,CAAC,CAAC,EAAE,QAAQ,CAAC,EAC7B,KAAK,EAAE,MAAM,GACX,IAAI,CAGN"}
1
+ {"version":3,"file":"id.d.ts","sourceRoot":"","sources":["../src/id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,cAAc,OAAO,CAAC;AACtB,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAE3D,6CAA6C;AAC7C,eAAO,MAAM,cAAc,eAAS,CAAC;AACrC,+CAA+C;AAC/C,eAAO,MAAM,YAAY,iBAAW,CAAC;AACrC,+CAA+C;AAC/C,eAAO,MAAM,cAAc,iBAAW,CAAC;AACvC,6CAA6C;AAC7C,eAAO,MAAM,QAAQ,eAAS,CAAC"}
package/dist/id.js CHANGED
@@ -1,204 +1,21 @@
1
1
  /**
2
- * The Ingram id codec a UUIDv7 and its base58 skin. It lives here in nk-db
3
- * (the lowest package in the graph) behind the `@ingram-tech/nk-db/id` subpath,
4
- * so it stays dependency-free no `pg` / `drizzle` — and any site can mint ids
5
- * without pulling a heavier slice.
2
+ * `@ingram-tech/nk-db/id`the fleet's id codec, now published standalone as
3
+ * [`id758`](https://github.com/ingram-technologies/id758). This subpath stays
4
+ * as the nextkit-facing entry point: it re-exports the whole `id758` surface
5
+ * plus the names nextkit sites adopted before the extraction, so nothing that
6
+ * imports from here needs to change. New code may import `id758` directly.
6
7
  *
7
- * **This module is isomorphic and must stay that way.** It has no imports at
8
- * all: randomness comes from Web Crypto (`crypto.getRandomValues`, a global on
9
- * Node 19+, Bun, Deno, edge runtimes and browsers), not `node:crypto`. That is
10
- * load-bearing, not incidental — a `node:crypto` import here makes every module
11
- * that touches an id node-only, which in practice means a Drizzle `schema.ts`
12
- * cannot encode/decode without dragging `node:crypto` into client bundles, and
13
- * sites end up dependency-injecting the codec to route around it. Keep the
14
- * import list empty.
15
- *
16
- * When a service has a non-JS twin of this codec (e.g. a Python API), keep its
17
- * byte → string vectors identical to the ones in `id.test.ts`, so a stored
18
- * UUIDv7 and a prefixed base58 id are the same encoding of the same 16 bytes.
19
- * That cross-impl contract is the most important property of this file — keep
20
- * the vectors in lockstep.
21
- *
22
- * Store the hyphenated UUIDv7 at rest (uuid columns stay native and time-ordered
23
- * for index locality) and use {@link toPrefixedId} to skin it as a prefixed
24
- * base58 id for the wire / display, {@link fromPrefixedId} to recover it.
25
- * {@link base58Id} mints a fresh one directly; {@link createIdRegistry} builds a
26
- * typed, prefix-validated set of helpers for a project's entities.
27
- */
28
- /**
29
- * Mint a **UUIDv7** (RFC 9562): a 48-bit Unix-ms timestamp prefix + random tail,
30
- * version `7`, variant `10`. UUID-shaped (drops straight into a `uuid` column)
31
- * while staying time-ordered for index locality. Used as Better Auth's
32
- * `advanced.database.generateId`. Node/Bun's `randomUUID` is v4-only, so we lay
33
- * the bytes out by hand.
34
- */
35
- export const uuidGenerateId = () => {
36
- const bytes = crypto.getRandomValues(new Uint8Array(16));
37
- const ts = Date.now();
38
- bytes[0] = Math.floor(ts / 2 ** 40) & 0xff;
39
- bytes[1] = Math.floor(ts / 2 ** 32) & 0xff;
40
- bytes[2] = Math.floor(ts / 2 ** 24) & 0xff;
41
- bytes[3] = Math.floor(ts / 2 ** 16) & 0xff;
42
- bytes[4] = Math.floor(ts / 2 ** 8) & 0xff;
43
- bytes[5] = ts & 0xff;
44
- bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x70; // version 7
45
- bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80; // variant 10
46
- return bytesToUuid(bytes); // mint site
47
- };
48
- const B58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
49
- // ceil(128 / log2(58)): a 16-byte value never needs more than 22 digits. We
50
- // left-pad to it so every body is uniform width and sorts lexically ==
51
- // chronologically (UUIDv7's ms-timestamp prefix lives in the high bytes).
52
- const WIDTH = 22;
53
- // A bare base58 body: 22 chars, Bitcoin alphabet (no 0 / I / O / l).
54
- const BODY = "[1-9A-HJ-NP-Za-km-z]{22}";
55
- /** Big-endian base58 (Bitcoin alphabet) of 16 bytes, left-padded to `WIDTH`. */
56
- function encode58(bytes) {
57
- let n = 0n;
58
- for (const b of bytes)
59
- n = (n << 8n) | BigInt(b);
60
- let out = "";
61
- while (n > 0n) {
62
- out = B58.charAt(Number(n % 58n)) + out;
63
- n /= 58n;
64
- }
65
- return out.padStart(WIDTH, B58.charAt(0));
66
- }
67
- /** Inverse of {@link encode58}: a base58 body back to 16 bytes. */
68
- function decode58(body) {
69
- let n = 0n;
70
- for (const ch of body) {
71
- const v = B58.indexOf(ch);
72
- if (v < 0)
73
- throw new Error(`invalid base58 char: ${ch}`);
74
- n = n * 58n + BigInt(v);
75
- }
76
- // 58^22 slightly exceeds 2^128, so a high-range 22-char body can overflow 16
77
- // bytes; silently truncating would alias two distinct wire ids to one UUID.
78
- if (n >= 1n << 128n)
79
- throw new Error(`base58 value out of uuid range: ${body}`);
80
- const bytes = new Uint8Array(16);
81
- for (let i = 15; i >= 0; i--) {
82
- bytes[i] = Number(n & 0xffn);
83
- n >>= 8n;
84
- }
85
- return bytes;
86
- }
87
- /** A hyphenated UUID string → its 16 raw bytes. */
88
- function uuidToBytes(uuid) {
89
- const hex = uuid.replace(/-/g, "");
90
- if (!/^[0-9a-fA-F]{32}$/.test(hex))
91
- throw new Error(`not a uuid: ${uuid}`);
92
- const bytes = new Uint8Array(16);
93
- for (let i = 0; i < 16; i++) {
94
- bytes[i] = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);
95
- }
96
- return bytes;
97
- }
98
- /** 16 raw bytes → a canonical hyphenated UUID string. */
99
- function bytesToUuid(bytes) {
100
- const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
101
- return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
102
- }
103
- /** Skin a stored hyphenated UUIDv7 as a prefixed base58 id, e.g. `team_…`. */
104
- export function toPrefixedId(uuid, prefix) {
105
- return `${prefix}_${encode58(uuidToBytes(uuid))}`;
106
- }
107
- /** Inverse of {@link toPrefixedId}: recover the hyphenated UUIDv7. */
108
- export function fromPrefixedId(id) {
109
- const body = id.slice(id.indexOf("_") + 1);
110
- return bytesToUuid(decode58(body));
111
- }
112
- /** Mint a fresh prefixed base58 id (UUIDv7 core), for text-id sites / API parity. */
113
- export function base58Id(prefix) {
114
- return toPrefixedId(uuidGenerateId(), prefix);
115
- }
116
- // Any RFC 9562 version (1-8): sites mint v7, but migrated rows are often v4.
117
- const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
118
- /**
119
- * Whether `value` is a hyphenated uuid — the sanctioned string→{@link Uuid}
120
- * bless: narrowing through the shape check is never a blind cast. Use at trust
121
- * boundaries (env/config, external payloads, `crypto.randomUUID()`).
122
- */
123
- export const isUuid = (value) => typeof value === "string" && UUID_RE.test(value);
124
- /** The throwing {@link isUuid}: bless a string you require to be a uuid. */
125
- export function asUuid(value) {
126
- if (!isUuid(value))
127
- throw new Error(`not a uuid: ${value}`);
128
- return value;
129
- }
130
- function makeHelper(prefix) {
131
- // Prefixes are developer-controlled identifier constants, never user input.
132
- const matcher = new RegExp(`^${prefix}_${BODY}$`);
133
- // The brands are erased at runtime; these casts are the sole mint sites.
134
- return {
135
- prefix,
136
- mint: () => base58Id(prefix),
137
- encode: (uuid) => toPrefixedId(uuid, prefix),
138
- decode: (id) => {
139
- if (!matcher.test(id))
140
- throw new Error(`not a ${prefix}_ id: ${id}`);
141
- return fromPrefixedId(id);
142
- },
143
- decodeOrNull: (id) => (matcher.test(id) ? fromPrefixedId(id) : null),
144
- is: (id) => matcher.test(id),
145
- };
146
- }
147
- /**
148
- * Build a typed, prefix-validated id registry for a project's entities — one
149
- * place to declare every prefix instead of hand-rolling encode/decode wrappers:
150
- *
151
- * ```ts
152
- * const ids = createIdRegistry({ org: "org", agent: "agt", session: "cs" });
153
- * ids.org.mint(); // "org_3k9…"
154
- * ids.org.encode(uuid); // "org_…"
155
- * ids.org.decode("org_…"); // uuid — throws on a wrong / missing prefix
156
- * ids.agent.is(someId); // boolean
157
- * ```
158
- */
159
- export function createIdRegistry(prefixes) {
160
- const reg = {};
161
- for (const [key, prefix] of Object.entries(prefixes)) {
162
- reg[key] = makeHelper(prefix);
163
- }
164
- return reg;
165
- }
166
- /**
167
- * Which entity a prefixed id belongs to, or `null` if no helper in `registry`
168
- * recognises it (a raw uuid, a sentinel, a foreign prefix).
169
- *
170
- * A public id is **self-describing**: its prefix names its entity, so resolving
171
- * one needs no surrounding context. That is the property behind every
172
- * entity-agnostic decode — a polymorphic FK whose target is named by a sibling
173
- * `*_type` column, a raw-SQL binding that only has a value, a webhook payload.
174
- * The inverse does **not** hold: a bare uuid carries no entity, so encoding
175
- * always needs to know which entity you meant.
176
- *
177
- * Standalone rather than a registry method: the registry is keyed by entity
178
- * name, so a method would collide with an entity literally called `entityOf`.
179
- */
180
- export function entityOf(registry, value) {
181
- // Cheap reject: every prefixed id has one, and raw uuids never do.
182
- if (!value.includes("_"))
183
- return null;
184
- for (const entity of Object.keys(registry)) {
185
- if (registry[entity].is(value))
186
- return entity;
187
- }
188
- return null;
189
- }
190
- /**
191
- * Decode a prefixed id belonging to **any** entity in `registry` (see
192
- * {@link entityOf}), for the boundaries that can't name one: polymorphic FKs,
193
- * raw-SQL id bindings, generic audit/event payloads.
194
- *
195
- * Tolerant by design — a value no helper recognises is returned unchanged, so an
196
- * already-decoded uuid passes straight through and this is safe to apply to a
197
- * value that may or may not be skinned. Use a helper's `decode`/`decodeOrNull`
198
- * when you know the entity and want a wrong prefix rejected.
8
+ * Like `id758` itself, this module must stay isomorphic (no node-only imports):
9
+ * it is pulled into Drizzle schemas, client components and edge runtimes.
199
10
  */
200
- export function decodeAnyId(registry, value) {
201
- const entity = entityOf(registry, value);
202
- return entity === null ? value : registry[entity].decode(value);
203
- }
11
+ export * from "id758";
12
+ import { decodeId, encodeId, mintId, uuidv7 } from "id758";
13
+ /** @deprecated Use `uuidv7` from `id758`. */
14
+ export const uuidGenerateId = uuidv7;
15
+ /** @deprecated Use `encodeId` from `id758`. */
16
+ export const toPrefixedId = encodeId;
17
+ /** @deprecated Use `decodeId` from `id758`. */
18
+ export const fromPrefixedId = decodeId;
19
+ /** @deprecated Use `mintId` from `id758`. */
20
+ export const base58Id = mintId;
204
21
  //# sourceMappingURL=id.js.map
package/dist/id.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"id.js","sourceRoot":"","sources":["../src/id.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"id.js","sourceRoot":"","sources":["../src/id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,cAAc,OAAO,CAAC;AACtB,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAE3D,6CAA6C;AAC7C,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC;AACrC,+CAA+C;AAC/C,MAAM,CAAC,MAAM,YAAY,GAAG,QAAQ,CAAC;AACrC,+CAA+C;AAC/C,MAAM,CAAC,MAAM,cAAc,GAAG,QAAQ,CAAC;AACvC,6CAA6C;AAC7C,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC"}
@@ -17,7 +17,7 @@
17
17
  // nk-pg-migrate --migrations <folder> (default: drizzle)
18
18
  //
19
19
  // Run directly by Node, so the relative import carries a `.js` extension.
20
- import { baselineMigrations, inspectMigrations, MigrationDriftError, runMigrations, } from "./migrate.js";
20
+ import { baselineMigrations, inspectMigrations, MigrationDriftError, MigrationOrderError, runMigrations, } from "./migrate.js";
21
21
  const argv = process.argv.slice(2);
22
22
  const flag = (name) => argv.includes(name);
23
23
  const value = (name) => {
@@ -40,6 +40,11 @@ const main = async () => {
40
40
  console.log(` drift: ${s.drift.reason}`);
41
41
  if (s.pending.length)
42
42
  console.log(` pending: ${s.pending.map((m) => m.tag).join(", ")}`);
43
+ if (s.unreachable.length) {
44
+ console.log(` UNREACHABLE (the migrator would skip these silently): ${s.unreachable.map((m) => m.tag).join(", ")}`);
45
+ }
46
+ if (s.journalIssues.length)
47
+ console.log(` journal: ${s.journalIssues.join("; ")}`);
43
48
  return;
44
49
  }
45
50
  if (flag("--baseline")) {
@@ -53,7 +58,7 @@ const main = async () => {
53
58
  : "nk-pg-migrate: up to date, nothing to apply.");
54
59
  };
55
60
  main().catch((error) => {
56
- if (error instanceof MigrationDriftError) {
61
+ if (error instanceof MigrationDriftError || error instanceof MigrationOrderError) {
57
62
  console.error(`nk-pg-migrate: ${error.message}`);
58
63
  process.exit(2);
59
64
  }
@@ -1 +1 @@
1
- {"version":3,"file":"migrate-bin.js","sourceRoot":"","sources":["../src/migrate-bin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"migrate-bin.js","sourceRoot":"","sources":["../src/migrate-bin.ts"],"names":[],"mappings":"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"}
package/dist/migrate.d.ts CHANGED
@@ -2,6 +2,8 @@ import type { Pool } from "pg";
2
2
  import { type CreatePoolConfig } from "./pool.js";
3
3
  /** One migration as recorded in `drizzle/meta/_journal.json` + its file hash. */
4
4
  export interface MigrationFileMeta {
5
+ /** Journal position. */
6
+ idx: number;
5
7
  /** Journal tag, e.g. `0003_illegal_jack_flag`. */
6
8
  tag: string;
7
9
  /** `sha256(fileContents)` — the exact value drizzle records, so our journal
@@ -40,8 +42,15 @@ export interface MigrationStatus {
40
42
  files: MigrationFileMeta[];
41
43
  /** Rows already in the journal table, oldest first. */
42
44
  recorded: RecordedMigration[];
43
- /** Files drizzle's migrator would apply next (folderMillis > max recorded). */
45
+ /** Files whose hash is not yet in the journal table — everything still to
46
+ * apply, by set difference rather than by timestamp (see {@link unreachable}). */
44
47
  pending: MigrationFileMeta[];
48
+ /** Pending files drizzle's migrator will never apply because their `when`
49
+ * doesn't beat the newest recorded `created_at`. Empty on a healthy chain. */
50
+ unreachable: MigrationFileMeta[];
51
+ /** Ordering defects in `meta/_journal.json` itself (non-increasing `when`,
52
+ * gaps or repeats in `idx`). */
53
+ journalIssues: string[];
45
54
  /** True when the journal table doesn't line up with the files (see {@link drift}). */
46
55
  drifted: boolean;
47
56
  drift?: MigrationDrift;
@@ -63,6 +72,27 @@ export declare class MigrationDriftError extends Error {
63
72
  readonly status: MigrationStatus;
64
73
  constructor(status: MigrationStatus);
65
74
  }
75
+ /**
76
+ * Thrown by {@link runMigrations} when the chain contains a migration the
77
+ * migrator would skip **silently and permanently**.
78
+ *
79
+ * drizzle's migrator applies exactly the files whose journal `when` is greater
80
+ * than the newest `created_at` in the journal table. A file below that mark
81
+ * that was never recorded — two branches generating migrations and merging in
82
+ * the other order, or a hand-edited `when` — is not applied, is not recorded,
83
+ * and is not drift: the recorded rows still match the files positionally, so
84
+ * the pre-flight passes and the run reports success having done nothing. The
85
+ * gap then persists for the life of the database.
86
+ *
87
+ * The fix is to renumber the stranded entry's `when` in `meta/_journal.json`
88
+ * past the newest applied migration. That edits the journal, not the `.sql`, so
89
+ * the file's hash — the thing every database recorded and `nk migrations`
90
+ * seals — is untouched.
91
+ */
92
+ export declare class MigrationOrderError extends Error {
93
+ readonly status: MigrationStatus;
94
+ constructor(status: MigrationStatus);
95
+ }
66
96
  export interface MigrateResult {
67
97
  /** Tags of the migrations applied by this run (empty when up to date). */
68
98
  applied: string[];
@@ -70,8 +100,10 @@ export interface MigrateResult {
70
100
  /**
71
101
  * Apply pending migrations with the real drizzle-orm migrator. Runs a drift
72
102
  * pre-flight first and throws {@link MigrationDriftError} (not a confusing
73
- * `already exists`) when the journal is out of sync. Surfaces the actual
74
- * Postgres error on a failing statement.
103
+ * `already exists`) when the journal is out of sync, and a
104
+ * {@link MigrationOrderError} when the chain contains a migration the migrator
105
+ * would skip silently. Surfaces the actual Postgres error on a failing
106
+ * statement.
75
107
  *
76
108
  * Concurrency-safe: the whole run (pre-flight + migrate) happens on one client
77
109
  * holding `pg_advisory_lock`, because drizzle's migrator takes no lock of its
@@ -1 +1 @@
1
- {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../src/migrate.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAG/B,OAAO,EAAE,KAAK,gBAAgB,EAAc,MAAM,WAAW,CAAC;AAE9D,iFAAiF;AACjF,MAAM,WAAW,iBAAiB;IACjC,kDAAkD;IAClD,GAAG,EAAE,MAAM,CAAC;IACZ;+DAC2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,YAAY,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IAClC,oDAAoD;IACpD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,0DAA0D;IAC1D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,aAAa,GAAG,gBAAgB,GAC3C,kBAAkB,GAAG;IACpB;;kEAE8D;IAC9D,IAAI,CAAC,EAAE,IAAI,CAAC;CACZ,CAAC;AAsBH;;;;GAIG;AACH,eAAO,MAAM,WAAW,sBACL,MAAM,KACtB,iBAAiB,EAcnB,CAAC;AAEF,0CAA0C;AAC1C,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC/B,mCAAmC;IACnC,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,uDAAuD;IACvD,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,+EAA+E;IAC/E,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,sFAAsF;IACtF,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,cAAc,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC7B;AA2DD;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,YACrB,aAAa,KACnB,OAAO,CAAC,eAAe,CAUzB,CAAC;AAgBF;8EAC8E;AAC9E,qBAAa,mBAAoB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,YAAY,MAAM,EAAE,eAAe,EAelC;CACD;AAED,MAAM,WAAW,aAAa;IAC7B,0EAA0E;IAC1E,OAAO,EAAE,MAAM,EAAE,CAAC;CAClB;AAQD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,aAAa,YACjB,aAAa,KACnB,OAAO,CAAC,aAAa,CAqCvB,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,YACtB,aAAa,KACnB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAmChC,CAAC"}
1
+ {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../src/migrate.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAG/B,OAAO,EAAE,KAAK,gBAAgB,EAAc,MAAM,WAAW,CAAC;AAE9D,iFAAiF;AACjF,MAAM,WAAW,iBAAiB;IACjC,wBAAwB;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,kDAAkD;IAClD,GAAG,EAAE,MAAM,CAAC;IACZ;+DAC2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,YAAY,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IAClC,oDAAoD;IACpD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,0DAA0D;IAC1D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,aAAa,GAAG,gBAAgB,GAC3C,kBAAkB,GAAG;IACpB;;kEAE8D;IAC9D,IAAI,CAAC,EAAE,IAAI,CAAC;CACZ,CAAC;AAsBH;;;;GAIG;AACH,eAAO,MAAM,WAAW,sBACL,MAAM,KACtB,iBAAiB,EAenB,CAAC;AA+BF,0CAA0C;AAC1C,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC/B,mCAAmC;IACnC,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,uDAAuD;IACvD,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B;uFACmF;IACnF,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B;mFAC+E;IAC/E,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC;qCACiC;IACjC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,sFAAsF;IACtF,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,cAAc,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC7B;AA2DD;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,YACrB,aAAa,KACnB,OAAO,CAAC,eAAe,CAUzB,CAAC;AA+BF;8EAC8E;AAC9E,qBAAa,mBAAoB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,YAAY,MAAM,EAAE,eAAe,EAelC;CACD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,YAAY,MAAM,EAAE,eAAe,EAmBlC;CACD;AAED,MAAM,WAAW,aAAa;IAC7B,0EAA0E;IAC1E,OAAO,EAAE,MAAM,EAAE,CAAC;CAClB;AAQD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,aAAa,YACjB,aAAa,KACnB,OAAO,CAAC,aAAa,CAwCvB,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,YACtB,aAAa,KACnB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAmChC,CAAC"}
package/dist/migrate.js CHANGED
@@ -1,5 +1,5 @@
1
- // Migration runner with drift detection — the framework answer to two recurring
2
- // pains with `drizzle-kit migrate`:
1
+ // Migration runner with drift detection — the framework answer to three
2
+ // recurring pains with `drizzle-kit migrate`:
3
3
  //
4
4
  // 1. It swallows the real database error and exits 1 opaquely ("applying
5
5
  // migrations..." then nothing). {@link runMigrations} uses drizzle-orm's
@@ -12,6 +12,11 @@
12
12
  // that explains exactly what happened and how to fix it, and
13
13
  // {@link baselineMigrations} reconciles a journal whose schema is already
14
14
  // correct without re-running any DDL.
15
+ // 3. It decides what to apply by `when > max(created_at)`, so a migration
16
+ // whose journal timestamp lands below an already-applied one is skipped
17
+ // **silently, permanently, and reported as success**. {@link runMigrations}
18
+ // computes pending as a set difference on hash instead, and throws a
19
+ // {@link MigrationOrderError} rather than under-applying.
15
20
  //
16
21
  // This module is node-only (pg + fs + the drizzle migrator); it is NOT exported
17
22
  // from the main entry, so a production bundle that only does runtime queries
@@ -53,12 +58,40 @@ export const readJournal = (migrationsFolder = DEFAULTS.migrationsFolder) => {
53
58
  return journal.entries.map((entry) => {
54
59
  const sql = readFileSync(join(migrationsFolder, `${entry.tag}.sql`), "utf8");
55
60
  return {
61
+ idx: entry.idx,
56
62
  tag: entry.tag,
57
63
  hash: createHash("sha256").update(sql).digest("hex"),
58
64
  folderMillis: entry.when,
59
65
  };
60
66
  });
61
67
  };
68
+ /**
69
+ * Journal integrity, checked on the files alone.
70
+ *
71
+ * Both properties the migrator silently depends on: drizzle decides what to
72
+ * apply by comparing `when` against the newest recorded `created_at` with a
73
+ * strict `>`, so a `when` that doesn't strictly increase down the journal marks
74
+ * a migration the migrator can never reach (see {@link MigrationOrderError}),
75
+ * and a gap or repeat in `idx` means the journal was hand-edited or merged
76
+ * badly and no longer describes one ordered chain.
77
+ */
78
+ const journalIssues = (files) => {
79
+ const issues = [];
80
+ for (let i = 1; i < files.length; i++) {
81
+ const prev = files[i - 1];
82
+ const cur = files[i];
83
+ if (!prev || !cur)
84
+ continue;
85
+ if (cur.folderMillis <= prev.folderMillis) {
86
+ issues.push(`${cur.tag} has when=${cur.folderMillis}, not after ${prev.tag}'s ${prev.folderMillis}`);
87
+ }
88
+ }
89
+ files.forEach((f, i) => {
90
+ if (f.idx !== i)
91
+ issues.push(`${f.tag} has idx=${f.idx} at journal position ${i}`);
92
+ });
93
+ return issues;
94
+ };
62
95
  const qualified = (schema, table) => `"${schema.replace(/"/g, '""')}"."${table.replace(/"/g, '""')}"`;
63
96
  /** Read the journal table; returns [] if it doesn't exist yet (fresh DB). */
64
97
  const readRecorded = async (pool, schema, table) => {
@@ -120,9 +153,23 @@ const inspectWith = async (db, folder, schema, table) => {
120
153
  const files = readJournal(folder);
121
154
  const recorded = await readRecorded(db, schema, table);
122
155
  const drift = detectDrift(files, recorded);
156
+ // Pending is a set difference on hash, NOT `folderMillis > max(created_at)`.
157
+ // The high-water mark is how drizzle's own migrator decides, and it is why
158
+ // `unreachable` has to be computed separately: a file below the mark whose
159
+ // hash was never recorded is not pending-and-waiting, it is pending-forever.
160
+ const appliedHashes = new Set(recorded.map((r) => r.hash));
161
+ const pending = files.filter((f) => !appliedHashes.has(f.hash));
123
162
  const maxRecorded = recorded.reduce((m, r) => Math.max(m, r.createdAt), 0);
124
- const pending = files.filter((f) => f.folderMillis > maxRecorded);
125
- return { files, recorded, pending, drifted: Boolean(drift), drift };
163
+ const unreachable = recorded.length > 0 ? pending.filter((f) => f.folderMillis <= maxRecorded) : [];
164
+ return {
165
+ files,
166
+ recorded,
167
+ pending,
168
+ unreachable,
169
+ journalIssues: journalIssues(files),
170
+ drifted: Boolean(drift),
171
+ drift,
172
+ };
126
173
  };
127
174
  /** Thrown by {@link runMigrations} when the journal is out of sync with the
128
175
  * files — applying would replay already-present DDL and fail confusingly. */
@@ -143,6 +190,42 @@ export class MigrationDriftError extends Error {
143
190
  this.status = status;
144
191
  }
145
192
  }
193
+ /**
194
+ * Thrown by {@link runMigrations} when the chain contains a migration the
195
+ * migrator would skip **silently and permanently**.
196
+ *
197
+ * drizzle's migrator applies exactly the files whose journal `when` is greater
198
+ * than the newest `created_at` in the journal table. A file below that mark
199
+ * that was never recorded — two branches generating migrations and merging in
200
+ * the other order, or a hand-edited `when` — is not applied, is not recorded,
201
+ * and is not drift: the recorded rows still match the files positionally, so
202
+ * the pre-flight passes and the run reports success having done nothing. The
203
+ * gap then persists for the life of the database.
204
+ *
205
+ * The fix is to renumber the stranded entry's `when` in `meta/_journal.json`
206
+ * past the newest applied migration. That edits the journal, not the `.sql`, so
207
+ * the file's hash — the thing every database recorded and `nk migrations`
208
+ * seals — is untouched.
209
+ */
210
+ export class MigrationOrderError extends Error {
211
+ status;
212
+ constructor(status) {
213
+ const stranded = status.unreachable.map((m) => `${m.tag} (when=${m.folderMillis})`);
214
+ const newest = status.recorded.reduce((m, r) => Math.max(m, r.createdAt), 0);
215
+ super([
216
+ `migration ordering: ${status.unreachable.length} unapplied migration(s) sit at or below the newest applied timestamp (${newest}), so the migrator would skip them and report success:`,
217
+ ` ${stranded.join("\n ")}`,
218
+ status.journalIssues.length
219
+ ? ` Journal defects: ${status.journalIssues.join("; ")}.`
220
+ : "",
221
+ ` Fix: raise each stranded entry's "when" in meta/_journal.json above ${newest} (and keep the journal's "when" values strictly increasing). That changes the journal, not the .sql — the file hash every database recorded stays the same.`,
222
+ ]
223
+ .filter(Boolean)
224
+ .join("\n"));
225
+ this.name = "MigrationOrderError";
226
+ this.status = status;
227
+ }
228
+ }
146
229
  // Advisory-lock identity for the migration runner (two arbitrary-but-stable
147
230
  // int32s, `classid`/`objid`). Session-scoped on the client that runs the whole
148
231
  // migration, so a crashed runner releases it with its connection.
@@ -151,8 +234,10 @@ const MIGRATE_LOCK_ID = 1;
151
234
  /**
152
235
  * Apply pending migrations with the real drizzle-orm migrator. Runs a drift
153
236
  * pre-flight first and throws {@link MigrationDriftError} (not a confusing
154
- * `already exists`) when the journal is out of sync. Surfaces the actual
155
- * Postgres error on a failing statement.
237
+ * `already exists`) when the journal is out of sync, and a
238
+ * {@link MigrationOrderError} when the chain contains a migration the migrator
239
+ * would skip silently. Surfaces the actual Postgres error on a failing
240
+ * statement.
156
241
  *
157
242
  * Concurrency-safe: the whole run (pre-flight + migrate) happens on one client
158
243
  * holding `pg_advisory_lock`, because drizzle's migrator takes no lock of its
@@ -177,6 +262,10 @@ export const runMigrations = async (config = {}) => {
177
262
  const status = await inspectWith(client, folder, schema, table);
178
263
  if (status.drifted)
179
264
  throw new MigrationDriftError(status);
265
+ // Refuse rather than silently under-apply: drizzle's migrator would
266
+ // skip these and report success. See {@link MigrationOrderError}.
267
+ if (status.unreachable.length > 0)
268
+ throw new MigrationOrderError(status);
180
269
  if (status.pending.length === 0)
181
270
  return { applied: [] };
182
271
  const { drizzle } = await import("drizzle-orm/node-postgres");
@@ -1 +1 @@
1
- {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../src/migrate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../src/migrate.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ingram-tech/nk-db",
3
- "version": "1.4.2",
3
+ "version": "1.6.0",
4
4
  "description": "The Ingram Postgres data layer: one TLS-aware pg pool, raw-SQL helpers, Drizzle wiring, and a PGlite (no-Docker) dev/test harness for Next.js sites.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -51,6 +51,7 @@
51
51
  "test": "vitest run"
52
52
  },
53
53
  "dependencies": {
54
+ "id758": "^1.0.0",
54
55
  "zod": "^4.4.3"
55
56
  },
56
57
  "peerDependencies": {
@@ -68,13 +69,13 @@
68
69
  }
69
70
  },
70
71
  "devDependencies": {
71
- "@electric-sql/pglite": "^0.5.4",
72
- "@electric-sql/pglite-socket": "^0.2.7",
73
- "@ingram-tech/nk-dev": "0.8.0",
74
- "@types/node": "^26.1.1",
75
- "@types/pg": "^8.20.0",
72
+ "@electric-sql/pglite": "^0.5.5",
73
+ "@electric-sql/pglite-socket": "^0.2.8",
74
+ "@ingram-tech/nk-dev": "0.11.1",
75
+ "@types/node": "^26.2.0",
76
+ "@types/pg": "^8.23.1",
76
77
  "drizzle-orm": "^0.45.2",
77
- "pg": "^8.22.0",
78
+ "pg": "^8.23.0",
78
79
  "typescript": "^7.0.2",
79
80
  "vitest": "^4.1.10"
80
81
  }