@fuzdev/fuz_app 0.101.0 → 0.101.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.
- package/dist/db/status.d.ts +42 -1
- package/dist/db/status.d.ts.map +1 -1
- package/dist/db/status.js +48 -5
- package/package.json +1 -1
package/dist/db/status.d.ts
CHANGED
|
@@ -4,10 +4,41 @@
|
|
|
4
4
|
* Queries migration state and table info without a running server.
|
|
5
5
|
* Returns structured data that consumer scripts can print however they like.
|
|
6
6
|
*
|
|
7
|
+
* The migration check is **name-divergence aware**: it name-prefix-verifies the
|
|
8
|
+
* applied migrations against the code's list (mirroring `run_migrations`), so a
|
|
9
|
+
* divergent history (same count, different names) reports a `divergence` and
|
|
10
|
+
* renders `DIVERGED` rather than a false `up_to_date`.
|
|
11
|
+
*
|
|
7
12
|
* @module
|
|
8
13
|
*/
|
|
9
14
|
import type { Db } from './db.js';
|
|
10
15
|
import type { MigrationNamespace } from './migrate.js';
|
|
16
|
+
/**
|
|
17
|
+
* A divergence between the recorded migration tracker and the code's list.
|
|
18
|
+
*
|
|
19
|
+
* Either variant is a state the migration runner refuses to boot against — a
|
|
20
|
+
* re-bootstrap (drop + migrate) is needed. Structured (not a pre-formatted
|
|
21
|
+
* string) so programmatic consumers can branch on `kind`; `format_db_status`
|
|
22
|
+
* renders the operator-facing line. The discriminated-union twin of the Rust
|
|
23
|
+
* `fuz_db` `Divergence` enum.
|
|
24
|
+
*/
|
|
25
|
+
export type Divergence = {
|
|
26
|
+
/** An applied name doesn't match the code's name at `position`. */
|
|
27
|
+
kind: 'name_mismatch';
|
|
28
|
+
/** Sequence position of the first mismatch. */
|
|
29
|
+
position: number;
|
|
30
|
+
/** The name recorded in the tracker at `position`. */
|
|
31
|
+
applied: string;
|
|
32
|
+
/** The name the code declares at `position`. */
|
|
33
|
+
expected: string;
|
|
34
|
+
} | {
|
|
35
|
+
/** The tracker records more migrations than the code declares. */
|
|
36
|
+
kind: 'binary_older';
|
|
37
|
+
/** Count recorded in the tracker. */
|
|
38
|
+
applied: number;
|
|
39
|
+
/** Count the code declares. */
|
|
40
|
+
declared: number;
|
|
41
|
+
};
|
|
11
42
|
/**
|
|
12
43
|
* Migration status for a single namespace.
|
|
13
44
|
*/
|
|
@@ -17,8 +48,18 @@ export interface MigrationStatus {
|
|
|
17
48
|
applied_names: Array<string>;
|
|
18
49
|
/** Names of code migrations not yet applied (suffix of the code array). */
|
|
19
50
|
pending_names: Array<string>;
|
|
20
|
-
/**
|
|
51
|
+
/**
|
|
52
|
+
* Whether `applied_names` is the full code array with no name divergence
|
|
53
|
+
* (no pending work, no diverged history).
|
|
54
|
+
*/
|
|
21
55
|
up_to_date: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* The first applied/code divergence, if any. Absent when the applied names
|
|
58
|
+
* are a clean prefix of the code's list (the only state the runner boots
|
|
59
|
+
* against). Present means a divergent bootstrap history — a re-bootstrap
|
|
60
|
+
* (drop + migrate) is needed.
|
|
61
|
+
*/
|
|
62
|
+
divergence?: Divergence;
|
|
22
63
|
}
|
|
23
64
|
/**
|
|
24
65
|
* Table info with row count.
|
package/dist/db/status.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/status.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,SAAS,CAAC;AAChC,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,cAAc,CAAC;AAErD;;;;;;;;GAQG;AACH,MAAM,MAAM,UAAU,GACnB;IACA,mEAAmE;IACnE,IAAI,EAAE,eAAe,CAAC;IACtB,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,OAAO,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC;CAChB,GACD;IACA,kEAAkE;IAClE,IAAI,EAAE,cAAc,CAAC;IACrB,qCAAqC;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;CAChB,CAAC;AAEL;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7B,2EAA2E;IAC3E,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7B;;;OAGG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACxB,yCAAyC;IACzC,SAAS,EAAE,OAAO,CAAC;IACnB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;IAC3B,sCAAsC;IACtC,UAAU,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC;IACnC;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC5B;AA8BD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,eAAe,GAC3B,IAAI,EAAE,EACN,aAAa,KAAK,CAAC,kBAAkB,CAAC,KACpC,OAAO,CAAC,QAAQ,CA2GlB,CAAC;AAeF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAAI,QAAQ,QAAQ,KAAG,MAoDnD,CAAC"}
|
package/dist/db/status.js
CHANGED
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
* Queries migration state and table info without a running server.
|
|
5
5
|
* Returns structured data that consumer scripts can print however they like.
|
|
6
6
|
*
|
|
7
|
+
* The migration check is **name-divergence aware**: it name-prefix-verifies the
|
|
8
|
+
* applied migrations against the code's list (mirroring `run_migrations`), so a
|
|
9
|
+
* divergent history (same count, different names) reports a `divergence` and
|
|
10
|
+
* renders `DIVERGED` rather than a false `up_to_date`.
|
|
11
|
+
*
|
|
7
12
|
* @module
|
|
8
13
|
*/
|
|
9
14
|
import { to_error_message } from '@fuzdev/fuz_util/error.ts';
|
|
@@ -78,14 +83,37 @@ export const query_db_status = async (db, namespaces) => {
|
|
|
78
83
|
ORDER BY sequence ASC`, [namespace]);
|
|
79
84
|
const applied_names = rows.map((r) => r.name);
|
|
80
85
|
const code_names = ns_migrations.map((m) => m.name);
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
86
|
+
const total = code_names.length;
|
|
87
|
+
const applied = applied_names.length;
|
|
88
|
+
// Name-prefix verify, mirroring the migration runner: the applied
|
|
89
|
+
// names must equal the first `applied` code names by position. A
|
|
90
|
+
// divergent history (a renamed/reordered migration, same count or not)
|
|
91
|
+
// is the exact state `run_migrations` refuses to boot against, so a
|
|
92
|
+
// count-only check would report a DB the runner rejects as up-to-date.
|
|
93
|
+
let divergence;
|
|
94
|
+
if (applied > total) {
|
|
95
|
+
divergence = { kind: 'binary_older', applied, declared: total };
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
const position = applied_names.findIndex((name, i) => name !== code_names[i]);
|
|
99
|
+
if (position !== -1) {
|
|
100
|
+
divergence = {
|
|
101
|
+
kind: 'name_mismatch',
|
|
102
|
+
position,
|
|
103
|
+
applied: applied_names[position],
|
|
104
|
+
expected: code_names[position],
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// pending = the suffix of code names past the applied count (clamped:
|
|
109
|
+
// a binary-older history has no pending tail)
|
|
110
|
+
const pending_names = code_names.slice(Math.min(applied, total));
|
|
84
111
|
migrations.push({
|
|
85
112
|
namespace,
|
|
86
113
|
applied_names,
|
|
87
114
|
pending_names,
|
|
88
|
-
up_to_date:
|
|
115
|
+
up_to_date: applied === total && pending_names.length === 0 && divergence === undefined,
|
|
116
|
+
...(divergence ? { divergence } : {}),
|
|
89
117
|
});
|
|
90
118
|
}
|
|
91
119
|
}
|
|
@@ -110,6 +138,18 @@ export const query_db_status = async (db, namespaces) => {
|
|
|
110
138
|
...(old_tracker_shape ? { old_tracker_shape: true } : {}),
|
|
111
139
|
};
|
|
112
140
|
};
|
|
141
|
+
/**
|
|
142
|
+
* Render a `Divergence` as the operator-facing detail line. Twin of the Rust
|
|
143
|
+
* `Divergence` `Display`.
|
|
144
|
+
*/
|
|
145
|
+
const format_divergence = (divergence) => {
|
|
146
|
+
switch (divergence.kind) {
|
|
147
|
+
case 'name_mismatch':
|
|
148
|
+
return `position ${divergence.position}: database has '${divergence.applied}', code has '${divergence.expected}'`;
|
|
149
|
+
case 'binary_older':
|
|
150
|
+
return `database has ${divergence.applied} applied but code declares ${divergence.declared} (binary older than database)`;
|
|
151
|
+
}
|
|
152
|
+
};
|
|
113
153
|
/**
|
|
114
154
|
* Format a `DbStatus` as a human-readable string for CLI output.
|
|
115
155
|
*
|
|
@@ -141,7 +181,10 @@ export const format_db_status = (status) => {
|
|
|
141
181
|
lines.push(' Migrations:');
|
|
142
182
|
for (const m of status.migrations) {
|
|
143
183
|
const total = m.applied_names.length + m.pending_names.length;
|
|
144
|
-
if (m.
|
|
184
|
+
if (m.divergence) {
|
|
185
|
+
lines.push(` ${m.namespace}: DIVERGED (${m.applied_names.length}/${total}) — ${format_divergence(m.divergence)}`);
|
|
186
|
+
}
|
|
187
|
+
else if (m.up_to_date) {
|
|
145
188
|
lines.push(` ${m.namespace}: up to date (${m.applied_names.length}/${total})`);
|
|
146
189
|
}
|
|
147
190
|
else {
|