@sequenceholdings/orm 2.1.1 → 2.3.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 (68) hide show
  1. package/README.md +3 -1
  2. package/dist/authoring.cjs +284 -99
  3. package/dist/authoring.cjs.map +1 -1
  4. package/dist/authoring.d.cts +31 -8
  5. package/dist/authoring.d.ts +31 -8
  6. package/dist/authoring.js +282 -100
  7. package/dist/authoring.js.map +1 -1
  8. package/dist/canonical.cjs +51 -3
  9. package/dist/canonical.cjs.map +1 -1
  10. package/dist/canonical.d.cts +838 -12
  11. package/dist/canonical.d.ts +838 -12
  12. package/dist/canonical.js +47 -4
  13. package/dist/canonical.js.map +1 -1
  14. package/dist/cli.cjs +5876 -4198
  15. package/dist/cli.cjs.map +1 -1
  16. package/dist/cli.js +5876 -4198
  17. package/dist/cli.js.map +1 -1
  18. package/dist/client.cjs +49 -32
  19. package/dist/client.cjs.map +1 -1
  20. package/dist/client.d.cts +49 -6
  21. package/dist/client.d.ts +49 -6
  22. package/dist/client.js +49 -32
  23. package/dist/client.js.map +1 -1
  24. package/dist/compiler.cjs +1275 -264
  25. package/dist/compiler.cjs.map +1 -1
  26. package/dist/compiler.d.cts +57 -3
  27. package/dist/compiler.d.ts +57 -3
  28. package/dist/compiler.js +1268 -265
  29. package/dist/compiler.js.map +1 -1
  30. package/dist/{constants-YoFGjIBM.d.cts → constants-C6EG6Wq7.d.cts} +1 -1
  31. package/dist/{constants-YoFGjIBM.d.ts → constants-C6EG6Wq7.d.ts} +1 -1
  32. package/dist/definition-DjfC7Lll.d.cts +91 -0
  33. package/dist/definition-DjfC7Lll.d.ts +91 -0
  34. package/dist/dynamic-input.cjs +2 -1
  35. package/dist/dynamic-input.cjs.map +1 -1
  36. package/dist/dynamic-input.d.cts +9 -2
  37. package/dist/dynamic-input.d.ts +9 -2
  38. package/dist/dynamic-input.js +2 -1
  39. package/dist/dynamic-input.js.map +1 -1
  40. package/dist/index.cjs +1103 -322
  41. package/dist/index.cjs.map +1 -1
  42. package/dist/index.d.cts +479 -19
  43. package/dist/index.d.ts +479 -19
  44. package/dist/index.js +1090 -323
  45. package/dist/index.js.map +1 -1
  46. package/dist/ir.cjs +93 -11
  47. package/dist/ir.cjs.map +1 -1
  48. package/dist/ir.d.cts +226 -15
  49. package/dist/ir.d.ts +226 -15
  50. package/dist/ir.js +88 -12
  51. package/dist/ir.js.map +1 -1
  52. package/dist/predicate-v2.cjs +116 -10
  53. package/dist/predicate-v2.cjs.map +1 -1
  54. package/dist/predicate-v2.d.cts +11 -3
  55. package/dist/predicate-v2.d.ts +11 -3
  56. package/dist/predicate-v2.js +116 -10
  57. package/dist/predicate-v2.js.map +1 -1
  58. package/dist/sdl.cjs +158 -22
  59. package/dist/sdl.cjs.map +1 -1
  60. package/dist/sdl.d.cts +8 -1
  61. package/dist/sdl.d.ts +8 -1
  62. package/dist/sdl.js +158 -22
  63. package/dist/sdl.js.map +1 -1
  64. package/package.json +5 -4
  65. package/src/codegen-gql/server-fns.cjs +2 -2
  66. package/templates/orm-namespace/AGENTS.md +10 -0
  67. package/templates/orm-namespace/CLAUDE.md +1 -84
  68. package/templates/orm-namespace/package.json +1 -1
package/dist/sdl.cjs CHANGED
@@ -206,6 +206,7 @@ function compileCheckExpression(source, columns) {
206
206
  // src/constants.ts
207
207
  var COLUMN_IDENTIFIER_PATTERN = /^_?[a-z][a-z0-9_]*$/;
208
208
  var MAX_IDENTIFIER_LENGTH = 63;
209
+ var QUALIFIED_TABLE_PATTERN = /^[a-z][a-z0-9_]{0,62}\.[a-z][a-z0-9_]{0,62}$/;
209
210
  var CELL_PARTS = ["at", "by", "rev", "source", "conflicts"];
210
211
  var CELL_PART_SUFFIX = {
211
212
  at: "__at",
@@ -538,6 +539,8 @@ var canonicalLinkSchema = zod.z.object({
538
539
  kind: zod.z.enum(["toOne", "toMany", "toPlatformUser"]),
539
540
  /** Target table name (namespace-local). Absent for toPlatformUser. */
540
541
  target: identifier2.optional(),
542
+ /** Owning namespace of an imported target; omitted for local links. */
543
+ namespace: identifier2.max(41).optional(),
541
544
  /** FK column on the owning side (toOne/toPlatformUser: on this table; toMany: on the target). */
542
545
  on: columnIdentifier,
543
546
  /** Referenced column on the target (default: target's PK / platform user `sub`). */
@@ -639,11 +642,12 @@ var canonicalForeignKeySchema = zod.z.object({
639
642
  }).strict();
640
643
  var canonicalTableSchema = zod.z.object({
641
644
  table: identifier2,
645
+ displayName: zod.z.string().trim().min(1).max(120).optional(),
642
646
  description: zod.z.string().max(2e3).optional(),
643
647
  /** Table-level rename hint (new in v2). */
644
648
  renamedFrom: identifier2.optional(),
645
- /** Synced/reflected read-only tables (`source: gold.*`) — v1 semantics. */
646
- source: zod.z.string().regex(/^gold\.[a-z][a-z0-9_]*$/).optional(),
649
+ /** Synced/reflected read-only tables (`source: schema.table`) — v1 semantics. */
650
+ source: zod.z.string().regex(QUALIFIED_TABLE_PATTERN).optional(),
647
651
  columns: zod.z.array(canonicalColumnSchema).default([]),
648
652
  primaryKey: zod.z.array(columnIdentifier).min(1).max(8).optional(),
649
653
  links: zod.z.array(canonicalLinkSchema).default([]),
@@ -796,7 +800,9 @@ function validateCellMetadata(table, index, ctx) {
796
800
  }
797
801
  }
798
802
  }
799
- var canonicalDefinitionSchema = zod.z.object({
803
+ var exportGateSchema = zod.z.union([zod.z.literal(true), zod.z.object({ capability: zod.z.string().min(1) }).strict(), zod.z.object({ role: zod.z.string().min(1) }).strict()]);
804
+ var relationExportSchema = zod.z.object({ read: exportGateSchema, write: exportGateSchema.optional() }).strict();
805
+ var localDefinitionSchema = zod.z.object({
800
806
  definition_format: zod.z.literal(CANONICAL_FORMAT),
801
807
  namespace: identifier2.max(41),
802
808
  description: zod.z.string().max(2e3).optional(),
@@ -804,6 +810,8 @@ var canonicalDefinitionSchema = zod.z.object({
804
810
  tables: zod.z.array(canonicalTableSchema).min(0).max(500),
805
811
  /** Optional to preserve byte-identical hashes for pre-view canonical v2 documents. */
806
812
  views: zod.z.array(canonicalViewSchema).max(500).optional(),
813
+ /** Target-owned cross-namespace access contract, using existing namespace grants. */
814
+ exports: zod.z.record(identifier2, relationExportSchema).optional(),
807
815
  /** Verbatim custom-roles grammar (@sequenceholdings/custom-roles-manifest). */
808
816
  capabilities: zod.z.object({
809
817
  roles: zod.z.unknown().optional(),
@@ -830,7 +838,16 @@ var canonicalDefinitionSchema = zod.z.object({
830
838
  }
831
839
  }
832
840
  const fkTables = new Map(definition.tables.map((table) => [table.table, table]));
841
+ const relations = /* @__PURE__ */ new Set([...fkTables.keys(), ...(definition.views ?? []).map((view) => view.view)]);
842
+ for (const name of Object.keys(definition.exports ?? {})) {
843
+ if (!relations.has(name)) ctx.addIssue({ code: "custom", path: ["exports", name], message: `export '${name}' is not a local object` });
844
+ }
833
845
  for (const [tableIndex, table] of definition.tables.entries()) {
846
+ for (const [linkIndex, link] of table.links.entries()) {
847
+ if (link.enforce && link.namespace !== void 0 && link.namespace !== definition.namespace) {
848
+ ctx.addIssue({ code: "custom", path: ["tables", tableIndex, "links", linkIndex], message: "physical foreign keys require a local target; use an ORM link without enforce" });
849
+ }
850
+ }
834
851
  const names = /* @__PURE__ */ new Set([
835
852
  ...table.primaryKey?.length ? [`${table.table}_pkey`] : [],
836
853
  ...table.columns.filter((column) => column.unique && !(table.primaryKey?.length === 1 && table.primaryKey[0] === column.columnName)).map((column) => `${table.table}_${column.columnName}_unique`),
@@ -1000,6 +1017,10 @@ var canonicalDefinitionSchema = zod.z.object({
1000
1017
  };
1001
1018
  for (const view of views) visit(view.view, []);
1002
1019
  });
1020
+ var canonicalDefinitionSchema = localDefinitionSchema.safeExtend({
1021
+ /** Flattened, pinned snapshots. Imported relations never participate in this namespace's DDL. */
1022
+ imports: zod.z.array(localDefinitionSchema).max(32).optional()
1023
+ });
1003
1024
  function canonicalRelations(definition) {
1004
1025
  const views = (definition.views ?? []).map((view) => ({
1005
1026
  table: view.view,
@@ -1043,6 +1064,11 @@ function normalizeCanonical(definition) {
1043
1064
  dependencies: [...view.dependencies].sort()
1044
1065
  }));
1045
1066
  }
1067
+ if (definition.imports?.length) {
1068
+ normalized.imports = definition.imports.map(normalizeCanonical).sort((a, b) => a.namespace.localeCompare(b.namespace));
1069
+ } else {
1070
+ delete normalized.imports;
1071
+ }
1046
1072
  return normalized;
1047
1073
  }
1048
1074
 
@@ -1173,15 +1199,19 @@ var CELL_TYPENAMES = {
1173
1199
  function cellsTypename(typename) {
1174
1200
  return `${typename}Cells`;
1175
1201
  }
1176
- var IR_VERSION = 2;
1177
1202
  var LEGACY_IR_VERSION = 1;
1178
- var irVersionSchema = zod.z.union([zod.z.literal(LEGACY_IR_VERSION), zod.z.literal(IR_VERSION)]);
1203
+ var GUARDED_IR_VERSION = 2;
1204
+ var COMPOSED_IR_VERSION = 3;
1205
+ var SQL_IR_VERSION = 4;
1206
+ var RUNTIME_SQL_IR_VERSION = 5;
1207
+ var irVersionSchema = zod.z.union([zod.z.literal(LEGACY_IR_VERSION), zod.z.literal(GUARDED_IR_VERSION), zod.z.literal(COMPOSED_IR_VERSION), zod.z.literal(SQL_IR_VERSION), zod.z.literal(RUNTIME_SQL_IR_VERSION)]);
1179
1208
  zod.z.object({ irVersion: irVersionSchema });
1209
+ var EXTERNAL_POLICY_CLAIM_KEYS = ["ext_subject", "ext_email"];
1180
1210
  var scalarLiteral = zod.z.union([zod.z.string(), zod.z.number(), zod.z.boolean(), zod.z.null()]);
1181
1211
  var valueIrSchema = zod.z.discriminatedUnion("kind", [
1182
1212
  zod.z.object({ kind: zod.z.literal("literal"), value: zod.z.union([scalarLiteral, zod.z.array(scalarLiteral)]) }),
1183
1213
  zod.z.object({ kind: zod.z.literal("variable"), name: zod.z.string() }),
1184
- zod.z.object({ kind: zod.z.literal("claim"), key: zod.z.enum(["sub", "org"]) })
1214
+ zod.z.object({ kind: zod.z.literal("claim"), key: zod.z.enum(["sub", "org", ...EXTERNAL_POLICY_CLAIM_KEYS]) })
1185
1215
  ]);
1186
1216
  var CMP_OPS = [
1187
1217
  "eq",
@@ -1213,8 +1243,8 @@ var predIrSchema = zod.z.lazy(
1213
1243
  value: zod.z.number(),
1214
1244
  where: predIrSchema.optional()
1215
1245
  }),
1216
- zod.z.object({ kind: zod.z.literal("capability"), key: zod.z.string() }),
1217
- zod.z.object({ kind: zod.z.literal("role"), key: zod.z.string() }),
1246
+ zod.z.object({ kind: zod.z.literal("capability"), key: zod.z.string(), namespace: zod.z.string().optional() }),
1247
+ zod.z.object({ kind: zod.z.literal("role"), key: zod.z.string(), namespace: zod.z.string().optional() }),
1218
1248
  zod.z.object({ kind: zod.z.literal("dynamicFilter"), slot: zod.z.string() }),
1219
1249
  zod.z.object({ kind: zod.z.literal("const"), value: zod.z.boolean() })
1220
1250
  ])
@@ -1441,7 +1471,31 @@ var variableIrSchema = zod.z.object({
1441
1471
  /** Absent = no default declared; see {@link variableDefaultIrSchema}. */
1442
1472
  defaultValue: variableDefaultIrSchema.optional()
1443
1473
  });
1474
+ var sqlColumnSchema = zod.z.object({ name: zod.z.string(), type: zod.z.enum(["text", "boolean", "integer", "bigint", "numeric", "double", "uuid", "date", "timestamptz"]), nullable: zod.z.boolean() });
1444
1475
  var compiledOperationSchema = zod.z.object({
1476
+ language: zod.z.literal("sql").optional(),
1477
+ /** Server-compiled object catalog and permission ceiling, never caller SQL. */
1478
+ sqlQuery: zod.z.object({
1479
+ catalog: zod.z.object({
1480
+ identity: zod.z.string(),
1481
+ objects: zod.z.array(zod.z.object({
1482
+ ref: zod.z.string(),
1483
+ table: zod.z.string(),
1484
+ columns: zod.z.array(sqlColumnSchema.extend({ type: zod.z.string() })).min(1),
1485
+ scan: zod.z.string().min(1),
1486
+ read: zod.z.array(zod.z.string()).min(1)
1487
+ }).strict()).min(1).max(256)
1488
+ }).strict(),
1489
+ read: zod.z.array(zod.z.string()).min(1).max(256),
1490
+ maxRows: zod.z.number().int().min(1).max(1e4)
1491
+ }).strict().optional(),
1492
+ sql: zod.z.object({
1493
+ text: zod.z.string().min(1).max(1048576),
1494
+ columns: zod.z.array(sqlColumnSchema).min(1).max(256),
1495
+ parameters: zod.z.array(zod.z.string()).max(128),
1496
+ read: zod.z.array(zod.z.string()).min(1).max(256),
1497
+ maxRows: zod.z.number().int().min(1).max(1e4)
1498
+ }).strict().optional(),
1445
1499
  irVersion: irVersionSchema,
1446
1500
  name: zod.z.string(),
1447
1501
  opHash: zod.z.string().regex(/^sha256:[0-9a-f]{64}$/),
@@ -1453,8 +1507,16 @@ var compiledOperationSchema = zod.z.object({
1453
1507
  variables: zod.z.array(variableIrSchema),
1454
1508
  /** Every table the op touches — data-token scoping + audit. */
1455
1509
  tableSet: zod.z.array(zod.z.string()).min(1),
1456
- roots: zod.z.array(rootIrSchema).min(1)
1510
+ roots: zod.z.array(rootIrSchema)
1457
1511
  }).superRefine((operation, ctx) => {
1512
+ if (operation.language === "sql") {
1513
+ const validPlan = operation.sqlQuery ? !operation.sql && operation.irVersion === RUNTIME_SQL_IR_VERSION : !!operation.sql && operation.irVersion === SQL_IR_VERSION;
1514
+ if (!validPlan || operation.kind !== "query" || operation.roots.length !== 0 || !operation.requires?.capability) {
1515
+ ctx.addIssue({ code: "custom", message: "SQL operations require a query-only v4 plan or v5 runtime contract, capability, and no GraphQL roots" });
1516
+ }
1517
+ } else if (operation.sql || operation.sqlQuery || operation.roots.length === 0) {
1518
+ ctx.addIssue({ code: "custom", message: "GraphQL operations require roots and cannot carry SQL" });
1519
+ }
1458
1520
  for (const [index, root] of operation.roots.entries()) {
1459
1521
  if (root.kind !== "mutation" || root.assertAffectedRows === void 0) continue;
1460
1522
  if (operation.irVersion < 2 || operation.kind !== "mutation" || root.includeIf !== void 0) {
@@ -1501,11 +1563,16 @@ var resolvedMetaIrSchema = zod.z.object({
1501
1563
  });
1502
1564
  var tableMetaIrSchema = zod.z.object({
1503
1565
  table: zod.z.string(),
1566
+ namespace: zod.z.string().optional(),
1567
+ dependencies: zod.z.array(zod.z.string()).optional(),
1568
+ foreignReferences: zod.z.array(zod.z.object({ column: zod.z.string(), target: zod.z.string(), targetColumn: zod.z.string() })).optional(),
1569
+ exportRead: zod.z.union([zod.z.literal(true), zod.z.object({ capability: zod.z.string() }), zod.z.object({ role: zod.z.string() })]).optional(),
1570
+ exportWrite: zod.z.union([zod.z.literal(true), zod.z.object({ capability: zod.z.string() }), zod.z.object({ role: zod.z.string() })]).optional(),
1504
1571
  schema: zod.z.string(),
1505
1572
  typename: zod.z.string(),
1506
1573
  /**
1507
1574
  * True when statements over this relation evaluate a claims-gated synced
1508
- * view: synced twins (`source: gold.*`) materialize as views whose baked
1575
+ * view: synced twins (`source: schema.table`) materialize as views whose baked
1509
1576
  * policy reads `current_setting('request.jwt.claims')`, and namespace views
1510
1577
  * inherit the gate transitively through their declared dependencies. The
1511
1578
  * executor must stamp that GUC (transaction-scoped) before any statement
@@ -1564,10 +1631,18 @@ zod.z.object({
1564
1631
  irVersion: irVersionSchema,
1565
1632
  namespace: zod.z.string(),
1566
1633
  schemaHash: zod.z.string(),
1634
+ ownSchemaHash: zod.z.string().optional(),
1635
+ dependencies: zod.z.record(zod.z.string(), zod.z.string()).optional(),
1636
+ readPolicies: zod.z.record(zod.z.string(), predIrSchema).optional(),
1567
1637
  opsHash: zod.z.string(),
1638
+ /** Apply-observed synced objects without a serving backing; not part of the authored schema hash. */
1639
+ unbackedTables: zod.z.array(zod.z.string()).optional(),
1568
1640
  tables: zod.z.record(zod.z.string(), tableMetaIrSchema),
1569
1641
  operations: zod.z.record(zod.z.string(), compiledOperationSchema)
1570
1642
  }).superRefine((artifact, ctx) => {
1643
+ if (Object.keys(artifact.dependencies ?? {}).length > 0 && artifact.irVersion < COMPOSED_IR_VERSION) {
1644
+ ctx.addIssue({ code: "custom", path: ["irVersion"], message: "cross-namespace dependencies require IR v3" });
1645
+ }
1571
1646
  for (const [name, operation] of Object.entries(artifact.operations)) {
1572
1647
  if (operation.irVersion > artifact.irVersion) {
1573
1648
  ctx.addIssue({ code: "custom", path: ["operations", name, "irVersion"], message: "operation requires a newer IR version than its artifact" });
@@ -1575,6 +1650,70 @@ zod.z.object({
1575
1650
  }
1576
1651
  });
1577
1652
 
1653
+ // src/errors.ts
1654
+ var OrmDefinitionError = class extends Error {
1655
+ constructor(message, file) {
1656
+ super(file ? `${file}: ${message}` : message);
1657
+ this.file = file;
1658
+ }
1659
+ name = "OrmDefinitionError";
1660
+ };
1661
+ function stableJson(value) {
1662
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
1663
+ if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
1664
+ const entries = Object.entries(value).filter(([, entryValue]) => entryValue !== void 0).sort(([a], [b]) => a < b ? -1 : 1).map(([key, entryValue]) => `${JSON.stringify(key)}:${stableJson(entryValue)}`);
1665
+ return `{${entries.join(",")}}`;
1666
+ }
1667
+
1668
+ // src/canonical/composition.ts
1669
+ function localContract(definition) {
1670
+ return normalizeCanonical(localDefinitionSchema.parse(definition));
1671
+ }
1672
+ function composeNamespace(definition) {
1673
+ const all = [localContract(definition), ...definition.imports ?? []];
1674
+ const owners = /* @__PURE__ */ new Map();
1675
+ const namespaces = /* @__PURE__ */ new Set();
1676
+ const enums = /* @__PURE__ */ new Map();
1677
+ for (const owner of all) {
1678
+ if (namespaces.has(owner.namespace)) throw new OrmDefinitionError(`duplicate imported namespace '${owner.namespace}'`);
1679
+ namespaces.add(owner.namespace);
1680
+ for (const value of owner.enums) {
1681
+ const previous = enums.get(value.name);
1682
+ if (previous && stableJson(previous) !== stableJson(value)) {
1683
+ throw new OrmDefinitionError(`conflicting imported enum '${value.name}'`);
1684
+ }
1685
+ enums.set(value.name, value);
1686
+ }
1687
+ for (const relation of canonicalRelations(owner)) {
1688
+ if (owners.has(relation.table)) throw new OrmDefinitionError(`ambiguous imported relation '${relation.table}'`);
1689
+ owners.set(relation.table, owner);
1690
+ }
1691
+ }
1692
+ for (const owner of definition.imports?.length ? all : []) {
1693
+ for (const relation of canonicalRelations(owner)) {
1694
+ for (const link of relation.links) {
1695
+ if (link.kind === "toPlatformUser") continue;
1696
+ const target = owners.get(link.target ?? "");
1697
+ if (!target || target.namespace !== (link.namespace ?? owner.namespace)) {
1698
+ throw new OrmDefinitionError(`link '${owner.namespace}/${relation.table}.${link.name}' has no matching imported target`);
1699
+ }
1700
+ if (target.namespace !== owner.namespace && !target.exports?.[link.target ?? ""]) {
1701
+ throw new OrmDefinitionError(`target '${target.namespace}/${link.target}' is not exported`);
1702
+ }
1703
+ }
1704
+ }
1705
+ }
1706
+ return {
1707
+ owners,
1708
+ definition: {
1709
+ ...localContract(definition),
1710
+ tables: all.flatMap((item) => item.tables),
1711
+ views: all.flatMap((item) => item.views ?? []),
1712
+ enums: [...enums.values()]
1713
+ }
1714
+ };
1715
+ }
1716
+
1578
1717
  // src/sdl/generate.ts
1579
1718
  var SdlGenerationError = class extends Error {
1580
1719
  constructor(message) {
@@ -1595,7 +1734,7 @@ var PLATFORM_USER_FIELDS = [
1595
1734
  { name: "accountEnabled", gqlType: "Boolean", nullable: false }
1596
1735
  ];
1597
1736
  function generateSdl(canonical, options = {}) {
1598
- const def = normalizeCanonical(canonicalDefinitionSchema.parse(canonical));
1737
+ const def = composeNamespace(normalizeCanonical(canonicalDefinitionSchema.parse(canonical))).definition;
1599
1738
  const exposed = canonicalRelations(def).filter((table) => table.source === void 0 && table.internal !== true);
1600
1739
  const cellsByTable = new Map(exposed.map((table) => [table.table, trackedCells(table)]));
1601
1740
  const tables = exposed.map((table) => ({ ...table, columns: table.columns.filter((column) => column.cell === void 0) }));
@@ -1668,11 +1807,12 @@ function generateSdl(canonical, options = {}) {
1668
1807
  for (const value of entry.values) assertEnumValue(value, `enum "${enumName}"`);
1669
1808
  blocks.push(renderEnum(enumTypeName(enumName), entry.values));
1670
1809
  }
1810
+ const patternTypes = options.stringOnlyPatternOperators ? STRING_PATTERN_COMPARISON_TYPES : PATTERN_COMPARISON_TYPES;
1671
1811
  for (const scalar of [...usedComparisonScalars].sort()) {
1672
- blocks.push(renderComparisonExp(scalar));
1812
+ blocks.push(renderComparisonExp({ gqlTypeName: scalar, patternTypes }));
1673
1813
  }
1674
1814
  for (const enumName of [...usedEnums].sort()) {
1675
- blocks.push(renderComparisonExp(enumTypeName(enumName)));
1815
+ blocks.push(renderComparisonExp({ gqlTypeName: enumTypeName(enumName), patternTypes }));
1676
1816
  }
1677
1817
  if (hasPlatformUser) blocks.push(...renderPlatformUserBlocks());
1678
1818
  for (const table of tables) {
@@ -1726,7 +1866,9 @@ function descriptionLines(text, indent) {
1726
1866
  const escaped = text.replace(/"""/g, '\\"""');
1727
1867
  return [`${indent}"""`, ...escaped.split("\n").map((line) => `${indent}${line}`), `${indent}"""`];
1728
1868
  }
1729
- function renderComparisonExp(gqlTypeName) {
1869
+ var PATTERN_COMPARISON_TYPES = /* @__PURE__ */ new Set(["String", "Int", "bigint", "uuid"]);
1870
+ var STRING_PATTERN_COMPARISON_TYPES = /* @__PURE__ */ new Set(["String"]);
1871
+ function renderComparisonExp({ gqlTypeName, patternTypes }) {
1730
1872
  const fields = [
1731
1873
  ["_eq", gqlTypeName],
1732
1874
  ["_neq", gqlTypeName],
@@ -1738,7 +1880,7 @@ function renderComparisonExp(gqlTypeName) {
1738
1880
  ["_nin", `[${gqlTypeName}!]`],
1739
1881
  ["_isNull", "Boolean"]
1740
1882
  ];
1741
- if (gqlTypeName === "String") {
1883
+ if (patternTypes.has(gqlTypeName)) {
1742
1884
  fields.push(["_like", "String"], ["_ilike", "String"]);
1743
1885
  }
1744
1886
  if (gqlTypeName === "jsonb") {
@@ -2237,12 +2379,6 @@ function renderCowMutationFields(table, names) {
2237
2379
  }
2238
2380
  return lines;
2239
2381
  }
2240
- function stableJson(value) {
2241
- if (value === null || typeof value !== "object") return JSON.stringify(value);
2242
- if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
2243
- const entries = Object.entries(value).filter(([, entryValue]) => entryValue !== void 0).sort(([a], [b]) => a < b ? -1 : 1).map(([key, entryValue]) => `${JSON.stringify(key)}:${stableJson(entryValue)}`);
2244
- return `{${entries.join(",")}}`;
2245
- }
2246
2382
 
2247
2383
  // src/codegen-gql/errors.ts
2248
2384
  var CodegenGqlError = class extends Error {
@@ -2313,7 +2449,7 @@ function normalizeRequires(requires) {
2313
2449
 
2314
2450
  // src/codegen-gql/type-policies.ts
2315
2451
  function generateTypePolicies(canonical) {
2316
- const def = normalizeCanonical(canonicalDefinitionSchema.parse(canonical));
2452
+ const def = composeNamespace(normalizeCanonical(canonicalDefinitionSchema.parse(canonical))).definition;
2317
2453
  const entries = [];
2318
2454
  let hasPlatformUser = false;
2319
2455
  for (const table of canonicalRelations(def)) {