@intentius/sql-yodeler 0.2.0 → 0.4.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.
Files changed (308) hide show
  1. package/README.md +3 -3
  2. package/dist/apply-steps/index.d.ts +65 -0
  3. package/dist/apply-steps/index.js +106 -0
  4. package/dist/apply-steps/index.js.map +1 -0
  5. package/dist/approval-mode/index.d.ts +78 -0
  6. package/dist/approval-mode/index.js +105 -0
  7. package/dist/approval-mode/index.js.map +1 -0
  8. package/dist/chant/access.d.ts +87 -0
  9. package/dist/chant/access.js +169 -0
  10. package/dist/chant/access.js.map +1 -0
  11. package/dist/chant/build.js +7 -0
  12. package/dist/chant/build.js.map +1 -1
  13. package/dist/chant/drift.d.ts +17 -1
  14. package/dist/chant/drift.js +55 -2
  15. package/dist/chant/drift.js.map +1 -1
  16. package/dist/chant/plan.d.ts +18 -2
  17. package/dist/chant/plan.js +21 -3
  18. package/dist/chant/plan.js.map +1 -1
  19. package/dist/ci/render.d.ts +333 -0
  20. package/dist/ci/render.js +885 -0
  21. package/dist/ci/render.js.map +1 -0
  22. package/dist/ci/replay.d.ts +17 -0
  23. package/dist/ci/replay.js +69 -0
  24. package/dist/ci/replay.js.map +1 -0
  25. package/dist/cleanup/index.d.ts +86 -0
  26. package/dist/cleanup/index.js +207 -0
  27. package/dist/cleanup/index.js.map +1 -0
  28. package/dist/commands/apply.d.ts +113 -0
  29. package/dist/commands/apply.js +370 -30
  30. package/dist/commands/apply.js.map +1 -1
  31. package/dist/commands/approve.d.ts +13 -0
  32. package/dist/commands/approve.js +239 -13
  33. package/dist/commands/approve.js.map +1 -1
  34. package/dist/commands/checkpoint.d.ts +3 -0
  35. package/dist/commands/checkpoint.js +78 -0
  36. package/dist/commands/checkpoint.js.map +1 -0
  37. package/dist/commands/ci.d.ts +3 -0
  38. package/dist/commands/ci.js +130 -0
  39. package/dist/commands/ci.js.map +1 -0
  40. package/dist/commands/cleanup.d.ts +13 -0
  41. package/dist/commands/cleanup.js +138 -0
  42. package/dist/commands/cleanup.js.map +1 -0
  43. package/dist/commands/config.d.ts +3 -0
  44. package/dist/commands/config.js +136 -0
  45. package/dist/commands/config.js.map +1 -0
  46. package/dist/commands/docs.d.ts +11 -0
  47. package/dist/commands/docs.js +108 -0
  48. package/dist/commands/docs.js.map +1 -0
  49. package/dist/commands/drift.d.ts +13 -1
  50. package/dist/commands/drift.js +52 -5
  51. package/dist/commands/drift.js.map +1 -1
  52. package/dist/commands/index.js +16 -0
  53. package/dist/commands/index.js.map +1 -1
  54. package/dist/commands/init.js +1 -1
  55. package/dist/commands/init.js.map +1 -1
  56. package/dist/commands/lint.js +39 -7
  57. package/dist/commands/lint.js.map +1 -1
  58. package/dist/commands/new.js +133 -34
  59. package/dist/commands/new.js.map +1 -1
  60. package/dist/commands/override.js +48 -16
  61. package/dist/commands/override.js.map +1 -1
  62. package/dist/commands/plan.js +47 -6
  63. package/dist/commands/plan.js.map +1 -1
  64. package/dist/commands/report.d.ts +13 -0
  65. package/dist/commands/report.js +121 -0
  66. package/dist/commands/report.js.map +1 -0
  67. package/dist/commands/revert.d.ts +20 -0
  68. package/dist/commands/revert.js +246 -0
  69. package/dist/commands/revert.js.map +1 -0
  70. package/dist/commands/status.js +32 -5
  71. package/dist/commands/status.js.map +1 -1
  72. package/dist/commands/test.d.ts +3 -0
  73. package/dist/commands/test.js +164 -0
  74. package/dist/commands/test.js.map +1 -0
  75. package/dist/config/base.d.ts +69 -0
  76. package/dist/config/base.js +121 -0
  77. package/dist/config/base.js.map +1 -0
  78. package/dist/config/define.d.ts +240 -3
  79. package/dist/config/define.js +4 -0
  80. package/dist/config/define.js.map +1 -1
  81. package/dist/config/index.d.ts +2 -0
  82. package/dist/config/index.js +2 -0
  83. package/dist/config/index.js.map +1 -1
  84. package/dist/config/load.d.ts +1 -1
  85. package/dist/config/load.js +156 -7
  86. package/dist/config/load.js.map +1 -1
  87. package/dist/config/settings.d.ts +22 -1
  88. package/dist/config/settings.js +34 -2
  89. package/dist/config/settings.js.map +1 -1
  90. package/dist/credentials.d.ts +119 -0
  91. package/dist/credentials.js +119 -0
  92. package/dist/credentials.js.map +1 -0
  93. package/dist/exit.js +1 -1
  94. package/dist/exit.js.map +1 -1
  95. package/dist/history/postgres/ddl.d.ts +18 -0
  96. package/dist/history/postgres/ddl.js +27 -2
  97. package/dist/history/postgres/ddl.js.map +1 -1
  98. package/dist/history/postgres/store.d.ts +2 -0
  99. package/dist/history/postgres/store.js +7 -1
  100. package/dist/history/postgres/store.js.map +1 -1
  101. package/dist/history/rows.d.ts +16 -3
  102. package/dist/history/rows.js +30 -1
  103. package/dist/history/rows.js.map +1 -1
  104. package/dist/history/store.d.ts +2 -0
  105. package/dist/history/store.js +2 -2
  106. package/dist/history/store.js.map +1 -1
  107. package/dist/index.d.ts +8 -1
  108. package/dist/index.js +3 -0
  109. package/dist/index.js.map +1 -1
  110. package/dist/init/adopt.js +1 -1
  111. package/dist/init/adopt.js.map +1 -1
  112. package/dist/init/clickhouse-access.d.ts +64 -0
  113. package/dist/init/clickhouse-access.js +211 -0
  114. package/dist/init/clickhouse-access.js.map +1 -0
  115. package/dist/init/live.d.ts +4 -0
  116. package/dist/init/live.js +16 -0
  117. package/dist/init/live.js.map +1 -1
  118. package/dist/lint/access.d.ts +18 -0
  119. package/dist/lint/access.js +34 -0
  120. package/dist/lint/access.js.map +1 -0
  121. package/dist/lint/check.js +38 -6
  122. package/dist/lint/check.js.map +1 -1
  123. package/dist/lint/config.d.ts +7 -1
  124. package/dist/lint/config.js +11 -5
  125. package/dist/lint/config.js.map +1 -1
  126. package/dist/lint/index.d.ts +2 -0
  127. package/dist/lint/index.js +2 -0
  128. package/dist/lint/index.js.map +1 -1
  129. package/dist/lint/naming.d.ts +62 -0
  130. package/dist/lint/naming.js +138 -0
  131. package/dist/lint/naming.js.map +1 -0
  132. package/dist/lint/report.js +1 -1
  133. package/dist/lint/report.js.map +1 -1
  134. package/dist/lint/routines.d.ts +26 -0
  135. package/dist/lint/routines.js +65 -0
  136. package/dist/lint/routines.js.map +1 -0
  137. package/dist/lint/rules.d.ts +51 -6
  138. package/dist/lint/rules.js +23 -6
  139. package/dist/lint/rules.js.map +1 -1
  140. package/dist/lint/schema-checks.d.ts +63 -0
  141. package/dist/lint/schema-checks.js +128 -0
  142. package/dist/lint/schema-checks.js.map +1 -0
  143. package/dist/lint/statements.d.ts +22 -1
  144. package/dist/lint/statements.js +40 -1
  145. package/dist/lint/statements.js.map +1 -1
  146. package/dist/mcp/tools.d.ts +1 -1
  147. package/dist/mcp/tools.js +1 -1
  148. package/dist/mcp/tools.js.map +1 -1
  149. package/dist/migrations/checkpoint.d.ts +45 -0
  150. package/dist/migrations/checkpoint.js +108 -0
  151. package/dist/migrations/checkpoint.js.map +1 -0
  152. package/dist/migrations/checks.d.ts +19 -1
  153. package/dist/migrations/checks.js +15 -0
  154. package/dist/migrations/checks.js.map +1 -1
  155. package/dist/migrations/create.d.ts +13 -4
  156. package/dist/migrations/create.js +24 -7
  157. package/dist/migrations/create.js.map +1 -1
  158. package/dist/migrations/document.d.ts +10 -0
  159. package/dist/migrations/document.js +1 -0
  160. package/dist/migrations/document.js.map +1 -1
  161. package/dist/migrations/index.d.ts +2 -0
  162. package/dist/migrations/index.js +2 -0
  163. package/dist/migrations/index.js.map +1 -1
  164. package/dist/migrations/routines.d.ts +21 -0
  165. package/dist/migrations/routines.js +30 -0
  166. package/dist/migrations/routines.js.map +1 -0
  167. package/dist/notify/index.d.ts +124 -0
  168. package/dist/notify/index.js +210 -0
  169. package/dist/notify/index.js.map +1 -0
  170. package/dist/notify/verify.d.ts +53 -0
  171. package/dist/notify/verify.js +71 -0
  172. package/dist/notify/verify.js.map +1 -0
  173. package/dist/pr/model.d.ts +7 -1
  174. package/dist/pr/model.js +29 -7
  175. package/dist/pr/model.js.map +1 -1
  176. package/dist/pr/render.d.ts +4 -1
  177. package/dist/pr/render.js +49 -9
  178. package/dist/pr/render.js.map +1 -1
  179. package/dist/pr/tenants.d.ts +37 -0
  180. package/dist/pr/tenants.js +138 -0
  181. package/dist/pr/tenants.js.map +1 -0
  182. package/dist/probe.d.ts +27 -0
  183. package/dist/probe.js +106 -0
  184. package/dist/probe.js.map +1 -0
  185. package/dist/project.d.ts +35 -2
  186. package/dist/project.js +62 -2
  187. package/dist/project.js.map +1 -1
  188. package/dist/replay/clickhouse.d.ts +31 -0
  189. package/dist/replay/clickhouse.js +103 -6
  190. package/dist/replay/clickhouse.js.map +1 -1
  191. package/dist/replay/replay.d.ts +14 -3
  192. package/dist/replay/replay.js +62 -31
  193. package/dist/replay/replay.js.map +1 -1
  194. package/dist/replay/report.js +1 -1
  195. package/dist/replay/report.js.map +1 -1
  196. package/dist/report/audit.d.ts +138 -0
  197. package/dist/report/audit.js +219 -0
  198. package/dist/report/audit.js.map +1 -0
  199. package/dist/report/jsonl.d.ts +21 -0
  200. package/dist/report/jsonl.js +52 -0
  201. package/dist/report/jsonl.js.map +1 -0
  202. package/dist/report/model.d.ts +68 -0
  203. package/dist/report/model.js +127 -0
  204. package/dist/report/model.js.map +1 -0
  205. package/dist/report/render.d.ts +18 -0
  206. package/dist/report/render.js +127 -0
  207. package/dist/report/render.js.map +1 -0
  208. package/dist/schema-docs/render.d.ts +49 -0
  209. package/dist/schema-docs/render.js +359 -0
  210. package/dist/schema-docs/render.js.map +1 -0
  211. package/dist/schemas.d.ts +7 -2
  212. package/dist/schemas.js +7 -2
  213. package/dist/schemas.js.map +1 -1
  214. package/dist/sources/ddl.d.ts +48 -0
  215. package/dist/sources/ddl.js +53 -0
  216. package/dist/sources/ddl.js.map +1 -0
  217. package/dist/sources/index.d.ts +69 -0
  218. package/dist/sources/index.js +170 -0
  219. package/dist/sources/index.js.map +1 -0
  220. package/dist/steps/backfill.d.ts +40 -5
  221. package/dist/steps/backfill.js +128 -8
  222. package/dist/steps/backfill.js.map +1 -1
  223. package/dist/steps/index.d.ts +19 -1
  224. package/dist/steps/index.js +34 -7
  225. package/dist/steps/index.js.map +1 -1
  226. package/dist/steps/kinds.d.ts +42 -4
  227. package/dist/steps/kinds.js +88 -14
  228. package/dist/steps/kinds.js.map +1 -1
  229. package/dist/steps/postgres-migration.d.ts +38 -25
  230. package/dist/steps/postgres-migration.js +49 -32
  231. package/dist/steps/postgres-migration.js.map +1 -1
  232. package/dist/steps/rebuild.d.ts +15 -6
  233. package/dist/steps/rebuild.js +12 -9
  234. package/dist/steps/rebuild.js.map +1 -1
  235. package/dist/tenants/index.d.ts +41 -0
  236. package/dist/tenants/index.js +121 -0
  237. package/dist/tenants/index.js.map +1 -0
  238. package/dist/tenants/target.d.ts +23 -0
  239. package/dist/tenants/target.js +29 -0
  240. package/dist/tenants/target.js.map +1 -0
  241. package/dist/tenants/wave.d.ts +128 -0
  242. package/dist/tenants/wave.js +254 -0
  243. package/dist/tenants/wave.js.map +1 -0
  244. package/dist/testing/define.d.ts +62 -0
  245. package/dist/testing/define.js +32 -0
  246. package/dist/testing/define.js.map +1 -0
  247. package/dist/testing/files.d.ts +5 -0
  248. package/dist/testing/files.js +18 -0
  249. package/dist/testing/files.js.map +1 -0
  250. package/dist/testing/report.d.ts +14 -0
  251. package/dist/testing/report.js +83 -0
  252. package/dist/testing/report.js.map +1 -0
  253. package/dist/testing/run.d.ts +104 -0
  254. package/dist/testing/run.js +328 -0
  255. package/dist/testing/run.js.map +1 -0
  256. package/dist/versioned/approval.d.ts +6 -0
  257. package/dist/versioned/approval.js +11 -5
  258. package/dist/versioned/approval.js.map +1 -1
  259. package/dist/versioned/checks.d.ts +8 -2
  260. package/dist/versioned/checks.js +34 -13
  261. package/dist/versioned/checks.js.map +1 -1
  262. package/dist/versioned/driver.d.ts +2 -2
  263. package/dist/versioned/engine.d.ts +16 -0
  264. package/dist/versioned/engine.js +20 -6
  265. package/dist/versioned/engine.js.map +1 -1
  266. package/dist/versioned/explain.d.ts +2 -0
  267. package/dist/versioned/explain.js +3 -1
  268. package/dist/versioned/explain.js.map +1 -1
  269. package/dist/versioned/index.d.ts +1 -0
  270. package/dist/versioned/index.js +1 -0
  271. package/dist/versioned/index.js.map +1 -1
  272. package/dist/versioned/op.d.ts +6 -1
  273. package/dist/versioned/op.js +7 -2
  274. package/dist/versioned/op.js.map +1 -1
  275. package/dist/versioned/policy.d.ts +33 -2
  276. package/dist/versioned/policy.js +59 -8
  277. package/dist/versioned/policy.js.map +1 -1
  278. package/dist/versioned/report.js +9 -0
  279. package/dist/versioned/report.js.map +1 -1
  280. package/dist/versioned/revert.d.ts +128 -0
  281. package/dist/versioned/revert.js +251 -0
  282. package/dist/versioned/revert.js.map +1 -0
  283. package/dist/versioned/state.d.ts +25 -0
  284. package/dist/versioned/state.js +37 -4
  285. package/dist/versioned/state.js.map +1 -1
  286. package/dist/waves/index.d.ts +224 -0
  287. package/dist/waves/index.js +353 -0
  288. package/dist/waves/index.js.map +1 -0
  289. package/dist/waves/promotion.d.ts +56 -0
  290. package/dist/waves/promotion.js +108 -0
  291. package/dist/waves/promotion.js.map +1 -0
  292. package/dist/waves/record.d.ts +34 -0
  293. package/dist/waves/record.js +20 -0
  294. package/dist/waves/record.js.map +1 -0
  295. package/package.json +11 -7
  296. package/schemas/apply.schema.json +162 -3
  297. package/schemas/checkpoint.schema.json +19 -0
  298. package/schemas/cleanup.schema.json +40 -0
  299. package/schemas/drift.schema.json +26 -1
  300. package/schemas/event.schema.json +36 -0
  301. package/schemas/lint-rules.schema.json +4 -0
  302. package/schemas/lint.schema.json +4 -0
  303. package/schemas/new.schema.json +41 -3
  304. package/schemas/plan.schema.json +157 -0
  305. package/schemas/report.schema.json +114 -0
  306. package/schemas/revert.schema.json +69 -0
  307. package/schemas/status.schema.json +64 -3
  308. package/schemas/test.schema.json +41 -0
@@ -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;
@@ -0,0 +1,127 @@
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
+ const short = (d) => (d ? (d.length > 24 ? `${d.slice(0, 24)}...` : d) : "");
8
+ const day = (t) => (t ? t.slice(0, 16).replace("T", " ") : "");
9
+ function cell(m) {
10
+ if (!m)
11
+ return "-";
12
+ if (m.state === "applied")
13
+ return `applied ${day(m.at)}`;
14
+ return m.state;
15
+ }
16
+ export function renderReportText(r, extra = {}) {
17
+ const lines = [`Report for ${r.project} (${r.dialect}, ${String(r.environments.length)} environment${r.environments.length === 1 ? "" : "s"})`, ""];
18
+ const head = ["migration", ...r.environments.map((e) => e.name)];
19
+ const rows = r.migrations.map((id) => [id, ...r.environments.map((e) => (e.error ? "unread" : cell(e.migrations.find((m) => m.id === id))))]);
20
+ const widths = head.map((h, i) => Math.max(h.length, ...rows.map((row) => (row[i] ?? "").length)));
21
+ const fmt = (row) => row.map((c, i) => c.padEnd(widths[i] ?? 0)).join(" ").trimEnd();
22
+ lines.push(fmt(head), ...rows.map(fmt));
23
+ if (r.migrations.length === 0)
24
+ lines.push("(no migrations)");
25
+ for (const e of r.environments) {
26
+ if (e.error)
27
+ lines.push("", `${e.name}: ${e.error}`);
28
+ for (const n of e.notes)
29
+ lines.push("", `${e.name}: ${n}`);
30
+ }
31
+ lines.push("", r.gaps.length === 0 ? "Gaps: none. Every applied migration has its approval on the ledger, and no history row is missing." : `Gaps (${String(r.gaps.length)}):`);
32
+ for (const g of r.gaps)
33
+ lines.push(` ${g.environment}: ${g.detail}`);
34
+ if (extra.check) {
35
+ const c = extra.check;
36
+ if (c.missing.length === 0)
37
+ lines.push("", `${c.file}: every entry is still in the sources${c.appended > 0 ? `; ${String(c.appended)} new entr${c.appended === 1 ? "y" : "ies"} appended` : ""}.`);
38
+ else
39
+ lines.push("", `${c.file}: ${String(c.missing.length)} entr${c.missing.length === 1 ? "y is" : "ies are"} no longer in the history or the ledger:`, ...c.missing.map((m) => ` ${m}`));
40
+ }
41
+ lines.push("", `Audit (${String(r.audit.length)} entries):`);
42
+ for (const a of r.audit)
43
+ lines.push(` ${auditLine(a)}`);
44
+ return `${lines.join("\n")}\n`;
45
+ }
46
+ export function auditLine(a) {
47
+ return [a.at, a.environment, a.kind, a.migration ?? "", a.by ? `by ${a.by}` : "", a.digest ? short(a.digest) : "", a.detail ? `(${a.detail})` : ""].filter(Boolean).join(" ");
48
+ }
49
+ const esc = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
50
+ /** The run view: a page with no external resources, safe to upload as a CI artifact and open from disk. */
51
+ export function renderReportHtml(r) {
52
+ const th = r.environments.map((e) => `<th scope="col">${esc(e.name)}${e.op ? `<br><small>${esc(e.op.name)}</small>` : ""}</th>`).join("");
53
+ const body = r.migrations
54
+ .map((id) => {
55
+ const tds = r.environments
56
+ .map((e) => {
57
+ if (e.error)
58
+ return `<td class="unread">unread</td>`;
59
+ const m = e.migrations.find((x) => x.id === id);
60
+ if (!m)
61
+ return `<td class="none">-</td>`;
62
+ const lines = [m.state];
63
+ if (m.at)
64
+ lines.push(day(m.at));
65
+ if (m.by)
66
+ lines.push(`by ${m.by}`);
67
+ if (m.approvedBy)
68
+ lines.push(`approved by ${m.approvedBy}`);
69
+ const title = m.digest ? ` title="${esc(m.digest)}"` : "";
70
+ return `<td class="${m.state}"${title}>${lines.map((l, i) => (i === 0 ? `<b>${esc(l)}</b>` : `<small>${esc(l)}</small>`)).join("<br>")}</td>`;
71
+ })
72
+ .join("");
73
+ return `<tr><th scope="row"><code>${esc(id)}</code></th>${tds}</tr>`;
74
+ })
75
+ .join("\n");
76
+ const notes = r.environments.flatMap((e) => [...(e.error ? [`${e.name}: ${e.error}`] : []), ...e.notes.map((n) => `${e.name}: ${n}`)]);
77
+ const gaps = r.gaps.length === 0 ? `<p class="ok">No gaps: every applied migration has its approval on the ledger, and no history row is missing.</p>` : `<ul class="gaps">${r.gaps.map((g) => `<li><b>${esc(g.environment)}</b> ${esc(g.detail)}</li>`).join("")}</ul>`;
78
+ const audit = r.audit
79
+ .map((a) => `<tr class="k-${a.kind}"><td>${esc(day(a.at))}</td><td>${esc(a.environment)}</td><td>${esc(a.kind)}</td><td><code>${esc(a.migration ?? "")}</code></td><td>${esc(a.by ?? "")}</td><td title="${esc(a.digest ?? "")}"><code>${esc(short(a.digest))}</code></td><td>${esc(a.detail ?? "")}</td></tr>`)
80
+ .join("\n");
81
+ return `<!doctype html>
82
+ <html lang="en">
83
+ <head>
84
+ <meta charset="utf-8">
85
+ <meta name="viewport" content="width=device-width, initial-scale=1">
86
+ <title>Migrations report</title>
87
+ <style>
88
+ :root { --bg: #fff; --fg: #1d1d1f; --muted: #6e6e73; --line: #d2d2d7; --applied: #e3f4e8; --pending: #fff6db; --failed: #fde4e1; --started: #fde4e1; }
89
+ @media (prefers-color-scheme: dark) { :root { --bg: #161618; --fg: #ececf0; --muted: #a1a1a6; --line: #3a3a3c; --applied: #1f3a29; --pending: #3d3317; --failed: #4a2420; --started: #4a2420; } }
90
+ body { background: var(--bg); color: var(--fg); font: 14px/1.45 system-ui, sans-serif; margin: 0; padding: 24px 16px; }
91
+ main { max-width: 1200px; margin: 0 auto; }
92
+ h1 { font-size: 20px; margin: 0 0 4px; } h2 { font-size: 16px; margin: 28px 0 8px; }
93
+ .meta, small { color: var(--muted); }
94
+ .scroll { overflow-x: auto; }
95
+ table { border-collapse: collapse; width: 100%; }
96
+ th, td { border-bottom: 1px solid var(--line); padding: 6px 8px; text-align: left; vertical-align: top; }
97
+ td.applied { background: var(--applied); } td.pending { background: var(--pending); } td.failed, td.started { background: var(--failed); }
98
+ code { font: 12px ui-monospace, monospace; }
99
+ .gaps li { color: #c0392b; } .ok { color: var(--muted); }
100
+ </style>
101
+ </head>
102
+ <body>
103
+ <main>
104
+ <h1>Migrations report</h1>
105
+ <p class="meta">${esc(r.project)} (${esc(r.dialect)}), generated ${esc(r.generatedAt)}. One row per migration, one column per environment.</p>
106
+ ${notes.length > 0 ? `<ul>${notes.map((n) => `<li>${esc(n)}</li>`).join("")}</ul>` : ""}
107
+ <div class="scroll"><table>
108
+ <thead><tr><th scope="col">migration</th>${th}</tr></thead>
109
+ <tbody>
110
+ ${body}
111
+ </tbody>
112
+ </table></div>
113
+ <h2>Gaps</h2>
114
+ ${gaps}
115
+ <h2>Audit log (${String(r.audit.length)} entries)</h2>
116
+ <div class="scroll"><table>
117
+ <thead><tr><th>when</th><th>environment</th><th>what</th><th>migration</th><th>by</th><th>digest</th><th>detail</th></tr></thead>
118
+ <tbody>
119
+ ${audit}
120
+ </tbody>
121
+ </table></div>
122
+ </main>
123
+ </body>
124
+ </html>
125
+ `;
126
+ }
127
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/report/render.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * `yodel docs` (#62): the declared schema as a static reference, from the
3
+ * sql lexicon's build output (or a migration's recorded schema), with no
4
+ * server read and nothing to run in the browser.
5
+ *
6
+ * - {@link schemaHtml}: one self-contained HTML page (inline CSS, no
7
+ * scripts): every object with its columns, keys, relations, ClickHouse
8
+ * engine and sort key, comments, DDL, and the migrations that changed it.
9
+ * - {@link erdMermaid}: a Mermaid `erDiagram` of the tables and views and
10
+ * how they relate: Postgres foreign keys, what a view or materialized view
11
+ * reads, the table a materialized view writes to, and the local table a
12
+ * ClickHouse `Distributed` table serves.
13
+ *
14
+ * Both are deterministic: the same input gives the same bytes, so the
15
+ * output can be committed and compared.
16
+ */
17
+ import type { BuildOutput } from "../chant/build.js";
18
+ import type { MigrationStep } from "../migrations/index.js";
19
+ /** A migration as far as the reference needs it: its id and its steps. */
20
+ export interface DocsMigration {
21
+ id: string;
22
+ steps: readonly MigrationStep[];
23
+ }
24
+ export interface DocsInput {
25
+ /** The page's title, e.g. the project's name. */
26
+ title: string;
27
+ output: BuildOutput;
28
+ /** Where the schema came from, said under the title: "the declared schema (chant build)", "migration <id>". */
29
+ source: string;
30
+ /** The migrations directory's chain, oldest first, for each object's history. */
31
+ migrations?: readonly DocsMigration[];
32
+ }
33
+ /** One relation between two objects, by export name. */
34
+ export interface Relation {
35
+ from: string;
36
+ to: string;
37
+ kind: "foreign key" | "reads" | "writes to" | "distributes";
38
+ label: string;
39
+ /** Foreign keys only: the referencing columns may be null. */
40
+ optional?: boolean;
41
+ }
42
+ /** Every relation between the objects the ERD draws, in a stable order. */
43
+ export declare function relations(output: BuildOutput): Relation[];
44
+ /** The Mermaid `erDiagram`: one entity per table or view, one line per relation. */
45
+ export declare function erdMermaid(output: BuildOutput): string;
46
+ /** The ERD as Markdown, which GitHub, GitLab and Forgejo render. */
47
+ export declare function erdMarkdown(input: DocsInput): string;
48
+ /** The self-contained HTML reference. */
49
+ export declare function schemaHtml(input: DocsInput): string;