@sequenceholdings/orm 2.8.5 → 2.9.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/dist/authoring.cjs.map +1 -1
- package/dist/authoring.d.cts +2 -2
- package/dist/authoring.d.ts +2 -2
- package/dist/authoring.js.map +1 -1
- package/dist/canonical.cjs.map +1 -1
- package/dist/canonical.d.cts +72 -72
- package/dist/canonical.d.ts +72 -72
- package/dist/canonical.js.map +1 -1
- package/dist/cli.cjs +93 -53
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.cts +23 -1
- package/dist/cli.d.ts +23 -1
- package/dist/cli.js +90 -54
- package/dist/cli.js.map +1 -1
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js.map +1 -1
- package/dist/compiler.cjs +1 -1
- package/dist/compiler.cjs.map +1 -1
- package/dist/compiler.d.cts +2 -2
- package/dist/compiler.d.ts +2 -2
- package/dist/compiler.js +1 -1
- package/dist/compiler.js.map +1 -1
- package/dist/{constants-Dou1RkTo.d.cts → constants-D2o0vK6U.d.cts} +8 -1
- package/dist/{constants-Dou1RkTo.d.ts → constants-D2o0vK6U.d.ts} +8 -1
- package/dist/dynamic-input.d.cts +1 -1
- package/dist/dynamic-input.d.ts +1 -1
- package/dist/index.cjs +44 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +60 -59
- package/dist/index.d.ts +60 -59
- package/dist/index.js +43 -25
- package/dist/index.js.map +1 -1
- package/dist/ir.cjs.map +1 -1
- package/dist/ir.d.cts +73 -73
- package/dist/ir.d.ts +73 -73
- package/dist/ir.js.map +1 -1
- package/dist/predicate-v2.cjs.map +1 -1
- package/dist/predicate-v2.d.cts +1 -1
- package/dist/predicate-v2.d.ts +1 -1
- package/dist/predicate-v2.js.map +1 -1
- package/dist/sdl.cjs.map +1 -1
- package/dist/sdl.d.cts +1 -1
- package/dist/sdl.d.ts +1 -1
- package/dist/sdl.js.map +1 -1
- package/package.json +3 -3
- package/templates/orm-namespace/package.json +2 -1
- package/dist/{definition-DjfC7Lll.d.cts → definition-B99BsOAO.d.cts} +4 -4
- package/dist/{definition-DjfC7Lll.d.ts → definition-B99BsOAO.d.ts} +4 -4
package/dist/cli.cjs
CHANGED
|
@@ -105,6 +105,8 @@ function materializedRefreshFunctionName(table) {
|
|
|
105
105
|
function materializeLockKey(schema, table) {
|
|
106
106
|
return `orm:materialize:${schema}.${table}`;
|
|
107
107
|
}
|
|
108
|
+
var OPERATION_DOCUMENTS_FILE = "operations.documents.json";
|
|
109
|
+
var OPERATION_DOCUMENTS_VERSION = 1;
|
|
108
110
|
|
|
109
111
|
// src/hash.ts
|
|
110
112
|
function stableJson(value) {
|
|
@@ -10346,6 +10348,42 @@ async function readSnapshot(dir, ordinal) {
|
|
|
10346
10348
|
const path$1 = path.join(dir, MIGRATIONS_DIRNAME, META_DIRNAME, `${pad(ordinal)}.snapshot.json`);
|
|
10347
10349
|
return parseJson(path$1, await readSnapshotText(dir, ordinal));
|
|
10348
10350
|
}
|
|
10351
|
+
async function verifyCommittedLedger(dir, entries) {
|
|
10352
|
+
const firstRequiredSnapshot = entries.length - 2;
|
|
10353
|
+
let previousId3;
|
|
10354
|
+
let previousSnapshotPresent = false;
|
|
10355
|
+
let previousHash = null;
|
|
10356
|
+
for (const [index3, entry] of entries.entries()) {
|
|
10357
|
+
const sql4 = await readMigrationSql(dir, entry);
|
|
10358
|
+
if (checksumOf(sql4) !== entry.checksum) {
|
|
10359
|
+
return `${MIGRATIONS_DIRNAME}/${entry.name}.sql does not match its journal checksum \u2014 committed migrations must not be edited`;
|
|
10360
|
+
}
|
|
10361
|
+
const snapshotText = index3 >= firstRequiredSnapshot ? await readSnapshotText(dir, entry.ordinal) : await readPrunableSnapshotText(dir, entry.ordinal);
|
|
10362
|
+
if (snapshotText !== void 0) {
|
|
10363
|
+
if (checksumOf(snapshotText) !== entry.snapshot_checksum) {
|
|
10364
|
+
return `the snapshot for ${entry.name} does not match its journal checksum \u2014 committed snapshots must not be edited (the next diff builds on it)`;
|
|
10365
|
+
}
|
|
10366
|
+
const snapshot = JSON.parse(snapshotText);
|
|
10367
|
+
if (previousSnapshotPresent && snapshot.prevId !== previousId3) {
|
|
10368
|
+
return `snapshot chain broken at ${entry.name} \u2014 regenerate the workspace with \`seq-studio orm diff\``;
|
|
10369
|
+
}
|
|
10370
|
+
previousId3 = snapshot.id;
|
|
10371
|
+
}
|
|
10372
|
+
previousSnapshotPresent = snapshotText !== void 0;
|
|
10373
|
+
if (entry.previous_content_hash !== previousHash) {
|
|
10374
|
+
return `content-hash chain broken at ${entry.name} \u2014 migrations must be appended in order by \`seq-studio orm diff\``;
|
|
10375
|
+
}
|
|
10376
|
+
previousHash = entry.content_hash;
|
|
10377
|
+
}
|
|
10378
|
+
return void 0;
|
|
10379
|
+
}
|
|
10380
|
+
async function readPrunableSnapshotText(dir, ordinal) {
|
|
10381
|
+
const path$1 = path.join(dir, MIGRATIONS_DIRNAME, META_DIRNAME, `${pad(ordinal)}.snapshot.json`);
|
|
10382
|
+
return promises.readFile(path$1, "utf8").catch((error) => {
|
|
10383
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") return void 0;
|
|
10384
|
+
throw error;
|
|
10385
|
+
});
|
|
10386
|
+
}
|
|
10349
10387
|
async function readMigrationSql(dir, entry) {
|
|
10350
10388
|
const path$1 = path.join(dir, MIGRATIONS_DIRNAME, `${entry.name}.sql`);
|
|
10351
10389
|
return promises.readFile(path$1, "utf8").catch(() => {
|
|
@@ -10506,30 +10544,10 @@ async function checkWorkspace({
|
|
|
10506
10544
|
log(`no committed migrations for '${loaded.definition.namespace}' \u2014 run \`seq-studio orm diff\` and commit the result`);
|
|
10507
10545
|
return 1;
|
|
10508
10546
|
}
|
|
10509
|
-
|
|
10510
|
-
|
|
10511
|
-
|
|
10512
|
-
|
|
10513
|
-
if (checksumOf(sql4) !== entry.checksum) {
|
|
10514
|
-
log(`${MIGRATIONS_DIRNAME}/${entry.name}.sql does not match its journal checksum \u2014 committed migrations must not be edited`);
|
|
10515
|
-
return 1;
|
|
10516
|
-
}
|
|
10517
|
-
const snapshotText = await readSnapshotText(dir, entry.ordinal);
|
|
10518
|
-
if (checksumOf(snapshotText) !== entry.snapshot_checksum) {
|
|
10519
|
-
log(`the snapshot for ${entry.name} does not match its journal checksum \u2014 committed snapshots must not be edited (the next diff builds on it)`);
|
|
10520
|
-
return 1;
|
|
10521
|
-
}
|
|
10522
|
-
const snapshot = JSON.parse(snapshotText);
|
|
10523
|
-
if (entry.ordinal > 1 && snapshot.prevId !== previousId3) {
|
|
10524
|
-
log(`snapshot chain broken at ${entry.name} \u2014 regenerate the workspace with \`seq-studio orm diff\``);
|
|
10525
|
-
return 1;
|
|
10526
|
-
}
|
|
10527
|
-
if (entry.previous_content_hash !== previousHash) {
|
|
10528
|
-
log(`content-hash chain broken at ${entry.name} \u2014 migrations must be appended in order by \`seq-studio orm diff\``);
|
|
10529
|
-
return 1;
|
|
10530
|
-
}
|
|
10531
|
-
previousId3 = snapshot.id;
|
|
10532
|
-
previousHash = entry.content_hash;
|
|
10547
|
+
const broken = await verifyCommittedLedger(dir, workspace.journal.entries);
|
|
10548
|
+
if (broken) {
|
|
10549
|
+
log(broken);
|
|
10550
|
+
return 1;
|
|
10533
10551
|
}
|
|
10534
10552
|
if (tip.content_hash !== loaded.contentHash) {
|
|
10535
10553
|
log(`definitions changed since ${tip.name} \u2014 run \`seq-studio orm diff\` and commit the new migration`);
|
|
@@ -11408,6 +11426,22 @@ function parseArgs(argv) {
|
|
|
11408
11426
|
// src/cli.ts
|
|
11409
11427
|
var BASE_URL_ENV = "SEQUENCE_ORM_BASE_URL";
|
|
11410
11428
|
var TOKEN_ENV = "SEQUENCE_ORM_TOKEN";
|
|
11429
|
+
var SOURCE_ENV = "SEQUENCE_ORM_SOURCE";
|
|
11430
|
+
var UNVERIFIED_SOURCE_REASON_ENV = "SEQUENCE_ORM_UNVERIFIED_SOURCE_REASON";
|
|
11431
|
+
function applySourceFromEnv(env = process.env) {
|
|
11432
|
+
const reason = env[UNVERIFIED_SOURCE_REASON_ENV]?.trim();
|
|
11433
|
+
const override = reason ? { unverified_source_reason: reason } : {};
|
|
11434
|
+
const raw = env[SOURCE_ENV];
|
|
11435
|
+
if (!raw) return override;
|
|
11436
|
+
let parsed;
|
|
11437
|
+
try {
|
|
11438
|
+
parsed = JSON.parse(raw);
|
|
11439
|
+
} catch {
|
|
11440
|
+
throw new Error(`${SOURCE_ENV} is not valid JSON`);
|
|
11441
|
+
}
|
|
11442
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) throw new Error(`${SOURCE_ENV} must be a JSON object`);
|
|
11443
|
+
return { source: Object.fromEntries(Object.entries(parsed)), ...override };
|
|
11444
|
+
}
|
|
11411
11445
|
var ORM_MODULE_PATH_ENV = "SEQUENCE_ORM_MODULE_PATH";
|
|
11412
11446
|
var USAGE = `usage:
|
|
11413
11447
|
seq-studio orm init <dir> scaffold a namespace package (v2: TypeScript schema + persisted operations)
|
|
@@ -11725,15 +11759,21 @@ async function generateCommand(rest) {
|
|
|
11725
11759
|
await writeGenerateOutputs(dir, compiled.project);
|
|
11726
11760
|
const { loaded, manifest } = compiled.project;
|
|
11727
11761
|
console.log(
|
|
11728
|
-
`wrote ${SCHEMA_GRAPHQL_FILE}, ${OPERATIONS_MANIFEST_FILE}, ${TYPE_POLICIES_FILE}, sql-operations.gen.ts, namespace.contract.json (${loaded.canonical.tables.length} table(s), ${loaded.canonical.views?.length ?? 0} view(s), ${Object.keys(manifest.operations).length} operation(s))`
|
|
11762
|
+
`wrote ${SCHEMA_GRAPHQL_FILE}, ${OPERATIONS_MANIFEST_FILE}, ${OPERATION_DOCUMENTS_FILE}, ${TYPE_POLICIES_FILE}, sql-operations.gen.ts, namespace.contract.json (${loaded.canonical.tables.length} table(s), ${loaded.canonical.views?.length ?? 0} view(s), ${Object.keys(manifest.operations).length} operation(s))`
|
|
11729
11763
|
);
|
|
11730
11764
|
return runConsumerCodegen(dir);
|
|
11731
11765
|
}
|
|
11732
11766
|
async function writeGenerateOutputs(dir, project) {
|
|
11733
|
-
const { loaded, sdl, manifest } = project;
|
|
11767
|
+
const { loaded, sdl, manifest, documents } = project;
|
|
11734
11768
|
await promises.writeFile(path.join(dir, SCHEMA_GRAPHQL_FILE), sdl);
|
|
11735
11769
|
await promises.writeFile(path.join(dir, "namespace.contract.json"), `${JSON.stringify(loaded.canonical, null, 2)}
|
|
11736
11770
|
`);
|
|
11771
|
+
const sortedDocuments = [...documents].sort((a, b) => a.path.localeCompare(b.path)).map(({ path, contents }) => ({ path, contents }));
|
|
11772
|
+
await promises.writeFile(
|
|
11773
|
+
path.join(dir, OPERATION_DOCUMENTS_FILE),
|
|
11774
|
+
`${JSON.stringify({ documentsVersion: OPERATION_DOCUMENTS_VERSION, documents: sortedDocuments }, null, 2)}
|
|
11775
|
+
`
|
|
11776
|
+
);
|
|
11737
11777
|
const operations = Object.entries(manifest.operations).map(([name2, op]) => ({
|
|
11738
11778
|
name: name2,
|
|
11739
11779
|
kind: op.kind,
|
|
@@ -11939,8 +11979,20 @@ function reportRegistryState(registry) {
|
|
|
11939
11979
|
if (match && match.id === registry.activeVersionId) console.log("-- registry: this content is the ACTIVE version");
|
|
11940
11980
|
else if (match) console.log(`-- registry: registered (status ${match.status}), not active`);
|
|
11941
11981
|
else console.log(`-- registry: new content (active is ${active ? active.content_hash.slice(0, 12) : "none"})`);
|
|
11982
|
+
if (registry.activeActivation) console.log(`-- registry: ${describeActivation(registry.activeActivation)}`);
|
|
11942
11983
|
return 0;
|
|
11943
11984
|
}
|
|
11985
|
+
function describeActivation(activation) {
|
|
11986
|
+
const since = `live since ${activation.activated_at.slice(0, 16).replace("T", " ")}Z`;
|
|
11987
|
+
const by = `by ${activation.actor_sub.replace(/^google-apps\|/, "")}`;
|
|
11988
|
+
if (activation.source_commit && activation.source_branch) {
|
|
11989
|
+
const at = activation.source_path ? ` at ${activation.source_path}` : "";
|
|
11990
|
+
return `${since} from ${activation.source_commit.slice(0, 12)} on ${activation.source_branch}${at} (${activation.provenance_class}) ${by}`;
|
|
11991
|
+
}
|
|
11992
|
+
const failure = activation.reported_source?.verification_failure;
|
|
11993
|
+
const why = typeof failure === "string" ? `: ${failure}` : "";
|
|
11994
|
+
return `${since} from an untraced source (${activation.provenance_class}${why}) ${by}`;
|
|
11995
|
+
}
|
|
11944
11996
|
var META_DIRNAME2 = "meta";
|
|
11945
11997
|
var JOURNAL_FILENAME2 = "journal.json";
|
|
11946
11998
|
var padOrdinal = (ordinal) => String(ordinal).padStart(4, "0");
|
|
@@ -12028,30 +12080,10 @@ async function checkWorkspaceV2({
|
|
|
12028
12080
|
log(`no committed migrations for '${namespace}' \u2014 run \`seq-studio orm diff\` and commit the result`);
|
|
12029
12081
|
return 1;
|
|
12030
12082
|
}
|
|
12031
|
-
|
|
12032
|
-
|
|
12033
|
-
|
|
12034
|
-
|
|
12035
|
-
if (checksumOf(sql4) !== entry.checksum) {
|
|
12036
|
-
log(`${MIGRATIONS_DIRNAME}/${entry.name}.sql does not match its journal checksum \u2014 committed migrations must not be edited`);
|
|
12037
|
-
return 1;
|
|
12038
|
-
}
|
|
12039
|
-
const snapshotText = await readSnapshotText(dir, entry.ordinal);
|
|
12040
|
-
if (checksumOf(snapshotText) !== entry.snapshot_checksum) {
|
|
12041
|
-
log(`the snapshot for ${entry.name} does not match its journal checksum \u2014 committed snapshots must not be edited (the next diff builds on it)`);
|
|
12042
|
-
return 1;
|
|
12043
|
-
}
|
|
12044
|
-
const snapshot = JSON.parse(snapshotText);
|
|
12045
|
-
if (entry.ordinal > 1 && snapshot.prevId !== previousId3) {
|
|
12046
|
-
log(`snapshot chain broken at ${entry.name} \u2014 regenerate the workspace with \`seq-studio orm diff\``);
|
|
12047
|
-
return 1;
|
|
12048
|
-
}
|
|
12049
|
-
if (entry.previous_content_hash !== previousHash) {
|
|
12050
|
-
log(`content-hash chain broken at ${entry.name} \u2014 migrations must be appended in order by \`seq-studio orm diff\``);
|
|
12051
|
-
return 1;
|
|
12052
|
-
}
|
|
12053
|
-
previousId3 = snapshot.id;
|
|
12054
|
-
previousHash = entry.content_hash;
|
|
12083
|
+
const broken = await verifyCommittedLedger(dir, workspace.journal.entries);
|
|
12084
|
+
if (broken) {
|
|
12085
|
+
log(broken);
|
|
12086
|
+
return 1;
|
|
12055
12087
|
}
|
|
12056
12088
|
if (tip.content_hash !== loaded.hash) {
|
|
12057
12089
|
log(`definitions changed since ${tip.name} \u2014 run \`seq-studio orm diff\` and commit the new migration`);
|
|
@@ -12165,7 +12197,8 @@ async function applyV2Command(rest, dir) {
|
|
|
12165
12197
|
const applied = await apiRequestStrict("POST", `/api/orm/namespaces/${namespace}/apply`, {
|
|
12166
12198
|
version_id: registered.version_id,
|
|
12167
12199
|
...allowDestructive ? { allow_destructive: true } : {},
|
|
12168
|
-
...schemaAlreadyActive && registered.operation_set_id ? { operation_set_id: registered.operation_set_id } : {}
|
|
12200
|
+
...schemaAlreadyActive && registered.operation_set_id ? { operation_set_id: registered.operation_set_id } : {},
|
|
12201
|
+
...applySourceFromEnv()
|
|
12169
12202
|
});
|
|
12170
12203
|
const live = { namespace, contentHash: registered.content_hash };
|
|
12171
12204
|
if ("ops_only" in applied) {
|
|
@@ -12622,7 +12655,8 @@ async function applyCommand(rest) {
|
|
|
12622
12655
|
if (dryRun) return dryRunRehearsal({ namespace, versionId: registered.version_id, contentHash: registered.content_hash });
|
|
12623
12656
|
const applied = await apiRequestStrict("POST", `/api/orm/namespaces/${namespace}/apply`, {
|
|
12624
12657
|
version_id: registered.version_id,
|
|
12625
|
-
...allowDestructive ? { allow_destructive: true } : {}
|
|
12658
|
+
...allowDestructive ? { allow_destructive: true } : {},
|
|
12659
|
+
...applySourceFromEnv()
|
|
12626
12660
|
});
|
|
12627
12661
|
if ("status" in applied) {
|
|
12628
12662
|
const verdict = await awaitQueuedApply({ dir, namespace, contentHash: registered.content_hash, runId: applied.run_id, applyWait });
|
|
@@ -12802,11 +12836,13 @@ async function apiRequestStrict(method, path, body) {
|
|
|
12802
12836
|
}
|
|
12803
12837
|
async function fetchRegistryState(namespace, contentHash) {
|
|
12804
12838
|
if (!process.env[BASE_URL_ENV]?.trim() || !await resolveToken()) return { kind: "offline" };
|
|
12805
|
-
const body = await apiRequest("GET", `/api/orm/namespaces/${namespace}?hash=${encodeURIComponent(contentHash)}`, void 0, { allow404: true });
|
|
12839
|
+
const body = await apiRequest("GET", `/api/orm/namespaces/${namespace}?hash=${encodeURIComponent(contentHash)}&activations_limit=1`, void 0, { allow404: true });
|
|
12806
12840
|
if (!body) return { kind: "missing" };
|
|
12841
|
+
const latest = body.activations?.[0];
|
|
12807
12842
|
return {
|
|
12808
12843
|
kind: "found",
|
|
12809
12844
|
activeVersionId: body.namespace.active_version_id,
|
|
12845
|
+
activeActivation: latest && latest.id === body.namespace.active_activation_id ? latest : null,
|
|
12810
12846
|
versions: body.versions,
|
|
12811
12847
|
hashVersion: body.hash_version ?? null
|
|
12812
12848
|
};
|
|
@@ -12823,7 +12859,11 @@ var firstLine2 = (sql4) => sql4.split("\n")[0] ?? sql4;
|
|
|
12823
12859
|
|
|
12824
12860
|
exports.BASE_URL_ENV = BASE_URL_ENV;
|
|
12825
12861
|
exports.ORM_MODULE_PATH_ENV = ORM_MODULE_PATH_ENV;
|
|
12862
|
+
exports.SOURCE_ENV = SOURCE_ENV;
|
|
12826
12863
|
exports.TOKEN_ENV = TOKEN_ENV;
|
|
12864
|
+
exports.UNVERIFIED_SOURCE_REASON_ENV = UNVERIFIED_SOURCE_REASON_ENV;
|
|
12865
|
+
exports.applySourceFromEnv = applySourceFromEnv;
|
|
12866
|
+
exports.describeActivation = describeActivation;
|
|
12827
12867
|
exports.errorDetail = errorDetail;
|
|
12828
12868
|
exports.parseApplyWait = parseApplyWait;
|
|
12829
12869
|
exports.runCli = runCli;
|