@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/index.cjs CHANGED
@@ -4967,6 +4967,149 @@ function compileStaticPolicySql({ table, predicate, tables, namespace, alias, ro
4967
4967
  });
4968
4968
  return render(table, predicate, alias, rootRelation);
4969
4969
  }
4970
+ var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
4971
+ var DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
4972
+ var TIMESTAMPTZ_RE = /^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:?\d{2})$/;
4973
+ var INTEGER_RE = /^-?\d+$/;
4974
+ var NUMERIC_RE = /^-?\d+(\.\d+)?$/;
4975
+ function sourceSchemaAllowed(schema) {
4976
+ return schema !== "information_schema" && !schema.startsWith("pg_");
4977
+ }
4978
+ function isRelationIdentifier(value) {
4979
+ return value.length <= 63 && IDENTIFIER_PATTERN.test(value);
4980
+ }
4981
+ function isSourceColumn(value) {
4982
+ return value.length <= 63 && COLUMN_IDENTIFIER_PATTERN.test(value);
4983
+ }
4984
+ function splitQualifiedRelation(from) {
4985
+ const dot = from.indexOf(".");
4986
+ if (dot <= 0 || dot !== from.lastIndexOf(".")) return null;
4987
+ const schema = from.slice(0, dot);
4988
+ const table = from.slice(dot + 1);
4989
+ if (!isRelationIdentifier(schema) || !isRelationIdentifier(table)) return null;
4990
+ return { schema, table };
4991
+ }
4992
+ function postgresTypeName(type) {
4993
+ if (type === "double") return "double precision";
4994
+ if (type === "timestamptz") return "timestamp with time zone";
4995
+ return type;
4996
+ }
4997
+ function columnPostgresType(column, schemaName, enums) {
4998
+ if (typeof column.type === "string") return postgresTypeName(column.type);
4999
+ if (!enums.has(column.type.enum)) return null;
5000
+ return `${quoteIdentifier(schemaName)}.${quoteIdentifier(column.type.enum)}`;
5001
+ }
5002
+ function quoteQualified(schema, table) {
5003
+ return `${quoteIdentifier(schema)}.${quoteIdentifier(table)}`;
5004
+ }
5005
+ var INT4_MIN = -2147483648;
5006
+ var INT4_MAX = 2147483647;
5007
+ function resumeLiteralSql({
5008
+ column,
5009
+ after,
5010
+ schemaName,
5011
+ enums
5012
+ }) {
5013
+ const coerced = coerceResumeValue(column, after);
5014
+ if (!coerced.ok) return coerced;
5015
+ return literalSql({ column, value: coerced.value, schemaName, enums });
5016
+ }
5017
+ function coerceResumeValue(column, after) {
5018
+ const type = typeof column.type === "string" ? column.type : null;
5019
+ if (type === "integer") {
5020
+ if (!INTEGER_RE.test(after)) return { ok: false, error: `${column.name}: after must be an integer` };
5021
+ const parsed = Number(after);
5022
+ if (!Number.isSafeInteger(parsed) || parsed < INT4_MIN || parsed > INT4_MAX) {
5023
+ return { ok: false, error: `${column.name}: after must be an integer` };
5024
+ }
5025
+ return { ok: true, value: parsed };
5026
+ }
5027
+ if (type === "boolean") {
5028
+ if (after !== "true" && after !== "false") return { ok: false, error: `${column.name}: after must be true or false` };
5029
+ return { ok: true, value: after === "true" };
5030
+ }
5031
+ return { ok: true, value: after };
5032
+ }
5033
+ function literalSql({
5034
+ column,
5035
+ value,
5036
+ schemaName,
5037
+ enums
5038
+ }) {
5039
+ const label = column.name;
5040
+ if (typeof value === "string" && value.includes("\0")) {
5041
+ return { ok: false, error: `${label}: null default contains a NUL character` };
5042
+ }
5043
+ if (typeof column.type !== "string") {
5044
+ const enumDef = enums.get(column.type.enum);
5045
+ if (!enumDef) return { ok: false, error: `${label}: enum '${column.type.enum}' is not declared` };
5046
+ if (typeof value !== "string" || !enumDef.values.includes(value)) {
5047
+ return { ok: false, error: `${label}: null default must be one of ${enumDef.values.join(", ")}` };
5048
+ }
5049
+ const typeName = columnPostgresType(column, schemaName, enums);
5050
+ return { ok: true, sql: `${quoteLiteral(value)}::${typeName}` };
5051
+ }
5052
+ return scalarLiteral({ column, type: column.type, value, label });
5053
+ }
5054
+ var SCALAR_LITERALS = {
5055
+ text: (value, label) => typeof value === "string" ? { ok: true, sql: quoteLiteral(value) } : { ok: false, error: `${label}: null default must be a string` },
5056
+ 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` },
5057
+ boolean: (value, label) => typeof value === "boolean" ? { ok: true, sql: value ? "TRUE" : "FALSE" } : { ok: false, error: `${label}: null default must be true or false` },
5058
+ integer: (value, label) => typeof value === "number" && Number.isSafeInteger(value) ? { ok: true, sql: String(value) } : { ok: false, error: `${label}: null default must be an integer` },
5059
+ 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` },
5060
+ numeric: numericLiteral,
5061
+ double: numericLiteral,
5062
+ 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` },
5063
+ 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` },
5064
+ jsonb: jsonbLiteral
5065
+ };
5066
+ function numericLiteral(value, label) {
5067
+ if (typeof value === "number" && Number.isFinite(value)) return { ok: true, sql: String(value) };
5068
+ if (typeof value === "string" && NUMERIC_RE.test(value)) return { ok: true, sql: value };
5069
+ return { ok: false, error: `${label}: null default must be a finite number` };
5070
+ }
5071
+ function scalarLiteral({
5072
+ column,
5073
+ type,
5074
+ value,
5075
+ label
5076
+ }) {
5077
+ const encode = SCALAR_LITERALS[type];
5078
+ if (!encode) return { ok: false, error: `${column.name}: unsupported type '${type}'` };
5079
+ return encode(value, label);
5080
+ }
5081
+ function jsonbLiteral(value, label) {
5082
+ if (typeof value !== "string") return { ok: false, error: `${label}: null default must be a JSON string` };
5083
+ try {
5084
+ JSON.parse(value);
5085
+ } catch {
5086
+ return { ok: false, error: `${label}: null default must be valid JSON` };
5087
+ }
5088
+ return { ok: true, sql: `${quoteLiteral(value)}::jsonb` };
5089
+ }
5090
+ function dollarQuote(body) {
5091
+ const digest = crypto.createHash("sha256").update(body).digest("hex");
5092
+ const candidates = ["seq_orm_import", `seq_orm_${digest.slice(0, 16)}`, `seq_orm_${digest}`];
5093
+ const tag = candidates.find((candidate) => !body.includes(`$${candidate}$`)) ?? `seq_orm_${digest}_body`;
5094
+ return `$${tag}$${body}$${tag}$`;
5095
+ }
5096
+
5097
+ // src/engine/synced-backing-absent.ts
5098
+ var SYNCED_BACKING_ABSENT_FUNCTION = "orm_synced_backing_absent";
5099
+ var SYNCED_BACKING_ABSENT_SQLSTATE = "55000";
5100
+ var REASON = "is disabled in this environment: its synced pipeline is not deployed here";
5101
+ var SYNCED_BACKING_ABSENT_RAISE = `RAISE EXCEPTION 'ORM object % ${REASON}', object
5102
+ USING ERRCODE = '${SYNCED_BACKING_ABSENT_SQLSTATE}';`;
5103
+ var RAISED = new RegExp(`^ORM object ([a-z][a-z0-9_]*\\.[a-z][a-z0-9_]*) ${REASON}`);
5104
+ function disabledSyncedObjectFromError(error) {
5105
+ if (error === null || typeof error !== "object") return null;
5106
+ const { code, message } = error;
5107
+ if (code !== SYNCED_BACKING_ABSENT_SQLSTATE || typeof message !== "string") return null;
5108
+ return RAISED.exec(message)?.[1] ?? null;
5109
+ }
5110
+ function disabledSyncedObjectMessage(object) {
5111
+ return `${object} ${REASON}`;
5112
+ }
4970
5113
 
4971
5114
  // src/engine/security.ts
4972
5115
  var CONSUMER_TABLE_PRIVILEGES = ["SELECT", "INSERT", "UPDATE", "DELETE"];
@@ -5143,6 +5286,42 @@ function splitPhysicalRelation(physicalRelation) {
5143
5286
  `synced view physical relation must be "table" or "schema.table" (got "${physicalRelation}")`
5144
5287
  );
5145
5288
  }
5289
+ function syncedViewUnbackedStatements({
5290
+ definition,
5291
+ tables,
5292
+ columnTypesByTable
5293
+ }) {
5294
+ if (tables.length === 0) return [];
5295
+ const schema = quoteIdentifier(ormSchemaName(definition.namespace));
5296
+ const role = quoteIdentifier(consumerRoleName(definition.namespace));
5297
+ const guard = `${schema}.${quoteIdentifier(SYNCED_BACKING_ABSENT_FUNCTION)}`;
5298
+ const wanted = new Set(tables);
5299
+ const statements = [
5300
+ `CREATE OR REPLACE FUNCTION ${guard}(object text, typed anyelement) RETURNS anyelement LANGUAGE plpgsql VOLATILE AS ${quoteLiteral(`BEGIN
5301
+ ${SYNCED_BACKING_ABSENT_RAISE}
5302
+ END`)}`
5303
+ ];
5304
+ for (const table of syncedTables(definition)) {
5305
+ if (!wanted.has(table.table)) continue;
5306
+ const columns = Object.entries(table.columns ?? {});
5307
+ if (columns.length === 0) {
5308
+ throw new OrmDefinitionError(`synced table "${table.table}" needs declared columns to be disabled while its backing is absent`);
5309
+ }
5310
+ const object = quoteLiteral(`${definition.namespace}.${table.table}`);
5311
+ const canonicalTypes = columnTypesByTable?.get(table.table);
5312
+ const projection = columns.map(([name2, column]) => {
5313
+ const declared = canonicalTypes?.[name2];
5314
+ const sqlType = typeof declared === "object" ? `${schema}.${quoteIdentifier(declared.enum)}` : postgresTypeName(column.type);
5315
+ return `${guard}(${object}, NULL::${sqlType}) AS ${quoteIdentifier(name2)}`;
5316
+ }).join(", ");
5317
+ const viewName = `${schema}.${quoteIdentifier(table.table)}`;
5318
+ statements.push(
5319
+ `CREATE OR REPLACE VIEW ${viewName} AS SELECT ${projection} WHERE ${guard}(${object}, true)`,
5320
+ `GRANT SELECT ON ${viewName} TO ${role}`
5321
+ );
5322
+ }
5323
+ return statements;
5324
+ }
5146
5325
  function syncedViewDropStatements({
5147
5326
  schemaName,
5148
5327
  tables
@@ -6225,11 +6404,13 @@ function applyMigrationHintsV2(previous, definition) {
6225
6404
  if (column.renamedFrom) {
6226
6405
  const previousColumn = snapshotTable.columns[column.renamedFrom];
6227
6406
  if (previousColumn && snapshotTable.columns[name2]) {
6228
- throw new OrmDefinitionError(
6229
- `'${table.table}.${name2}' declares renamedFrom '${column.renamedFrom}', but both columns exist in the previous schema \u2014 a rename cannot overwrite a live column`
6230
- );
6231
- }
6232
- if (previousColumn) {
6407
+ const reused = table.columns.some((candidate) => candidate.columnName === column.renamedFrom);
6408
+ if (!reused) {
6409
+ throw new OrmDefinitionError(
6410
+ `'${table.table}.${name2}' declares renamedFrom '${column.renamedFrom}', but both columns exist in the previous schema \u2014 a rename cannot overwrite a live column`
6411
+ );
6412
+ }
6413
+ } else if (previousColumn) {
6233
6414
  statements.push(
6234
6415
  `ALTER TABLE ${qualified2(table.table)} RENAME COLUMN ${quoteIdentifier(column.renamedFrom)} TO ${quoteIdentifier(name2)}`
6235
6416
  );
@@ -6322,7 +6503,7 @@ async function planWithViewRecreation({
6322
6503
  const schema = ormSchemaName(canonical.namespace);
6323
6504
  const previous = previousSnapshot ? normalizeSnapshot(previousSnapshot) : emptySnapshot(canonical.namespace);
6324
6505
  assertValidViewDependencies(canonical);
6325
- const hints = applyMigrationHintsV2(previous, canonical);
6506
+ const hints = previousSnapshot === void 0 ? { statements: [], adjusted: previous } : applyMigrationHintsV2(previous, canonical);
6326
6507
  const snapshot = generateSnapshotV2(canonical, previousId(previous));
6327
6508
  const generatedBaseDdl = await diffStatements(withoutViews(hints.adjusted), withoutViews(snapshot));
6328
6509
  const baseDdl = orderForeignKeyAdditions(canonical, generatedBaseDdl);
@@ -7074,52 +7255,6 @@ async function planMigration({
7074
7255
  }
7075
7256
  var compileNamespace = (definition) => planMigration({ definition });
7076
7257
  var previousId2 = (snapshot) => snapshot.id;
7077
- var ORM_MIGRATION_EXPORT_FILE = "orm.migration.json";
7078
- var ORM_MIGRATION_EXPORT_MAX_BYTES = ORM_REGISTRATION_MAX_BYTES;
7079
- var hash = zod.z.string().regex(/^sha256:[0-9a-f]{64}$/);
7080
- var ormMigrationPayloadSchema = zod.z.object({
7081
- canonical_definition: canonicalDefinitionSchema,
7082
- documents: zod.z.array(zod.z.object({ path: zod.z.string().min(1).max(2048), contents: zod.z.string().max(1e6) }).strict()).max(5e3),
7083
- client_manifest: zod.z.object({ ops_hash: hash, operations: zod.z.record(zod.z.string(), hash) }).strict(),
7084
- sdl: zod.z.string().refine((value) => Buffer.byteLength(value, "utf8") <= MAX_GENERATED_SDL_BYTES, {
7085
- message: `sdl exceeds ${MAX_GENERATED_SDL_BYTES} bytes`
7086
- }),
7087
- schema_snapshot: zod.z.json(),
7088
- // The existing ORM committed-migration validator and replay engine remain
7089
- // authoritative. This envelope hashes the provenance, never authorizes SQL.
7090
- migration: zod.z.json().optional()
7091
- }).strict();
7092
- var ormMigrationExportSchema = zod.z.object({
7093
- schema_version: zod.z.literal(1),
7094
- schema_hash: hash,
7095
- payload: ormMigrationPayloadSchema,
7096
- checksum: zod.z.string().regex(/^[0-9a-f]{64}$/)
7097
- }).strict();
7098
- function checksum(value) {
7099
- return crypto.createHash("sha256").update(stableJson(value)).digest("hex");
7100
- }
7101
- function createOrmMigrationExport({ schemaHash, payload }) {
7102
- const contents = { schema_version: 1, schema_hash: hash.parse(schemaHash), payload: ormMigrationPayloadSchema.parse(payload) };
7103
- return { ...contents, checksum: checksum(contents) };
7104
- }
7105
- function parseOrmMigrationExport(text4) {
7106
- if (Buffer.byteLength(text4, "utf8") > ORM_MIGRATION_EXPORT_MAX_BYTES) throw new Error("ORM migration export exceeds the size limit");
7107
- const exported = ormMigrationExportSchema.parse(JSON.parse(text4));
7108
- const { checksum: expected, ...contents } = exported;
7109
- if (checksum(contents) !== expected) throw new Error("ORM migration export checksum mismatch; regenerate and commit it");
7110
- return exported;
7111
- }
7112
- function renderOrmMigrationExport(exported) {
7113
- const text4 = `${JSON.stringify(exported, null, 2)}
7114
- `;
7115
- if (Buffer.byteLength(text4, "utf8") > ORM_MIGRATION_EXPORT_MAX_BYTES) throw new Error("ORM migration export exceeds the size limit");
7116
- return text4;
7117
- }
7118
-
7119
- // src/client/sql.ts
7120
- var BUILTIN_SQL_READ_HASH = "sha256:a50c477c952a5e0fe68ed158a4530e4aab573c09bcbb1a8ac454dc88a39a6258";
7121
-
7122
- // src/ir/index.ts
7123
7258
  var IR_VERSION = 6;
7124
7259
  var LEGACY_IR_VERSION = 1;
7125
7260
  var GUARDED_IR_VERSION = 2;
@@ -7155,9 +7290,9 @@ var EXTERNAL_POLICY_CLAIM_KEYS = ["ext_subject", "ext_email"];
7155
7290
  function isExternalPolicyClaimKey(key) {
7156
7291
  return EXTERNAL_POLICY_CLAIM_KEYS.includes(key);
7157
7292
  }
7158
- var scalarLiteral = zod.z.union([zod.z.string(), zod.z.number(), zod.z.boolean(), zod.z.null()]);
7293
+ var scalarLiteral2 = zod.z.union([zod.z.string(), zod.z.number(), zod.z.boolean(), zod.z.null()]);
7159
7294
  var valueIrSchema = zod.z.discriminatedUnion("kind", [
7160
- zod.z.object({ kind: zod.z.literal("literal"), value: zod.z.union([scalarLiteral, zod.z.array(scalarLiteral)]) }),
7295
+ zod.z.object({ kind: zod.z.literal("literal"), value: zod.z.union([scalarLiteral2, zod.z.array(scalarLiteral2)]) }),
7161
7296
  zod.z.object({ kind: zod.z.literal("variable"), name: zod.z.string() }),
7162
7297
  zod.z.object({ kind: zod.z.literal("claim"), key: zod.z.enum(["sub", "org", ...EXTERNAL_POLICY_CLAIM_KEYS]) })
7163
7298
  ]);
@@ -7404,7 +7539,7 @@ var INPUT_REF_KINDS = [
7404
7539
  "onConflict"
7405
7540
  ];
7406
7541
  var variableDefaultIrSchema = zod.z.object({
7407
- value: zod.z.union([scalarLiteral, zod.z.array(scalarLiteral)])
7542
+ value: zod.z.union([scalarLiteral2, zod.z.array(scalarLiteral2)])
7408
7543
  });
7409
7544
  var variableIrSchema = zod.z.object({
7410
7545
  name: zod.z.string(),
@@ -7447,8 +7582,7 @@ var compiledOperationSchema = zod.z.object({
7447
7582
  maxRows: zod.z.number().int().min(1).max(1e4)
7448
7583
  }).strict().optional(),
7449
7584
  irVersion: irVersionSchema,
7450
- name: zod.z.string(),
7451
- opHash: zod.z.string().regex(/^sha256:[0-9a-f]{64}$/),
7585
+ name: zod.z.string().regex(/^[_A-Za-z][_0-9A-Za-z]{0,254}$/),
7452
7586
  kind: zod.z.enum(["query", "mutation"]),
7453
7587
  requires: zod.z.object({
7454
7588
  capability: zod.z.string().optional(),
@@ -7464,7 +7598,7 @@ var compiledOperationSchema = zod.z.object({
7464
7598
  }
7465
7599
  if (operation.language === "sql") {
7466
7600
  const validPlan = operation.sqlQuery ? !operation.sql && operation.irVersion === RUNTIME_SQL_IR_VERSION : !!operation.sql && operation.irVersion === SQL_IR_VERSION;
7467
- const builtin = operation.name === "BuiltinSqlRead" && operation.opHash === BUILTIN_SQL_READ_HASH && operation.requires === null;
7601
+ const builtin = operation.name === "BuiltinSqlRead" && operation.requires === null;
7468
7602
  if (!validPlan || operation.kind !== "query" || operation.roots.length !== 0 || !builtin && !operation.requires?.capability) {
7469
7603
  ctx.addIssue({ code: "custom", message: "SQL operations require a query-only v4 plan or v5 runtime contract, capability, and no GraphQL roots" });
7470
7604
  }
@@ -7479,7 +7613,7 @@ var compiledOperationSchema = zod.z.object({
7479
7613
  }
7480
7614
  });
7481
7615
  var resolvedSourceIrSchema = zod.z.object({
7482
- name: zod.z.string(),
7616
+ name: zod.z.string().regex(/^[_A-Za-z][_0-9A-Za-z]{0,254}$/),
7483
7617
  kind: zod.z.enum(["manual", "etl", "prefetch"]),
7484
7618
  /** Logical table key of the backing relation. */
7485
7619
  table: zod.z.string(),
@@ -7593,7 +7727,6 @@ var compiledArtifactSchema = zod.z.object({
7593
7727
  ownSchemaHash: zod.z.string().optional(),
7594
7728
  dependencies: zod.z.record(zod.z.string(), zod.z.string()).optional(),
7595
7729
  readPolicies: zod.z.record(zod.z.string(), predIrSchema).optional(),
7596
- opsHash: zod.z.string(),
7597
7730
  /** Apply-observed synced objects without a serving backing; not part of the authored schema hash. */
7598
7731
  unbackedTables: zod.z.array(zod.z.string()).optional(),
7599
7732
  tables: zod.z.record(zod.z.string(), tableMetaIrSchema),
@@ -7623,11 +7756,52 @@ function normalizeIr(raw) {
7623
7756
  if (!irVersionSchema.safeParse(version).success) throw new IrVersionError(version);
7624
7757
  return compiledArtifactSchema.parse(raw);
7625
7758
  }
7626
- function indexByHash(artifact) {
7759
+ function indexByName(artifact) {
7627
7760
  const map = /* @__PURE__ */ new Map();
7628
- for (const op of Object.values(artifact.operations)) map.set(op.opHash, op);
7761
+ for (const op of Object.values(artifact.operations)) map.set(op.name, op);
7629
7762
  return map;
7630
7763
  }
7764
+ var ORM_MIGRATION_EXPORT_FILE = "orm.migration.json";
7765
+ var ORM_MIGRATION_EXPORT_MAX_BYTES = ORM_REGISTRATION_MAX_BYTES;
7766
+ var hash = zod.z.string().regex(/^sha256:[0-9a-f]{64}$/);
7767
+ var ormMigrationPayloadSchema = zod.z.object({
7768
+ canonical_definition: canonicalDefinitionSchema,
7769
+ documents: zod.z.array(zod.z.object({ path: zod.z.string().min(1).max(2048), contents: zod.z.string().max(1e6) }).strict()).max(5e3),
7770
+ client_manifest: zod.z.object({ operations: zod.z.record(zod.z.string(), compiledOperationSchema) }).strict(),
7771
+ sdl: zod.z.string().refine((value) => Buffer.byteLength(value, "utf8") <= MAX_GENERATED_SDL_BYTES, {
7772
+ message: `sdl exceeds ${MAX_GENERATED_SDL_BYTES} bytes`
7773
+ }),
7774
+ schema_snapshot: zod.z.json(),
7775
+ // The existing ORM committed-migration validator and replay engine remain
7776
+ // authoritative. This envelope hashes the provenance, never authorizes SQL.
7777
+ migration: zod.z.json().optional()
7778
+ }).strict();
7779
+ var ormMigrationExportSchema = zod.z.object({
7780
+ schema_version: zod.z.literal(1),
7781
+ schema_hash: hash,
7782
+ payload: ormMigrationPayloadSchema,
7783
+ checksum: zod.z.string().regex(/^[0-9a-f]{64}$/)
7784
+ }).strict();
7785
+ function checksum(value) {
7786
+ return crypto.createHash("sha256").update(stableJson(value)).digest("hex");
7787
+ }
7788
+ function createOrmMigrationExport({ schemaHash, payload }) {
7789
+ const contents = { schema_version: 1, schema_hash: hash.parse(schemaHash), payload: ormMigrationPayloadSchema.parse(payload) };
7790
+ return { ...contents, checksum: checksum(contents) };
7791
+ }
7792
+ function parseOrmMigrationExport(text4) {
7793
+ if (Buffer.byteLength(text4, "utf8") > ORM_MIGRATION_EXPORT_MAX_BYTES) throw new Error("ORM migration export exceeds the size limit");
7794
+ const exported = ormMigrationExportSchema.parse(JSON.parse(text4));
7795
+ const { checksum: expected, ...contents } = exported;
7796
+ if (checksum(contents) !== expected) throw new Error("ORM migration export checksum mismatch; regenerate and commit it");
7797
+ return exported;
7798
+ }
7799
+ function renderOrmMigrationExport(exported) {
7800
+ const text4 = `${JSON.stringify(exported, null, 2)}
7801
+ `;
7802
+ if (Buffer.byteLength(text4, "utf8") > ORM_MIGRATION_EXPORT_MAX_BYTES) throw new Error("ORM migration export exceeds the size limit");
7803
+ return text4;
7804
+ }
7631
7805
 
7632
7806
  // src/schema/namespace.ts
7633
7807
  var EMPTY_CAPABILITIES = { roles: { definitions: {}, capabilities: {} }, uses: [] };
@@ -8358,132 +8532,6 @@ var importSpecSchema = zod.z.object({
8358
8532
  onConflict: zod.z.enum(IMPORT_CONFLICT_MODES).default("skip"),
8359
8533
  batchSize: zod.z.number().int().min(1).max(2e4).default(5e3)
8360
8534
  }).strict();
8361
- var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
8362
- var DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
8363
- var TIMESTAMPTZ_RE = /^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:?\d{2})$/;
8364
- var INTEGER_RE = /^-?\d+$/;
8365
- var NUMERIC_RE = /^-?\d+(\.\d+)?$/;
8366
- function sourceSchemaAllowed(schema) {
8367
- return schema !== "information_schema" && !schema.startsWith("pg_");
8368
- }
8369
- function isRelationIdentifier(value) {
8370
- return value.length <= 63 && IDENTIFIER_PATTERN.test(value);
8371
- }
8372
- function isSourceColumn(value) {
8373
- return value.length <= 63 && COLUMN_IDENTIFIER_PATTERN.test(value);
8374
- }
8375
- function splitQualifiedRelation(from) {
8376
- const dot = from.indexOf(".");
8377
- if (dot <= 0 || dot !== from.lastIndexOf(".")) return null;
8378
- const schema = from.slice(0, dot);
8379
- const table = from.slice(dot + 1);
8380
- if (!isRelationIdentifier(schema) || !isRelationIdentifier(table)) return null;
8381
- return { schema, table };
8382
- }
8383
- function postgresTypeName(type) {
8384
- if (type === "double") return "double precision";
8385
- if (type === "timestamptz") return "timestamp with time zone";
8386
- return type;
8387
- }
8388
- function columnPostgresType(column, schemaName, enums) {
8389
- if (typeof column.type === "string") return postgresTypeName(column.type);
8390
- if (!enums.has(column.type.enum)) return null;
8391
- return `${quoteIdentifier(schemaName)}.${quoteIdentifier(column.type.enum)}`;
8392
- }
8393
- function quoteQualified(schema, table) {
8394
- return `${quoteIdentifier(schema)}.${quoteIdentifier(table)}`;
8395
- }
8396
- var INT4_MIN = -2147483648;
8397
- var INT4_MAX = 2147483647;
8398
- function resumeLiteralSql({
8399
- column,
8400
- after,
8401
- schemaName,
8402
- enums
8403
- }) {
8404
- const coerced = coerceResumeValue(column, after);
8405
- if (!coerced.ok) return coerced;
8406
- return literalSql({ column, value: coerced.value, schemaName, enums });
8407
- }
8408
- function coerceResumeValue(column, after) {
8409
- const type = typeof column.type === "string" ? column.type : null;
8410
- if (type === "integer") {
8411
- if (!INTEGER_RE.test(after)) return { ok: false, error: `${column.name}: after must be an integer` };
8412
- const parsed = Number(after);
8413
- if (!Number.isSafeInteger(parsed) || parsed < INT4_MIN || parsed > INT4_MAX) {
8414
- return { ok: false, error: `${column.name}: after must be an integer` };
8415
- }
8416
- return { ok: true, value: parsed };
8417
- }
8418
- if (type === "boolean") {
8419
- if (after !== "true" && after !== "false") return { ok: false, error: `${column.name}: after must be true or false` };
8420
- return { ok: true, value: after === "true" };
8421
- }
8422
- return { ok: true, value: after };
8423
- }
8424
- function literalSql({
8425
- column,
8426
- value,
8427
- schemaName,
8428
- enums
8429
- }) {
8430
- const label = column.name;
8431
- if (typeof value === "string" && value.includes("\0")) {
8432
- return { ok: false, error: `${label}: null default contains a NUL character` };
8433
- }
8434
- if (typeof column.type !== "string") {
8435
- const enumDef = enums.get(column.type.enum);
8436
- if (!enumDef) return { ok: false, error: `${label}: enum '${column.type.enum}' is not declared` };
8437
- if (typeof value !== "string" || !enumDef.values.includes(value)) {
8438
- return { ok: false, error: `${label}: null default must be one of ${enumDef.values.join(", ")}` };
8439
- }
8440
- const typeName = columnPostgresType(column, schemaName, enums);
8441
- return { ok: true, sql: `${quoteLiteral(value)}::${typeName}` };
8442
- }
8443
- return scalarLiteral2({ column, type: column.type, value, label });
8444
- }
8445
- var SCALAR_LITERALS = {
8446
- text: (value, label) => typeof value === "string" ? { ok: true, sql: quoteLiteral(value) } : { ok: false, error: `${label}: null default must be a string` },
8447
- 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` },
8448
- boolean: (value, label) => typeof value === "boolean" ? { ok: true, sql: value ? "TRUE" : "FALSE" } : { ok: false, error: `${label}: null default must be true or false` },
8449
- integer: (value, label) => typeof value === "number" && Number.isSafeInteger(value) ? { ok: true, sql: String(value) } : { ok: false, error: `${label}: null default must be an integer` },
8450
- 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` },
8451
- numeric: numericLiteral,
8452
- double: numericLiteral,
8453
- 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` },
8454
- 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` },
8455
- jsonb: jsonbLiteral
8456
- };
8457
- function numericLiteral(value, label) {
8458
- if (typeof value === "number" && Number.isFinite(value)) return { ok: true, sql: String(value) };
8459
- if (typeof value === "string" && NUMERIC_RE.test(value)) return { ok: true, sql: value };
8460
- return { ok: false, error: `${label}: null default must be a finite number` };
8461
- }
8462
- function scalarLiteral2({
8463
- column,
8464
- type,
8465
- value,
8466
- label
8467
- }) {
8468
- const encode = SCALAR_LITERALS[type];
8469
- if (!encode) return { ok: false, error: `${column.name}: unsupported type '${type}'` };
8470
- return encode(value, label);
8471
- }
8472
- function jsonbLiteral(value, label) {
8473
- if (typeof value !== "string") return { ok: false, error: `${label}: null default must be a JSON string` };
8474
- try {
8475
- JSON.parse(value);
8476
- } catch {
8477
- return { ok: false, error: `${label}: null default must be valid JSON` };
8478
- }
8479
- return { ok: true, sql: `${quoteLiteral(value)}::jsonb` };
8480
- }
8481
- function dollarQuote(body) {
8482
- const digest = crypto.createHash("sha256").update(body).digest("hex");
8483
- const candidates = ["seq_orm_import", `seq_orm_${digest.slice(0, 16)}`, `seq_orm_${digest}`];
8484
- const tag = candidates.find((candidate) => !body.includes(`$${candidate}$`)) ?? `seq_orm_${digest}_body`;
8485
- return `$${tag}$${body}$${tag}$`;
8486
- }
8487
8535
 
8488
8536
  // src/import/script.ts
8489
8537
  function renderImportScript({
@@ -8947,6 +8995,8 @@ exports.SCHEMA_DIR = SCHEMA_DIR;
8947
8995
  exports.SERVICE_PRINCIPAL_IR_VERSION = SERVICE_PRINCIPAL_IR_VERSION;
8948
8996
  exports.SQL_IR_VERSION = SQL_IR_VERSION;
8949
8997
  exports.STATEMENT_KINDS = STATEMENT_KINDS;
8998
+ exports.SYNCED_BACKING_ABSENT_FUNCTION = SYNCED_BACKING_ABSENT_FUNCTION;
8999
+ exports.SYNCED_BACKING_ABSENT_SQLSTATE = SYNCED_BACKING_ABSENT_SQLSTATE;
8950
9000
  exports.SYNCED_CONTRACT_HASH_DOMAIN = SYNCED_CONTRACT_HASH_DOMAIN;
8951
9001
  exports.SYNCED_SOURCE_PATTERN = SYNCED_SOURCE_PATTERN;
8952
9002
  exports.SYNCED_VIEW_EXECUTION_OWNER_ROLE = SYNCED_VIEW_EXECUTION_OWNER_ROLE;
@@ -9016,6 +9066,8 @@ exports.defineView = defineView;
9016
9066
  exports.deriveColumnName = deriveColumnName;
9017
9067
  exports.diffCommand = diffCommand;
9018
9068
  exports.diffStatements = diffStatements;
9069
+ exports.disabledSyncedObjectFromError = disabledSyncedObjectFromError;
9070
+ exports.disabledSyncedObjectMessage = disabledSyncedObjectMessage;
9019
9071
  exports.emptyJournal = emptyJournal;
9020
9072
  exports.emptySnapshot = emptySnapshot;
9021
9073
  exports.endAuthoringContext = endAuthoringContext;
@@ -9028,7 +9080,7 @@ exports.generateSnapshotV2 = generateSnapshotV2;
9028
9080
  exports.highest = highest;
9029
9081
  exports.identifierSchema = identifierSchema;
9030
9082
  exports.importSpecSchema = importSpecSchema;
9031
- exports.indexByHash = indexByHash;
9083
+ exports.indexByName = indexByName;
9032
9084
  exports.isColumnBuilder = isColumnBuilder;
9033
9085
  exports.isEnumRef = isEnumRef;
9034
9086
  exports.isExternalPolicyClaimKey = isExternalPolicyClaimKey;
@@ -9116,6 +9168,7 @@ exports.syncedIndexStatements = syncedIndexStatements;
9116
9168
  exports.syncedTables = syncedTables;
9117
9169
  exports.syncedViewDropStatements = syncedViewDropStatements;
9118
9170
  exports.syncedViewStatements = syncedViewStatements;
9171
+ exports.syncedViewUnbackedStatements = syncedViewUnbackedStatements;
9119
9172
  exports.t = t;
9120
9173
  exports.tableFileSchema = tableFileSchema;
9121
9174
  exports.tableMetaIrSchema = tableMetaIrSchema;