@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.
- package/README.md +3 -3
- package/dist/apply-steps/index.d.ts +65 -0
- package/dist/apply-steps/index.js +106 -0
- package/dist/apply-steps/index.js.map +1 -0
- package/dist/approval-mode/index.d.ts +78 -0
- package/dist/approval-mode/index.js +105 -0
- package/dist/approval-mode/index.js.map +1 -0
- package/dist/chant/access.d.ts +87 -0
- package/dist/chant/access.js +169 -0
- package/dist/chant/access.js.map +1 -0
- package/dist/chant/build.js +7 -0
- package/dist/chant/build.js.map +1 -1
- package/dist/chant/drift.d.ts +17 -1
- package/dist/chant/drift.js +55 -2
- package/dist/chant/drift.js.map +1 -1
- package/dist/chant/plan.d.ts +18 -2
- package/dist/chant/plan.js +21 -3
- package/dist/chant/plan.js.map +1 -1
- package/dist/ci/render.d.ts +333 -0
- package/dist/ci/render.js +885 -0
- package/dist/ci/render.js.map +1 -0
- package/dist/ci/replay.d.ts +17 -0
- package/dist/ci/replay.js +69 -0
- package/dist/ci/replay.js.map +1 -0
- package/dist/cleanup/index.d.ts +86 -0
- package/dist/cleanup/index.js +207 -0
- package/dist/cleanup/index.js.map +1 -0
- package/dist/commands/apply.d.ts +113 -0
- package/dist/commands/apply.js +370 -30
- package/dist/commands/apply.js.map +1 -1
- package/dist/commands/approve.d.ts +13 -0
- package/dist/commands/approve.js +239 -13
- package/dist/commands/approve.js.map +1 -1
- package/dist/commands/checkpoint.d.ts +3 -0
- package/dist/commands/checkpoint.js +78 -0
- package/dist/commands/checkpoint.js.map +1 -0
- package/dist/commands/ci.d.ts +3 -0
- package/dist/commands/ci.js +130 -0
- package/dist/commands/ci.js.map +1 -0
- package/dist/commands/cleanup.d.ts +13 -0
- package/dist/commands/cleanup.js +138 -0
- package/dist/commands/cleanup.js.map +1 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.js +136 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/docs.d.ts +11 -0
- package/dist/commands/docs.js +108 -0
- package/dist/commands/docs.js.map +1 -0
- package/dist/commands/drift.d.ts +13 -1
- package/dist/commands/drift.js +52 -5
- package/dist/commands/drift.js.map +1 -1
- package/dist/commands/index.js +16 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/init.js +1 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/lint.js +39 -7
- package/dist/commands/lint.js.map +1 -1
- package/dist/commands/new.js +133 -34
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/override.js +48 -16
- package/dist/commands/override.js.map +1 -1
- package/dist/commands/plan.js +47 -6
- package/dist/commands/plan.js.map +1 -1
- package/dist/commands/report.d.ts +13 -0
- package/dist/commands/report.js +121 -0
- package/dist/commands/report.js.map +1 -0
- package/dist/commands/revert.d.ts +20 -0
- package/dist/commands/revert.js +246 -0
- package/dist/commands/revert.js.map +1 -0
- package/dist/commands/status.js +32 -5
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/test.d.ts +3 -0
- package/dist/commands/test.js +164 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/config/base.d.ts +69 -0
- package/dist/config/base.js +121 -0
- package/dist/config/base.js.map +1 -0
- package/dist/config/define.d.ts +240 -3
- package/dist/config/define.js +4 -0
- package/dist/config/define.js.map +1 -1
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.js +2 -0
- package/dist/config/index.js.map +1 -1
- package/dist/config/load.d.ts +1 -1
- package/dist/config/load.js +156 -7
- package/dist/config/load.js.map +1 -1
- package/dist/config/settings.d.ts +22 -1
- package/dist/config/settings.js +34 -2
- package/dist/config/settings.js.map +1 -1
- package/dist/credentials.d.ts +119 -0
- package/dist/credentials.js +119 -0
- package/dist/credentials.js.map +1 -0
- package/dist/exit.js +1 -1
- package/dist/exit.js.map +1 -1
- package/dist/history/postgres/ddl.d.ts +18 -0
- package/dist/history/postgres/ddl.js +27 -2
- package/dist/history/postgres/ddl.js.map +1 -1
- package/dist/history/postgres/store.d.ts +2 -0
- package/dist/history/postgres/store.js +7 -1
- package/dist/history/postgres/store.js.map +1 -1
- package/dist/history/rows.d.ts +16 -3
- package/dist/history/rows.js +30 -1
- package/dist/history/rows.js.map +1 -1
- package/dist/history/store.d.ts +2 -0
- package/dist/history/store.js +2 -2
- package/dist/history/store.js.map +1 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/init/adopt.js +1 -1
- package/dist/init/adopt.js.map +1 -1
- package/dist/init/clickhouse-access.d.ts +64 -0
- package/dist/init/clickhouse-access.js +211 -0
- package/dist/init/clickhouse-access.js.map +1 -0
- package/dist/init/live.d.ts +4 -0
- package/dist/init/live.js +16 -0
- package/dist/init/live.js.map +1 -1
- package/dist/lint/access.d.ts +18 -0
- package/dist/lint/access.js +34 -0
- package/dist/lint/access.js.map +1 -0
- package/dist/lint/check.js +38 -6
- package/dist/lint/check.js.map +1 -1
- package/dist/lint/config.d.ts +7 -1
- package/dist/lint/config.js +11 -5
- package/dist/lint/config.js.map +1 -1
- package/dist/lint/index.d.ts +2 -0
- package/dist/lint/index.js +2 -0
- package/dist/lint/index.js.map +1 -1
- package/dist/lint/naming.d.ts +62 -0
- package/dist/lint/naming.js +138 -0
- package/dist/lint/naming.js.map +1 -0
- package/dist/lint/report.js +1 -1
- package/dist/lint/report.js.map +1 -1
- package/dist/lint/routines.d.ts +26 -0
- package/dist/lint/routines.js +65 -0
- package/dist/lint/routines.js.map +1 -0
- package/dist/lint/rules.d.ts +51 -6
- package/dist/lint/rules.js +23 -6
- package/dist/lint/rules.js.map +1 -1
- package/dist/lint/schema-checks.d.ts +63 -0
- package/dist/lint/schema-checks.js +128 -0
- package/dist/lint/schema-checks.js.map +1 -0
- package/dist/lint/statements.d.ts +22 -1
- package/dist/lint/statements.js +40 -1
- package/dist/lint/statements.js.map +1 -1
- package/dist/mcp/tools.d.ts +1 -1
- package/dist/mcp/tools.js +1 -1
- package/dist/mcp/tools.js.map +1 -1
- package/dist/migrations/checkpoint.d.ts +45 -0
- package/dist/migrations/checkpoint.js +108 -0
- package/dist/migrations/checkpoint.js.map +1 -0
- package/dist/migrations/checks.d.ts +19 -1
- package/dist/migrations/checks.js +15 -0
- package/dist/migrations/checks.js.map +1 -1
- package/dist/migrations/create.d.ts +13 -4
- package/dist/migrations/create.js +24 -7
- package/dist/migrations/create.js.map +1 -1
- package/dist/migrations/document.d.ts +10 -0
- package/dist/migrations/document.js +1 -0
- package/dist/migrations/document.js.map +1 -1
- package/dist/migrations/index.d.ts +2 -0
- package/dist/migrations/index.js +2 -0
- package/dist/migrations/index.js.map +1 -1
- package/dist/migrations/routines.d.ts +21 -0
- package/dist/migrations/routines.js +30 -0
- package/dist/migrations/routines.js.map +1 -0
- package/dist/notify/index.d.ts +124 -0
- package/dist/notify/index.js +210 -0
- package/dist/notify/index.js.map +1 -0
- package/dist/notify/verify.d.ts +53 -0
- package/dist/notify/verify.js +71 -0
- package/dist/notify/verify.js.map +1 -0
- package/dist/pr/model.d.ts +7 -1
- package/dist/pr/model.js +29 -7
- package/dist/pr/model.js.map +1 -1
- package/dist/pr/render.d.ts +4 -1
- package/dist/pr/render.js +49 -9
- package/dist/pr/render.js.map +1 -1
- package/dist/pr/tenants.d.ts +37 -0
- package/dist/pr/tenants.js +138 -0
- package/dist/pr/tenants.js.map +1 -0
- package/dist/probe.d.ts +27 -0
- package/dist/probe.js +106 -0
- package/dist/probe.js.map +1 -0
- package/dist/project.d.ts +35 -2
- package/dist/project.js +62 -2
- package/dist/project.js.map +1 -1
- package/dist/replay/clickhouse.d.ts +31 -0
- package/dist/replay/clickhouse.js +103 -6
- package/dist/replay/clickhouse.js.map +1 -1
- package/dist/replay/replay.d.ts +14 -3
- package/dist/replay/replay.js +62 -31
- package/dist/replay/replay.js.map +1 -1
- package/dist/replay/report.js +1 -1
- package/dist/replay/report.js.map +1 -1
- package/dist/report/audit.d.ts +138 -0
- package/dist/report/audit.js +219 -0
- package/dist/report/audit.js.map +1 -0
- package/dist/report/jsonl.d.ts +21 -0
- package/dist/report/jsonl.js +52 -0
- package/dist/report/jsonl.js.map +1 -0
- package/dist/report/model.d.ts +68 -0
- package/dist/report/model.js +127 -0
- package/dist/report/model.js.map +1 -0
- package/dist/report/render.d.ts +18 -0
- package/dist/report/render.js +127 -0
- package/dist/report/render.js.map +1 -0
- package/dist/schema-docs/render.d.ts +49 -0
- package/dist/schema-docs/render.js +359 -0
- package/dist/schema-docs/render.js.map +1 -0
- package/dist/schemas.d.ts +7 -2
- package/dist/schemas.js +7 -2
- package/dist/schemas.js.map +1 -1
- package/dist/sources/ddl.d.ts +48 -0
- package/dist/sources/ddl.js +53 -0
- package/dist/sources/ddl.js.map +1 -0
- package/dist/sources/index.d.ts +69 -0
- package/dist/sources/index.js +170 -0
- package/dist/sources/index.js.map +1 -0
- package/dist/steps/backfill.d.ts +40 -5
- package/dist/steps/backfill.js +128 -8
- package/dist/steps/backfill.js.map +1 -1
- package/dist/steps/index.d.ts +19 -1
- package/dist/steps/index.js +34 -7
- package/dist/steps/index.js.map +1 -1
- package/dist/steps/kinds.d.ts +42 -4
- package/dist/steps/kinds.js +88 -14
- package/dist/steps/kinds.js.map +1 -1
- package/dist/steps/postgres-migration.d.ts +38 -25
- package/dist/steps/postgres-migration.js +49 -32
- package/dist/steps/postgres-migration.js.map +1 -1
- package/dist/steps/rebuild.d.ts +15 -6
- package/dist/steps/rebuild.js +12 -9
- package/dist/steps/rebuild.js.map +1 -1
- package/dist/tenants/index.d.ts +41 -0
- package/dist/tenants/index.js +121 -0
- package/dist/tenants/index.js.map +1 -0
- package/dist/tenants/target.d.ts +23 -0
- package/dist/tenants/target.js +29 -0
- package/dist/tenants/target.js.map +1 -0
- package/dist/tenants/wave.d.ts +128 -0
- package/dist/tenants/wave.js +254 -0
- package/dist/tenants/wave.js.map +1 -0
- package/dist/testing/define.d.ts +62 -0
- package/dist/testing/define.js +32 -0
- package/dist/testing/define.js.map +1 -0
- package/dist/testing/files.d.ts +5 -0
- package/dist/testing/files.js +18 -0
- package/dist/testing/files.js.map +1 -0
- package/dist/testing/report.d.ts +14 -0
- package/dist/testing/report.js +83 -0
- package/dist/testing/report.js.map +1 -0
- package/dist/testing/run.d.ts +104 -0
- package/dist/testing/run.js +328 -0
- package/dist/testing/run.js.map +1 -0
- package/dist/versioned/approval.d.ts +6 -0
- package/dist/versioned/approval.js +11 -5
- package/dist/versioned/approval.js.map +1 -1
- package/dist/versioned/checks.d.ts +8 -2
- package/dist/versioned/checks.js +34 -13
- package/dist/versioned/checks.js.map +1 -1
- package/dist/versioned/driver.d.ts +2 -2
- package/dist/versioned/engine.d.ts +16 -0
- package/dist/versioned/engine.js +20 -6
- package/dist/versioned/engine.js.map +1 -1
- package/dist/versioned/explain.d.ts +2 -0
- package/dist/versioned/explain.js +3 -1
- package/dist/versioned/explain.js.map +1 -1
- package/dist/versioned/index.d.ts +1 -0
- package/dist/versioned/index.js +1 -0
- package/dist/versioned/index.js.map +1 -1
- package/dist/versioned/op.d.ts +6 -1
- package/dist/versioned/op.js +7 -2
- package/dist/versioned/op.js.map +1 -1
- package/dist/versioned/policy.d.ts +33 -2
- package/dist/versioned/policy.js +59 -8
- package/dist/versioned/policy.js.map +1 -1
- package/dist/versioned/report.js +9 -0
- package/dist/versioned/report.js.map +1 -1
- package/dist/versioned/revert.d.ts +128 -0
- package/dist/versioned/revert.js +251 -0
- package/dist/versioned/revert.js.map +1 -0
- package/dist/versioned/state.d.ts +25 -0
- package/dist/versioned/state.js +37 -4
- package/dist/versioned/state.js.map +1 -1
- package/dist/waves/index.d.ts +224 -0
- package/dist/waves/index.js +353 -0
- package/dist/waves/index.js.map +1 -0
- package/dist/waves/promotion.d.ts +56 -0
- package/dist/waves/promotion.js +108 -0
- package/dist/waves/promotion.js.map +1 -0
- package/dist/waves/record.d.ts +34 -0
- package/dist/waves/record.js +20 -0
- package/dist/waves/record.js.map +1 -0
- package/package.json +11 -7
- package/schemas/apply.schema.json +162 -3
- package/schemas/checkpoint.schema.json +19 -0
- package/schemas/cleanup.schema.json +40 -0
- package/schemas/drift.schema.json +26 -1
- package/schemas/event.schema.json +36 -0
- package/schemas/lint-rules.schema.json +4 -0
- package/schemas/lint.schema.json +4 -0
- package/schemas/new.schema.json +41 -3
- package/schemas/plan.schema.json +157 -0
- package/schemas/report.schema.json +114 -0
- package/schemas/revert.schema.json +69 -0
- package/schemas/status.schema.json +64 -3
- package/schemas/test.schema.json +41 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checkpoints (#63): a migration that creates its parent's recorded schema
|
|
3
|
+
* from nothing, so a new environment starts there instead of running the
|
|
4
|
+
* whole chain.
|
|
5
|
+
*
|
|
6
|
+
* `yodel checkpoint <name>` writes one after the newest migration. Its
|
|
7
|
+
* steps are the diff from an empty schema to the parent's recorded schema
|
|
8
|
+
* (what `yodel new` writes for a first migration), its recorded schema is
|
|
9
|
+
* the parent's, and `migration.json` marks it with
|
|
10
|
+
* `checkpoint: { schema: <sha256 of that recorded schema> }`. The mark and
|
|
11
|
+
* the recorded schema are in its checksum like every other value.
|
|
12
|
+
*
|
|
13
|
+
* How an environment treats one is `../versioned/state.ts`'s: an
|
|
14
|
+
* environment whose history is empty starts at the newest checkpoint and
|
|
15
|
+
* never runs the migrations before it; one that already ran the chain skips
|
|
16
|
+
* the checkpoint. `yodel lint` checks that a checkpoint's recorded schema
|
|
17
|
+
* is still its parent's (rule `checkpoint`, offline), and `--replay` that
|
|
18
|
+
* its statements, run into an empty database, give that schema.
|
|
19
|
+
*/
|
|
20
|
+
import { type SchemaStatements } from "@intentius/chant-lexicon-sql/migration-statements";
|
|
21
|
+
import type { BuildOutput } from "../chant/build.js";
|
|
22
|
+
import { type MigrationDocument, type MigrationFiles } from "./document.js";
|
|
23
|
+
import type { Migration } from "./directory.js";
|
|
24
|
+
/** `sha256:<hex>` of a recorded schema, over its JSON with every object's keys sorted. */
|
|
25
|
+
export declare function schemaSha(schema: BuildOutput): string;
|
|
26
|
+
/** Whether a migration is a checkpoint. */
|
|
27
|
+
export declare const isCheckpoint: (m: Pick<Migration, "document">) => boolean;
|
|
28
|
+
export interface CreatedCheckpoint {
|
|
29
|
+
id: string;
|
|
30
|
+
document: MigrationDocument;
|
|
31
|
+
files: MigrationFiles;
|
|
32
|
+
statements: SchemaStatements;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The checkpoint that follows `parent`: statements that create `parent`'s
|
|
36
|
+
* recorded schema in an empty database. Throws a YodelError when that
|
|
37
|
+
* schema is empty, or when making it takes a step that is not a statement.
|
|
38
|
+
*/
|
|
39
|
+
export declare function createCheckpoint(options: {
|
|
40
|
+
name: string;
|
|
41
|
+
parent: Migration;
|
|
42
|
+
now?: Date;
|
|
43
|
+
}): CreatedCheckpoint;
|
|
44
|
+
/** What is wrong with a checkpoint, as `yodel lint` reports it (rule `checkpoint`): `[]` for a sound one, or for a migration that is not one. */
|
|
45
|
+
export declare function checkpointProblems(m: Migration, byId: ReadonlyMap<string, Migration>): string[];
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checkpoints (#63): a migration that creates its parent's recorded schema
|
|
3
|
+
* from nothing, so a new environment starts there instead of running the
|
|
4
|
+
* whole chain.
|
|
5
|
+
*
|
|
6
|
+
* `yodel checkpoint <name>` writes one after the newest migration. Its
|
|
7
|
+
* steps are the diff from an empty schema to the parent's recorded schema
|
|
8
|
+
* (what `yodel new` writes for a first migration), its recorded schema is
|
|
9
|
+
* the parent's, and `migration.json` marks it with
|
|
10
|
+
* `checkpoint: { schema: <sha256 of that recorded schema> }`. The mark and
|
|
11
|
+
* the recorded schema are in its checksum like every other value.
|
|
12
|
+
*
|
|
13
|
+
* How an environment treats one is `../versioned/state.ts`'s: an
|
|
14
|
+
* environment whose history is empty starts at the newest checkpoint and
|
|
15
|
+
* never runs the migrations before it; one that already ran the chain skips
|
|
16
|
+
* the checkpoint. `yodel lint` checks that a checkpoint's recorded schema
|
|
17
|
+
* is still its parent's (rule `checkpoint`, offline), and `--replay` that
|
|
18
|
+
* its statements, run into an empty database, give that schema.
|
|
19
|
+
*/
|
|
20
|
+
import { createHash } from "node:crypto";
|
|
21
|
+
import { diffStatements } from "@intentius/chant-lexicon-sql/migration-statements";
|
|
22
|
+
import { YodelError } from "../project.js";
|
|
23
|
+
import { computeChecksum } from "./checksum.js";
|
|
24
|
+
import { emptyBuild, migrationId, refusedSteps, renderMigrationSql } from "./create.js";
|
|
25
|
+
import { MIGRATION_FORMAT, serializeDocument, sortKeys } from "./document.js";
|
|
26
|
+
/** `sha256:<hex>` of a recorded schema, over its JSON with every object's keys sorted. */
|
|
27
|
+
export function schemaSha(schema) {
|
|
28
|
+
return `sha256:${createHash("sha256").update(JSON.stringify(sortKeys(schema)), "utf8").digest("hex")}`;
|
|
29
|
+
}
|
|
30
|
+
/** Whether a migration is a checkpoint. */
|
|
31
|
+
export const isCheckpoint = (m) => m.document.checkpoint !== undefined;
|
|
32
|
+
/**
|
|
33
|
+
* The checkpoint that follows `parent`: statements that create `parent`'s
|
|
34
|
+
* recorded schema in an empty database. Throws a YodelError when that
|
|
35
|
+
* schema is empty, or when making it takes a step that is not a statement.
|
|
36
|
+
*/
|
|
37
|
+
export function createCheckpoint(options) {
|
|
38
|
+
const { parent } = options;
|
|
39
|
+
const now = options.now ?? new Date();
|
|
40
|
+
const id = migrationId(options.name, now);
|
|
41
|
+
const schema = parent.document.schema;
|
|
42
|
+
if (!Array.isArray(schema.objects) || schema.objects.length === 0) {
|
|
43
|
+
throw new YodelError(`${parent.id}'s recorded schema declares nothing; there is nothing for a checkpoint to create`);
|
|
44
|
+
}
|
|
45
|
+
const before = emptyBuild(schema);
|
|
46
|
+
let statements;
|
|
47
|
+
try {
|
|
48
|
+
statements = diffStatements(before, schema, {
|
|
49
|
+
...(parent.document.defaultDatabase !== undefined ? { defaultDatabase: parent.document.defaultDatabase } : {}),
|
|
50
|
+
...(parent.document.defaultSchema !== undefined ? { defaultSchema: parent.document.defaultSchema } : {}),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
throw new YodelError(e instanceof Error ? e.message : String(e));
|
|
55
|
+
}
|
|
56
|
+
const refused = refusedSteps(statements.steps);
|
|
57
|
+
if (refused.length > 0) {
|
|
58
|
+
throw new YodelError(`${parent.id}'s recorded schema cannot be created by statements alone (${refused.map((s) => `${s.object}: ${s.kind} step`).join(", ")}); a checkpoint holds statements only`);
|
|
59
|
+
}
|
|
60
|
+
const unsigned = {
|
|
61
|
+
format: MIGRATION_FORMAT,
|
|
62
|
+
id,
|
|
63
|
+
parent: parent.id,
|
|
64
|
+
checksum: "",
|
|
65
|
+
createdAt: `${now.toISOString().slice(0, 19)}Z`,
|
|
66
|
+
dialect: statements.dialect,
|
|
67
|
+
...(statements.defaultDatabase !== undefined ? { defaultDatabase: statements.defaultDatabase } : {}),
|
|
68
|
+
...(statements.defaultSchema !== undefined ? { defaultSchema: statements.defaultSchema } : {}),
|
|
69
|
+
...(statements.major !== undefined ? { major: statements.major } : {}),
|
|
70
|
+
checkpoint: { schema: schemaSha(schema) },
|
|
71
|
+
refused: false,
|
|
72
|
+
hints: [],
|
|
73
|
+
steps: statements.steps,
|
|
74
|
+
schema,
|
|
75
|
+
};
|
|
76
|
+
const sql = renderMigrationSql(unsigned, statements).replace(/^-- yodel migration .*\n-- parent: .*\n/, `-- yodel checkpoint ${id}\n-- parent: ${parent.id}\n` +
|
|
77
|
+
`-- Creates ${parent.id}'s recorded schema from nothing. An environment whose history is empty\n` +
|
|
78
|
+
`-- starts here and never runs the migrations before it; one that already ran them skips this.\n`);
|
|
79
|
+
const document = { ...unsigned, checksum: computeChecksum({ sql, json: unsigned }) };
|
|
80
|
+
return { id, document, files: { sql, json: serializeDocument(document) }, statements };
|
|
81
|
+
}
|
|
82
|
+
/** What is wrong with a checkpoint, as `yodel lint` reports it (rule `checkpoint`): `[]` for a sound one, or for a migration that is not one. */
|
|
83
|
+
export function checkpointProblems(m, byId) {
|
|
84
|
+
const mark = m.document.checkpoint;
|
|
85
|
+
if (mark === undefined)
|
|
86
|
+
return [];
|
|
87
|
+
if (typeof mark !== "object" || mark === null || typeof mark.schema !== "string") {
|
|
88
|
+
return [`${m.id}: its checkpoint mark is not { "schema": "sha256:..." }`];
|
|
89
|
+
}
|
|
90
|
+
const recorded = mark.schema;
|
|
91
|
+
const out = [];
|
|
92
|
+
if (m.parent === null)
|
|
93
|
+
out.push(`${m.id} is a checkpoint with no parent; a checkpoint follows the migration whose recorded schema it creates`);
|
|
94
|
+
const own = schemaSha(m.document.schema);
|
|
95
|
+
if (own !== recorded)
|
|
96
|
+
out.push(`${m.id}: its recorded schema hashes to ${own}, but its checkpoint mark records ${recorded}; the checkpoint was edited after yodel checkpoint wrote it`);
|
|
97
|
+
const parent = m.parent === null ? undefined : byId.get(m.parent);
|
|
98
|
+
if (parent) {
|
|
99
|
+
const theirs = schemaSha(parent.document.schema);
|
|
100
|
+
if (theirs !== recorded)
|
|
101
|
+
out.push(`${m.id}: it was written from a recorded schema hashing to ${recorded}, but its parent ${parent.id}'s recorded schema now hashes to ${theirs}; write the checkpoint again (delete it, then yodel checkpoint)`);
|
|
102
|
+
}
|
|
103
|
+
const steps = m.document.steps.filter((s) => s.kind !== "statement");
|
|
104
|
+
if (steps.length > 0)
|
|
105
|
+
out.push(`${m.id}: a checkpoint holds statements only, and it has ${String(steps.length)} other step${steps.length === 1 ? "" : "s"}`);
|
|
106
|
+
return out;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=checkpoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint.js","sourceRoot":"","sources":["../../src/migrations/checkpoint.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,8 +7,26 @@
|
|
|
7
7
|
* the plan digest: editing, adding or removing one moves the digest, and an
|
|
8
8
|
* approval given before does not carry over.
|
|
9
9
|
*/
|
|
10
|
-
import type { MigrationCheck } from "./document.js";
|
|
10
|
+
import type { MigrationCheck, MigrationDocument } from "./document.js";
|
|
11
11
|
export type { MigrationCheck };
|
|
12
|
+
/**
|
|
13
|
+
* A check a migration runs before its first statement: one of its own
|
|
14
|
+
* `checks`, or a statement's pre-check (#51). chant marks a Postgres
|
|
15
|
+
* statement that can fail on the rows already there (a unique index over
|
|
16
|
+
* duplicates, SET NOT NULL over NULLs, a check or foreign key a row breaks)
|
|
17
|
+
* with a query counting those rows; it must return 0. `migration.json`
|
|
18
|
+
* records it on the step, so it is in the checksum like a check.
|
|
19
|
+
*/
|
|
20
|
+
export interface RunnableCheck extends MigrationCheck {
|
|
21
|
+
/** Set on a statement's pre-check: the step, its statement, and what the count is of. */
|
|
22
|
+
step?: {
|
|
23
|
+
index: number;
|
|
24
|
+
sql: string;
|
|
25
|
+
detail: string;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/** The checks run before a migration's first statement: its `checks`, then each statement's pre-check, named `precheck-<step>`. */
|
|
29
|
+
export declare function migrationChecks(doc: Pick<MigrationDocument, "checks" | "steps">): RunnableCheck[];
|
|
12
30
|
/** What is wrong with a `checks` value read from `migration.json`, or `undefined` when it is well formed. */
|
|
13
31
|
export declare function checksProblem(value: unknown): string | undefined;
|
|
14
32
|
/** What a check expects, in words. */
|
|
@@ -7,6 +7,21 @@
|
|
|
7
7
|
* the plan digest: editing, adding or removing one moves the digest, and an
|
|
8
8
|
* approval given before does not carry over.
|
|
9
9
|
*/
|
|
10
|
+
/** The checks run before a migration's first statement: its `checks`, then each statement's pre-check, named `precheck-<step>`. */
|
|
11
|
+
export function migrationChecks(doc) {
|
|
12
|
+
const own = [...(doc.checks ?? [])];
|
|
13
|
+
const taken = new Set(own.map((c) => c.name));
|
|
14
|
+
doc.steps.forEach((s, index) => {
|
|
15
|
+
if (s.kind !== "statement" || !s.precheck)
|
|
16
|
+
return;
|
|
17
|
+
let name = `precheck-${String(index)}`;
|
|
18
|
+
while (taken.has(name))
|
|
19
|
+
name = `${name}-statement`;
|
|
20
|
+
taken.add(name);
|
|
21
|
+
own.push({ name, sql: s.precheck.sql, expect: { max: 0 }, step: { index, sql: s.sql, detail: s.precheck.detail } });
|
|
22
|
+
});
|
|
23
|
+
return own;
|
|
24
|
+
}
|
|
10
25
|
const NAME = /^[a-z0-9][a-z0-9_-]*$/;
|
|
11
26
|
const isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
12
27
|
/** What is wrong with a `checks` value read from `migration.json`, or `undefined` when it is well formed. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checks.js","sourceRoot":"","sources":["../../src/migrations/checks.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"checks.js","sourceRoot":"","sources":["../../src/migrations/checks.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,7 @@ import { type DiffStatementsOptions, type SchemaStatements } from "@intentius/ch
|
|
|
11
11
|
import type { BuildOutput } from "../chant/build.js";
|
|
12
12
|
import { type MigrationCheck, type MigrationDocument, type MigrationFiles, type MigrationStep } from "./document.js";
|
|
13
13
|
import { type Migration } from "./directory.js";
|
|
14
|
+
import { type BackfillForm } from "../steps/kinds.js";
|
|
14
15
|
export interface CreateMigrationOptions {
|
|
15
16
|
/** The migration's name, the part of its id after the timestamp. */
|
|
16
17
|
name: string;
|
|
@@ -27,15 +28,23 @@ export interface CreateMigrationOptions {
|
|
|
27
28
|
/** Postgres: the schema a bare name means. Default: chant's, `public`. */
|
|
28
29
|
defaultSchema?: string;
|
|
29
30
|
/**
|
|
30
|
-
* A backfill step to end the migration with (#12):
|
|
31
|
-
*
|
|
32
|
-
* and counted in its checksum.
|
|
33
|
-
* build has no schema change.
|
|
31
|
+
* A backfill step to end the migration with (#12): a form, written as
|
|
32
|
+
* the step's options, or a module's text, written into the migration's
|
|
33
|
+
* directory as `file` (default `backfill.ts`) and counted in its checksum.
|
|
34
|
+
* With one, a migration is made even when the build has no schema change.
|
|
34
35
|
*/
|
|
35
36
|
backfill?: {
|
|
36
37
|
text: string;
|
|
37
38
|
file?: string;
|
|
39
|
+
} | {
|
|
40
|
+
form: BackfillForm;
|
|
38
41
|
};
|
|
42
|
+
/**
|
|
43
|
+
* How long a `PostgresMigrationOp` step keeps the old column, or a
|
|
44
|
+
* `ClickHouseRebuildOp` step the old table, after the switch: written
|
|
45
|
+
* into each such step's options (`retain`).
|
|
46
|
+
*/
|
|
47
|
+
retain?: string;
|
|
39
48
|
/** Pre-migration checks (#52), written to `migration.json`. */
|
|
40
49
|
checks?: MigrationCheck[];
|
|
41
50
|
}
|
|
@@ -12,8 +12,8 @@ import { YodelError } from "../project.js";
|
|
|
12
12
|
import { computeChecksum } from "./checksum.js";
|
|
13
13
|
import { MIGRATION_FORMAT, serializeDocument } from "./document.js";
|
|
14
14
|
import { MIGRATION_NAME } from "./directory.js";
|
|
15
|
-
import { asBackfill, BACKFILL_FILE } from "../steps/kinds.js";
|
|
16
|
-
import { backfillStep } from "../steps/backfill.js";
|
|
15
|
+
import { asBackfill, BACKFILL_FILE, describeForm, PG_MIGRATION_OP, REBUILD_OP } from "../steps/kinds.js";
|
|
16
|
+
import { backfillFormStep, backfillStep, describeFormSql } from "../steps/backfill.js";
|
|
17
17
|
/** `YYYYMMDDTHHMM` in UTC. */
|
|
18
18
|
export function migrationTimestamp(now) {
|
|
19
19
|
const iso = now.toISOString(); // 2026-10-09T14:12:34.567Z
|
|
@@ -43,8 +43,11 @@ export function emptyBuild(like) {
|
|
|
43
43
|
export const refusedSteps = (steps) => steps.filter((s) => s.kind !== "statement");
|
|
44
44
|
function describeRefused(s) {
|
|
45
45
|
const backfill = asBackfill(s);
|
|
46
|
-
if (backfill)
|
|
46
|
+
if (backfill) {
|
|
47
|
+
if (!("file" in backfill.options))
|
|
48
|
+
return `a backfill of ${describeForm(backfill.options)}, its batches resumable from their receipts`;
|
|
47
49
|
return `a backfill: the Op ${backfill.options.file} exports, its effect() batches resumable from their receipts`;
|
|
50
|
+
}
|
|
48
51
|
const rules = s.changes.map((c) => c.rule).join(", ");
|
|
49
52
|
return s.kind === "op"
|
|
50
53
|
? `${s.op} for ${s.object} (${s.name}), ${rules}: not SQL; migration.json holds its declaration`
|
|
@@ -64,12 +67,24 @@ export function renderMigrationSql(doc, statements) {
|
|
|
64
67
|
const body = statements.steps
|
|
65
68
|
.map((s) => {
|
|
66
69
|
const backfill = asBackfill(s);
|
|
67
|
-
|
|
70
|
+
if (!backfill)
|
|
71
|
+
return renderStatements({ ...statements, steps: [s] });
|
|
72
|
+
if ("file" in backfill.options)
|
|
73
|
+
return `-- ${backfill.object} (${backfill.name}): made by the Op ${backfill.options.file} exports, not a statement\n`;
|
|
74
|
+
const sql = describeFormSql(backfill.options).split("\n").map((l) => `-- ${l}`);
|
|
75
|
+
return `-- ${backfill.object} (${backfill.name}): a backfill of ${describeForm(backfill.options)}, not a statement; each batch runs:\n${sql.join("\n")}\n`;
|
|
68
76
|
})
|
|
69
77
|
.join("\n")
|
|
70
78
|
.replace(/\n+$/, "");
|
|
71
79
|
return `${head.join("\n")}\n\n${body}\n`;
|
|
72
80
|
}
|
|
81
|
+
/** `step` with `retain` in its options (and its declaration) when it is a column migration or a rebuild. */
|
|
82
|
+
function withRetain(step, retain) {
|
|
83
|
+
if (step.kind !== "op" || ![PG_MIGRATION_OP, REBUILD_OP].includes(step.op))
|
|
84
|
+
return step;
|
|
85
|
+
const declaration = /\s*\}\);?\s*$/.test(step.declaration) ? step.declaration.replace(/\s*\}\)(;?)\s*$/, `, retain: ${JSON.stringify(retain)} })$1`) : step.declaration;
|
|
86
|
+
return { ...step, options: { ...step.options, retain }, declaration };
|
|
87
|
+
}
|
|
73
88
|
/**
|
|
74
89
|
* The next migration, or a {@link NoChange} when the build declares the
|
|
75
90
|
* schema the previous migration recorded. Throws a YodelError when the
|
|
@@ -90,9 +105,11 @@ export function createMigration(options) {
|
|
|
90
105
|
catch (e) {
|
|
91
106
|
throw new YodelError(e instanceof Error ? e.message : String(e));
|
|
92
107
|
}
|
|
108
|
+
if (options.retain !== undefined)
|
|
109
|
+
statements = { ...statements, steps: statements.steps.map((s) => withRetain(s, options.retain)) };
|
|
93
110
|
if (options.backfill) {
|
|
94
|
-
const
|
|
95
|
-
statements = { ...statements, refused: true, steps: [...statements.steps,
|
|
111
|
+
const step = "form" in options.backfill ? backfillFormStep(options.name, options.backfill.form) : backfillStep(options.name, options.backfill.file ?? BACKFILL_FILE);
|
|
112
|
+
statements = { ...statements, refused: true, steps: [...statements.steps, step] };
|
|
96
113
|
}
|
|
97
114
|
if (statements.steps.length === 0)
|
|
98
115
|
return { id: undefined, statements };
|
|
@@ -113,7 +130,7 @@ export function createMigration(options) {
|
|
|
113
130
|
schema: options.build,
|
|
114
131
|
};
|
|
115
132
|
const sql = renderMigrationSql(unsigned, statements);
|
|
116
|
-
const extra = options.backfill ? { [options.backfill.file ?? BACKFILL_FILE]: options.backfill.text } : undefined;
|
|
133
|
+
const extra = options.backfill && "text" in options.backfill ? { [options.backfill.file ?? BACKFILL_FILE]: options.backfill.text } : undefined;
|
|
117
134
|
const document = { ...unsigned, checksum: computeChecksum({ sql, json: unsigned, extra }) };
|
|
118
135
|
return { id, document, files: { sql, json: serializeDocument(document), ...(extra ? { extra } : {}) }, statements };
|
|
119
136
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/migrations/create.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAqD,MAAM,mDAAmD,CAAC;AACxJ,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAwF,MAAM,eAAe,CAAC;AAC1J,OAAO,EAAE,cAAc,EAAkB,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/migrations/create.ts"],"names":[],"mappings":"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"}
|
|
@@ -63,6 +63,16 @@ export interface MigrationDocument {
|
|
|
63
63
|
major?: number;
|
|
64
64
|
/** ClickHouse: unset (or `single`): yodel writes migrations topology-neutral and renders them per environment at apply time. */
|
|
65
65
|
topology?: string;
|
|
66
|
+
/**
|
|
67
|
+
* Set on a checkpoint (`yodel checkpoint`, #63): its steps create its
|
|
68
|
+
* parent's recorded schema from nothing, and `schema` is the SHA-256 of
|
|
69
|
+
* that recorded schema (see `./checkpoint.ts`). An environment whose
|
|
70
|
+
* history is empty starts at the newest checkpoint; one that already ran
|
|
71
|
+
* the chain skips it.
|
|
72
|
+
*/
|
|
73
|
+
checkpoint?: {
|
|
74
|
+
schema: string;
|
|
75
|
+
};
|
|
66
76
|
/** True when a step is an Op or a manual step: the migration is more than its SQL. */
|
|
67
77
|
refused: boolean;
|
|
68
78
|
/** What the diff pointed out besides the changes, e.g. a likely rename written as a drop and an add. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document.js","sourceRoot":"","sources":["../../src/migrations/document.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAqBH,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAAC;AAC7C,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAE/C,qGAAqG;AACrG,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"document.js","sourceRoot":"","sources":["../../src/migrations/document.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,11 +10,13 @@
|
|
|
10
10
|
* verifyChecksum(m) recorded against recomputed
|
|
11
11
|
* createMigration(options) the next migration from a build, offline (pure)
|
|
12
12
|
* writeMigration(dir, migration) puts it on disk
|
|
13
|
+
* createCheckpoint(options) a checkpoint: the parent's recorded schema from nothing (#63)
|
|
13
14
|
*
|
|
14
15
|
* The file layout is in `./document.ts`, the checksum's exact definition in
|
|
15
16
|
* `./checksum.ts`, the ordering rules in `./directory.ts`.
|
|
16
17
|
*/
|
|
17
18
|
export * from "./checks.js";
|
|
19
|
+
export * from "./checkpoint.js";
|
|
18
20
|
export * from "./checksum.js";
|
|
19
21
|
export * from "./create.js";
|
|
20
22
|
export * from "./directory.js";
|
package/dist/migrations/index.js
CHANGED
|
@@ -10,11 +10,13 @@
|
|
|
10
10
|
* verifyChecksum(m) recorded against recomputed
|
|
11
11
|
* createMigration(options) the next migration from a build, offline (pure)
|
|
12
12
|
* writeMigration(dir, migration) puts it on disk
|
|
13
|
+
* createCheckpoint(options) a checkpoint: the parent's recorded schema from nothing (#63)
|
|
13
14
|
*
|
|
14
15
|
* The file layout is in `./document.ts`, the checksum's exact definition in
|
|
15
16
|
* `./checksum.ts`, the ordering rules in `./directory.ts`.
|
|
16
17
|
*/
|
|
17
18
|
export * from "./checks.js";
|
|
19
|
+
export * from "./checkpoint.js";
|
|
18
20
|
export * from "./checksum.js";
|
|
19
21
|
export * from "./create.js";
|
|
20
22
|
export * from "./directory.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Postgres functions, procedures and triggers in a migration (#44): the
|
|
3
|
+
* objects of a Postgres build as chant's plan reads them, for lint.
|
|
4
|
+
*
|
|
5
|
+
* chant labels a trigger created on a table that already exists SQLPG283
|
|
6
|
+
* (metadata: SHARE ROW EXCLUSIVE on the table) itself, and one created
|
|
7
|
+
* with its table SQLPG200 create.
|
|
8
|
+
*/
|
|
9
|
+
import type { BuildOutput } from "../chant/build.js";
|
|
10
|
+
/** A Postgres build's objects as chant's plan reads them: kind, schema-qualified names, a trigger's table and function. */
|
|
11
|
+
export interface PgObject {
|
|
12
|
+
export: string;
|
|
13
|
+
kind: string;
|
|
14
|
+
/** `schema.name`. */
|
|
15
|
+
qualified: string;
|
|
16
|
+
/** A routine's parameter types, `(bigint,integer)`. */
|
|
17
|
+
signature?: string;
|
|
18
|
+
fields: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
/** The objects of a Postgres build, canonical; `[]` for a build the lexicon cannot read (lint reports that on its own). */
|
|
21
|
+
export declare function pgObjects(build: BuildOutput, defaultSchema?: string): PgObject[];
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Postgres functions, procedures and triggers in a migration (#44): the
|
|
3
|
+
* objects of a Postgres build as chant's plan reads them, for lint.
|
|
4
|
+
*
|
|
5
|
+
* chant labels a trigger created on a table that already exists SQLPG283
|
|
6
|
+
* (metadata: SHARE ROW EXCLUSIVE on the table) itself, and one created
|
|
7
|
+
* with its table SQLPG200 create.
|
|
8
|
+
*/
|
|
9
|
+
import { pgSchemaFromBuildOutput } from "@intentius/chant-lexicon-sql/postgres/plan/schema";
|
|
10
|
+
/** The objects of a Postgres build, canonical; `[]` for a build the lexicon cannot read (lint reports that on its own). */
|
|
11
|
+
export function pgObjects(build, defaultSchema = "public") {
|
|
12
|
+
if (build.dialect !== "postgres" || !Array.isArray(build.objects))
|
|
13
|
+
return [];
|
|
14
|
+
try {
|
|
15
|
+
return pgSchemaFromBuildOutput(JSON.stringify(build), defaultSchema).map((o) => {
|
|
16
|
+
const c = o.canonical;
|
|
17
|
+
return {
|
|
18
|
+
export: c.exportName ?? o.key,
|
|
19
|
+
kind: c.kind,
|
|
20
|
+
qualified: c.schema ? `${c.schema}.${c.name}` : c.name,
|
|
21
|
+
...(c.kind === "function" || c.kind === "procedure" ? { signature: c.signature ?? "()" } : {}),
|
|
22
|
+
fields: c.fields,
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=routines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routines.js","sourceRoot":"","sources":["../../src/migrations/routines.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,mDAAmD,CAAC;AAc5F,2HAA2H;AAC3H,MAAM,UAAU,SAAS,CAAC,KAAkB,EAAE,aAAa,GAAG,QAAQ;IACpE,IAAI,KAAK,CAAC,OAAO,KAAK,UAAU,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IAC7E,IAAI,CAAC;QACH,OAAO,uBAAuB,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YAC7E,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC;YACtB,OAAO;gBACL,MAAM,EAAE,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG;gBAC7B,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI;gBACtD,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC9F,MAAM,EAAE,CAAC,CAAC,MAAM;aACjB,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
|