@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.
Files changed (194) hide show
  1. package/README.md +3 -3
  2. package/dist/chant/build.js +7 -0
  3. package/dist/chant/build.js.map +1 -1
  4. package/dist/ci/render.d.ts +289 -0
  5. package/dist/ci/render.js +688 -0
  6. package/dist/ci/render.js.map +1 -0
  7. package/dist/ci/replay.d.ts +17 -0
  8. package/dist/ci/replay.js +69 -0
  9. package/dist/ci/replay.js.map +1 -0
  10. package/dist/commands/apply.d.ts +113 -0
  11. package/dist/commands/apply.js +228 -21
  12. package/dist/commands/apply.js.map +1 -1
  13. package/dist/commands/approve.js +44 -0
  14. package/dist/commands/approve.js.map +1 -1
  15. package/dist/commands/checkpoint.d.ts +3 -0
  16. package/dist/commands/checkpoint.js +78 -0
  17. package/dist/commands/checkpoint.js.map +1 -0
  18. package/dist/commands/ci.d.ts +3 -0
  19. package/dist/commands/ci.js +118 -0
  20. package/dist/commands/ci.js.map +1 -0
  21. package/dist/commands/docs.d.ts +11 -0
  22. package/dist/commands/docs.js +108 -0
  23. package/dist/commands/docs.js.map +1 -0
  24. package/dist/commands/drift.d.ts +13 -1
  25. package/dist/commands/drift.js +18 -2
  26. package/dist/commands/drift.js.map +1 -1
  27. package/dist/commands/index.js +10 -0
  28. package/dist/commands/index.js.map +1 -1
  29. package/dist/commands/init.js +1 -1
  30. package/dist/commands/init.js.map +1 -1
  31. package/dist/commands/lint.js +11 -3
  32. package/dist/commands/lint.js.map +1 -1
  33. package/dist/commands/override.js +48 -16
  34. package/dist/commands/override.js.map +1 -1
  35. package/dist/commands/plan.js +5 -1
  36. package/dist/commands/plan.js.map +1 -1
  37. package/dist/commands/report.d.ts +13 -0
  38. package/dist/commands/report.js +121 -0
  39. package/dist/commands/report.js.map +1 -0
  40. package/dist/commands/revert.d.ts +20 -0
  41. package/dist/commands/revert.js +246 -0
  42. package/dist/commands/revert.js.map +1 -0
  43. package/dist/commands/status.js +32 -5
  44. package/dist/commands/status.js.map +1 -1
  45. package/dist/config/base.d.ts +69 -0
  46. package/dist/config/base.js +121 -0
  47. package/dist/config/base.js.map +1 -0
  48. package/dist/config/define.d.ts +123 -1
  49. package/dist/config/define.js +2 -0
  50. package/dist/config/define.js.map +1 -1
  51. package/dist/config/index.d.ts +2 -0
  52. package/dist/config/index.js +2 -0
  53. package/dist/config/index.js.map +1 -1
  54. package/dist/config/load.d.ts +1 -1
  55. package/dist/config/load.js +90 -5
  56. package/dist/config/load.js.map +1 -1
  57. package/dist/config/settings.d.ts +4 -1
  58. package/dist/config/settings.js +8 -2
  59. package/dist/config/settings.js.map +1 -1
  60. package/dist/exit.js +1 -1
  61. package/dist/exit.js.map +1 -1
  62. package/dist/history/postgres/ddl.d.ts +18 -0
  63. package/dist/history/postgres/ddl.js +27 -2
  64. package/dist/history/postgres/ddl.js.map +1 -1
  65. package/dist/history/postgres/store.d.ts +2 -0
  66. package/dist/history/postgres/store.js +7 -1
  67. package/dist/history/postgres/store.js.map +1 -1
  68. package/dist/history/rows.d.ts +16 -3
  69. package/dist/history/rows.js +30 -1
  70. package/dist/history/rows.js.map +1 -1
  71. package/dist/history/store.d.ts +2 -0
  72. package/dist/history/store.js +2 -2
  73. package/dist/history/store.js.map +1 -1
  74. package/dist/index.d.ts +4 -1
  75. package/dist/index.js +1 -0
  76. package/dist/index.js.map +1 -1
  77. package/dist/lint/check.js +17 -2
  78. package/dist/lint/check.js.map +1 -1
  79. package/dist/lint/report.js +1 -1
  80. package/dist/lint/report.js.map +1 -1
  81. package/dist/lint/routines.d.ts +26 -0
  82. package/dist/lint/routines.js +65 -0
  83. package/dist/lint/routines.js.map +1 -0
  84. package/dist/lint/rules.d.ts +16 -4
  85. package/dist/lint/rules.js +9 -4
  86. package/dist/lint/rules.js.map +1 -1
  87. package/dist/mcp/tools.d.ts +1 -1
  88. package/dist/mcp/tools.js +1 -1
  89. package/dist/mcp/tools.js.map +1 -1
  90. package/dist/migrations/checkpoint.d.ts +45 -0
  91. package/dist/migrations/checkpoint.js +110 -0
  92. package/dist/migrations/checkpoint.js.map +1 -0
  93. package/dist/migrations/create.js +2 -0
  94. package/dist/migrations/create.js.map +1 -1
  95. package/dist/migrations/document.d.ts +10 -0
  96. package/dist/migrations/document.js +1 -0
  97. package/dist/migrations/document.js.map +1 -1
  98. package/dist/migrations/index.d.ts +2 -0
  99. package/dist/migrations/index.js +2 -0
  100. package/dist/migrations/index.js.map +1 -1
  101. package/dist/migrations/routines.d.ts +31 -0
  102. package/dist/migrations/routines.js +55 -0
  103. package/dist/migrations/routines.js.map +1 -0
  104. package/dist/notify/index.d.ts +124 -0
  105. package/dist/notify/index.js +210 -0
  106. package/dist/notify/index.js.map +1 -0
  107. package/dist/notify/verify.d.ts +53 -0
  108. package/dist/notify/verify.js +71 -0
  109. package/dist/notify/verify.js.map +1 -0
  110. package/dist/pr/model.d.ts +3 -0
  111. package/dist/pr/model.js +16 -2
  112. package/dist/pr/model.js.map +1 -1
  113. package/dist/pr/render.js +27 -1
  114. package/dist/pr/render.js.map +1 -1
  115. package/dist/project.d.ts +19 -2
  116. package/dist/project.js +33 -1
  117. package/dist/project.js.map +1 -1
  118. package/dist/replay/replay.d.ts +9 -1
  119. package/dist/replay/replay.js +62 -31
  120. package/dist/replay/replay.js.map +1 -1
  121. package/dist/replay/report.js +1 -1
  122. package/dist/replay/report.js.map +1 -1
  123. package/dist/report/audit.d.ts +138 -0
  124. package/dist/report/audit.js +202 -0
  125. package/dist/report/audit.js.map +1 -0
  126. package/dist/report/jsonl.d.ts +21 -0
  127. package/dist/report/jsonl.js +52 -0
  128. package/dist/report/jsonl.js.map +1 -0
  129. package/dist/report/model.d.ts +68 -0
  130. package/dist/report/model.js +127 -0
  131. package/dist/report/model.js.map +1 -0
  132. package/dist/report/render.d.ts +18 -0
  133. package/dist/report/render.js +127 -0
  134. package/dist/report/render.js.map +1 -0
  135. package/dist/schema-docs/render.d.ts +49 -0
  136. package/dist/schema-docs/render.js +359 -0
  137. package/dist/schema-docs/render.js.map +1 -0
  138. package/dist/schemas.d.ts +5 -2
  139. package/dist/schemas.js +5 -2
  140. package/dist/schemas.js.map +1 -1
  141. package/dist/sources/ddl.d.ts +53 -0
  142. package/dist/sources/ddl.js +347 -0
  143. package/dist/sources/ddl.js.map +1 -0
  144. package/dist/sources/index.d.ts +69 -0
  145. package/dist/sources/index.js +170 -0
  146. package/dist/sources/index.js.map +1 -0
  147. package/dist/steps/postgres-migration.d.ts +35 -25
  148. package/dist/steps/postgres-migration.js +42 -29
  149. package/dist/steps/postgres-migration.js.map +1 -1
  150. package/dist/tenants/index.d.ts +40 -0
  151. package/dist/tenants/index.js +122 -0
  152. package/dist/tenants/index.js.map +1 -0
  153. package/dist/tenants/target.d.ts +23 -0
  154. package/dist/tenants/target.js +29 -0
  155. package/dist/tenants/target.js.map +1 -0
  156. package/dist/versioned/engine.d.ts +6 -0
  157. package/dist/versioned/engine.js +12 -2
  158. package/dist/versioned/engine.js.map +1 -1
  159. package/dist/versioned/index.d.ts +1 -0
  160. package/dist/versioned/index.js +1 -0
  161. package/dist/versioned/index.js.map +1 -1
  162. package/dist/versioned/op.d.ts +6 -1
  163. package/dist/versioned/op.js +7 -2
  164. package/dist/versioned/op.js.map +1 -1
  165. package/dist/versioned/policy.d.ts +33 -2
  166. package/dist/versioned/policy.js +59 -8
  167. package/dist/versioned/policy.js.map +1 -1
  168. package/dist/versioned/report.js +9 -0
  169. package/dist/versioned/report.js.map +1 -1
  170. package/dist/versioned/revert.d.ts +128 -0
  171. package/dist/versioned/revert.js +251 -0
  172. package/dist/versioned/revert.js.map +1 -0
  173. package/dist/versioned/state.d.ts +25 -0
  174. package/dist/versioned/state.js +36 -3
  175. package/dist/versioned/state.js.map +1 -1
  176. package/dist/waves/index.d.ts +179 -0
  177. package/dist/waves/index.js +268 -0
  178. package/dist/waves/index.js.map +1 -0
  179. package/dist/waves/promotion.d.ts +56 -0
  180. package/dist/waves/promotion.js +108 -0
  181. package/dist/waves/promotion.js.map +1 -0
  182. package/dist/waves/record.d.ts +24 -0
  183. package/dist/waves/record.js +20 -0
  184. package/dist/waves/record.js.map +1 -0
  185. package/package.json +11 -7
  186. package/schemas/apply.schema.json +162 -3
  187. package/schemas/checkpoint.schema.json +19 -0
  188. package/schemas/drift.schema.json +26 -1
  189. package/schemas/event.schema.json +36 -0
  190. package/schemas/lint.schema.json +4 -0
  191. package/schemas/plan.schema.json +118 -0
  192. package/schemas/report.schema.json +114 -0
  193. package/schemas/revert.schema.json +69 -0
  194. package/schemas/status.schema.json +64 -3
@@ -0,0 +1,170 @@
1
+ /**
2
+ * DDL sources (#67): schema that an ORM defines, read from the DDL it
3
+ * prints, beside the declarations in `src/`.
4
+ *
5
+ * ```ts
6
+ * // yodel.config.ts
7
+ * export default defineConfig({
8
+ * sources: {
9
+ * prisma: { command: "npx prisma migrate diff --from-empty --to-schema-datamodel prisma/schema.prisma --script", schema: "app" },
10
+ * legacy: { file: "db/legacy.sql" },
11
+ * },
12
+ * });
13
+ * ```
14
+ *
15
+ * Before each build, yodel runs each source's command (or reads its file)
16
+ * in the project directory and writes the DDL out as declarations in
17
+ * `<sourceDir>/<name>.generated.ts`, the file `chant import` would write.
18
+ * The build, and so plan, new, apply and drift, read it like any other
19
+ * declaration; the ApplyOp's own build finds it there too. Commit it: a
20
+ * build that does not run yodel (chant build, an Op run elsewhere) reads
21
+ * the committed file.
22
+ *
23
+ * Each object has one owner: an object a source creates that `src/` (or
24
+ * another source) also declares is an error, naming both.
25
+ */
26
+ import { exec } from "node:child_process";
27
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
28
+ import { isAbsolute, join, relative } from "node:path";
29
+ import { YodelError } from "../project.js";
30
+ import { ddlToDeclarations } from "./ddl.js";
31
+ const SOURCE_NAME = /^[a-z][a-z0-9-]*$/;
32
+ /** The generated file a source writes, relative to the project directory. */
33
+ export const generatedPath = (project, name) => join(project.sourceDir, `${name}.generated.ts`);
34
+ /** Checks `sources` in yodel.config.ts. */
35
+ export function checkSources(value, where) {
36
+ if (typeof value !== "object" || value === null || Array.isArray(value))
37
+ throw new YodelError(`${where}: expected an object keyed by source name`);
38
+ for (const [name, source] of Object.entries(value)) {
39
+ const at = `${where}.${name}`;
40
+ if (!SOURCE_NAME.test(name))
41
+ throw new YodelError(`${at}: a source's name is lowercase letters, digits and -, starting with a letter`);
42
+ if (typeof source !== "object" || source === null || Array.isArray(source))
43
+ throw new YodelError(`${at}: expected { command } or { file }`);
44
+ for (const k of Object.keys(source))
45
+ if (!["command", "file", "schema"].includes(k))
46
+ throw new YodelError(`${at}.${k}: unknown setting (expected command, file, schema)`);
47
+ const s = source;
48
+ if ((s.command === undefined) === (s.file === undefined))
49
+ throw new YodelError(`${at}: give one of command and file`);
50
+ for (const k of ["command", "file", "schema"]) {
51
+ if (s[k] !== undefined && (typeof s[k] !== "string" || s[k] === ""))
52
+ throw new YodelError(`${at}.${k}: expected a non-empty string`);
53
+ }
54
+ }
55
+ return value;
56
+ }
57
+ function runCommand(command, cwd, env) {
58
+ return new Promise((resolve, reject) => {
59
+ exec(command, { cwd, env: env ?? process.env, maxBuffer: 64 * 1024 * 1024 }, (error, stdout, stderr) => {
60
+ if (error)
61
+ reject(new YodelError(`${command} failed (exit ${String(error.code ?? "?")})${stderr.trim() ? `:\n${stderr.trim()}` : ""}`));
62
+ else
63
+ resolve(stdout);
64
+ });
65
+ });
66
+ }
67
+ /** Reads one source's DDL. */
68
+ async function readDdl(project, name, source, env) {
69
+ if (source.command !== undefined) {
70
+ const origin = `sources.${name} (${source.command})`;
71
+ try {
72
+ return { ddl: await runCommand(source.command, project.dir, env), origin };
73
+ }
74
+ catch (e) {
75
+ throw new YodelError(`yodel.config.ts sources.${name}: ${e instanceof Error ? e.message : String(e)}`);
76
+ }
77
+ }
78
+ const given = source.file ?? "";
79
+ const file = isAbsolute(given) ? given : join(project.dir, given);
80
+ if (!existsSync(file))
81
+ throw new YodelError(`yodel.config.ts sources.${name}: no file ${relative(project.dir, file)}`);
82
+ return { ddl: readFileSync(file, "utf8"), origin: `sources.${name} (${relative(project.dir, file)})` };
83
+ }
84
+ /**
85
+ * Writes each source's declarations to its generated file, and returns what
86
+ * each declared. A file whose content is unchanged is not rewritten.
87
+ */
88
+ export async function syncSources(project, options = {}) {
89
+ const sources = project.yodel?.config.sources ?? {};
90
+ const synced = [];
91
+ for (const [name, source] of Object.entries(sources)) {
92
+ const { ddl, origin } = await readDdl(project, name, source, options.env);
93
+ const how = source.command !== undefined ? `the output of: ${source.command}` : `the DDL in ${source.file ?? ""}`;
94
+ const declarations = await ddlToDeclarations(project.dialect, ddl, {
95
+ origin: `yodel.config.ts ${origin}`,
96
+ schema: source.schema,
97
+ header: `Generated by yodel from the DDL source "${name}" in yodel.config.ts,\n${how}\nDo not edit: yodel writes it again before each build.`,
98
+ });
99
+ const path = generatedPath(project, name);
100
+ const full = join(project.dir, path);
101
+ const before = existsSync(full) ? readFileSync(full, "utf8") : undefined;
102
+ if (before !== declarations.content)
103
+ writeFileSync(full, declarations.content);
104
+ synced.push({ name, path, objects: declarations.objects });
105
+ }
106
+ return synced;
107
+ }
108
+ /**
109
+ * chant's build refuses two declarations exported under one name. When one
110
+ * of them is a source's, that is an object declared twice: say so, naming
111
+ * the source.
112
+ */
113
+ export function duplicateExport(buildOutput, synced) {
114
+ const name = /Duplicate export name "([^"]+)"/.exec(buildOutput)?.[1];
115
+ if (!name)
116
+ return undefined;
117
+ const owners = synced.flatMap((s) => s.objects.filter((o) => o.export === name).map((o) => ({ source: s, object: o })));
118
+ const [first] = owners;
119
+ if (!first)
120
+ return undefined;
121
+ const elsewhere = owners.length > 1 ? `the source "${owners[1]?.source.name ?? ""}"` : "src/";
122
+ return new YodelError(`each object has one owner, and ${first.object.name} is declared twice: by ${elsewhere} (export ${name}) and by the source "${first.source.name}" (${first.source.path}). Leave it to one of them.`);
123
+ }
124
+ /** `schema.name` of a built object, read from its CREATE, or undefined when it cannot be read. */
125
+ async function builtName(dialect, type, ddl) {
126
+ try {
127
+ const first = ddl.split(/;\s*\n\s*COMMENT ON\b/i)[0] ?? ddl;
128
+ const [object] = (await ddlToDeclarations(dialect, first, { origin: "build" })).objects;
129
+ return object && (type === undefined || object.type === type) ? object.name : undefined;
130
+ }
131
+ catch {
132
+ return undefined;
133
+ }
134
+ }
135
+ /**
136
+ * Each object declared once: an object a source creates that another export
137
+ * in the build (in `src/`, or another source) also creates is an error.
138
+ */
139
+ export async function checkOwnership(output, synced) {
140
+ if (synced.length === 0)
141
+ return;
142
+ const owner = new Map();
143
+ for (const source of synced)
144
+ for (const object of source.objects)
145
+ owner.set(`${object.type} ${object.name}`, { source, object });
146
+ const problems = [];
147
+ for (const built of output.objects) {
148
+ if (synced.some((s) => s.objects.some((o) => o.export === built.export)))
149
+ continue;
150
+ const name = await builtName(output.dialect, built.type, built.ddl);
151
+ if (!name)
152
+ continue;
153
+ const hit = owner.get(`${built.type ?? ""} ${name}`);
154
+ if (hit)
155
+ problems.push(`${name} is declared by ${built.export} and by the source "${hit.source.name}" (${hit.object.export} in ${hit.source.path})`);
156
+ }
157
+ const seen = new Map();
158
+ for (const source of synced) {
159
+ for (const object of source.objects) {
160
+ const key = `${object.type} ${object.name}`;
161
+ const other = seen.get(key);
162
+ if (other && other !== source.name)
163
+ problems.push(`${object.name} is declared by the sources "${other}" and "${source.name}"`);
164
+ seen.set(key, source.name);
165
+ }
166
+ }
167
+ if (problems.length > 0)
168
+ throw new YodelError(`each object has one owner, and ${problems.length === 1 ? "one is declared twice" : `${String(problems.length)} are declared twice`}:\n${problems.map((p) => ` - ${p}`).join("\n")}`);
169
+ }
170
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sources/index.ts"],"names":[],"mappings":"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"}
@@ -15,40 +15,50 @@
15
15
  *
16
16
  * - The declaration is the migration's recorded schema (`migration.json`'s
17
17
  * `schema`), written to a temporary build file, not a fresh `chant build`.
18
- * - Its two gates (before the switch, before the contract) are left out. The
19
- * approval is the migration's: the step and its options are in the
20
- * migration's checksum, so in the plan digest the migrations Op's gate
21
- * approved. The verification still runs before the switch, and a
18
+ * - It is built with `gates: "outer"`: the approval is the migration's (the
19
+ * step and its options are in the migration's checksum, so in the plan
20
+ * digest the migrations Op's gate approved), so the Op has neither of its
21
+ * gates (before the switch, before the contract) and no Contract phase of
22
+ * its own. The verification still runs before the switch, and a
22
23
  * difference (a row whose new column is not the expression over the old,
23
24
  * a NULL where NOT NULL is declared) fails the step with nothing switched.
24
- * - The old column's retention is the step's `options.retain` when it sets
25
- * one, else none (`0s`): the contract drops the old column (and a rename's
26
- * trigger) in the same run, right after the switch, as the migration's
27
- * recorded schema says it is gone. A step that sets `retain` keeps the old
28
- * column that long; the step succeeds with it kept, its note says until
29
- * when, and dropping it after the date is `chant run` of the Op's
30
- * declaration (in `migration.json`), whose contract is convergent.
31
- * - Its onFailure (which drops what the expand added) is left out, so a step
32
- * that failed or was stopped resumes on the next `yodel apply`. Every
33
- * phase of the Op re-reads the server and does what is left of it: the
34
- * expand finds the new column there and adds nothing, the dual write finds
35
- * its trigger, the backfill skips every batch whose receipt is in
36
- * `<schema>.__chant_receipts` (each receipt commits with its batch, so a
37
- * batch is never filled twice), the carry over builds only the indexes and
38
- * constraints not yet built (an INVALID one it left is built again), the
39
- * verification runs again over every row, and a switch that already ran is
40
- * not run again. To start over instead, drop the new column, its trigger
41
- * and function (chant's working objects, named in their comments).
25
+ * - After the Retain phase the step runs the lexicon's contract activity
26
+ * (`postgresMigrationContract`, the Op's own Contract step, with the same
27
+ * arguments), under the same approval. It drops the old column (and a
28
+ * rename's trigger) only once its retention date has passed. The
29
+ * retention is the step's `options.retain` when it sets one, else none
30
+ * (`0s`): the contract drops the old column in the same run, right after
31
+ * the switch, as the migration's recorded schema says it is gone. A step
32
+ * that sets `retain` keeps the old column that long; the step succeeds
33
+ * with it kept, its note says until when, and dropping it after the date
34
+ * is `chant run` of the Op's declaration (in `migration.json`), whose
35
+ * contract is convergent.
36
+ * - It is built with `onFailure: "keep"`, so a step that failed or was
37
+ * stopped keeps what the expand added and resumes on the next `yodel
38
+ * apply`. Every phase of the Op re-reads the server and does what is left
39
+ * of it: the expand finds the new column there and adds nothing, the dual
40
+ * write finds its trigger, the backfill skips every batch whose receipt
41
+ * is in `<schema>.__chant_receipts` (each receipt commits with its batch,
42
+ * so a batch is never filled twice), the carry over builds only the
43
+ * indexes and constraints not yet built (an INVALID one it left is built
44
+ * again), the verification runs again over every row, and a switch that
45
+ * already ran is not run again. To start over instead, drop the new
46
+ * column, its trigger and function (chant's working objects, named in
47
+ * their comments; a refusal says so).
42
48
  */
43
- import type { OpConfig, PhaseDefinition } from "@intentius/chant/op/types";
49
+ import type { OpConfig } from "@intentius/chant/op/types";
44
50
  import type { ActivityFn } from "@intentius/chant/op/activity-registry";
45
51
  import type { StepRecord } from "@intentius/chant/op/local-executor";
46
52
  import type { PgMigrationOptions } from "./kinds.js";
47
53
  import { type RunOpOptions } from "./run.js";
48
54
  /** The retention a step runs with when its options set none: the contract runs in the same apply. */
49
55
  export declare const STEP_RETAIN = "0s";
50
- /** `PostgresMigrationOp`'s phases as a step runs them: no gates, no onFailure. */
51
- export declare function pgStepPhases(config: OpConfig): PhaseDefinition[];
56
+ /**
57
+ * The Op's Contract step for a config built with `gates: "outer"`: the
58
+ * lexicon's contract activity with the Retain step's arguments. It drops the
59
+ * old column only once its retention date has passed.
60
+ */
61
+ export declare function contractPhase(config: OpConfig): OpConfig["phases"][number];
52
62
  /** The Op a step runs. `buildPath` is the recorded schema's file; `projectDir` holds chant.config.ts. */
53
63
  export declare function pgMigrationOpConfig(options: PgMigrationOptions, ctx: {
54
64
  environment: string;
@@ -15,30 +15,36 @@
15
15
  *
16
16
  * - The declaration is the migration's recorded schema (`migration.json`'s
17
17
  * `schema`), written to a temporary build file, not a fresh `chant build`.
18
- * - Its two gates (before the switch, before the contract) are left out. The
19
- * approval is the migration's: the step and its options are in the
20
- * migration's checksum, so in the plan digest the migrations Op's gate
21
- * approved. The verification still runs before the switch, and a
18
+ * - It is built with `gates: "outer"`: the approval is the migration's (the
19
+ * step and its options are in the migration's checksum, so in the plan
20
+ * digest the migrations Op's gate approved), so the Op has neither of its
21
+ * gates (before the switch, before the contract) and no Contract phase of
22
+ * its own. The verification still runs before the switch, and a
22
23
  * difference (a row whose new column is not the expression over the old,
23
24
  * a NULL where NOT NULL is declared) fails the step with nothing switched.
24
- * - The old column's retention is the step's `options.retain` when it sets
25
- * one, else none (`0s`): the contract drops the old column (and a rename's
26
- * trigger) in the same run, right after the switch, as the migration's
27
- * recorded schema says it is gone. A step that sets `retain` keeps the old
28
- * column that long; the step succeeds with it kept, its note says until
29
- * when, and dropping it after the date is `chant run` of the Op's
30
- * declaration (in `migration.json`), whose contract is convergent.
31
- * - Its onFailure (which drops what the expand added) is left out, so a step
32
- * that failed or was stopped resumes on the next `yodel apply`. Every
33
- * phase of the Op re-reads the server and does what is left of it: the
34
- * expand finds the new column there and adds nothing, the dual write finds
35
- * its trigger, the backfill skips every batch whose receipt is in
36
- * `<schema>.__chant_receipts` (each receipt commits with its batch, so a
37
- * batch is never filled twice), the carry over builds only the indexes and
38
- * constraints not yet built (an INVALID one it left is built again), the
39
- * verification runs again over every row, and a switch that already ran is
40
- * not run again. To start over instead, drop the new column, its trigger
41
- * and function (chant's working objects, named in their comments).
25
+ * - After the Retain phase the step runs the lexicon's contract activity
26
+ * (`postgresMigrationContract`, the Op's own Contract step, with the same
27
+ * arguments), under the same approval. It drops the old column (and a
28
+ * rename's trigger) only once its retention date has passed. The
29
+ * retention is the step's `options.retain` when it sets one, else none
30
+ * (`0s`): the contract drops the old column in the same run, right after
31
+ * the switch, as the migration's recorded schema says it is gone. A step
32
+ * that sets `retain` keeps the old column that long; the step succeeds
33
+ * with it kept, its note says until when, and dropping it after the date
34
+ * is `chant run` of the Op's declaration (in `migration.json`), whose
35
+ * contract is convergent.
36
+ * - It is built with `onFailure: "keep"`, so a step that failed or was
37
+ * stopped keeps what the expand added and resumes on the next `yodel
38
+ * apply`. Every phase of the Op re-reads the server and does what is left
39
+ * of it: the expand finds the new column there and adds nothing, the dual
40
+ * write finds its trigger, the backfill skips every batch whose receipt
41
+ * is in `<schema>.__chant_receipts` (each receipt commits with its batch,
42
+ * so a batch is never filled twice), the carry over builds only the
43
+ * indexes and constraints not yet built (an INVALID one it left is built
44
+ * again), the verification runs again over every row, and a switch that
45
+ * already ran is not run again. To start over instead, drop the new
46
+ * column, its trigger and function (chant's working objects, named in
47
+ * their comments; a refusal says so).
42
48
  */
43
49
  import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
44
50
  import { tmpdir } from "node:os";
@@ -46,9 +52,16 @@ import { join } from "node:path";
46
52
  import { runOp, StepOpFailed } from "./run.js";
47
53
  /** The retention a step runs with when its options set none: the contract runs in the same apply. */
48
54
  export const STEP_RETAIN = "0s";
49
- /** `PostgresMigrationOp`'s phases as a step runs them: no gates, no onFailure. */
50
- export function pgStepPhases(config) {
51
- return config.phases.map((p) => ({ ...p, steps: p.steps.filter((s) => s.kind !== "gate") })).filter((p) => p.steps.length > 0);
55
+ /**
56
+ * The Op's Contract step for a config built with `gates: "outer"`: the
57
+ * lexicon's contract activity with the Retain step's arguments. It drops the
58
+ * old column only once its retention date has passed.
59
+ */
60
+ export function contractPhase(config) {
61
+ const retain = config.phases.flatMap((p) => p.steps).find((s) => s.kind === "activity" && s.fn === "postgresMigrationRetain");
62
+ if (!retain)
63
+ throw new Error(`PostgresMigrationOp "${config.name}" has no Retain step`);
64
+ return { name: "Contract", steps: [{ kind: "activity", fn: "postgresMigrationContract", ...(retain.args ? { args: retain.args } : {}) }] };
52
65
  }
53
66
  /** The Op a step runs. `buildPath` is the recorded schema's file; `projectDir` holds chant.config.ts. */
54
67
  export async function pgMigrationOpConfig(options, ctx) {
@@ -68,11 +81,11 @@ export async function pgMigrationOpConfig(options, ctx) {
68
81
  build: false,
69
82
  output: ctx.buildPath,
70
83
  path: ctx.projectDir,
84
+ gates: "outer",
85
+ onFailure: "keep",
71
86
  });
72
- const full = op.props;
73
- const rest = { ...full, phases: pgStepPhases(full) };
74
- delete rest.onFailure;
75
- return rest;
87
+ const config = op.props;
88
+ return { ...config, phases: [...config.phases, contractPhase(config)] };
76
89
  }
77
90
  /** The migration activities whose results the history's summary keeps. */
78
91
  const SUMMARIZED = ["postgresMigrationPlan", "postgresMigrationBackfill", "postgresMigrationCarry", "postgresMigrationVerify", "postgresMigrationSwitch", "postgresMigrationContract"];
@@ -1 +1 @@
1
- {"version":3,"file":"postgres-migration.js","sourceRoot":"","sources":["../../src/steps/postgres-migration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAKjC,OAAO,EAAE,KAAK,EAAE,YAAY,EAAqB,MAAM,UAAU,CAAC;AAElE,qGAAqG;AACrG,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC;AAEhC,kFAAkF;AAClF,MAAM,UAAU,YAAY,CAAC,MAAgB;IAC3C,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACjI,CAAC;AAED,yGAAyG;AACzG,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAA2B,EAAE,GAAuG;IAC5K,MAAM,EAAE,mBAAmB,EAAE,GAAG,MAAM,MAAM,CAAC,kDAAkD,CAAC,CAAC;IACjG,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,GAAG,CAAC,aAAa,CAAC;IACjE,MAAM,EAAE,EAAE,EAAE,GAAG,mBAAmB,CAAC;QACjC,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,GAAG,EAAE,GAAG,CAAC,WAAW;QACpB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,WAAW;QACrC,GAAG,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5E,GAAG,CAAC,OAAO,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3F,GAAG,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,GAAG,CAAC,OAAO,CAAC,kBAAkB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvG,KAAK,EAAE,KAAK;QACZ,MAAM,EAAE,GAAG,CAAC,SAAS;QACrB,IAAI,EAAE,GAAG,CAAC,UAAU;KACrB,CAAC,CAAC;IACH,MAAM,IAAI,GAAI,EAAqC,CAAC,KAAK,CAAC;IAC1D,MAAM,IAAI,GAAa,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;IAC/D,OAAO,IAAI,CAAC,SAAS,CAAC;IACtB,OAAO,IAAI,CAAC;AACd,CAAC;AAuBD,0EAA0E;AAC1E,MAAM,UAAU,GAAG,CAAC,uBAAuB,EAAE,2BAA2B,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,2BAA2B,CAAU,CAAC;AAEhM,MAAM,GAAG,GAAG,CAAC,CAAU,EAAsB,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AACxF,MAAM,GAAG,GAAG,CAAC,CAAU,EAAsB,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AAExF,8DAA8D;AAC9D,MAAM,UAAU,WAAW,CAAC,OAA2B,EAAE,EAAU,EAAE,MAAe;IAClF,MAAM,CAAC,GAAG,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAA4B,CAAC;IACnG,MAAM,GAAG,GAAG,CAAqC,CAAI,EAAE,CAAoC,EAAE,EAAE;QAC7F,IAAI,CAAC,KAAK,SAAS;YAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACtC,CAAC,CAAC;IACF,IAAI,EAAE,KAAK,uBAAuB,EAAE,CAAC;QACnC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3B,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/B,CAAC;IACD,IAAI,EAAE,KAAK,2BAA2B,EAAE,CAAC;QACvC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QAC7B,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;QAC/B,GAAG,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACrC,CAAC;IACD,IAAI,EAAE,KAAK,wBAAwB;QAAE,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IAClE,IAAI,EAAE,KAAK,yBAAyB;QAAE,GAAG,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACvE,IAAI,EAAE,KAAK,yBAAyB,EAAE,CAAC;QACrC,GAAG,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC1E,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;QACnC,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;IACzC,CAAC;IACD,IAAI,EAAE,KAAK,2BAA2B,EAAE,CAAC;QACvC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACvE,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;QACnC,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;IACzC,CAAC;AACH,CAAC;AAaD,2IAA2I;AAC3I,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAA2B,EAC3B,GAA0B,EAC1B,UAA8B,EAAE,EAAE,EAAE,qBAAqB,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;IAEzG,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAC/D,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QAC3C,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QACrD,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC;QAC7J,MAAM,OAAO,GAAG,GAAG,CAAC,UAAU,IAAK,CAAC,MAAM,MAAM,CAAC,4CAA4C,CAAC,CAA2C,CAAC;QAC1I,MAAM,OAAO,GAA+B,EAAE,CAAC;QAC/C,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;YAC1B,IAAI,CAAC,KAAK;gBAAE,SAAS;YACrB,OAAO,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;gBACnC,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBACzC,WAAW,CAAC,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;gBACjC,OAAO,MAAM,CAAC;YAChB,CAAC,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE;YAClC,GAAG,EAAE,GAAG,CAAC,UAAU;YACnB,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,UAAU,EAAE,EAAE,GAAG,CAAC,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE,GAAG,OAAO,EAAE;YACrD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7C,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACpD,CAAC,CAAC,KAAK,CAAC,CAAC,CAAU,EAAE,EAAE;YACtB,IAAI,CAAC,YAAY,YAAY;gBAAE,CAAC,CAAC,OAAO,GAAG,OAAO,CAAC;YACnD,MAAM,CAAC,CAAC;QACV,CAAC,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;IAC9B,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"postgres-migration.js","sourceRoot":"","sources":["../../src/steps/postgres-migration.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Tenant sets (#56): one environment over many databases (ClickHouse) or
3
+ * schemas (Postgres) with the same migrations.
4
+ *
5
+ * `yodel.config.ts` `environments.<env>.tenants` lists them (names, a file,
6
+ * or a read-only query on the environment's server). Each tenant is a
7
+ * target of its own, `<env>/<tenant>`: its profile is the environment's on
8
+ * the tenant's database or schema (`resolveEnvironment`), its history is
9
+ * `<history database>_<tenant>` (`environmentSettings`), and every
10
+ * statement and check is sent with the template's name replaced by the
11
+ * tenant's ({@link tenantDriver}). The apply pipeline renders the
12
+ * environment's wave with a run per tenant, one gate over all of them.
13
+ */
14
+ import type { TenantSet } from "../config/define.js";
15
+ import { type Environment, type Project, type TenantOf } from "../project.js";
16
+ import type { VersionedDriver } from "../versioned/driver.js";
17
+ export * from "./target.js";
18
+ /** `env`'s tenant set in yodel.config.ts, if it has one. */
19
+ export declare const tenantSetOf: (project: Pick<Project, "yodel">, env: string) => TenantSet | undefined;
20
+ /** Reads a tenant file: a JSON array of names, or one name per line (`#` starts a comment). */
21
+ export declare function readTenantFile(path: string): string[];
22
+ /**
23
+ * The tenants of `env`, in the order the set gives them; undefined when it
24
+ * has no set. A query runs read-only on the environment's server, with its
25
+ * profile, and its rows' first column are the names.
26
+ */
27
+ export declare function listTenants(project: Project, env: string): Promise<string[] | undefined>;
28
+ /** Throws unless `env`'s tenant set names the tenant `env` is. */
29
+ export declare function checkTenant(project: Project, env: Environment): Promise<void>;
30
+ /**
31
+ * The targets `names` stand for: an environment with a tenant set is each
32
+ * of its tenants, `<env>/<tenant>`; any other name is itself.
33
+ */
34
+ export declare function expandTargets(project: Project, names: readonly string[]): Promise<string[]>;
35
+ /**
36
+ * A tenant's driver: the environment's, with the template's name replaced
37
+ * by the tenant's in every statement and check it sends. An Op step (a
38
+ * rebuild, a backfill) names its tables itself and does not run on a tenant.
39
+ */
40
+ export declare function tenantDriver(driver: VersionedDriver, tenant: TenantOf): VersionedDriver;
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Tenant sets (#56): one environment over many databases (ClickHouse) or
3
+ * schemas (Postgres) with the same migrations.
4
+ *
5
+ * `yodel.config.ts` `environments.<env>.tenants` lists them (names, a file,
6
+ * or a read-only query on the environment's server). Each tenant is a
7
+ * target of its own, `<env>/<tenant>`: its profile is the environment's on
8
+ * the tenant's database or schema (`resolveEnvironment`), its history is
9
+ * `<history database>_<tenant>` (`environmentSettings`), and every
10
+ * statement and check is sent with the template's name replaced by the
11
+ * tenant's ({@link tenantDriver}). The apply pipeline renders the
12
+ * environment's wave with a run per tenant, one gate over all of them.
13
+ */
14
+ import { existsSync, readFileSync } from "node:fs";
15
+ import { resolve } from "node:path";
16
+ import { resolveEnvironment, YodelError } from "../project.js";
17
+ import { renameIdentifier, splitTarget, TENANT_NAME, tenantTarget } from "./target.js";
18
+ export * from "./target.js";
19
+ /** `env`'s tenant set in yodel.config.ts, if it has one. */
20
+ export const tenantSetOf = (project, env) => project.yodel?.config.environments?.[env]?.tenants;
21
+ function checked(names, where) {
22
+ const bad = names.filter((n) => !TENANT_NAME.test(n));
23
+ if (bad.length > 0)
24
+ throw new YodelError(`${where} lists ${bad.map((b) => JSON.stringify(b)).join(", ")}, which ${bad.length === 1 ? "is not a tenant name" : "are not tenant names"} (letters, digits and _, not starting with a digit)`);
25
+ return [...new Set(names)];
26
+ }
27
+ /** Reads a tenant file: a JSON array of names, or one name per line (`#` starts a comment). */
28
+ export function readTenantFile(path) {
29
+ if (!existsSync(path))
30
+ throw new YodelError(`the tenant file ${path} does not exist`);
31
+ const text = readFileSync(path, "utf8");
32
+ if (text.trimStart().startsWith("[")) {
33
+ let parsed;
34
+ try {
35
+ parsed = JSON.parse(text);
36
+ }
37
+ catch (e) {
38
+ throw new YodelError(`${path}: ${e instanceof Error ? e.message : String(e)}`);
39
+ }
40
+ if (!Array.isArray(parsed) || !parsed.every((t) => typeof t === "string"))
41
+ throw new YodelError(`${path}: expected a JSON array of tenant names`);
42
+ return checked(parsed, path);
43
+ }
44
+ return checked(text.split("\n").map((l) => l.replace(/#.*/, "").trim()).filter(Boolean), path);
45
+ }
46
+ /**
47
+ * The tenants of `env`, in the order the set gives them; undefined when it
48
+ * has no set. A query runs read-only on the environment's server, with its
49
+ * profile, and its rows' first column are the names.
50
+ */
51
+ export async function listTenants(project, env) {
52
+ const set = tenantSetOf(project, env);
53
+ if (set === undefined)
54
+ return undefined;
55
+ if (Array.isArray(set))
56
+ return [...set];
57
+ if ("file" in set)
58
+ return readTenantFile(resolve(project.dir, set.file));
59
+ const { openVersioned, closeVersioned } = await import("../versioned/engine.js");
60
+ const venv = await openVersioned(project, resolveEnvironment(project, env));
61
+ try {
62
+ let rows;
63
+ try {
64
+ rows = await venv.driver.readCheck(set.query, {});
65
+ }
66
+ catch (e) {
67
+ throw new YodelError(`${env}'s tenant query failed: ${e instanceof Error ? e.message : String(e)}`);
68
+ }
69
+ return checked(rows.map((r) => { const v = Object.values(r)[0]; return typeof v === "string" ? v : JSON.stringify(v ?? ""); }), `${env}'s tenant query`);
70
+ }
71
+ finally {
72
+ await closeVersioned(venv);
73
+ }
74
+ }
75
+ /** Throws unless `env`'s tenant set names the tenant `env` is. */
76
+ export async function checkTenant(project, env) {
77
+ if (!env.tenant)
78
+ return;
79
+ const set = tenantSetOf(project, env.tenant.env);
80
+ if (Array.isArray(set))
81
+ return; // resolveEnvironment checked it.
82
+ const names = (await listTenants(project, env.tenant.env)) ?? [];
83
+ if (!names.includes(env.tenant.name)) {
84
+ throw new YodelError(`no tenant "${env.tenant.name}" in ${env.tenant.env}'s tenant set (${set && "file" in set ? set.file : "its query"} lists ${names.length > 0 ? names.join(", ") : "none"})`);
85
+ }
86
+ }
87
+ /**
88
+ * The targets `names` stand for: an environment with a tenant set is each
89
+ * of its tenants, `<env>/<tenant>`; any other name is itself.
90
+ */
91
+ export async function expandTargets(project, names) {
92
+ const out = [];
93
+ for (const name of names) {
94
+ const tenants = splitTarget(name).tenant === undefined ? await listTenants(project, name) : undefined;
95
+ if (tenants)
96
+ out.push(...tenants.map((t) => tenantTarget(name, t)));
97
+ else
98
+ out.push(name);
99
+ }
100
+ return out;
101
+ }
102
+ /**
103
+ * A tenant's driver: the environment's, with the template's name replaced
104
+ * by the tenant's in every statement and check it sends. An Op step (a
105
+ * rebuild, a backfill) names its tables itself and does not run on a tenant.
106
+ */
107
+ export function tenantDriver(driver, tenant) {
108
+ const rename = (sql) => renameIdentifier(sql, tenant.template, tenant.name);
109
+ const where = (w) => ({
110
+ ...(w.defaultDatabase !== undefined ? { defaultDatabase: rename(w.defaultDatabase) } : {}),
111
+ ...(w.defaultSchema !== undefined ? { defaultSchema: rename(w.defaultSchema) } : {}),
112
+ });
113
+ return {
114
+ ...driver,
115
+ readCheck: (sql, w) => driver.readCheck(rename(sql), where(w)),
116
+ runStatement: (step, run) => driver.runStatement({ ...step, sql: rename(step.sql) }, run),
117
+ stepContext: () => {
118
+ throw new YodelError(`an Op step does not run on a tenant (${tenantTarget(tenant.env, tenant.name)}): only statements are renamed from ${tenant.template} to ${tenant.name}`);
119
+ },
120
+ };
121
+ }
122
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tenants/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Tenant targets (#56), the parts every module can import: a tenant of
3
+ * environment `prod` is the target `prod/<tenant>`, and its migrations are
4
+ * the environment's with the template database or schema renamed.
5
+ */
6
+ /** Between an environment and a tenant in a target's name. */
7
+ export declare const TENANT_SEPARATOR = "/";
8
+ /** A tenant's name: a database or schema name, and part of a target's name and of a file's. */
9
+ export declare const TENANT_NAME: RegExp;
10
+ /** `prod/acme` is environment `prod`, tenant `acme`; `prod` is `prod` alone. */
11
+ export declare function splitTarget(name: string): {
12
+ env: string;
13
+ tenant?: string;
14
+ };
15
+ /** The environment a target belongs to: `prod` for `prod/acme` and for `prod`. */
16
+ export declare const baseEnvironment: (name: string) => string;
17
+ export declare const tenantTarget: (env: string, tenant: string) => string;
18
+ /**
19
+ * `sql` with every identifier `from` replaced by `to`: the name standing
20
+ * alone, bare or quoted (`from.orders`, `"from"`, `` `from` ``), never a
21
+ * longer name that contains it (`from_archive`).
22
+ */
23
+ export declare function renameIdentifier(sql: string, from: string, to: string): string;