@intentius/sql-yodeler 0.2.0 → 0.3.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 +3 -3
- package/dist/chant/build.js +7 -0
- package/dist/chant/build.js.map +1 -1
- package/dist/ci/render.d.ts +289 -0
- package/dist/ci/render.js +688 -0
- package/dist/ci/render.js.map +1 -0
- package/dist/ci/replay.d.ts +17 -0
- package/dist/ci/replay.js +69 -0
- package/dist/ci/replay.js.map +1 -0
- package/dist/commands/apply.d.ts +113 -0
- package/dist/commands/apply.js +228 -21
- package/dist/commands/apply.js.map +1 -1
- package/dist/commands/approve.js +44 -0
- package/dist/commands/approve.js.map +1 -1
- package/dist/commands/checkpoint.d.ts +3 -0
- package/dist/commands/checkpoint.js +78 -0
- package/dist/commands/checkpoint.js.map +1 -0
- package/dist/commands/ci.d.ts +3 -0
- package/dist/commands/ci.js +118 -0
- package/dist/commands/ci.js.map +1 -0
- package/dist/commands/docs.d.ts +11 -0
- package/dist/commands/docs.js +108 -0
- package/dist/commands/docs.js.map +1 -0
- package/dist/commands/drift.d.ts +13 -1
- package/dist/commands/drift.js +18 -2
- package/dist/commands/drift.js.map +1 -1
- package/dist/commands/index.js +10 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/init.js +1 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/lint.js +11 -3
- package/dist/commands/lint.js.map +1 -1
- package/dist/commands/override.js +48 -16
- package/dist/commands/override.js.map +1 -1
- package/dist/commands/plan.js +5 -1
- package/dist/commands/plan.js.map +1 -1
- package/dist/commands/report.d.ts +13 -0
- package/dist/commands/report.js +121 -0
- package/dist/commands/report.js.map +1 -0
- package/dist/commands/revert.d.ts +20 -0
- package/dist/commands/revert.js +246 -0
- package/dist/commands/revert.js.map +1 -0
- package/dist/commands/status.js +32 -5
- package/dist/commands/status.js.map +1 -1
- package/dist/config/base.d.ts +69 -0
- package/dist/config/base.js +121 -0
- package/dist/config/base.js.map +1 -0
- package/dist/config/define.d.ts +123 -1
- package/dist/config/define.js +2 -0
- package/dist/config/define.js.map +1 -1
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.js +2 -0
- package/dist/config/index.js.map +1 -1
- package/dist/config/load.d.ts +1 -1
- package/dist/config/load.js +90 -5
- package/dist/config/load.js.map +1 -1
- package/dist/config/settings.d.ts +4 -1
- package/dist/config/settings.js +8 -2
- package/dist/config/settings.js.map +1 -1
- package/dist/exit.js +1 -1
- package/dist/exit.js.map +1 -1
- package/dist/history/postgres/ddl.d.ts +18 -0
- package/dist/history/postgres/ddl.js +27 -2
- package/dist/history/postgres/ddl.js.map +1 -1
- package/dist/history/postgres/store.d.ts +2 -0
- package/dist/history/postgres/store.js +7 -1
- package/dist/history/postgres/store.js.map +1 -1
- package/dist/history/rows.d.ts +16 -3
- package/dist/history/rows.js +30 -1
- package/dist/history/rows.js.map +1 -1
- package/dist/history/store.d.ts +2 -0
- package/dist/history/store.js +2 -2
- package/dist/history/store.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/lint/check.js +17 -2
- package/dist/lint/check.js.map +1 -1
- package/dist/lint/report.js +1 -1
- package/dist/lint/report.js.map +1 -1
- package/dist/lint/routines.d.ts +26 -0
- package/dist/lint/routines.js +65 -0
- package/dist/lint/routines.js.map +1 -0
- package/dist/lint/rules.d.ts +16 -4
- package/dist/lint/rules.js +9 -4
- package/dist/lint/rules.js.map +1 -1
- package/dist/mcp/tools.d.ts +1 -1
- package/dist/mcp/tools.js +1 -1
- package/dist/mcp/tools.js.map +1 -1
- package/dist/migrations/checkpoint.d.ts +45 -0
- package/dist/migrations/checkpoint.js +110 -0
- package/dist/migrations/checkpoint.js.map +1 -0
- package/dist/migrations/create.js +2 -0
- package/dist/migrations/create.js.map +1 -1
- package/dist/migrations/document.d.ts +10 -0
- package/dist/migrations/document.js +1 -0
- package/dist/migrations/document.js.map +1 -1
- package/dist/migrations/index.d.ts +2 -0
- package/dist/migrations/index.js +2 -0
- package/dist/migrations/index.js.map +1 -1
- package/dist/migrations/routines.d.ts +31 -0
- package/dist/migrations/routines.js +55 -0
- package/dist/migrations/routines.js.map +1 -0
- package/dist/notify/index.d.ts +124 -0
- package/dist/notify/index.js +210 -0
- package/dist/notify/index.js.map +1 -0
- package/dist/notify/verify.d.ts +53 -0
- package/dist/notify/verify.js +71 -0
- package/dist/notify/verify.js.map +1 -0
- package/dist/pr/model.d.ts +3 -0
- package/dist/pr/model.js +16 -2
- package/dist/pr/model.js.map +1 -1
- package/dist/pr/render.js +27 -1
- package/dist/pr/render.js.map +1 -1
- package/dist/project.d.ts +19 -2
- package/dist/project.js +33 -1
- package/dist/project.js.map +1 -1
- package/dist/replay/replay.d.ts +9 -1
- package/dist/replay/replay.js +62 -31
- package/dist/replay/replay.js.map +1 -1
- package/dist/replay/report.js +1 -1
- package/dist/replay/report.js.map +1 -1
- package/dist/report/audit.d.ts +138 -0
- package/dist/report/audit.js +202 -0
- package/dist/report/audit.js.map +1 -0
- package/dist/report/jsonl.d.ts +21 -0
- package/dist/report/jsonl.js +52 -0
- package/dist/report/jsonl.js.map +1 -0
- package/dist/report/model.d.ts +68 -0
- package/dist/report/model.js +127 -0
- package/dist/report/model.js.map +1 -0
- package/dist/report/render.d.ts +18 -0
- package/dist/report/render.js +127 -0
- package/dist/report/render.js.map +1 -0
- package/dist/schema-docs/render.d.ts +49 -0
- package/dist/schema-docs/render.js +359 -0
- package/dist/schema-docs/render.js.map +1 -0
- package/dist/schemas.d.ts +5 -2
- package/dist/schemas.js +5 -2
- package/dist/schemas.js.map +1 -1
- package/dist/sources/ddl.d.ts +53 -0
- package/dist/sources/ddl.js +347 -0
- package/dist/sources/ddl.js.map +1 -0
- package/dist/sources/index.d.ts +69 -0
- package/dist/sources/index.js +170 -0
- package/dist/sources/index.js.map +1 -0
- package/dist/steps/postgres-migration.d.ts +35 -25
- package/dist/steps/postgres-migration.js +42 -29
- package/dist/steps/postgres-migration.js.map +1 -1
- package/dist/tenants/index.d.ts +40 -0
- package/dist/tenants/index.js +122 -0
- package/dist/tenants/index.js.map +1 -0
- package/dist/tenants/target.d.ts +23 -0
- package/dist/tenants/target.js +29 -0
- package/dist/tenants/target.js.map +1 -0
- package/dist/versioned/engine.d.ts +6 -0
- package/dist/versioned/engine.js +12 -2
- package/dist/versioned/engine.js.map +1 -1
- package/dist/versioned/index.d.ts +1 -0
- package/dist/versioned/index.js +1 -0
- package/dist/versioned/index.js.map +1 -1
- package/dist/versioned/op.d.ts +6 -1
- package/dist/versioned/op.js +7 -2
- package/dist/versioned/op.js.map +1 -1
- package/dist/versioned/policy.d.ts +33 -2
- package/dist/versioned/policy.js +59 -8
- package/dist/versioned/policy.js.map +1 -1
- package/dist/versioned/report.js +9 -0
- package/dist/versioned/report.js.map +1 -1
- package/dist/versioned/revert.d.ts +128 -0
- package/dist/versioned/revert.js +251 -0
- package/dist/versioned/revert.js.map +1 -0
- package/dist/versioned/state.d.ts +25 -0
- package/dist/versioned/state.js +36 -3
- package/dist/versioned/state.js.map +1 -1
- package/dist/waves/index.d.ts +179 -0
- package/dist/waves/index.js +268 -0
- package/dist/waves/index.js.map +1 -0
- package/dist/waves/promotion.d.ts +56 -0
- package/dist/waves/promotion.js +108 -0
- package/dist/waves/promotion.js.map +1 -0
- package/dist/waves/record.d.ts +24 -0
- package/dist/waves/record.js +20 -0
- package/dist/waves/record.js.map +1 -0
- package/package.json +11 -7
- package/schemas/apply.schema.json +162 -3
- package/schemas/checkpoint.schema.json +19 -0
- package/schemas/drift.schema.json +26 -1
- package/schemas/event.schema.json +36 -0
- package/schemas/lint.schema.json +4 -0
- package/schemas/plan.schema.json +118 -0
- package/schemas/report.schema.json +114 -0
- package/schemas/revert.schema.json +69 -0
- package/schemas/status.schema.json +64 -3
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The audit log (#57), derived and never written by hand: every entry comes
|
|
3
|
+
* from a row of an environment's history table or a line of chant's gate
|
|
4
|
+
* ledger (`_gates/<op>.jsonl` on the `chant/lifecycle` branch), so the log
|
|
5
|
+
* cannot say something those two do not. Pure: rows and ledger lines in,
|
|
6
|
+
* entries and gaps out.
|
|
7
|
+
*
|
|
8
|
+
* Entries, by where they come from:
|
|
9
|
+
*
|
|
10
|
+
* | kind | source |
|
|
11
|
+
* |----------------------|---------------------------------------------------------------|
|
|
12
|
+
* | `approval-requested` | a pending fact on the ledger: a run stopped at the gate |
|
|
13
|
+
* | `approved` | a resolution of the migrations Op's gate |
|
|
14
|
+
* | `override` | a resolution of an `override-<rule>` gate (`yodel override`) |
|
|
15
|
+
* | `silenced` | a `-- yodel:allow` silence on a migration's first started row |
|
|
16
|
+
* | `applied` | the migration row that first recorded a migration succeeded |
|
|
17
|
+
* | `refused` | a failed migration row naming a pre-migration check |
|
|
18
|
+
* | `failed` | any other failed migration row |
|
|
19
|
+
* | `repaired` | a succeeded migration row after it was applied (`yodel repair`) |
|
|
20
|
+
*
|
|
21
|
+
* Each entry's `id` is a hash of what it says and where it came from, so
|
|
22
|
+
* deriving again from the same sources gives the same ids, and an audit.jsonl
|
|
23
|
+
* written earlier can be checked against the sources now (`./jsonl.ts`).
|
|
24
|
+
*
|
|
25
|
+
* Gaps are what the sources show is missing from themselves:
|
|
26
|
+
*
|
|
27
|
+
* - `history-row`: the history's seqs run from 1 with no hole (every run
|
|
28
|
+
* appends at the highest seq plus one, under the lock); a hole is a row
|
|
29
|
+
* that was deleted.
|
|
30
|
+
* - `approval`: a migration applied under a plan digest that the ledger
|
|
31
|
+
* holds no approval of the environment's gate for. A baseline (`yodel init
|
|
32
|
+
* --from`, no digest) needs none. A migration a wave of the apply pipeline
|
|
33
|
+
* applied (#87) was approved on the wave's gate (`<op>-wave-<k>`), for the
|
|
34
|
+
* wave's set digest its `started` row records (`note.wave`); a wave whose
|
|
35
|
+
* policy at the base needed no approval records that instead, and needs
|
|
36
|
+
* none.
|
|
37
|
+
*/
|
|
38
|
+
import { createHash } from "node:crypto";
|
|
39
|
+
import { waveRecordOf } from "../waves/record.js";
|
|
40
|
+
export const AUDIT_KINDS = ["approval-requested", "approved", "override", "silenced", "applied", "refused", "failed", "repaired", "reverted"];
|
|
41
|
+
/** `2026-10-10 09:12:44.123456` (the history's UTC) as ISO 8601. An ISO time is returned as it is. */
|
|
42
|
+
export function isoTime(t) {
|
|
43
|
+
if (!t)
|
|
44
|
+
return "";
|
|
45
|
+
if (/T.*(Z|[+-]\d\d:?\d\d)$/.test(t))
|
|
46
|
+
return t;
|
|
47
|
+
return `${t.replace(" ", "T")}Z`;
|
|
48
|
+
}
|
|
49
|
+
/** A key that orders ISO times written to the millisecond (the ledger) and the microsecond (the history) together. */
|
|
50
|
+
export function timeKey(t) {
|
|
51
|
+
const m = /^(.*?)(?:\.(\d+))?Z$/.exec(t);
|
|
52
|
+
return m ? `${m[1] ?? ""}.${(m[2] ?? "").padEnd(6, "0")}Z` : t;
|
|
53
|
+
}
|
|
54
|
+
/** Oldest first. */
|
|
55
|
+
export const byTime = (a, b) => {
|
|
56
|
+
const x = timeKey(a.at);
|
|
57
|
+
const y = timeKey(b.at);
|
|
58
|
+
return x < y ? -1 : x > y ? 1 : 0;
|
|
59
|
+
};
|
|
60
|
+
function entry(fields) {
|
|
61
|
+
// An entry with no wave hashes as it did before waves were recorded, so audit files written then still match.
|
|
62
|
+
const key = JSON.stringify([fields.environment, fields.kind, fields.at, fields.by ?? "", fields.migration ?? "", fields.digest ?? "", fields.detail ?? "", fields.source, ...(fields.wave ? [fields.wave] : [])]);
|
|
63
|
+
return { id: `sha256:${createHash("sha256").update(key).digest("hex").slice(0, 24)}`, ...fields };
|
|
64
|
+
}
|
|
65
|
+
const CHECK_FAILED = /\bcheck \S+ failed\b/;
|
|
66
|
+
function fromHistory(input) {
|
|
67
|
+
const { environment, history } = input;
|
|
68
|
+
const out = [];
|
|
69
|
+
const applied = new Set();
|
|
70
|
+
const silenced = new Set();
|
|
71
|
+
/** Each migration's wave, from its latest started row. */
|
|
72
|
+
const waveOf = new Map();
|
|
73
|
+
for (const r of [...input.rows].sort((a, b) => a.seq - b.seq)) {
|
|
74
|
+
if (r.kind !== "migration")
|
|
75
|
+
continue;
|
|
76
|
+
const source = { history, seq: r.seq, run: r.run_id };
|
|
77
|
+
const base = { at: isoTime(r.recorded_at ?? ""), environment, by: r.applied_by, migration: r.migration_id, ...(r.plan_digest ? { digest: r.plan_digest } : {}), source };
|
|
78
|
+
if (r.status === "started") {
|
|
79
|
+
const w = waveRecordOf(r.note);
|
|
80
|
+
if (w)
|
|
81
|
+
waveOf.set(r.migration_id, { gate: w.gate, digest: w.digest, status: w.status });
|
|
82
|
+
else
|
|
83
|
+
waveOf.delete(r.migration_id);
|
|
84
|
+
let list = [];
|
|
85
|
+
try {
|
|
86
|
+
list = JSON.parse(r.silences || "[]");
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
list = [];
|
|
90
|
+
}
|
|
91
|
+
for (const s of list) {
|
|
92
|
+
const key = `${r.migration_id}\u0000${String(s.step)}\u0000${s.rule ?? ""}\u0000${s.reason ?? ""}`;
|
|
93
|
+
if (silenced.has(key))
|
|
94
|
+
continue;
|
|
95
|
+
silenced.add(key);
|
|
96
|
+
out.push(entry({ ...base, kind: "silenced", detail: `step ${String(s.step)}: ${s.rule ?? ""} ${s.reason ?? ""}`.trim() }));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else if (r.status === "reverted") {
|
|
100
|
+
// yodel revert (#55): applied again later, it is applied, not repaired.
|
|
101
|
+
applied.delete(r.migration_id);
|
|
102
|
+
out.push(entry({ ...base, kind: "reverted", ...(r.note ? { detail: r.note } : {}) }));
|
|
103
|
+
}
|
|
104
|
+
else if (r.status === "succeeded") {
|
|
105
|
+
if (applied.has(r.migration_id))
|
|
106
|
+
out.push(entry({ ...base, kind: "repaired", detail: r.note || `checksum ${r.checksum}` }));
|
|
107
|
+
else {
|
|
108
|
+
applied.add(r.migration_id);
|
|
109
|
+
const wave = waveOf.get(r.migration_id);
|
|
110
|
+
out.push(entry({ ...base, kind: "applied", ...(r.note ? { detail: r.note } : {}), ...(wave ? { wave } : {}) }));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
out.push(entry({ ...base, kind: CHECK_FAILED.test(r.error) ? "refused" : "failed", detail: r.error }));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return out;
|
|
118
|
+
}
|
|
119
|
+
function fromLedger(environment, l) {
|
|
120
|
+
const out = [];
|
|
121
|
+
const source = { ledger: l.path, op: l.op, gate: l.gate };
|
|
122
|
+
for (const p of l.pending) {
|
|
123
|
+
if (p.gate !== l.gate)
|
|
124
|
+
continue;
|
|
125
|
+
out.push(entry({ at: p.timestamp, environment, kind: "approval-requested", ...(p.planDigest ? { digest: p.planDigest } : {}), ...(p.runId ? { detail: `run ${p.runId}` } : {}), source }));
|
|
126
|
+
}
|
|
127
|
+
for (const r of l.resolutions) {
|
|
128
|
+
const override = r.gate.startsWith("override-");
|
|
129
|
+
if (!override && r.gate !== l.gate)
|
|
130
|
+
continue;
|
|
131
|
+
out.push(entry({
|
|
132
|
+
at: r.timestamp,
|
|
133
|
+
environment,
|
|
134
|
+
kind: override ? "override" : "approved",
|
|
135
|
+
by: r.resolvedBy,
|
|
136
|
+
...(r.planDigest ? { digest: r.planDigest } : {}),
|
|
137
|
+
...(override ? { detail: `${r.gate.slice("override-".length)}: ${r.note ?? ""}`.trim() } : r.note ? { detail: r.note } : {}),
|
|
138
|
+
source: { ...source, gate: r.gate },
|
|
139
|
+
}));
|
|
140
|
+
}
|
|
141
|
+
return out;
|
|
142
|
+
}
|
|
143
|
+
/** The wave gates' lines that are this environment's: its configured wave gate, and every gate its history's waves recorded. */
|
|
144
|
+
function fromWaves(environment, w, history) {
|
|
145
|
+
const gates = new Set([...(w.gate ? [w.gate] : []), ...history.flatMap((e) => (e.wave ? [e.wave.gate] : []))]);
|
|
146
|
+
const out = [];
|
|
147
|
+
for (const gate of gates)
|
|
148
|
+
out.push(...fromLedger(environment, { op: w.op, gate, path: w.path, pending: w.pending, resolutions: w.resolutions.filter((r) => !r.gate.startsWith("override-")) }));
|
|
149
|
+
return out;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* The approval an `applied` entry was let through by, among `entries`: on
|
|
153
|
+
* the wave's gate for the wave's set digest when a wave applied it, else
|
|
154
|
+
* on the migrations gate for its plan digest. Undefined when none is there.
|
|
155
|
+
*/
|
|
156
|
+
export function approvalOf(applied, entries, same = (a, b) => a === b) {
|
|
157
|
+
const approvals = entries.filter((e) => e.kind === "approved" && e.environment === applied.environment);
|
|
158
|
+
const wave = applied.wave;
|
|
159
|
+
if (wave)
|
|
160
|
+
return approvals.filter((x) => "ledger" in x.source && x.source.gate === wave.gate && same(x.digest, wave.digest)).at(-1);
|
|
161
|
+
return approvals.filter((x) => same(x.digest, applied.digest)).at(-1);
|
|
162
|
+
}
|
|
163
|
+
/** The entries one environment's history and ledger add up to, oldest first, and the gaps they show. */
|
|
164
|
+
export function deriveAudit(input) {
|
|
165
|
+
const same = input.sameDigest ?? ((a, b) => a === b);
|
|
166
|
+
const history = fromHistory(input);
|
|
167
|
+
const entries = [...history, ...(input.ledger ? fromLedger(input.environment, input.ledger) : []), ...(input.waves ? fromWaves(input.environment, input.waves, history) : [])].sort(byTime);
|
|
168
|
+
const gaps = [];
|
|
169
|
+
const seqs = new Set(input.rows.map((r) => r.seq));
|
|
170
|
+
const max = Math.max(0, ...seqs);
|
|
171
|
+
const missing = [];
|
|
172
|
+
for (let s = 1; s <= max; s++)
|
|
173
|
+
if (!seqs.has(s))
|
|
174
|
+
missing.push(s);
|
|
175
|
+
if (missing.length > 0) {
|
|
176
|
+
gaps.push({ environment: input.environment, kind: "history-row", detail: `${input.history} has no row with seq ${missing.join(", ")} of 1..${String(max)}: rows are only ever appended, so ${missing.length === 1 ? "that row was" : "those rows were"} deleted` });
|
|
177
|
+
}
|
|
178
|
+
for (const a of entries.filter((e) => (e.kind === "applied" || e.kind === "reverted") && e.digest)) {
|
|
179
|
+
const seq = "history" in a.source ? a.source.seq : 0;
|
|
180
|
+
const wave = a.wave;
|
|
181
|
+
if (wave) {
|
|
182
|
+
// A wave's policy at the base let it through with no approval; the run checked that under the lock.
|
|
183
|
+
if (wave.status === "not-required" || !input.waves || approvalOf(a, entries, same))
|
|
184
|
+
continue;
|
|
185
|
+
gaps.push({
|
|
186
|
+
environment: input.environment,
|
|
187
|
+
kind: "approval",
|
|
188
|
+
detail: `${String(a.migration)} was applied by a wave under ${wave.digest} (${input.history} seq ${String(seq)}), but ${input.waves.path} holds no approval of ${input.waves.op} / ${wave.gate} for that digest`,
|
|
189
|
+
});
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
if (!input.ledger || approvalOf(a, entries, same))
|
|
193
|
+
continue;
|
|
194
|
+
gaps.push({
|
|
195
|
+
environment: input.environment,
|
|
196
|
+
kind: "approval",
|
|
197
|
+
detail: `${String(a.migration)} was ${a.kind} under ${String(a.digest)} (${input.history} seq ${String(seq)}), but ${input.ledger.path} holds no approval of ${input.ledger.op} / ${input.ledger.gate} for that digest`,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
return { entries, gaps };
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/report/audit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* audit.jsonl (#57): the derived audit log kept as a file, one entry per
|
|
3
|
+
* line, only ever appended to. `yodel report --audit <file>` appends the
|
|
4
|
+
* entries the sources hold that the file does not; `--check` appends nothing
|
|
5
|
+
* and names every entry of the file that the sources no longer give, which
|
|
6
|
+
* is a ledger line or a history row removed since the file was written.
|
|
7
|
+
*/
|
|
8
|
+
import type { AuditEntry } from "./audit.js";
|
|
9
|
+
export interface AuditFile {
|
|
10
|
+
path: string;
|
|
11
|
+
entries: AuditEntry[];
|
|
12
|
+
}
|
|
13
|
+
export declare function readAuditFile(path: string): AuditFile;
|
|
14
|
+
/** Compares the file with what the sources give now, for the environments read. */
|
|
15
|
+
export declare function compareAudit(file: AuditFile, derived: readonly AuditEntry[], environments: readonly string[]): {
|
|
16
|
+
missing: AuditEntry[];
|
|
17
|
+
added: AuditEntry[];
|
|
18
|
+
};
|
|
19
|
+
export declare function appendAudit(path: string, entries: readonly AuditEntry[]): void;
|
|
20
|
+
/** One line for a missing entry. */
|
|
21
|
+
export declare function describeEntry(e: AuditEntry): string;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* audit.jsonl (#57): the derived audit log kept as a file, one entry per
|
|
3
|
+
* line, only ever appended to. `yodel report --audit <file>` appends the
|
|
4
|
+
* entries the sources hold that the file does not; `--check` appends nothing
|
|
5
|
+
* and names every entry of the file that the sources no longer give, which
|
|
6
|
+
* is a ledger line or a history row removed since the file was written.
|
|
7
|
+
*/
|
|
8
|
+
import { appendFileSync, existsSync, readFileSync } from "node:fs";
|
|
9
|
+
import { YodelError } from "../project.js";
|
|
10
|
+
export function readAuditFile(path) {
|
|
11
|
+
if (!existsSync(path))
|
|
12
|
+
return { path, entries: [] };
|
|
13
|
+
const entries = [];
|
|
14
|
+
readFileSync(path, "utf8")
|
|
15
|
+
.split("\n")
|
|
16
|
+
.forEach((line, i) => {
|
|
17
|
+
if (line.trim() === "")
|
|
18
|
+
return;
|
|
19
|
+
let e;
|
|
20
|
+
try {
|
|
21
|
+
e = JSON.parse(line);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
throw new YodelError(`${path}:${String(i + 1)} is not a JSON line; an audit file holds one entry per line, as yodel report --audit writes it`);
|
|
25
|
+
}
|
|
26
|
+
if (typeof e !== "object" || e === null || typeof e.id !== "string" || typeof e.environment !== "string") {
|
|
27
|
+
throw new YodelError(`${path}:${String(i + 1)} is not an audit entry (no id or environment)`);
|
|
28
|
+
}
|
|
29
|
+
entries.push(e);
|
|
30
|
+
});
|
|
31
|
+
return { path, entries };
|
|
32
|
+
}
|
|
33
|
+
/** Compares the file with what the sources give now, for the environments read. */
|
|
34
|
+
export function compareAudit(file, derived, environments) {
|
|
35
|
+
const now = new Set(derived.map((e) => e.id));
|
|
36
|
+
const had = new Set(file.entries.map((e) => e.id));
|
|
37
|
+
return {
|
|
38
|
+
missing: file.entries.filter((e) => environments.includes(e.environment) && !now.has(e.id)),
|
|
39
|
+
added: derived.filter((e) => !had.has(e.id)),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export function appendAudit(path, entries) {
|
|
43
|
+
if (entries.length === 0)
|
|
44
|
+
return;
|
|
45
|
+
appendFileSync(path, entries.map((e) => `${JSON.stringify(e)}\n`).join(""));
|
|
46
|
+
}
|
|
47
|
+
/** One line for a missing entry. */
|
|
48
|
+
export function describeEntry(e) {
|
|
49
|
+
const source = "history" in e.source ? `${e.source.history} seq ${String(e.source.seq)}` : `${e.source.ledger} (${e.source.op} / ${e.source.gate})`;
|
|
50
|
+
return `${e.at} ${e.environment} ${e.kind}${e.migration ? ` ${e.migration}` : ""}${e.by ? ` by ${e.by}` : ""}${e.digest ? ` for ${e.digest}` : ""}, from ${source}`;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=jsonl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonl.js","sourceRoot":"","sources":["../../src/report/jsonl.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `yodel report` (#57): every environment's migrations side by side, the
|
|
3
|
+
* audit log derived from each environment's history and chant's gate ledger
|
|
4
|
+
* (`./audit.ts`), and the gaps those sources show. Read only: it takes no
|
|
5
|
+
* lock and writes nothing to a server or the ledger.
|
|
6
|
+
*/
|
|
7
|
+
import type { GateLedgerPort } from "@intentius/chant/op/gate";
|
|
8
|
+
import { type HistoryRow } from "../history/index.js";
|
|
9
|
+
import type { Migration } from "../migrations/index.js";
|
|
10
|
+
import { type Project } from "../project.js";
|
|
11
|
+
import { type MigrateOpRef } from "../versioned/index.js";
|
|
12
|
+
import { type AuditEntry, type AuditGap } from "./audit.js";
|
|
13
|
+
export declare const REPORT_VERSION = 1;
|
|
14
|
+
export type MigrationState = "applied" | "pending" | "failed" | "started" | "reverted";
|
|
15
|
+
export interface EnvironmentMigration {
|
|
16
|
+
id: string;
|
|
17
|
+
/** `started`: the runner stopped part way; `failed`: a statement or a check failed. */
|
|
18
|
+
state: MigrationState;
|
|
19
|
+
/** Whether the migrations directory still has it. */
|
|
20
|
+
inDirectory: boolean;
|
|
21
|
+
/** When it was applied, and by whom; for failed and started, its latest migration row's. */
|
|
22
|
+
at?: string;
|
|
23
|
+
by?: string;
|
|
24
|
+
digest?: string;
|
|
25
|
+
/** The approval on the ledger of the digest it was applied under. */
|
|
26
|
+
approvedBy?: string;
|
|
27
|
+
approvedAt?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface EnvironmentReport {
|
|
30
|
+
name: string;
|
|
31
|
+
/** `<database>.history`. */
|
|
32
|
+
history?: string;
|
|
33
|
+
/** The migrations Op whose gate the ledger is read for. */
|
|
34
|
+
op?: {
|
|
35
|
+
name: string;
|
|
36
|
+
gate: string;
|
|
37
|
+
};
|
|
38
|
+
/** Why the environment could not be read; its migrations are then empty. */
|
|
39
|
+
error?: string;
|
|
40
|
+
/** Something read only in part, such as a ledger that could not be read. */
|
|
41
|
+
notes: string[];
|
|
42
|
+
migrations: EnvironmentMigration[];
|
|
43
|
+
}
|
|
44
|
+
export interface Report {
|
|
45
|
+
version: typeof REPORT_VERSION;
|
|
46
|
+
generatedAt: string;
|
|
47
|
+
project: string;
|
|
48
|
+
dialect: string;
|
|
49
|
+
/** The migrations, in chain order, then any an environment applied that the directory no longer has. */
|
|
50
|
+
migrations: string[];
|
|
51
|
+
/** In the order they were asked for (default: chant.config.ts's sql.profiles). */
|
|
52
|
+
environments: EnvironmentReport[];
|
|
53
|
+
/** Every environment's entries, oldest first. */
|
|
54
|
+
audit: AuditEntry[];
|
|
55
|
+
gaps: AuditGap[];
|
|
56
|
+
}
|
|
57
|
+
/** What reading one environment needs; tests stand in for the server and the ledger. */
|
|
58
|
+
export interface ReportSources {
|
|
59
|
+
rows(project: Project, env: string): Promise<{
|
|
60
|
+
rows: HistoryRow[];
|
|
61
|
+
history: string;
|
|
62
|
+
}>;
|
|
63
|
+
op(project: Project, env: string): Promise<MigrateOpRef>;
|
|
64
|
+
ledger(project: Project): Promise<GateLedgerPort>;
|
|
65
|
+
}
|
|
66
|
+
export declare const liveSources: ReportSources;
|
|
67
|
+
/** Reads every environment in `names` and derives the report. An environment that cannot be read is reported with its error. */
|
|
68
|
+
export declare function collectReport(project: Project, chain: readonly Migration[], names: readonly string[], sources?: ReportSources, now?: Date): Promise<Report>;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `yodel report` (#57): every environment's migrations side by side, the
|
|
3
|
+
* audit log derived from each environment's history and chant's gate ledger
|
|
4
|
+
* (`./audit.ts`), and the gaps those sources show. Read only: it takes no
|
|
5
|
+
* lock and writes nothing to a server or the ledger.
|
|
6
|
+
*/
|
|
7
|
+
import { deriveState } from "../history/index.js";
|
|
8
|
+
import { resolveEnvironment } from "../project.js";
|
|
9
|
+
import { closeVersioned, findMigrateOp, gitLedger, openVersioned } from "../versioned/index.js";
|
|
10
|
+
import { WAVES_PIPELINE } from "../waves/record.js";
|
|
11
|
+
import { baseEnvironment } from "../tenants/target.js";
|
|
12
|
+
import { approvalOf, byTime, deriveAudit, isoTime } from "./audit.js";
|
|
13
|
+
export const REPORT_VERSION = 1;
|
|
14
|
+
export const liveSources = {
|
|
15
|
+
async rows(project, name) {
|
|
16
|
+
const venv = await openVersioned(project, resolveEnvironment(project, name));
|
|
17
|
+
try {
|
|
18
|
+
return { rows: await venv.store.rows({ sync: false }), history: `${venv.location.database}.history` };
|
|
19
|
+
}
|
|
20
|
+
finally {
|
|
21
|
+
await closeVersioned(venv);
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
op: (project, name) => findMigrateOp(project, resolveEnvironment(project, name)),
|
|
25
|
+
ledger: (project) => gitLedger(project.dir),
|
|
26
|
+
};
|
|
27
|
+
const firstLine = (e) => (e instanceof Error ? (e.message.split("\n")[0] ?? "") : String(e));
|
|
28
|
+
/** Reads every environment in `names` and derives the report. An environment that cannot be read is reported with its error. */
|
|
29
|
+
export async function collectReport(project, chain, names, sources = liveSources, now = new Date()) {
|
|
30
|
+
const { samePlanDigest } = await import("@intentius/chant/lifecycle/plan-digest");
|
|
31
|
+
const { gateLedgerPath } = await import("@intentius/chant/lifecycle/gate-ledger");
|
|
32
|
+
let port;
|
|
33
|
+
let portError;
|
|
34
|
+
try {
|
|
35
|
+
port = await sources.ledger(project);
|
|
36
|
+
}
|
|
37
|
+
catch (e) {
|
|
38
|
+
portError = firstLine(e);
|
|
39
|
+
}
|
|
40
|
+
const environments = [];
|
|
41
|
+
const audit = [];
|
|
42
|
+
const gaps = [];
|
|
43
|
+
const known = new Set(chain.map((m) => m.id));
|
|
44
|
+
const extra = [];
|
|
45
|
+
for (const name of names) {
|
|
46
|
+
const env = { name, notes: [], migrations: [] };
|
|
47
|
+
environments.push(env);
|
|
48
|
+
let rows;
|
|
49
|
+
try {
|
|
50
|
+
const read = await sources.rows(project, name);
|
|
51
|
+
rows = read.rows;
|
|
52
|
+
env.history = read.history;
|
|
53
|
+
}
|
|
54
|
+
catch (e) {
|
|
55
|
+
env.error = `the history could not be read: ${firstLine(e)}`;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
let ledger;
|
|
59
|
+
try {
|
|
60
|
+
const op = await sources.op(project, name);
|
|
61
|
+
env.op = { name: op.name, gate: op.gate };
|
|
62
|
+
if (!port)
|
|
63
|
+
throw new Error(portError ?? "no ledger");
|
|
64
|
+
const lines = await port.read(op.name);
|
|
65
|
+
ledger = { op: op.name, gate: op.gate, path: gateLedgerPath(op.name), pending: lines.pending, resolutions: lines.resolutions };
|
|
66
|
+
}
|
|
67
|
+
catch (e) {
|
|
68
|
+
env.notes.push(env.op ? `chant's gate ledger could not be read (${firstLine(e)}); approvals are not shown and not checked` : `no migrations Op for ${name} (${firstLine(e)}); approvals are not shown and not checked`);
|
|
69
|
+
}
|
|
70
|
+
// The apply pipeline's waves (#87): their gates are on the waves' op's ledger, not the migrations Op's.
|
|
71
|
+
let waves;
|
|
72
|
+
const k = (project.yodel?.config.waves ?? []).findIndex((w) => w.env === baseEnvironment(name)) + 1;
|
|
73
|
+
if (port && (k > 0 || rows.some((r) => r.kind === "migration" && r.note.includes('"wave"')))) {
|
|
74
|
+
try {
|
|
75
|
+
const { waveGateName } = await import("@intentius/chant/gated-waves");
|
|
76
|
+
const lines = await port.read(WAVES_PIPELINE);
|
|
77
|
+
waves = { op: WAVES_PIPELINE, path: gateLedgerPath(WAVES_PIPELINE), ...(k > 0 ? { gate: waveGateName(WAVES_PIPELINE, k) } : {}), pending: lines.pending, resolutions: lines.resolutions };
|
|
78
|
+
}
|
|
79
|
+
catch (e) {
|
|
80
|
+
env.notes.push(`the waves' gate ledger could not be read (${firstLine(e)}); wave approvals are not shown and not checked`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const derived = deriveAudit({ environment: name, history: env.history ?? "history", rows, ledger, waves, sameDigest: samePlanDigest });
|
|
84
|
+
audit.push(...derived.entries);
|
|
85
|
+
gaps.push(...derived.gaps);
|
|
86
|
+
const state = deriveState(rows);
|
|
87
|
+
const listed = [...chain.map((m) => m.id), ...state.migrations.map((m) => m.id).filter((id) => !known.has(id))];
|
|
88
|
+
for (const id of state.migrations.map((m) => m.id)) {
|
|
89
|
+
if (!known.has(id) && !extra.includes(id))
|
|
90
|
+
extra.push(id);
|
|
91
|
+
}
|
|
92
|
+
for (const id of listed) {
|
|
93
|
+
const rec = state.byId.get(id);
|
|
94
|
+
if (!rec) {
|
|
95
|
+
env.migrations.push({ id, state: "pending", inDirectory: true });
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
const appliedEntry = derived.entries.filter((e) => e.kind === "applied" && e.migration === id).at(-1);
|
|
99
|
+
const approval = appliedEntry
|
|
100
|
+
? approvalOf(appliedEntry, derived.entries, samePlanDigest)
|
|
101
|
+
: rec.planDigest
|
|
102
|
+
? derived.entries.filter((a) => a.kind === "approved" && samePlanDigest(a.digest, rec.planDigest)).at(-1)
|
|
103
|
+
: undefined;
|
|
104
|
+
env.migrations.push({
|
|
105
|
+
id,
|
|
106
|
+
state: rec.status === "succeeded" ? "applied" : rec.status,
|
|
107
|
+
inDirectory: known.has(id),
|
|
108
|
+
...(rec.recordedAt ? { at: isoTime(rec.recordedAt) } : {}),
|
|
109
|
+
...(rec.appliedBy ? { by: rec.appliedBy } : {}),
|
|
110
|
+
...(rec.planDigest ? { digest: rec.planDigest } : {}),
|
|
111
|
+
...(approval?.by ? { approvedBy: approval.by, approvedAt: approval.at } : {}),
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
audit.sort(byTime);
|
|
116
|
+
return {
|
|
117
|
+
version: REPORT_VERSION,
|
|
118
|
+
generatedAt: now.toISOString(),
|
|
119
|
+
project: project.dir,
|
|
120
|
+
dialect: project.dialect,
|
|
121
|
+
migrations: [...chain.map((m) => m.id), ...extra],
|
|
122
|
+
environments,
|
|
123
|
+
audit,
|
|
124
|
+
gaps,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/report/model.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The report as text, and as a self-contained HTML page (the run view): one
|
|
3
|
+
* row per migration (each merge that added one), one column per
|
|
4
|
+
* environment, in the order they were asked for, so a change's progress from
|
|
5
|
+
* dev to prod reads left to right. Then the gaps and the audit log.
|
|
6
|
+
*/
|
|
7
|
+
import type { AuditEntry } from "./audit.js";
|
|
8
|
+
import type { Report } from "./model.js";
|
|
9
|
+
export declare function renderReportText(r: Report, extra?: {
|
|
10
|
+
check?: {
|
|
11
|
+
file: string;
|
|
12
|
+
missing: readonly string[];
|
|
13
|
+
appended: number;
|
|
14
|
+
};
|
|
15
|
+
}): string;
|
|
16
|
+
export declare function auditLine(a: AuditEntry): string;
|
|
17
|
+
/** The run view: a page with no external resources, safe to upload as a CI artifact and open from disk. */
|
|
18
|
+
export declare function renderReportHtml(r: Report): string;
|