@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
@@ -152,6 +152,10 @@
152
152
  },
153
153
  "skipped": {
154
154
  "$ref": "common.schema.json#/$defs/stringList"
155
+ },
156
+ "checkpoint": {
157
+ "description": "A checkpoint, replayed on its own into an empty database after the chain.",
158
+ "const": true
155
159
  }
156
160
  }
157
161
  },
@@ -24,7 +24,13 @@
24
24
  "type": "object",
25
25
  "additionalProperties": false,
26
26
  "required": ["op", "object", "name", "rules"],
27
- "properties": { "op": { "type": "string" }, "object": { "type": "string" }, "name": { "type": "string" }, "rules": { "$ref": "common.schema.json#/$defs/stringList" } }
27
+ "properties": {
28
+ "op": { "type": "string" },
29
+ "object": { "type": "string" },
30
+ "name": { "type": "string" },
31
+ "rules": { "$ref": "common.schema.json#/$defs/stringList" },
32
+ "retain": { "description": "A column rename or type change, or a rebuild: how long it keeps the old column or table after the switch (--retain).", "type": "string" }
33
+ }
28
34
  }
29
35
  },
30
36
  "manual": {
@@ -38,11 +44,43 @@
38
44
  }
39
45
  },
40
46
  "hints": { "$ref": "common.schema.json#/$defs/stringList" },
41
- "checks": { "type": "array", "items": { "$ref": "common.schema.json#/$defs/check" } }
47
+ "checks": { "type": "array", "items": { "$ref": "common.schema.json#/$defs/check" } },
48
+ "prechecks": {
49
+ "description": "Postgres: the statements that can fail on the rows already there, each with the pre-check yodel apply runs before the first statement; it must return 0.",
50
+ "type": "array",
51
+ "items": {
52
+ "type": "object",
53
+ "additionalProperties": false,
54
+ "required": ["name", "step", "sql", "detail"],
55
+ "properties": {
56
+ "name": { "type": "string" },
57
+ "step": { "type": "integer", "minimum": 0 },
58
+ "sql": { "type": "string" },
59
+ "detail": { "type": "string" }
60
+ }
61
+ }
62
+ },
63
+ "access": {
64
+ "description": "The steps about access control (Postgres: policies, row-level security, roles, grants, revokes, default privileges; ClickHouse: users, roles, row policies, grants, revokes), each with its rule and class; takesAway says why one takes access away.",
65
+ "type": "array",
66
+ "items": {
67
+ "type": "object",
68
+ "additionalProperties": false,
69
+ "required": ["step", "object", "name"],
70
+ "properties": {
71
+ "step": { "type": "integer", "minimum": 0 },
72
+ "object": { "type": "string" },
73
+ "name": { "type": "string" },
74
+ "rule": { "type": "string" },
75
+ "class": { "type": "string" },
76
+ "takesAway": { "type": "string" }
77
+ }
78
+ }
79
+ }
42
80
  }
43
81
  },
44
82
  "template": {
45
- "description": "--backfill named a file that is not there: the template was written to it, and no migration.",
83
+ "description": "--backfill's form (backfills/<name>.json, or the file it names) is not there: the template was written to it, and no migration.",
46
84
  "type": "object",
47
85
  "additionalProperties": false,
48
86
  "required": ["written", "template"],
@@ -66,6 +66,33 @@
66
66
  "type": "object"
67
67
  }
68
68
  },
69
+ "access": {
70
+ "description": "Whether access control is managed in the environment (environments.<env>.access in yodel.config.ts, else sql.profiles.<env>.access) and the plan's access changes: on Postgres policies, row-level security, roles and privileges; on ClickHouse users, roles, row policies and grants. byHand marks a revoke of a privilege no declaration grants: one granted by hand (or whose declaration was deleted), which the apply takes away. On ClickHouse every revoke is one.",
71
+ "type": "object",
72
+ "additionalProperties": false,
73
+ "required": ["managed", "source", "changes"],
74
+ "properties": {
75
+ "managed": { "type": "boolean" },
76
+ "source": { "type": "string" },
77
+ "changes": {
78
+ "type": "array",
79
+ "items": {
80
+ "type": "object",
81
+ "additionalProperties": false,
82
+ "required": ["object", "rule", "class", "field"],
83
+ "properties": {
84
+ "object": { "type": "string" },
85
+ "rule": { "type": "string" },
86
+ "class": { "type": "string" },
87
+ "field": { "type": "string" },
88
+ "before": {},
89
+ "after": {},
90
+ "byHand": { "const": true }
91
+ }
92
+ }
93
+ }
94
+ }
95
+ },
69
96
  "mode": false
70
97
  }
71
98
  },
@@ -278,6 +305,10 @@
278
305
  "description": "The command a person runs to approve this plan. An agent prints it and never runs it.",
279
306
  "type": "string"
280
307
  },
308
+ "approvalMode": {
309
+ "description": "Which approvals of the migrations Op's gate count, as yodel.config.ts at the base commit has it, when not ledger: sealed counts only an approval sealed by a key the signers file at base lists for its approver.",
310
+ "enum": ["sealed"]
311
+ },
281
312
  "approval": {
282
313
  "description": "The newest approval of the gate in chant's ledger.",
283
314
  "type": "object",
@@ -334,6 +365,10 @@
334
365
  "$ref": "#/$defs/moved"
335
366
  }
336
367
  }
368
+ },
369
+ "uncounted": {
370
+ "description": "The gate's approval mode does not count it (under sealed, it is not sealed by a signer at the base commit), and why.",
371
+ "type": "string"
337
372
  }
338
373
  }
339
374
  },
@@ -341,6 +376,128 @@
341
376
  "description": "The project declares no migrations Op for the environment: the first line of how to declare one.",
342
377
  "type": "string"
343
378
  },
379
+ "wave": {
380
+ "description": "The environment's wave of the apply pipeline, when yodel.config.ts declares waves and names it.",
381
+ "type": "object",
382
+ "additionalProperties": false,
383
+ "required": [
384
+ "wave",
385
+ "gate",
386
+ "base",
387
+ "baseSource",
388
+ "destructiveSteps",
389
+ "waits",
390
+ "planDigest",
391
+ "digest",
392
+ "approve",
393
+ "promotions",
394
+ "blocked"
395
+ ],
396
+ "properties": {
397
+ "wave": {
398
+ "description": "1-based, in yodel.config.ts waves.",
399
+ "type": "integer",
400
+ "minimum": 1
401
+ },
402
+ "gate": {
403
+ "description": "The gate policy at the base commit.",
404
+ "enum": [
405
+ "always",
406
+ "on-destructive",
407
+ "never"
408
+ ]
409
+ },
410
+ "base": {
411
+ "type": "string"
412
+ },
413
+ "baseSource": {
414
+ "type": "string"
415
+ },
416
+ "destructiveSteps": {
417
+ "type": "array",
418
+ "items": {
419
+ "$ref": "apply.schema.json#/$defs/destructiveStep"
420
+ }
421
+ },
422
+ "waits": {
423
+ "description": "Under that gate, the wave waits for an approval of this plan.",
424
+ "type": "boolean"
425
+ },
426
+ "planDigest": {
427
+ "description": "The wave plan digest.",
428
+ "type": "string"
429
+ },
430
+ "digest": {
431
+ "description": "The set digest the wave's gate binds.",
432
+ "type": "string"
433
+ },
434
+ "approve": {
435
+ "description": "The chant approve command for the wave, for a person to run.",
436
+ "type": "string"
437
+ },
438
+ "approval": {
439
+ "description": "Which approvals of the wave's digest count, as yodel.config.ts at the base commit has the wave, when not ledger.",
440
+ "enum": ["pr-review", "sealed"]
441
+ },
442
+ "promotions": {
443
+ "description": "Each environment this one requires (waves[].requires) and what its history records of each pending migration.",
444
+ "type": "array",
445
+ "items": {
446
+ "type": "object",
447
+ "additionalProperties": false,
448
+ "required": [
449
+ "env",
450
+ "from",
451
+ "migrations"
452
+ ],
453
+ "properties": {
454
+ "env": {
455
+ "type": "string"
456
+ },
457
+ "from": {
458
+ "description": "Where the requirement is declared: yodel.config.ts, at the base commit, or both.",
459
+ "type": "string"
460
+ },
461
+ "migrations": {
462
+ "type": "array",
463
+ "items": {
464
+ "type": "object",
465
+ "additionalProperties": false,
466
+ "required": [
467
+ "id",
468
+ "checksum",
469
+ "ran"
470
+ ],
471
+ "properties": {
472
+ "id": {
473
+ "type": "string"
474
+ },
475
+ "checksum": {
476
+ "type": "string"
477
+ },
478
+ "ran": {
479
+ "enum": [
480
+ "applied",
481
+ "not applied",
482
+ "applied with another checksum"
483
+ ]
484
+ },
485
+ "recorded": {
486
+ "description": "The checksum the required environment recorded, when it differs.",
487
+ "type": "string"
488
+ }
489
+ }
490
+ }
491
+ }
492
+ }
493
+ }
494
+ },
495
+ "blocked": {
496
+ "description": "A pending migration has not run where it must first: the wave refuses it until it has.",
497
+ "type": "boolean"
498
+ }
499
+ }
500
+ },
344
501
  "sinceLast": {
345
502
  "description": "The pull request comment this plan replaces showed another digest: what moved since.",
346
503
  "type": "object",
@@ -0,0 +1,114 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://intentius.io/sql-yodeler/schemas/v1/report.schema.json",
4
+ "title": "yodel report [<env>...] --json",
5
+ "description": "Version 1. Every environment's migrations side by side, the audit log derived from each environment's history table and chant's gate ledger, and the gaps those sources show. Within a version, fields are only added; a reader ignores fields it does not know.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["version", "generatedAt", "project", "dialect", "migrations", "environments", "audit", "gaps"],
9
+ "properties": {
10
+ "version": { "const": 1 },
11
+ "generatedAt": { "type": "string", "description": "When the report was read, ISO 8601 UTC." },
12
+ "project": { "type": "string", "description": "The project directory." },
13
+ "dialect": { "enum": ["clickhouse", "postgres"] },
14
+ "migrations": { "type": "array", "items": { "type": "string" }, "description": "The migrations in chain order, then any an environment applied that the directory no longer has." },
15
+ "environments": { "type": "array", "items": { "$ref": "#/$defs/environment" } },
16
+ "audit": { "type": "array", "items": { "$ref": "#/$defs/entry" }, "description": "Every environment's audit entries, oldest first." },
17
+ "gaps": { "type": "array", "items": { "$ref": "#/$defs/gap" } },
18
+ "auditFile": {
19
+ "type": "object",
20
+ "additionalProperties": false,
21
+ "required": ["path", "appended", "missing"],
22
+ "description": "With --audit: the file, how many entries were appended (0 with --check), and the entries of the file the sources no longer give.",
23
+ "properties": {
24
+ "path": { "type": "string" },
25
+ "appended": { "type": "integer", "minimum": 0 },
26
+ "missing": { "type": "array", "items": { "$ref": "#/$defs/entry" } }
27
+ }
28
+ }
29
+ },
30
+ "$defs": {
31
+ "environment": {
32
+ "type": "object",
33
+ "additionalProperties": false,
34
+ "required": ["name", "notes", "migrations"],
35
+ "properties": {
36
+ "name": { "type": "string" },
37
+ "history": { "type": "string", "description": "<database>.history" },
38
+ "op": {
39
+ "type": "object",
40
+ "additionalProperties": false,
41
+ "required": ["name", "gate"],
42
+ "properties": { "name": { "type": "string" }, "gate": { "type": "string" } }
43
+ },
44
+ "error": { "type": "string", "description": "Why the environment could not be read." },
45
+ "notes": { "type": "array", "items": { "type": "string" } },
46
+ "migrations": { "type": "array", "items": { "$ref": "#/$defs/migration" } }
47
+ }
48
+ },
49
+ "migration": {
50
+ "type": "object",
51
+ "additionalProperties": false,
52
+ "required": ["id", "state", "inDirectory"],
53
+ "properties": {
54
+ "id": { "type": "string" },
55
+ "state": { "enum": ["applied", "pending", "failed", "started", "reverted"] },
56
+ "inDirectory": { "type": "boolean" },
57
+ "at": { "type": "string" },
58
+ "by": { "type": "string" },
59
+ "digest": { "type": "string" },
60
+ "approvedBy": { "type": "string" },
61
+ "approvedAt": { "type": "string" }
62
+ }
63
+ },
64
+ "entry": {
65
+ "type": "object",
66
+ "additionalProperties": false,
67
+ "required": ["id", "at", "environment", "kind", "source"],
68
+ "description": "One audit entry; audit.jsonl holds one per line.",
69
+ "properties": {
70
+ "id": { "type": "string", "description": "A hash of the entry and its source: the same sources give the same id." },
71
+ "at": { "type": "string" },
72
+ "environment": { "type": "string" },
73
+ "kind": { "enum": ["approval-requested", "approved", "override", "silenced", "applied", "refused", "failed", "repaired", "reverted", "step"] },
74
+ "by": { "type": "string" },
75
+ "migration": { "type": "string" },
76
+ "digest": { "type": "string" },
77
+ "detail": { "type": "string" },
78
+ "wave": {
79
+ "type": "object",
80
+ "additionalProperties": false,
81
+ "required": ["gate", "digest", "status"],
82
+ "description": "On an applied entry a wave of the apply pipeline applied: the wave's gate, its set digest, and whether the wave was approved or its policy at the base needed no approval.",
83
+ "properties": { "gate": { "type": "string" }, "digest": { "type": "string" }, "status": { "enum": ["approved", "not-required"] } }
84
+ },
85
+ "source": {
86
+ "oneOf": [
87
+ {
88
+ "type": "object",
89
+ "additionalProperties": false,
90
+ "required": ["ledger", "op", "gate"],
91
+ "properties": { "ledger": { "type": "string" }, "op": { "type": "string" }, "gate": { "type": "string" } }
92
+ },
93
+ {
94
+ "type": "object",
95
+ "additionalProperties": false,
96
+ "required": ["history", "seq", "run"],
97
+ "properties": { "history": { "type": "string" }, "seq": { "type": "integer", "minimum": 1 }, "run": { "type": "string" } }
98
+ }
99
+ ]
100
+ }
101
+ }
102
+ },
103
+ "gap": {
104
+ "type": "object",
105
+ "additionalProperties": false,
106
+ "required": ["environment", "kind", "detail"],
107
+ "properties": {
108
+ "environment": { "type": "string" },
109
+ "kind": { "enum": ["history-row", "approval"] },
110
+ "detail": { "type": "string" }
111
+ }
112
+ }
113
+ }
114
+ }
@@ -0,0 +1,69 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://intentius.io/sql-yodeler/schemas/v1/revert.schema.json",
4
+ "title": "yodel revert <env> <id> --json",
5
+ "description": "Version 1. The revert of a migration: the statements that take the schema from its recorded schema back to its parent's (a hand-written revert step's first), the digest its gate binds, and what happened: planned (--dry-run), denied by a policy rule, gated (waiting for approval), reverted, or failed. Within a version, fields are only added; a reader ignores fields it does not know.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["environment", "migration", "to", "planDigest", "statements", "dataSteps", "status"],
9
+ "properties": {
10
+ "environment": { "type": "string" },
11
+ "migration": { "type": "string" },
12
+ "to": { "description": "The migration it goes back to; null when the first migration is reverted.", "type": ["string", "null"] },
13
+ "planDigest": { "type": "string" },
14
+ "statements": {
15
+ "type": "array",
16
+ "items": {
17
+ "type": "object",
18
+ "additionalProperties": false,
19
+ "required": ["index", "source", "sql", "rule", "class", "done"],
20
+ "properties": {
21
+ "index": { "type": "integer", "minimum": 0 },
22
+ "source": { "description": "step: the hand-written revert step; reverse: diffed from the recorded schemas.", "enum": ["step", "reverse"] },
23
+ "sql": { "type": "string" },
24
+ "rule": { "type": "string" },
25
+ "class": { "type": "string" },
26
+ "destructive": { "const": true },
27
+ "done": { "description": "It succeeded in an earlier run of this revert and is not sent again.", "type": "boolean" }
28
+ }
29
+ }
30
+ },
31
+ "dataSteps": { "description": "The migration's data steps, which the hand-written revert step undoes.", "$ref": "common.schema.json#/$defs/stringList" },
32
+ "step": {
33
+ "type": "object",
34
+ "additionalProperties": false,
35
+ "required": ["file", "sha", "statements"],
36
+ "properties": { "file": { "type": "string" }, "sha": { "type": "string" }, "statements": { "type": "integer", "minimum": 1 } }
37
+ },
38
+ "status": { "enum": ["planned", "denied", "gated", "reverted", "failed"] },
39
+ "policy": {
40
+ "description": "Each policy rule's outcome over the revert, the policy as the base commit has it; denied when a rule denies the revert and no override is recorded for its digest.",
41
+ "$ref": "common.schema.json#/$defs/policy"
42
+ },
43
+ "wave": {
44
+ "description": "When yodel.config.ts waves names the environment: the wave's gate policy at the base commit, the revert's statements it counts as destructive, and whether it asks for an approval of the revert. The revert waits at the migrations Op's gate either way.",
45
+ "type": "object",
46
+ "additionalProperties": false,
47
+ "required": ["gate", "base", "destructiveSteps", "policyWaits"],
48
+ "properties": {
49
+ "gate": { "enum": ["always", "on-destructive", "never"] },
50
+ "base": { "type": "string" },
51
+ "destructiveSteps": {
52
+ "type": "array",
53
+ "items": {
54
+ "type": "object",
55
+ "additionalProperties": false,
56
+ "required": ["migration", "step", "what", "why"],
57
+ "properties": { "migration": { "type": "string" }, "step": { "type": "integer", "minimum": 0 }, "what": { "type": "string" }, "why": { "type": "string" } }
58
+ }
59
+ },
60
+ "policyWaits": { "type": "boolean" }
61
+ }
62
+ },
63
+ "op": { "type": "string" },
64
+ "gate": { "type": "string" },
65
+ "approve": { "description": "The chant approve command that approves this revert.", "type": "string" },
66
+ "gatePlanDigest": { "type": "string" },
67
+ "exitCode": { "type": "integer" }
68
+ }
69
+ }
@@ -2,10 +2,18 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://intentius.io/sql-yodeler/schemas/v1/status.schema.json",
4
4
  "title": "yodel status <env> --json",
5
- "description": "Version 1. The environment's migrations against its history. Within a version, fields are only added; a reader ignores fields it does not know. yodel apply --json carries the same fields (apply.schema.json).",
5
+ "description": "Version 1. The environment's migrations against its history; for an environment with a tenant set (yodel.config.ts environments.<env>.tenants), each tenant's, against its own history. Within a version, fields are only added; a reader ignores fields it does not know. yodel apply --json carries the same fields (apply.schema.json).",
6
6
  "type": "object",
7
- "$ref": "#/$defs/report",
8
- "unevaluatedProperties": false,
7
+ "oneOf": [
8
+ {
9
+ "type": "object",
10
+ "$ref": "#/$defs/report",
11
+ "unevaluatedProperties": false
12
+ },
13
+ {
14
+ "$ref": "#/$defs/tenants"
15
+ }
16
+ ],
9
17
  "$defs": {
10
18
  "step": {
11
19
  "type": "object",
@@ -164,6 +172,13 @@
164
172
  "outOfOrder": {
165
173
  "type": "boolean"
166
174
  },
175
+ "reverted": {
176
+ "description": "It was applied, then yodel revert undid it: who reverted it and when. Applied again, every statement runs again.",
177
+ "type": "object",
178
+ "additionalProperties": false,
179
+ "required": ["by", "at"],
180
+ "properties": { "by": { "type": "string" }, "at": { "type": "string" } }
181
+ },
167
182
  "partWay": {
168
183
  "oneOf": [
169
184
  {
@@ -297,6 +312,20 @@
297
312
  }
298
313
  }
299
314
  },
315
+ "skipped": {
316
+ "description": "The migrations a checkpoint leaves out in this environment, in chain order: covered (before the checkpoint the environment starts from, named) or checkpoint (a checkpoint the environment does not start from). Absent when there are none.",
317
+ "type": "array",
318
+ "items": {
319
+ "type": "object",
320
+ "additionalProperties": false,
321
+ "required": ["id", "reason"],
322
+ "properties": {
323
+ "id": { "type": "string" },
324
+ "reason": { "enum": ["covered", "checkpoint"] },
325
+ "checkpoint": { "type": "string" }
326
+ }
327
+ }
328
+ },
300
329
  "planDigest": {
301
330
  "description": "The digest yodel apply would ask approval for, when it would not refuse.",
302
331
  "type": "string"
@@ -305,6 +334,38 @@
305
334
  "$ref": "common.schema.json#/$defs/refusal"
306
335
  }
307
336
  }
337
+ },
338
+ "tenants": {
339
+ "type": "object",
340
+ "additionalProperties": false,
341
+ "required": [
342
+ "environment",
343
+ "tenants",
344
+ "upToDate",
345
+ "total"
346
+ ],
347
+ "description": "A tenant set: each tenant's status, named <env>/<tenant>, and how many are up to date.",
348
+ "properties": {
349
+ "environment": {
350
+ "type": "string"
351
+ },
352
+ "tenants": {
353
+ "type": "array",
354
+ "items": {
355
+ "type": "object",
356
+ "$ref": "#/$defs/report",
357
+ "unevaluatedProperties": false
358
+ }
359
+ },
360
+ "upToDate": {
361
+ "type": "integer",
362
+ "minimum": 0
363
+ },
364
+ "total": {
365
+ "type": "integer",
366
+ "minimum": 0
367
+ }
368
+ }
308
369
  }
309
370
  }
310
371
  }
@@ -0,0 +1,41 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://intentius.io/sql-yodeler/schemas/v1/test.schema.json",
4
+ "title": "yodel test --json",
5
+ "description": "Version 1. The cases of tests/*.test.ts, each run on a database built from the migrations on a throwaway server: what passed, what failed and why. Within a version, fields are only added; a reader ignores fields it does not know.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["files", "summary", "cases"],
9
+ "properties": {
10
+ "environment": { "description": "The throwaway server's profile.", "type": "string" },
11
+ "dialect": { "enum": ["clickhouse", "postgres"] },
12
+ "where": { "description": "The server, without credentials.", "type": "string" },
13
+ "scope": { "description": "The databases (ClickHouse) or schemas (Postgres) each case empties and builds.", "$ref": "common.schema.json#/$defs/stringList" },
14
+ "reset": { "description": "The target held what the history names, and was emptied first (--reset).", "type": "boolean" },
15
+ "files": { "description": "The test files, relative to the project directory.", "$ref": "common.schema.json#/$defs/stringList" },
16
+ "summary": {
17
+ "type": "object",
18
+ "additionalProperties": false,
19
+ "required": ["passed", "failed", "errors"],
20
+ "properties": { "passed": { "type": "integer", "minimum": 0 }, "failed": { "type": "integer", "minimum": 0 }, "errors": { "type": "integer", "minimum": 0 } }
21
+ },
22
+ "cases": {
23
+ "type": "array",
24
+ "items": {
25
+ "type": "object",
26
+ "additionalProperties": false,
27
+ "required": ["file", "name", "status", "ms", "failures", "before", "after"],
28
+ "properties": {
29
+ "file": { "type": "string" },
30
+ "name": { "type": "string" },
31
+ "status": { "description": "passed: every expectation held. failed: one did not. error: the case could not run (a migration or seed statement failed, an unknown migration id).", "enum": ["passed", "failed", "error"] },
32
+ "ms": { "type": "integer", "minimum": 0 },
33
+ "failures": { "description": "The expectations that did not hold, one line each.", "$ref": "common.schema.json#/$defs/stringList" },
34
+ "error": { "type": "string" },
35
+ "before": { "description": "The migrations replayed before the seed.", "$ref": "common.schema.json#/$defs/stringList" },
36
+ "after": { "description": "The migrations run after the seed, with their steps.", "$ref": "common.schema.json#/$defs/stringList" }
37
+ }
38
+ }
39
+ }
40
+ }
41
+ }