@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.
Files changed (50) hide show
  1. package/dist/authoring.cjs.map +1 -1
  2. package/dist/authoring.d.cts +2 -2
  3. package/dist/authoring.d.ts +2 -2
  4. package/dist/authoring.js.map +1 -1
  5. package/dist/canonical.cjs.map +1 -1
  6. package/dist/canonical.d.cts +72 -72
  7. package/dist/canonical.d.ts +72 -72
  8. package/dist/canonical.js.map +1 -1
  9. package/dist/cli.cjs +93 -53
  10. package/dist/cli.cjs.map +1 -1
  11. package/dist/cli.d.cts +23 -1
  12. package/dist/cli.d.ts +23 -1
  13. package/dist/cli.js +90 -54
  14. package/dist/cli.js.map +1 -1
  15. package/dist/client.cjs.map +1 -1
  16. package/dist/client.d.cts +1 -1
  17. package/dist/client.d.ts +1 -1
  18. package/dist/client.js.map +1 -1
  19. package/dist/compiler.cjs +1 -1
  20. package/dist/compiler.cjs.map +1 -1
  21. package/dist/compiler.d.cts +2 -2
  22. package/dist/compiler.d.ts +2 -2
  23. package/dist/compiler.js +1 -1
  24. package/dist/compiler.js.map +1 -1
  25. package/dist/{constants-Dou1RkTo.d.cts → constants-D2o0vK6U.d.cts} +8 -1
  26. package/dist/{constants-Dou1RkTo.d.ts → constants-D2o0vK6U.d.ts} +8 -1
  27. package/dist/dynamic-input.d.cts +1 -1
  28. package/dist/dynamic-input.d.ts +1 -1
  29. package/dist/index.cjs +44 -24
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +60 -59
  32. package/dist/index.d.ts +60 -59
  33. package/dist/index.js +43 -25
  34. package/dist/index.js.map +1 -1
  35. package/dist/ir.cjs.map +1 -1
  36. package/dist/ir.d.cts +73 -73
  37. package/dist/ir.d.ts +73 -73
  38. package/dist/ir.js.map +1 -1
  39. package/dist/predicate-v2.cjs.map +1 -1
  40. package/dist/predicate-v2.d.cts +1 -1
  41. package/dist/predicate-v2.d.ts +1 -1
  42. package/dist/predicate-v2.js.map +1 -1
  43. package/dist/sdl.cjs.map +1 -1
  44. package/dist/sdl.d.cts +1 -1
  45. package/dist/sdl.d.ts +1 -1
  46. package/dist/sdl.js.map +1 -1
  47. package/package.json +3 -3
  48. package/templates/orm-namespace/package.json +2 -1
  49. package/dist/{definition-DjfC7Lll.d.cts → definition-B99BsOAO.d.cts} +4 -4
  50. 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
- let previousId3;
10510
- let previousHash = null;
10511
- for (const entry of workspace.journal.entries) {
10512
- const sql4 = await readMigrationSql(dir, entry);
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
- let previousId3;
12032
- let previousHash = null;
12033
- for (const entry of workspace.journal.entries) {
12034
- const sql4 = await readMigrationSql(dir, entry);
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;