@sequenceholdings/orm 2.11.0 → 2.11.1

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 (47) hide show
  1. package/README.md +3 -4
  2. package/dist/authoring.d.cts +1 -1
  3. package/dist/authoring.d.ts +1 -1
  4. package/dist/canonical.d.cts +43 -43
  5. package/dist/canonical.d.ts +43 -43
  6. package/dist/cli.cjs +147 -195
  7. package/dist/cli.cjs.map +1 -1
  8. package/dist/cli.js +148 -196
  9. package/dist/cli.js.map +1 -1
  10. package/dist/client.cjs +5 -10
  11. package/dist/client.cjs.map +1 -1
  12. package/dist/client.d.cts +2 -13
  13. package/dist/client.d.ts +2 -13
  14. package/dist/client.js +6 -10
  15. package/dist/client.js.map +1 -1
  16. package/dist/compiler.cjs +14 -67
  17. package/dist/compiler.cjs.map +1 -1
  18. package/dist/compiler.d.cts +6 -17
  19. package/dist/compiler.d.ts +6 -17
  20. package/dist/compiler.js +16 -66
  21. package/dist/compiler.js.map +1 -1
  22. package/dist/index.cjs +242 -189
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +541 -36
  25. package/dist/index.d.ts +541 -36
  26. package/dist/index.js +237 -189
  27. package/dist/index.js.map +1 -1
  28. package/dist/ir.cjs +6 -11
  29. package/dist/ir.cjs.map +1 -1
  30. package/dist/ir.d.cts +61 -64
  31. package/dist/ir.d.ts +61 -64
  32. package/dist/ir.js +6 -11
  33. package/dist/ir.js.map +1 -1
  34. package/dist/predicate-v2.cjs +3 -8
  35. package/dist/predicate-v2.cjs.map +1 -1
  36. package/dist/predicate-v2.js +3 -8
  37. package/dist/predicate-v2.js.map +1 -1
  38. package/dist/sdl.cjs +4 -11
  39. package/dist/sdl.cjs.map +1 -1
  40. package/dist/sdl.d.cts +1 -5
  41. package/dist/sdl.d.ts +1 -5
  42. package/dist/sdl.js +4 -11
  43. package/dist/sdl.js.map +1 -1
  44. package/package.json +1 -1
  45. package/src/codegen-gql/server-fns.cjs +1 -1
  46. package/dist/{definition-CevES7lM.d.cts → definition-B99BsOAO.d.cts} +2 -2
  47. package/dist/{definition-CevES7lM.d.ts → definition-B99BsOAO.d.ts} +2 -2
package/dist/cli.cjs CHANGED
@@ -2293,9 +2293,6 @@ function normalizeCanonical(definition) {
2293
2293
  return normalized;
2294
2294
  }
2295
2295
 
2296
- // src/client/sql.ts
2297
- var BUILTIN_SQL_READ_HASH = "sha256:a50c477c952a5e0fe68ed158a4530e4aab573c09bcbb1a8ac454dc88a39a6258";
2298
-
2299
2296
  // src/ir/index.ts
2300
2297
  var IR_VERSION = 6;
2301
2298
  var LEGACY_IR_VERSION = 1;
@@ -2624,8 +2621,7 @@ var compiledOperationSchema = zod.z.object({
2624
2621
  maxRows: zod.z.number().int().min(1).max(1e4)
2625
2622
  }).strict().optional(),
2626
2623
  irVersion: irVersionSchema,
2627
- name: zod.z.string(),
2628
- opHash: zod.z.string().regex(/^sha256:[0-9a-f]{64}$/),
2624
+ name: zod.z.string().regex(/^[_A-Za-z][_0-9A-Za-z]{0,254}$/),
2629
2625
  kind: zod.z.enum(["query", "mutation"]),
2630
2626
  requires: zod.z.object({
2631
2627
  capability: zod.z.string().optional(),
@@ -2641,7 +2637,7 @@ var compiledOperationSchema = zod.z.object({
2641
2637
  }
2642
2638
  if (operation.language === "sql") {
2643
2639
  const validPlan = operation.sqlQuery ? !operation.sql && operation.irVersion === RUNTIME_SQL_IR_VERSION : !!operation.sql && operation.irVersion === SQL_IR_VERSION;
2644
- const builtin = operation.name === "BuiltinSqlRead" && operation.opHash === BUILTIN_SQL_READ_HASH && operation.requires === null;
2640
+ const builtin = operation.name === "BuiltinSqlRead" && operation.requires === null;
2645
2641
  if (!validPlan || operation.kind !== "query" || operation.roots.length !== 0 || !builtin && !operation.requires?.capability) {
2646
2642
  ctx.addIssue({ code: "custom", message: "SQL operations require a query-only v4 plan or v5 runtime contract, capability, and no GraphQL roots" });
2647
2643
  }
@@ -2656,7 +2652,7 @@ var compiledOperationSchema = zod.z.object({
2656
2652
  }
2657
2653
  });
2658
2654
  var resolvedSourceIrSchema = zod.z.object({
2659
- name: zod.z.string(),
2655
+ name: zod.z.string().regex(/^[_A-Za-z][_0-9A-Za-z]{0,254}$/),
2660
2656
  kind: zod.z.enum(["manual", "etl", "prefetch"]),
2661
2657
  /** Logical table key of the backing relation. */
2662
2658
  table: zod.z.string(),
@@ -2770,7 +2766,6 @@ var compiledArtifactSchema = zod.z.object({
2770
2766
  ownSchemaHash: zod.z.string().optional(),
2771
2767
  dependencies: zod.z.record(zod.z.string(), zod.z.string()).optional(),
2772
2768
  readPolicies: zod.z.record(zod.z.string(), predIrSchema).optional(),
2773
- opsHash: zod.z.string(),
2774
2769
  /** Apply-observed synced objects without a serving backing; not part of the authored schema hash. */
2775
2770
  unbackedTables: zod.z.array(zod.z.string()).optional(),
2776
2771
  tables: zod.z.record(zod.z.string(), tableMetaIrSchema),
@@ -4437,24 +4432,6 @@ function flattenOperation({
4437
4432
  }) {
4438
4433
  return { ...operation, selectionSet: flattenSelectionSet(operation.selectionSet, fragments, []) };
4439
4434
  }
4440
- var COMPILER_MAJOR = 1;
4441
- var OP_HASH_DOMAIN = "sequence-orm-op\0";
4442
- var OPS_HASH_DOMAIN = "sequence-orm-opset\0";
4443
- function canonicalOperationText(definition) {
4444
- const document = { kind: graphql.Kind.DOCUMENT, definitions: [definition] };
4445
- return graphql.print(document);
4446
- }
4447
- function computeOpHash({
4448
- definition,
4449
- schemaHash
4450
- }) {
4451
- const digest = crypto.createHash("sha256").update(OP_HASH_DOMAIN).update(`${COMPILER_MAJOR}\0${schemaHash}\0`).update(canonicalOperationText(definition)).digest("hex");
4452
- return `sha256:${digest}`;
4453
- }
4454
- function computeOpsHash(opHashes) {
4455
- const digest = crypto.createHash("sha256").update(OPS_HASH_DOMAIN).update([...opHashes].sort().join("\n")).digest("hex");
4456
- return `sha256:${digest}`;
4457
- }
4458
4435
  var SOURCE_DIRECTIVES = /* @__PURE__ */ new Set(["prefetch", "writeback", "localOnly"]);
4459
4436
  var fail = (message, code) => {
4460
4437
  throw new DocumentCompileError(message, code);
@@ -5950,7 +5927,6 @@ function compileNamespace({ canonical, sdl, documents }) {
5950
5927
  operations[restricted.name] = {
5951
5928
  irVersion: usesServicePrincipal(roots) ? SERVICE_PRINCIPAL_IR_VERSION : canonical.imports?.length ? COMPOSED_IR_VERSION : roots.some((root) => root.kind === "mutation" && root.assertAffectedRows !== void 0) ? GUARDED_IR_VERSION : LEGACY_IR_VERSION,
5952
5929
  name: restricted.name,
5953
- opHash: computeOpHash({ definition: flattened, schemaHash }),
5954
5930
  kind: restricted.kind,
5955
5931
  requires: restricted.requires,
5956
5932
  variables: restricted.variables,
@@ -5983,7 +5959,6 @@ function compileNamespace({ canonical, sdl, documents }) {
5983
5959
  dependencies: Object.fromEntries(canonical.imports.map((owner) => [owner.namespace, computeSchemaHash(localContract(owner))]))
5984
5960
  } : {},
5985
5961
  readPolicies: Object.fromEntries(ctx.readPolicies),
5986
- opsHash: computeOpsHash(Object.values(operations).map((op) => op.opHash)),
5987
5962
  tables: ctx.tables,
5988
5963
  operations
5989
5964
  };
@@ -5991,11 +5966,10 @@ function compileNamespace({ canonical, sdl, documents }) {
5991
5966
  const manifest = {
5992
5967
  namespace: ctx.namespace,
5993
5968
  schemaHash,
5994
- opsHash: normalized.opsHash,
5995
5969
  operations: Object.fromEntries(
5996
5970
  Object.values(normalized.operations).map((op) => [
5997
5971
  op.name,
5998
- { opHash: op.opHash, kind: op.kind, requires: op.requires }
5972
+ op
5999
5973
  ])
6000
5974
  )
6001
5975
  };
@@ -6177,7 +6151,6 @@ function createSqlCatalog({ canonical, publishedObjects, executionTarget }) {
6177
6151
  }
6178
6152
  function createSqlCatalogFromContext({ canonical, publishedObjects, executionTarget, ctx, identity: suppliedIdentity }) {
6179
6153
  if (!publishedObjects.length || new Set(publishedObjects).size !== publishedObjects.length) throw new Error("SQL objects must be explicitly declared and unique");
6180
- const identity = suppliedIdentity ?? sqlHash(`ontology-sql-v1\0${computeSchemaHash(canonical)}\0${executionTarget}`);
6181
6154
  const logicalNames = new Map(Object.entries(ctx.tables).map(([key, meta]) => [meta, key]));
6182
6155
  const refOf = (meta) => `${meta.namespace ?? canonical.namespace}/${logicalNames.get(meta)}`;
6183
6156
  const definitions = [canonical, ...canonical.imports ?? []];
@@ -6202,7 +6175,7 @@ function createSqlCatalogFromContext({ canonical, publishedObjects, executionTar
6202
6175
  const scan = `SELECT ${projection} FROM ${quoteIdentifier(meta.schema)}.${quoteIdentifier(meta.table)} AS ${quoteIdentifier("p0")} WHERE ${compileStaticPolicySql({ table: meta, predicate: policy, tables: ctx.tables, namespace: canonical.namespace, alias: "p0", onRead: (target) => reads.add(refOf(target)) })}`;
6203
6176
  return { ref, table: meta.table, columns, scan, read: [...reads].sort() };
6204
6177
  });
6205
- return { identity, objects };
6178
+ return { identity: suppliedIdentity ?? sqlHash(JSON.stringify(["ontology-sql-catalog-v2", executionTarget, objects])), objects };
6206
6179
  }
6207
6180
 
6208
6181
  // src/sql/ast.ts
@@ -6730,20 +6703,10 @@ async function compileSqlDocuments({ input, result, sqlDocuments }) {
6730
6703
  const catalog = createSqlCatalog({ canonical: input.canonical, publishedObjects: read, executionTarget: "registered-operation" });
6731
6704
  if ("mode" in definition) {
6732
6705
  if (catalog.objects.some((object) => object.read.some((ref) => !read.includes(ref)))) throw new Error("SQL policy accesses an undeclared ontology object");
6733
- const opHash2 = sqlHash(JSON.stringify([
6734
- "sequence-runtime-sql-operation-v1",
6735
- definition.name,
6736
- definition.namespace,
6737
- definition.requires.capability,
6738
- read,
6739
- catalog.identity,
6740
- definition.maxRows
6741
- ]));
6742
6706
  result.artifact.operations[definition.name] = compiledOperationSchema.parse({
6743
6707
  irVersion: RUNTIME_SQL_IR_VERSION,
6744
6708
  language: "sql",
6745
6709
  name: definition.name,
6746
- opHash: opHash2,
6747
6710
  kind: "query",
6748
6711
  requires: definition.requires,
6749
6712
  variables: [
@@ -6754,7 +6717,7 @@ async function compileSqlDocuments({ input, result, sqlDocuments }) {
6754
6717
  tableSet: read.map((ref) => ref.split("/")[1]).sort(),
6755
6718
  sqlQuery: { catalog, read, maxRows: definition.maxRows }
6756
6719
  });
6757
- result.manifest.operations[definition.name] = { opHash: opHash2, kind: "query", requires: definition.requires };
6720
+ result.manifest.operations[definition.name] = result.artifact.operations[definition.name];
6758
6721
  continue;
6759
6722
  }
6760
6723
  const names = Object.keys(definition.parameters).sort();
@@ -6772,20 +6735,10 @@ async function compileSqlDocuments({ input, result, sqlDocuments }) {
6772
6735
  nullable: !definition.parameters[name2].required,
6773
6736
  list: false
6774
6737
  }));
6775
- const opHash = sqlHash(JSON.stringify([
6776
- "sequence-sql-operation-v1",
6777
- definition.name,
6778
- definition.namespace,
6779
- definition.requires.capability,
6780
- read,
6781
- variables,
6782
- plan.queryHash
6783
- ]));
6784
6738
  const operation = compiledOperationSchema.parse({
6785
6739
  irVersion: SQL_IR_VERSION,
6786
6740
  language: "sql",
6787
6741
  name: definition.name,
6788
- opHash,
6789
6742
  kind: "query",
6790
6743
  requires: definition.requires,
6791
6744
  variables,
@@ -6794,7 +6747,7 @@ async function compileSqlDocuments({ input, result, sqlDocuments }) {
6794
6747
  sql: { text: plan.text, columns: plan.columns, parameters: names, read, maxRows: plan.maxRows }
6795
6748
  });
6796
6749
  result.artifact.operations[definition.name] = operation;
6797
- result.manifest.operations[definition.name] = { opHash, kind: "query", requires: definition.requires };
6750
+ result.manifest.operations[definition.name] = result.artifact.operations[definition.name];
6798
6751
  } catch (error) {
6799
6752
  return { ok: false, diagnostics: [...result.diagnostics, {
6800
6753
  severity: "error",
@@ -6806,8 +6759,6 @@ async function compileSqlDocuments({ input, result, sqlDocuments }) {
6806
6759
  }
6807
6760
  const required = requiredArtifactIrVersion(Object.values(result.artifact.operations));
6808
6761
  if (required > result.artifact.irVersion) result.artifact.irVersion = required;
6809
- result.artifact.opsHash = computeOpsHash(Object.values(result.artifact.operations).map((op) => op.opHash));
6810
- result.manifest.opsHash = result.artifact.opsHash;
6811
6762
  return { ...result, artifact: normalizeIr(result.artifact) };
6812
6763
  }
6813
6764
  async function managedViewDiagnostics(canonical) {
@@ -7668,7 +7619,7 @@ var manifestOperationSchema = zod.z.object({
7668
7619
  requires: manifestRequiresSchema
7669
7620
  });
7670
7621
  var operationsManifestSchema = zod.z.object({
7671
- manifestVersion: zod.z.union([zod.z.literal(1), zod.z.literal(MANIFEST_VERSION)]),
7622
+ manifestVersion: zod.z.literal(MANIFEST_VERSION),
7672
7623
  operations: zod.z.record(zod.z.string().regex(GRAPHQL_NAME_RE), manifestOperationSchema)
7673
7624
  });
7674
7625
  function buildOperationsManifest({
@@ -8635,6 +8586,132 @@ function compilePredicate(predicate, columnTypes, options = {}) {
8635
8586
  return `(${options.statementClaimChecks ? "SELECT " : ""}${capabilityExpression(predicate.key)})`;
8636
8587
  }
8637
8588
  }
8589
+ var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
8590
+ var DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
8591
+ var TIMESTAMPTZ_RE = /^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:?\d{2})$/;
8592
+ var INTEGER_RE = /^-?\d+$/;
8593
+ var NUMERIC_RE = /^-?\d+(\.\d+)?$/;
8594
+ function sourceSchemaAllowed(schema) {
8595
+ return schema !== "information_schema" && !schema.startsWith("pg_");
8596
+ }
8597
+ function isRelationIdentifier(value) {
8598
+ return value.length <= 63 && IDENTIFIER_PATTERN.test(value);
8599
+ }
8600
+ function isSourceColumn(value) {
8601
+ return value.length <= 63 && COLUMN_IDENTIFIER_PATTERN.test(value);
8602
+ }
8603
+ function splitQualifiedRelation(from) {
8604
+ const dot = from.indexOf(".");
8605
+ if (dot <= 0 || dot !== from.lastIndexOf(".")) return null;
8606
+ const schema = from.slice(0, dot);
8607
+ const table = from.slice(dot + 1);
8608
+ if (!isRelationIdentifier(schema) || !isRelationIdentifier(table)) return null;
8609
+ return { schema, table };
8610
+ }
8611
+ function postgresTypeName(type) {
8612
+ if (type === "double") return "double precision";
8613
+ if (type === "timestamptz") return "timestamp with time zone";
8614
+ return type;
8615
+ }
8616
+ function columnPostgresType(column, schemaName, enums) {
8617
+ if (typeof column.type === "string") return postgresTypeName(column.type);
8618
+ if (!enums.has(column.type.enum)) return null;
8619
+ return `${quoteIdentifier(schemaName)}.${quoteIdentifier(column.type.enum)}`;
8620
+ }
8621
+ function quoteQualified(schema, table) {
8622
+ return `${quoteIdentifier(schema)}.${quoteIdentifier(table)}`;
8623
+ }
8624
+ var INT4_MIN = -2147483648;
8625
+ var INT4_MAX = 2147483647;
8626
+ function resumeLiteralSql({
8627
+ column,
8628
+ after,
8629
+ schemaName,
8630
+ enums
8631
+ }) {
8632
+ const coerced = coerceResumeValue(column, after);
8633
+ if (!coerced.ok) return coerced;
8634
+ return literalSql({ column, value: coerced.value, schemaName, enums });
8635
+ }
8636
+ function coerceResumeValue(column, after) {
8637
+ const type = typeof column.type === "string" ? column.type : null;
8638
+ if (type === "integer") {
8639
+ if (!INTEGER_RE.test(after)) return { ok: false, error: `${column.name}: after must be an integer` };
8640
+ const parsed = Number(after);
8641
+ if (!Number.isSafeInteger(parsed) || parsed < INT4_MIN || parsed > INT4_MAX) {
8642
+ return { ok: false, error: `${column.name}: after must be an integer` };
8643
+ }
8644
+ return { ok: true, value: parsed };
8645
+ }
8646
+ if (type === "boolean") {
8647
+ if (after !== "true" && after !== "false") return { ok: false, error: `${column.name}: after must be true or false` };
8648
+ return { ok: true, value: after === "true" };
8649
+ }
8650
+ return { ok: true, value: after };
8651
+ }
8652
+ function literalSql({
8653
+ column,
8654
+ value,
8655
+ schemaName,
8656
+ enums
8657
+ }) {
8658
+ const label = column.name;
8659
+ if (typeof value === "string" && value.includes("\0")) {
8660
+ return { ok: false, error: `${label}: null default contains a NUL character` };
8661
+ }
8662
+ if (typeof column.type !== "string") {
8663
+ const enumDef = enums.get(column.type.enum);
8664
+ if (!enumDef) return { ok: false, error: `${label}: enum '${column.type.enum}' is not declared` };
8665
+ if (typeof value !== "string" || !enumDef.values.includes(value)) {
8666
+ return { ok: false, error: `${label}: null default must be one of ${enumDef.values.join(", ")}` };
8667
+ }
8668
+ const typeName2 = columnPostgresType(column, schemaName, enums);
8669
+ return { ok: true, sql: `${quoteLiteral(value)}::${typeName2}` };
8670
+ }
8671
+ return scalarLiteral2({ column, type: column.type, value, label });
8672
+ }
8673
+ var SCALAR_LITERALS = {
8674
+ text: (value, label) => typeof value === "string" ? { ok: true, sql: quoteLiteral(value) } : { ok: false, error: `${label}: null default must be a string` },
8675
+ uuid: (value, label) => typeof value === "string" && UUID_RE.test(value) ? { ok: true, sql: `${quoteLiteral(value)}::uuid` } : { ok: false, error: `${label}: null default must be a UUID` },
8676
+ boolean: (value, label) => typeof value === "boolean" ? { ok: true, sql: value ? "TRUE" : "FALSE" } : { ok: false, error: `${label}: null default must be true or false` },
8677
+ integer: (value, label) => typeof value === "number" && Number.isSafeInteger(value) ? { ok: true, sql: String(value) } : { ok: false, error: `${label}: null default must be an integer` },
8678
+ bigint: (value, label) => typeof value === "string" && INTEGER_RE.test(value) ? { ok: true, sql: `${value}::bigint` } : { ok: false, error: `${label}: null default must be a base-10 integer string` },
8679
+ numeric: numericLiteral,
8680
+ double: numericLiteral,
8681
+ date: (value, label) => typeof value === "string" && DATE_RE.test(value) ? { ok: true, sql: `${quoteLiteral(value)}::date` } : { ok: false, error: `${label}: null default must be a YYYY-MM-DD date` },
8682
+ timestamptz: (value, label) => typeof value === "string" && TIMESTAMPTZ_RE.test(value) ? { ok: true, sql: `${quoteLiteral(value)}::${postgresTypeName("timestamptz")}` } : { ok: false, error: `${label}: null default must be an ISO-8601 timestamp` },
8683
+ jsonb: jsonbLiteral
8684
+ };
8685
+ function numericLiteral(value, label) {
8686
+ if (typeof value === "number" && Number.isFinite(value)) return { ok: true, sql: String(value) };
8687
+ if (typeof value === "string" && NUMERIC_RE.test(value)) return { ok: true, sql: value };
8688
+ return { ok: false, error: `${label}: null default must be a finite number` };
8689
+ }
8690
+ function scalarLiteral2({
8691
+ column,
8692
+ type,
8693
+ value,
8694
+ label
8695
+ }) {
8696
+ const encode = SCALAR_LITERALS[type];
8697
+ if (!encode) return { ok: false, error: `${column.name}: unsupported type '${type}'` };
8698
+ return encode(value, label);
8699
+ }
8700
+ function jsonbLiteral(value, label) {
8701
+ if (typeof value !== "string") return { ok: false, error: `${label}: null default must be a JSON string` };
8702
+ try {
8703
+ JSON.parse(value);
8704
+ } catch {
8705
+ return { ok: false, error: `${label}: null default must be valid JSON` };
8706
+ }
8707
+ return { ok: true, sql: `${quoteLiteral(value)}::jsonb` };
8708
+ }
8709
+ function dollarQuote(body) {
8710
+ const digest = crypto.createHash("sha256").update(body).digest("hex");
8711
+ const candidates = ["seq_orm_import", `seq_orm_${digest.slice(0, 16)}`, `seq_orm_${digest}`];
8712
+ const tag = candidates.find((candidate) => !body.includes(`$${candidate}$`)) ?? `seq_orm_${digest}_body`;
8713
+ return `$${tag}$${body}$${tag}$`;
8714
+ }
8638
8715
 
8639
8716
  // src/engine/security.ts
8640
8717
  var CONSUMER_TABLE_PRIVILEGES = ["SELECT", "INSERT", "UPDATE", "DELETE"];
@@ -9451,11 +9528,13 @@ function applyMigrationHintsV2(previous, definition) {
9451
9528
  if (column.renamedFrom) {
9452
9529
  const previousColumn = snapshotTable.columns[column.renamedFrom];
9453
9530
  if (previousColumn && snapshotTable.columns[name2]) {
9454
- throw new OrmDefinitionError(
9455
- `'${table.table}.${name2}' declares renamedFrom '${column.renamedFrom}', but both columns exist in the previous schema \u2014 a rename cannot overwrite a live column`
9456
- );
9457
- }
9458
- if (previousColumn) {
9531
+ const reused = table.columns.some((candidate) => candidate.columnName === column.renamedFrom);
9532
+ if (!reused) {
9533
+ throw new OrmDefinitionError(
9534
+ `'${table.table}.${name2}' declares renamedFrom '${column.renamedFrom}', but both columns exist in the previous schema \u2014 a rename cannot overwrite a live column`
9535
+ );
9536
+ }
9537
+ } else if (previousColumn) {
9459
9538
  statements.push(
9460
9539
  `ALTER TABLE ${qualified(table.table)} RENAME COLUMN ${quoteIdentifier(column.renamedFrom)} TO ${quoteIdentifier(name2)}`
9461
9540
  );
@@ -9548,7 +9627,7 @@ async function planWithViewRecreation({
9548
9627
  const schema = ormSchemaName(canonical.namespace);
9549
9628
  const previous = previousSnapshot ? normalizeSnapshot(previousSnapshot) : emptySnapshot(canonical.namespace);
9550
9629
  assertValidViewDependencies(canonical);
9551
- const hints = applyMigrationHintsV2(previous, canonical);
9630
+ const hints = previousSnapshot === void 0 ? { statements: [], adjusted: previous } : applyMigrationHintsV2(previous, canonical);
9552
9631
  const snapshot = generateSnapshotV2(canonical, previousId(previous));
9553
9632
  const generatedBaseDdl = await diffStatements(withoutViews(hints.adjusted), withoutViews(snapshot));
9554
9633
  const baseDdl = orderForeignKeyAdditions(canonical, generatedBaseDdl);
@@ -10778,7 +10857,7 @@ var hash = zod.z.string().regex(/^sha256:[0-9a-f]{64}$/);
10778
10857
  var ormMigrationPayloadSchema = zod.z.object({
10779
10858
  canonical_definition: canonicalDefinitionSchema,
10780
10859
  documents: zod.z.array(zod.z.object({ path: zod.z.string().min(1).max(2048), contents: zod.z.string().max(1e6) }).strict()).max(5e3),
10781
- client_manifest: zod.z.object({ ops_hash: hash, operations: zod.z.record(zod.z.string(), hash) }).strict(),
10860
+ client_manifest: zod.z.object({ operations: zod.z.record(zod.z.string(), compiledOperationSchema) }).strict(),
10782
10861
  sdl: zod.z.string().refine((value) => Buffer.byteLength(value, "utf8") <= MAX_GENERATED_SDL_BYTES, {
10783
10862
  message: `sdl exceeds ${MAX_GENERATED_SDL_BYTES} bytes`
10784
10863
  }),
@@ -10877,132 +10956,6 @@ var importSpecSchema = zod.z.object({
10877
10956
  onConflict: zod.z.enum(IMPORT_CONFLICT_MODES).default("skip"),
10878
10957
  batchSize: zod.z.number().int().min(1).max(2e4).default(5e3)
10879
10958
  }).strict();
10880
- var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
10881
- var DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
10882
- var TIMESTAMPTZ_RE = /^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:?\d{2})$/;
10883
- var INTEGER_RE = /^-?\d+$/;
10884
- var NUMERIC_RE = /^-?\d+(\.\d+)?$/;
10885
- function sourceSchemaAllowed(schema) {
10886
- return schema !== "information_schema" && !schema.startsWith("pg_");
10887
- }
10888
- function isRelationIdentifier(value) {
10889
- return value.length <= 63 && IDENTIFIER_PATTERN.test(value);
10890
- }
10891
- function isSourceColumn(value) {
10892
- return value.length <= 63 && COLUMN_IDENTIFIER_PATTERN.test(value);
10893
- }
10894
- function splitQualifiedRelation(from) {
10895
- const dot = from.indexOf(".");
10896
- if (dot <= 0 || dot !== from.lastIndexOf(".")) return null;
10897
- const schema = from.slice(0, dot);
10898
- const table = from.slice(dot + 1);
10899
- if (!isRelationIdentifier(schema) || !isRelationIdentifier(table)) return null;
10900
- return { schema, table };
10901
- }
10902
- function postgresTypeName(type) {
10903
- if (type === "double") return "double precision";
10904
- if (type === "timestamptz") return "timestamp with time zone";
10905
- return type;
10906
- }
10907
- function columnPostgresType(column, schemaName, enums) {
10908
- if (typeof column.type === "string") return postgresTypeName(column.type);
10909
- if (!enums.has(column.type.enum)) return null;
10910
- return `${quoteIdentifier(schemaName)}.${quoteIdentifier(column.type.enum)}`;
10911
- }
10912
- function quoteQualified(schema, table) {
10913
- return `${quoteIdentifier(schema)}.${quoteIdentifier(table)}`;
10914
- }
10915
- var INT4_MIN = -2147483648;
10916
- var INT4_MAX = 2147483647;
10917
- function resumeLiteralSql({
10918
- column,
10919
- after,
10920
- schemaName,
10921
- enums
10922
- }) {
10923
- const coerced = coerceResumeValue(column, after);
10924
- if (!coerced.ok) return coerced;
10925
- return literalSql({ column, value: coerced.value, schemaName, enums });
10926
- }
10927
- function coerceResumeValue(column, after) {
10928
- const type = typeof column.type === "string" ? column.type : null;
10929
- if (type === "integer") {
10930
- if (!INTEGER_RE.test(after)) return { ok: false, error: `${column.name}: after must be an integer` };
10931
- const parsed = Number(after);
10932
- if (!Number.isSafeInteger(parsed) || parsed < INT4_MIN || parsed > INT4_MAX) {
10933
- return { ok: false, error: `${column.name}: after must be an integer` };
10934
- }
10935
- return { ok: true, value: parsed };
10936
- }
10937
- if (type === "boolean") {
10938
- if (after !== "true" && after !== "false") return { ok: false, error: `${column.name}: after must be true or false` };
10939
- return { ok: true, value: after === "true" };
10940
- }
10941
- return { ok: true, value: after };
10942
- }
10943
- function literalSql({
10944
- column,
10945
- value,
10946
- schemaName,
10947
- enums
10948
- }) {
10949
- const label = column.name;
10950
- if (typeof value === "string" && value.includes("\0")) {
10951
- return { ok: false, error: `${label}: null default contains a NUL character` };
10952
- }
10953
- if (typeof column.type !== "string") {
10954
- const enumDef = enums.get(column.type.enum);
10955
- if (!enumDef) return { ok: false, error: `${label}: enum '${column.type.enum}' is not declared` };
10956
- if (typeof value !== "string" || !enumDef.values.includes(value)) {
10957
- return { ok: false, error: `${label}: null default must be one of ${enumDef.values.join(", ")}` };
10958
- }
10959
- const typeName2 = columnPostgresType(column, schemaName, enums);
10960
- return { ok: true, sql: `${quoteLiteral(value)}::${typeName2}` };
10961
- }
10962
- return scalarLiteral2({ column, type: column.type, value, label });
10963
- }
10964
- var SCALAR_LITERALS = {
10965
- text: (value, label) => typeof value === "string" ? { ok: true, sql: quoteLiteral(value) } : { ok: false, error: `${label}: null default must be a string` },
10966
- uuid: (value, label) => typeof value === "string" && UUID_RE.test(value) ? { ok: true, sql: `${quoteLiteral(value)}::uuid` } : { ok: false, error: `${label}: null default must be a UUID` },
10967
- boolean: (value, label) => typeof value === "boolean" ? { ok: true, sql: value ? "TRUE" : "FALSE" } : { ok: false, error: `${label}: null default must be true or false` },
10968
- integer: (value, label) => typeof value === "number" && Number.isSafeInteger(value) ? { ok: true, sql: String(value) } : { ok: false, error: `${label}: null default must be an integer` },
10969
- bigint: (value, label) => typeof value === "string" && INTEGER_RE.test(value) ? { ok: true, sql: `${value}::bigint` } : { ok: false, error: `${label}: null default must be a base-10 integer string` },
10970
- numeric: numericLiteral,
10971
- double: numericLiteral,
10972
- date: (value, label) => typeof value === "string" && DATE_RE.test(value) ? { ok: true, sql: `${quoteLiteral(value)}::date` } : { ok: false, error: `${label}: null default must be a YYYY-MM-DD date` },
10973
- timestamptz: (value, label) => typeof value === "string" && TIMESTAMPTZ_RE.test(value) ? { ok: true, sql: `${quoteLiteral(value)}::${postgresTypeName("timestamptz")}` } : { ok: false, error: `${label}: null default must be an ISO-8601 timestamp` },
10974
- jsonb: jsonbLiteral
10975
- };
10976
- function numericLiteral(value, label) {
10977
- if (typeof value === "number" && Number.isFinite(value)) return { ok: true, sql: String(value) };
10978
- if (typeof value === "string" && NUMERIC_RE.test(value)) return { ok: true, sql: value };
10979
- return { ok: false, error: `${label}: null default must be a finite number` };
10980
- }
10981
- function scalarLiteral2({
10982
- column,
10983
- type,
10984
- value,
10985
- label
10986
- }) {
10987
- const encode = SCALAR_LITERALS[type];
10988
- if (!encode) return { ok: false, error: `${column.name}: unsupported type '${type}'` };
10989
- return encode(value, label);
10990
- }
10991
- function jsonbLiteral(value, label) {
10992
- if (typeof value !== "string") return { ok: false, error: `${label}: null default must be a JSON string` };
10993
- try {
10994
- JSON.parse(value);
10995
- } catch {
10996
- return { ok: false, error: `${label}: null default must be valid JSON` };
10997
- }
10998
- return { ok: true, sql: `${quoteLiteral(value)}::jsonb` };
10999
- }
11000
- function dollarQuote(body) {
11001
- const digest = crypto.createHash("sha256").update(body).digest("hex");
11002
- const candidates = ["seq_orm_import", `seq_orm_${digest.slice(0, 16)}`, `seq_orm_${digest}`];
11003
- const tag = candidates.find((candidate) => !body.includes(`$${candidate}$`)) ?? `seq_orm_${digest}_body`;
11004
- return `$${tag}$${body}$${tag}$`;
11005
- }
11006
10959
 
11007
10960
  // src/import/script.ts
11008
10961
  function renderImportScript({
@@ -11516,7 +11469,7 @@ var USAGE = `usage:
11516
11469
  seq-studio orm generate [dir] --migration-export [--check]
11517
11470
  export reviewed ORM inputs for a coordinated pipeline migration; --check verifies without writing
11518
11471
  seq-studio orm validate [dir] parse + validate definitions and verify committed migrations are in sync
11519
- seq-studio orm plan [dir] -e <env> offline dry run: compile definitions and diff against the registry (no database, no writes)
11472
+ seq-studio orm plan [dir] -e <env> preview fresh-schema DDL and compare registry versions (no live migration diff, no writes)
11520
11473
  seq-studio orm apply [dir] -e <env> author the migration, register, apply, and refresh the generated outputs (the everyday command)
11521
11474
  seq-studio orm apply --dry-run -e <env> rehearse the migration on a copy of the environment's real data, then discard it (no real apply)
11522
11475
  seq-studio orm apply --no-create -e <env> apply only if the namespace is already registered (CI guard; never provisions a new namespace)
@@ -11802,7 +11755,7 @@ async function generateCommand(rest) {
11802
11755
  canonical_definition: loaded2.canonical,
11803
11756
  documents,
11804
11757
  sdl,
11805
- client_manifest: { ops_hash: manifest2.opsHash, operations: Object.fromEntries(Object.entries(manifest2.operations).map(([name2, operation]) => [name2, operation.opHash])) },
11758
+ client_manifest: { operations: manifest2.operations },
11806
11759
  schema_snapshot: workspace.tipSnapshot,
11807
11760
  ...migration ? { migration } : {}
11808
11761
  } });
@@ -12249,8 +12202,7 @@ async function applyV2Command(rest, dir) {
12249
12202
  canonical_definition: loaded.canonical,
12250
12203
  documents,
12251
12204
  client_manifest: {
12252
- ops_hash: manifest.opsHash,
12253
- operations: Object.fromEntries(Object.entries(manifest.operations).map(([name2, op]) => [name2, op.opHash]))
12205
+ operations: manifest.operations
12254
12206
  },
12255
12207
  sdl,
12256
12208
  ...workspace.tipSnapshot !== void 0 ? { schema_snapshot: workspace.tipSnapshot } : {},
@@ -12260,7 +12212,7 @@ async function applyV2Command(rest, dir) {
12260
12212
  ...noCreate ? { no_create: true } : {}
12261
12213
  });
12262
12214
  console.log(
12263
- (registered.created ? `registered ${namespace}@${registered.content_hash.slice(0, 12)}` : `already registered ${namespace}@${registered.content_hash.slice(0, 12)}`) + (registered.ops_hash ? ` (ops ${registered.ops_hash.slice(0, 19)})` : "") + (migration ? ` with committed migration ${migration.name}` : "")
12215
+ (registered.created ? `registered ${namespace}@${registered.content_hash.slice(0, 12)}` : `already registered ${namespace}@${registered.content_hash.slice(0, 12)}`) + (migration ? ` with committed migration ${migration.name}` : "")
12264
12216
  );
12265
12217
  if (dryRun) return dryRunRehearsal({ namespace, versionId: registered.version_id, contentHash: registered.content_hash });
12266
12218
  const registry = await fetchRegistryState(namespace, registered.content_hash);