@sequenceholdings/orm 2.3.0 → 2.5.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 (59) hide show
  1. package/dist/authoring.cjs +53 -7
  2. package/dist/authoring.cjs.map +1 -1
  3. package/dist/authoring.d.cts +11 -7
  4. package/dist/authoring.d.ts +11 -7
  5. package/dist/authoring.js +53 -7
  6. package/dist/authoring.js.map +1 -1
  7. package/dist/canonical.cjs +48 -2
  8. package/dist/canonical.cjs.map +1 -1
  9. package/dist/canonical.d.cts +72 -72
  10. package/dist/canonical.d.ts +72 -72
  11. package/dist/canonical.js +48 -2
  12. package/dist/canonical.js.map +1 -1
  13. package/dist/cli.cjs +337 -86
  14. package/dist/cli.cjs.map +1 -1
  15. package/dist/cli.js +337 -86
  16. package/dist/cli.js.map +1 -1
  17. package/dist/client.cjs +1 -1
  18. package/dist/client.cjs.map +1 -1
  19. package/dist/client.d.cts +1 -1
  20. package/dist/client.d.ts +1 -1
  21. package/dist/client.js +1 -1
  22. package/dist/client.js.map +1 -1
  23. package/dist/compiler.cjs +493 -52
  24. package/dist/compiler.cjs.map +1 -1
  25. package/dist/compiler.d.cts +22 -7
  26. package/dist/compiler.d.ts +22 -7
  27. package/dist/compiler.js +493 -53
  28. package/dist/compiler.js.map +1 -1
  29. package/dist/{constants-C6EG6Wq7.d.cts → constants-Dou1RkTo.d.cts} +7 -2
  30. package/dist/{constants-C6EG6Wq7.d.ts → constants-Dou1RkTo.d.ts} +7 -2
  31. package/dist/dynamic-input.d.cts +1 -1
  32. package/dist/dynamic-input.d.ts +1 -1
  33. package/dist/index.cjs +329 -130
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.cts +66 -58
  36. package/dist/index.d.ts +66 -58
  37. package/dist/index.js +329 -131
  38. package/dist/index.js.map +1 -1
  39. package/dist/ir.cjs +50 -3
  40. package/dist/ir.cjs.map +1 -1
  41. package/dist/ir.d.cts +71 -71
  42. package/dist/ir.d.ts +71 -71
  43. package/dist/ir.js +50 -3
  44. package/dist/ir.js.map +1 -1
  45. package/dist/predicate-v2.cjs +145 -22
  46. package/dist/predicate-v2.cjs.map +1 -1
  47. package/dist/predicate-v2.d.cts +41 -4
  48. package/dist/predicate-v2.d.ts +41 -4
  49. package/dist/predicate-v2.js +145 -22
  50. package/dist/predicate-v2.js.map +1 -1
  51. package/dist/sdl.cjs +53 -3
  52. package/dist/sdl.cjs.map +1 -1
  53. package/dist/sdl.d.cts +3 -1
  54. package/dist/sdl.d.ts +3 -1
  55. package/dist/sdl.js +53 -3
  56. package/dist/sdl.js.map +1 -1
  57. package/package.json +1 -1
  58. package/dist/{definition-DjfC7Lll.d.cts → definition-B99BsOAO.d.cts} +4 -4
  59. package/dist/{definition-DjfC7Lll.d.ts → definition-B99BsOAO.d.ts} +4 -4
package/dist/compiler.js CHANGED
@@ -6,12 +6,17 @@ import { PgParser } from '@supabase/pg-parser';
6
6
  // src/compiler-gql/artifact.ts
7
7
 
8
8
  // src/constants.ts
9
+ var NAMESPACE_PATTERN = /^(?!(?:events|native_sources)$)[a-z][a-z0-9_]{0,40}$/;
9
10
  var COLUMN_IDENTIFIER_PATTERN = /^_?[a-z][a-z0-9_]*$/;
10
11
  var MAX_IDENTIFIER_LENGTH = 63;
11
12
  var CAPABILITY_KEY_PATTERN = /^(?:org\/|app\/[a-z][a-z0-9-]{0,63}\/)?[a-z0-9-]{1,64}$/;
13
+ var MAX_PERSISTED_READ_ROWS = 50001;
12
14
  var QUALIFIED_TABLE_PATTERN = /^[a-z][a-z0-9_]{0,62}\.[a-z][a-z0-9_]{0,62}$/;
13
15
  var ORM_SCHEMA_PREFIX = "orm_";
14
- var ormSchemaName = (namespace) => `${ORM_SCHEMA_PREFIX}${namespace}`;
16
+ var ormSchemaName = (namespace) => {
17
+ if (!NAMESPACE_PATTERN.test(namespace)) throw new Error(`invalid or reserved ORM namespace '${namespace}'`);
18
+ return `${ORM_SCHEMA_PREFIX}${namespace}`;
19
+ };
15
20
  var CELL_PARTS = ["at", "by", "rev", "source", "conflicts"];
16
21
  var CELL_PART_SUFFIX = {
17
22
  at: "__at",
@@ -387,6 +392,7 @@ function validateResolvedView({ view, tables, views = [] }) {
387
392
  function validateSource({ scope, source, table }) {
388
393
  const { fail: fail4 } = scope;
389
394
  if (source.kind === "etl" && table.source === void 0) fail4(`etl source '${source.name}' must reference a synced table`);
395
+ if (source.kind === "etl" && table.primaryKey?.length === 0) fail4(`etl source '${source.name}' cannot use an unkeyed synced table for resolved row identity`);
390
396
  if (source.kind !== "etl" && (table.internal !== true || table.cellMetadata !== true)) {
391
397
  fail4(`${source.kind} source '${source.name}' must reference an internal table with cell metadata`);
392
398
  }
@@ -618,6 +624,163 @@ function isSingleViewQuerySql(value) {
618
624
  }
619
625
  return state === "normal" && !/\$[a-z_0-9]*\$/i.test(query);
620
626
  }
627
+ var VIEW_QUERY_FUNCTION_ALLOWLIST = [
628
+ "abs",
629
+ "age",
630
+ "array_agg",
631
+ "array_append",
632
+ "array_cat",
633
+ "array_dims",
634
+ "array_length",
635
+ "array_lower",
636
+ "array_ndims",
637
+ "array_position",
638
+ "array_positions",
639
+ "array_prepend",
640
+ "array_remove",
641
+ "array_replace",
642
+ "array_to_string",
643
+ "array_trim",
644
+ "array_upper",
645
+ "ascii",
646
+ "avg",
647
+ "bit_and",
648
+ "bit_or",
649
+ "bit_xor",
650
+ "bool_and",
651
+ "bool_or",
652
+ "btrim",
653
+ "cardinality",
654
+ "cbrt",
655
+ "ceil",
656
+ "ceiling",
657
+ "char_length",
658
+ "character_length",
659
+ "chr",
660
+ "concat",
661
+ "concat_ws",
662
+ "count",
663
+ "cume_dist",
664
+ "date_bin",
665
+ "date_part",
666
+ "date_trunc",
667
+ "decode",
668
+ "degrees",
669
+ "dense_rank",
670
+ "encode",
671
+ "enum_first",
672
+ "enum_last",
673
+ "enum_range",
674
+ "every",
675
+ "exp",
676
+ "first_value",
677
+ "floor",
678
+ "format",
679
+ "grouping",
680
+ "initcap",
681
+ "json_agg",
682
+ "json_array_length",
683
+ "json_build_array",
684
+ "json_build_object",
685
+ "json_extract_path",
686
+ "json_extract_path_text",
687
+ "json_object_agg",
688
+ "json_object_keys",
689
+ "json_strip_nulls",
690
+ "json_typeof",
691
+ "jsonb_agg",
692
+ "jsonb_array_length",
693
+ "jsonb_build_array",
694
+ "jsonb_build_object",
695
+ "jsonb_extract_path",
696
+ "jsonb_extract_path_text",
697
+ "jsonb_insert",
698
+ "jsonb_object_agg",
699
+ "jsonb_object_keys",
700
+ "jsonb_path_exists",
701
+ "jsonb_path_match",
702
+ "jsonb_path_query",
703
+ "jsonb_path_query_array",
704
+ "jsonb_path_query_first",
705
+ "jsonb_pretty",
706
+ "jsonb_set",
707
+ "jsonb_set_lax",
708
+ "jsonb_strip_nulls",
709
+ "jsonb_typeof",
710
+ "justify_days",
711
+ "justify_hours",
712
+ "justify_interval",
713
+ "lag",
714
+ "last_value",
715
+ "lead",
716
+ "left",
717
+ "length",
718
+ "ln",
719
+ "log",
720
+ "lower",
721
+ "lpad",
722
+ "ltrim",
723
+ "make_date",
724
+ "make_interval",
725
+ "make_time",
726
+ "make_timestamp",
727
+ "make_timestamptz",
728
+ "max",
729
+ "md5",
730
+ "min",
731
+ "mod",
732
+ "nth_value",
733
+ "ntile",
734
+ "octet_length",
735
+ "percent_rank",
736
+ "pi",
737
+ "power",
738
+ "quote_ident",
739
+ "quote_literal",
740
+ "quote_nullable",
741
+ "radians",
742
+ "rank",
743
+ "regexp_count",
744
+ "regexp_instr",
745
+ "regexp_like",
746
+ "regexp_match",
747
+ "regexp_matches",
748
+ "regexp_replace",
749
+ "regexp_split_to_array",
750
+ "regexp_split_to_table",
751
+ "repeat",
752
+ "replace",
753
+ "reverse",
754
+ "right",
755
+ "round",
756
+ "row_number",
757
+ "rpad",
758
+ "rtrim",
759
+ "sign",
760
+ "split_part",
761
+ "sqrt",
762
+ "starts_with",
763
+ "string_agg",
764
+ "string_to_array",
765
+ "strpos",
766
+ "substr",
767
+ "substring",
768
+ "sum",
769
+ "timezone",
770
+ "to_ascii",
771
+ "to_char",
772
+ "to_date",
773
+ "to_hex",
774
+ "to_json",
775
+ "to_jsonb",
776
+ "to_number",
777
+ "to_timestamp",
778
+ "translate",
779
+ "trunc",
780
+ "unnest",
781
+ "upper",
782
+ "width_bucket"
783
+ ];
621
784
  var canonicalActionSchema = z.object({
622
785
  name: identifier2,
623
786
  requires: z.string().max(1e3).optional(),
@@ -678,7 +841,7 @@ var canonicalTableSchema = z.object({
678
841
  /** Synced/reflected read-only tables (`source: schema.table`) — v1 semantics. */
679
842
  source: z.string().regex(QUALIFIED_TABLE_PATTERN).optional(),
680
843
  columns: z.array(canonicalColumnSchema).default([]),
681
- primaryKey: z.array(columnIdentifier).min(1).max(8).optional(),
844
+ primaryKey: z.array(columnIdentifier).max(8).optional(),
682
845
  links: z.array(canonicalLinkSchema).default([]),
683
846
  indexes: z.array(canonicalIndexSchema).default([]),
684
847
  /** Omitted by old definitions, preserving their existing content hashes. */
@@ -714,6 +877,29 @@ var canonicalTableSchema = z.object({
714
877
  * data plane. Omitted otherwise.
715
878
  */
716
879
  materializes: identifier2.optional()
880
+ }).superRefine((table, ctx) => {
881
+ if (table.primaryKey?.length !== 0) return;
882
+ const fail4 = (message, path = ["primaryKey"]) => ctx.addIssue({ code: "custom", path, message: `unkeyed table '${table.table}' ${message}` });
883
+ if (table.source === void 0 || table.columns.length === 0) {
884
+ fail4("requires a typed synced source");
885
+ }
886
+ if ([table.policies.write, table.policies.insert, table.policies.update].some((policy) => policy !== void 0)) {
887
+ fail4("is read-only and cannot declare write policies", ["policies"]);
888
+ }
889
+ const ownedCollections = [table.indexes, table.actions, table.checks, table.foreignKeys, table.cowMutations];
890
+ const ownedMetadata = [table.cellMetadata, table.internal, table.materializes, table.renamedFrom];
891
+ if (ownedCollections.some((items) => items !== void 0 && items.length > 0) || ownedMetadata.some((value) => value !== void 0)) {
892
+ fail4("cannot declare owned storage, constraints or identity operations");
893
+ }
894
+ for (const [index, column] of table.columns.entries()) {
895
+ const ownedColumnMetadata = [column.default, column.defaultFn, column.onUpdateFn, column.renamedFrom, column.cast, column.cell];
896
+ if (column.unique || ownedColumnMetadata.some((value) => value !== void 0)) {
897
+ fail4("cannot declare column uniqueness, mutation defaults or migration metadata", ["columns", index]);
898
+ }
899
+ }
900
+ for (const [index, link] of table.links.entries()) {
901
+ if (link.enforce || link.kind === "toMany") fail4("cannot provide an identity for this link", ["links", index]);
902
+ }
717
903
  });
718
904
  var MAX_VIEW_QUERY = 1e5;
719
905
  var MAX_RESOLVED_VIEW_QUERY = 5e6;
@@ -770,6 +956,26 @@ var canonicalViewSchema = z.object({
770
956
  }
771
957
  }
772
958
  });
959
+ function validateUnkeyedLinkIdentities({ definition, ctx }) {
960
+ const tables = new Map(definition.tables.map((table) => [table.table, table]));
961
+ const relations = [
962
+ ...definition.tables.map((table, index) => ({ kind: "tables", index, links: table.links })),
963
+ ...(definition.views ?? []).map((view, index) => ({ kind: "views", index, links: view.links }))
964
+ ];
965
+ for (const relation of relations) {
966
+ for (const [linkIndex, link] of relation.links.entries()) {
967
+ if (link.kind !== "toOne" || link.namespace !== void 0 && link.namespace !== definition.namespace) continue;
968
+ const target = link.target === void 0 ? void 0 : tables.get(link.target);
969
+ if (target?.source !== void 0 && target.primaryKey?.length === 0) {
970
+ ctx.addIssue({
971
+ code: "custom",
972
+ path: [relation.kind, relation.index, "links", linkIndex],
973
+ message: `link '${link.name}' cannot use unkeyed table '${target.table}' as a to-one identity`
974
+ });
975
+ }
976
+ }
977
+ }
978
+ }
773
979
  var CELL_PART_TYPES = {
774
980
  at: "timestamptz",
775
981
  by: "text",
@@ -833,7 +1039,7 @@ var exportGateSchema = z.union([z.literal(true), z.object({ capability: z.string
833
1039
  var relationExportSchema = z.object({ read: exportGateSchema, write: exportGateSchema.optional() }).strict();
834
1040
  var localDefinitionSchema = z.object({
835
1041
  definition_format: z.literal(CANONICAL_FORMAT),
836
- namespace: identifier2.max(41),
1042
+ namespace: identifier2.max(41).regex(NAMESPACE_PATTERN, "invalid or reserved ORM namespace"),
837
1043
  description: z.string().max(2e3).optional(),
838
1044
  enums: z.array(canonicalEnumSchema).default([]),
839
1045
  tables: z.array(canonicalTableSchema).min(0).max(500),
@@ -867,6 +1073,7 @@ var localDefinitionSchema = z.object({
867
1073
  }
868
1074
  }
869
1075
  const fkTables = new Map(definition.tables.map((table) => [table.table, table]));
1076
+ validateUnkeyedLinkIdentities({ definition, ctx });
870
1077
  const relations = /* @__PURE__ */ new Set([...fkTables.keys(), ...(definition.views ?? []).map((view) => view.view)]);
871
1078
  for (const name2 of Object.keys(definition.exports ?? {})) {
872
1079
  if (!relations.has(name2)) ctx.addIssue({ code: "custom", path: ["exports", name2], message: `export '${name2}' is not a local object` });
@@ -1189,7 +1396,7 @@ var limitIrSchema = z.object({
1189
1396
  variable: z.string().optional(),
1190
1397
  value: z.number().int().positive().optional(),
1191
1398
  default: z.number().int().positive(),
1192
- max: z.number().int().positive()
1399
+ max: z.number().int().positive().max(MAX_PERSISTED_READ_ROWS)
1193
1400
  });
1194
1401
  var selectionIrSchema = z.lazy(
1195
1402
  () => z.object({
@@ -1854,6 +2061,7 @@ var Parser2 = class {
1854
2061
  return node;
1855
2062
  }
1856
2063
  if (this.peekKeyword("exists")) return this.parseExists();
2064
+ if (this.peekKeyword("visible") && this.tokens[this.index + 1]?.kind === "lparen") return this.parseVisible();
1857
2065
  return this.parseComparison();
1858
2066
  }
1859
2067
  parseBooleanCall(fn) {
@@ -1873,6 +2081,13 @@ var Parser2 = class {
1873
2081
  this.expect("rparen", "')' closing exists(...)");
1874
2082
  return { kind: "exists", path, where };
1875
2083
  }
2084
+ parseVisible() {
2085
+ this.advance();
2086
+ this.expect("lparen", "'(' after visible");
2087
+ const path = this.parsePath("a link path in visible(...)");
2088
+ this.expect("rparen", "')' closing visible(...)");
2089
+ return { kind: "visible", path };
2090
+ }
1876
2091
  parseComparison() {
1877
2092
  const left = this.parseOperand();
1878
2093
  const operator = this.expect("operator", "a comparison operator");
@@ -1988,6 +2203,24 @@ function parsePolicy(source) {
1988
2203
 
1989
2204
  // src/predicate-v2/compile.ts
1990
2205
  var POLICY_MAX_LINK_DEPTH = 3;
2206
+ function scopeToNamespace(pred, namespace) {
2207
+ switch (pred.kind) {
2208
+ case "capability":
2209
+ case "role":
2210
+ return pred.namespace ? pred : { ...pred, namespace };
2211
+ case "and":
2212
+ case "or":
2213
+ return { ...pred, operands: pred.operands.map((operand) => scopeToNamespace(operand, namespace)) };
2214
+ case "not":
2215
+ return { ...pred, operand: scopeToNamespace(pred.operand, namespace) };
2216
+ case "exists":
2217
+ return { ...pred, where: scopeToNamespace(pred.where, namespace) };
2218
+ case "aggPredicate":
2219
+ return pred.where ? { ...pred, where: scopeToNamespace(pred.where, namespace) } : pred;
2220
+ default:
2221
+ return pred;
2222
+ }
2223
+ }
1991
2224
  var CMP_BY_OP = {
1992
2225
  "=": "eq",
1993
2226
  "!=": "neq",
@@ -2021,7 +2254,7 @@ function resolveLink(info, ref) {
2021
2254
  function columnCandidates(info) {
2022
2255
  return [...info.columns.map((c) => c.name), ...info.links.map((l) => l.name)];
2023
2256
  }
2024
- var PolicyCompiler = class {
2257
+ var PolicyCompiler = class _PolicyCompiler {
2025
2258
  constructor(ctx) {
2026
2259
  this.ctx = ctx;
2027
2260
  }
@@ -2034,13 +2267,15 @@ var PolicyCompiler = class {
2034
2267
  return { kind: node.kind, operands: node.operands.map((operand) => this.compile(operand, table, depth)) };
2035
2268
  case "not":
2036
2269
  assertNoNegatedExternalClaim(node.operand);
2037
- return { kind: "not", operand: this.compile(node.operand, table, depth) };
2270
+ return { kind: "not", operand: new _PolicyCompiler({ ...this.ctx, negated: true }).compile(node.operand, table, depth) };
2038
2271
  case "capability":
2039
2272
  return { kind: "capability", key: node.key };
2040
2273
  case "role":
2041
2274
  return { kind: "role", key: node.key };
2042
2275
  case "exists":
2043
2276
  return this.compileExists(node.path, node.where, table, depth);
2277
+ case "visible":
2278
+ return this.compileVisible(node.path, table, depth);
2044
2279
  case "compare":
2045
2280
  return this.compileCompare(node, table, depth);
2046
2281
  }
@@ -2054,6 +2289,36 @@ var PolicyCompiler = class {
2054
2289
  }
2055
2290
  return pred;
2056
2291
  }
2292
+ /** `visible(path)` → `exists(path, <final target's read policy>)`. */
2293
+ compileVisible(path, table, depth) {
2294
+ const { links, finalTable } = this.resolveLinkPath(path, table, depth, { toOneOnly: false });
2295
+ const readPolicy = this.ctx.resolver.readPolicy;
2296
+ if (!readPolicy) {
2297
+ throw new PolicyCompileError(
2298
+ `visible(${path.join(".")}) needs the target's read policy, which this compile context does not provide`,
2299
+ "visible-unresolvable"
2300
+ );
2301
+ }
2302
+ if (this.ctx.visiting.includes(finalTable)) {
2303
+ throw new PolicyCompileError(
2304
+ `visible(${path.join(".")}) on '${table}' reaches '${finalTable}' whose read policy is already being expanded (${[...this.ctx.visiting, finalTable].join(" \u2192 ")})`,
2305
+ "visible-cycle"
2306
+ );
2307
+ }
2308
+ const expression = readPolicy(finalTable);
2309
+ let pred = expression === void 0 ? { kind: "const", value: true } : compilePolicyAt({
2310
+ expression,
2311
+ table: finalTable,
2312
+ ctx: { ...this.ctx, visiting: [...this.ctx.visiting, finalTable] },
2313
+ depth: depth + links.length
2314
+ });
2315
+ const owner = this.ctx.resolver.policyNamespace?.(finalTable);
2316
+ if (owner) pred = scopeToNamespace(pred, owner);
2317
+ for (let i = links.length - 1; i >= 0; i -= 1) {
2318
+ pred = { kind: "exists", link: links[i].name, where: pred };
2319
+ }
2320
+ return pred;
2321
+ }
2057
2322
  resolveLinkPath(path, table, depth, { toOneOnly }) {
2058
2323
  const links = [];
2059
2324
  let current = table;
@@ -2114,6 +2379,7 @@ var PolicyCompiler = class {
2114
2379
  );
2115
2380
  }
2116
2381
  if (valueSide.kind === "claim" && isExternalPolicyClaimKey(valueSide.key)) {
2382
+ if (this.ctx.negated) throw negatedExternalClaim(valueSide.key);
2117
2383
  assertExternalClaimComparison({ op, key: valueSide.key, column: info.columns.find((c) => c.name === column) });
2118
2384
  }
2119
2385
  let cmp = this.buildCmp(op, column, valueSide);
@@ -2151,22 +2417,30 @@ function assertExternalClaimComparison({ op, key, column }) {
2151
2417
  );
2152
2418
  }
2153
2419
  }
2420
+ function negatedExternalClaim(key) {
2421
+ return new PolicyCompileError(
2422
+ `claim('${key}') cannot appear under not(): a negated borrower comparison admits other borrowers' rows`,
2423
+ "unsupported-comparison"
2424
+ );
2425
+ }
2154
2426
  function assertNoNegatedExternalClaim(operand) {
2155
2427
  walkPolicy(operand, (node) => {
2156
2428
  if (node.kind !== "compare") return;
2157
2429
  const claim = [node.left, node.right].find((side) => side.kind === "claim" && isExternalPolicyClaimKey(side.key));
2158
- if (claim?.kind === "claim") {
2159
- throw new PolicyCompileError(
2160
- `claim('${claim.key}') cannot appear under not(): a negated borrower comparison admits other borrowers' rows`,
2161
- "unsupported-comparison"
2162
- );
2163
- }
2430
+ if (claim?.kind === "claim") throw negatedExternalClaim(claim.key);
2164
2431
  });
2165
2432
  }
2166
2433
  function compilePredicateV2({ expression, table, resolver, maxLinkDepth }) {
2434
+ return compilePredicateAt({
2435
+ expression,
2436
+ table,
2437
+ depth: 0,
2438
+ ctx: { resolver, maxLinkDepth: maxLinkDepth ?? POLICY_MAX_LINK_DEPTH, visiting: [table] }
2439
+ });
2440
+ }
2441
+ function compilePredicateAt({ expression, table, ctx, depth }) {
2167
2442
  const parsed = typeof expression === "string" ? parsePolicy(expression) : expression;
2168
- const compiler = new PolicyCompiler({ resolver, maxLinkDepth: maxLinkDepth ?? POLICY_MAX_LINK_DEPTH });
2169
- return compiler.compile(parsed.ast, table, 0);
2443
+ return new PolicyCompiler(ctx).compile(parsed.ast, table, depth);
2170
2444
  }
2171
2445
  function assertClaimsOnlyWhen(parsed) {
2172
2446
  walkPolicy(parsed.ast, (node) => {
@@ -2183,25 +2457,34 @@ function assertClaimsOnlyWhen(parsed) {
2183
2457
  "when-not-claims-only"
2184
2458
  );
2185
2459
  }
2186
- if (node.kind === "exists") {
2460
+ if (node.kind === "exists" || node.kind === "visible") {
2187
2461
  throw new PolicyCompileError(
2188
- "variant 'when' guards are claims-only \u2014 exists() is not allowed",
2462
+ `variant 'when' guards are claims-only \u2014 ${node.kind}() is not allowed`,
2189
2463
  "when-not-claims-only"
2190
2464
  );
2191
2465
  }
2192
2466
  });
2193
2467
  }
2194
- function compilePolicy({ expression, table, resolver, maxLinkDepth }) {
2195
- if (typeof expression === "string") {
2196
- return compilePredicateV2({ expression, table, resolver, maxLinkDepth });
2197
- }
2198
- const defaultPred = compilePredicateV2({ expression: expression.default, table, resolver, maxLinkDepth });
2468
+ function initialVisiting({ table, access }) {
2469
+ return (access ?? "read") === "read" ? [table] : [];
2470
+ }
2471
+ function compilePolicy({ expression, table, resolver, maxLinkDepth, access }) {
2472
+ return compilePolicyAt({
2473
+ expression,
2474
+ table,
2475
+ depth: 0,
2476
+ ctx: { resolver, maxLinkDepth: maxLinkDepth ?? POLICY_MAX_LINK_DEPTH, visiting: initialVisiting({ table, access }) }
2477
+ });
2478
+ }
2479
+ function compilePolicyAt({ expression, table, ctx, depth }) {
2480
+ if (typeof expression === "string") return compilePredicateAt({ expression, table, ctx, depth });
2481
+ const defaultPred = compilePredicateAt({ expression: expression.default, table, ctx, depth });
2199
2482
  if (expression.variants.length === 0) return defaultPred;
2200
2483
  const branches = expression.variants.map((variant) => {
2201
2484
  const parsedWhen = parsePolicy(variant.when);
2202
2485
  assertClaimsOnlyWhen(parsedWhen);
2203
- const when = compilePredicateV2({ expression: parsedWhen, table, resolver, maxLinkDepth });
2204
- const grant = variant.allow === true ? { kind: "const", value: true } : compilePredicateV2({ expression: variant.policy, table, resolver, maxLinkDepth });
2486
+ const when = compilePredicateAt({ expression: parsedWhen, table, ctx, depth });
2487
+ const grant = variant.allow === true ? { kind: "const", value: true } : compilePredicateAt({ expression: variant.policy, table, ctx, depth });
2205
2488
  return { kind: "and", operands: [when, grant] };
2206
2489
  });
2207
2490
  return { kind: "or", operands: [defaultPred, ...branches] };
@@ -2417,12 +2700,6 @@ var PolicyInjector = class {
2417
2700
  if (root.op === "resolvedWrite") return this.injectResolvedWrite(root, returning);
2418
2701
  if (root.op === "insert" || root.op === "insertOne") {
2419
2702
  const insertPolicy = this.insert(table);
2420
- if (predContainsExists(insertPolicy)) {
2421
- throw new DocumentCompileError(
2422
- `table '${table}' cannot be inserted into: v2.0 insert checks are claims + inserted-values only, but its insert policy traverses a link (exists)`,
2423
- "insert-check-unrepresentable"
2424
- );
2425
- }
2426
2703
  const pins = (this.ctx.pins.get(table) ?? []).map(
2427
2704
  (pin) => ({ column: pin.column, value: { kind: "claim", key: pin.claim } })
2428
2705
  );
@@ -2437,22 +2714,14 @@ var PolicyInjector = class {
2437
2714
  const updatePolicy = this.update(table);
2438
2715
  const where = andPred(updatePolicy, root.where ? this.injectDocPred(root.where, table) : void 0);
2439
2716
  if (root.op === "update" || root.op === "updateByPk") {
2440
- const check = predContainsExists(updatePolicy) && !this.ctx.composed ? {} : { insertCheck: updatePolicy };
2441
- return { ...root, where, ...check, returning };
2717
+ return { ...root, where, insertCheck: updatePolicy, returning };
2442
2718
  }
2443
2719
  if (root.op === "cowOverride") {
2444
2720
  const insertPolicy = this.insert(table);
2445
- if (predContainsExists(insertPolicy)) {
2446
- throw new DocumentCompileError(
2447
- `table '${table}' cannot be copy-on-write overridden: v2.0 insert checks are claims + inserted-values only, but its insert policy traverses a link (exists)`,
2448
- "insert-check-unrepresentable"
2449
- );
2450
- }
2451
2721
  const pins = (this.ctx.pins.get(table) ?? []).map(
2452
2722
  (pin) => ({ column: pin.column, value: { kind: "claim", key: pin.claim } })
2453
2723
  );
2454
- const check = predContainsExists(updatePolicy) && !this.ctx.composed ? {} : { insertCheck: updatePolicy };
2455
- return { ...root, pinnedColumns: pins, cowCopyCheck: insertPolicy, where, ...check, returning };
2724
+ return { ...root, pinnedColumns: pins, cowCopyCheck: insertPolicy, where, insertCheck: updatePolicy, returning };
2456
2725
  }
2457
2726
  return { ...root, where, returning };
2458
2727
  }
@@ -2674,7 +2943,7 @@ function scopePolicy(pred, namespace) {
2674
2943
  switch (pred.kind) {
2675
2944
  case "capability":
2676
2945
  case "role":
2677
- return { ...pred, namespace };
2946
+ return pred.namespace ? pred : { ...pred, namespace };
2678
2947
  case "and":
2679
2948
  case "or":
2680
2949
  return { ...pred, operands: pred.operands.map((p) => scopePolicy(p, namespace)) };
@@ -2764,6 +3033,7 @@ function buildCompileContext(rawCanonical) {
2764
3033
  const platformMeta = usesPlatformUsers ? platformUserMeta() : void 0;
2765
3034
  if (platformMeta) tables[PLATFORM_USER_TABLE] = platformMeta;
2766
3035
  const syncedTableNames = new Set(canonical.tables.filter((t) => t.source !== void 0).map((t) => t.table));
3036
+ const unkeyedSyncedTableNames = new Set(relations.filter((table) => table.source !== void 0 && table.primaryKey?.length === 0).map((table) => table.table));
2767
3037
  const viewDependencies = new Map((canonical.views ?? []).map((view) => [view.view, view.dependencies]));
2768
3038
  const claimsGatedMemo = /* @__PURE__ */ new Map();
2769
3039
  const relationIsClaimsGated = (name2) => {
@@ -2777,6 +3047,7 @@ function buildCompileContext(rawCanonical) {
2777
3047
  };
2778
3048
  for (const table of relations) {
2779
3049
  const isView = viewNames.has(table.table);
3050
+ const readOnly = isView || unkeyedSyncedTableNames.has(table.table);
2780
3051
  const owner = owners.get(table.table);
2781
3052
  const entries = resolveColumnEntries(table, enums, diagnostics);
2782
3053
  columnEntries.set(table.table, entries);
@@ -2824,13 +3095,13 @@ function buildCompileContext(rawCanonical) {
2824
3095
  // are claims-gated — see tableMetaIrSchema.claimsGated.
2825
3096
  claimsGated: relationIsClaimsGated(table.table),
2826
3097
  columns: entries.map(({ deprecated: _deprecated, onUpdateFn: _onUpdateFn, ...column }) => column),
2827
- primaryKey: isView ? primaryKey : primaryKey.length > 0 ? primaryKey : ["id"],
3098
+ primaryKey: isView || unkeyedSyncedTableNames.has(table.table) ? primaryKey : primaryKey.length > 0 ? primaryKey : ["id"],
2828
3099
  links: [],
2829
3100
  filterable: data.map((c) => c.name),
2830
3101
  orderable: data.filter((c) => c.type !== "jsonb").map((c) => c.name),
2831
- insertable: resolved ? resolvedWritable(data) : isView ? [] : active.map((c) => c.name),
2832
- settable: resolved ? resolvedWritable(data).filter((name2) => !primaryKey.includes(name2)) : isView ? [] : active.filter((c) => !c.onUpdateFn).map((c) => c.name),
2833
- appendable: isView ? [] : active.filter((c) => c.type === "jsonb").map((c) => c.name),
3102
+ insertable: resolved ? resolvedWritable(data) : readOnly ? [] : active.map((c) => c.name),
3103
+ settable: resolved ? resolvedWritable(data).filter((name2) => !primaryKey.includes(name2)) : readOnly ? [] : active.filter((c) => !c.onUpdateFn).map((c) => c.name),
3104
+ appendable: readOnly ? [] : active.filter((c) => c.type === "jsonb").map((c) => c.name),
2834
3105
  ...touchOnUpdate.length > 0 ? { touchOnUpdate } : {},
2835
3106
  ...cells ? { cells } : {},
2836
3107
  ...resolved ? { resolved: resolvedMeta({ resolved, pk: primaryKey[0] }) } : {},
@@ -2854,6 +3125,16 @@ function buildCompileContext(rawCanonical) {
2854
3125
  });
2855
3126
  continue;
2856
3127
  }
3128
+ const identityTable = link.kind === "toOne" ? targetName : link.kind === "toMany" ? table.table : void 0;
3129
+ if (identityTable !== void 0 && unkeyedSyncedTableNames.has(identityTable)) {
3130
+ diagnostics.push({
3131
+ severity: "error",
3132
+ code: "unkeyed-link-identity",
3133
+ table: table.table,
3134
+ message: `link '${link.name}' cannot use unkeyed table '${identityTable}' as a row identity`
3135
+ });
3136
+ continue;
3137
+ }
2857
3138
  const targetEntries = targetName === PLATFORM_USER_TABLE ? target.columns.map((c) => ({ ...c, deprecated: false, onUpdateFn: false })) : columnEntries.get(targetName);
2858
3139
  const onEntries = link.kind === "toMany" ? targetEntries : entries;
2859
3140
  const referencesEntries = link.kind === "toMany" ? entries : targetEntries;
@@ -2883,7 +3164,14 @@ function buildCompileContext(rawCanonical) {
2883
3164
  const updatePolicies = /* @__PURE__ */ new Map();
2884
3165
  const pins = /* @__PURE__ */ new Map();
2885
3166
  const splitWritePolicyTables = /* @__PURE__ */ new Set();
2886
- const resolver = { tables };
3167
+ const readPolicyExpressions = new Map(relations.map((relation) => [relation.table, relation.policies.read]));
3168
+ const resolver = {
3169
+ tables,
3170
+ readPolicy: (table) => readPolicyExpressions.get(table),
3171
+ // In a composed namespace, an imported table's read policy (inlined by
3172
+ // visible()) is checked against the namespace that owns it.
3173
+ ...normalized.imports?.length ? { policyNamespace: (table) => owners.get(table)?.namespace } : {}
3174
+ };
2887
3175
  for (const table of relations) {
2888
3176
  const isView = viewNames.has(table.table);
2889
3177
  const compilePolicyFor = (access, store) => {
@@ -2892,7 +3180,7 @@ function buildCompileContext(rawCanonical) {
2892
3180
  return;
2893
3181
  }
2894
3182
  try {
2895
- const pred = compilePolicy({ expression, table: table.table, resolver });
3183
+ const pred = compilePolicy({ expression, table: table.table, resolver, access });
2896
3184
  store.set(table.table, normalized.imports?.length ? scopePolicy(pred, owners.get(table.table).namespace) : pred);
2897
3185
  } catch (error) {
2898
3186
  if (error instanceof PolicyCompileError || error instanceof PolicyParseError) {
@@ -2912,7 +3200,7 @@ function buildCompileContext(rawCanonical) {
2912
3200
  compilePolicyFor("write", writePolicies);
2913
3201
  compilePolicyFor("insert", insertPolicies);
2914
3202
  compilePolicyFor("update", updatePolicies);
2915
- if (isView && table.resolved === void 0) {
3203
+ if (isView && table.resolved === void 0 || unkeyedSyncedTableNames.has(table.table)) {
2916
3204
  writePolicies.set(table.table, CONST_FALSE);
2917
3205
  insertPolicies.set(table.table, CONST_FALSE);
2918
3206
  updatePolicies.set(table.table, CONST_FALSE);
@@ -2987,7 +3275,7 @@ function buildCompileContext(rawCanonical) {
2987
3275
  const queryRoots = /* @__PURE__ */ new Map();
2988
3276
  const mutationRoots = /* @__PURE__ */ new Map();
2989
3277
  for (const table of relations) {
2990
- if (table.internal === true) continue;
3278
+ if (table.internal === true || unkeyedSyncedTableNames.has(table.table)) continue;
2991
3279
  const roots = queryRootNames(table.table);
2992
3280
  queryRoots.set(roots.select, { kind: "select", table: table.table });
2993
3281
  if ((tables[table.table]?.primaryKey.length ?? 0) > 0) {
@@ -3367,8 +3655,10 @@ var OperationLowerer = class {
3367
3655
  constructor(ctx, restricted) {
3368
3656
  this.ctx = ctx;
3369
3657
  this.variables = new Map(restricted.variables.map((v) => [v.name, v]));
3658
+ this.maxRows = restricted.readBudget ?? MAX_LIMIT;
3370
3659
  }
3371
3660
  variables;
3661
+ maxRows;
3372
3662
  meta(table) {
3373
3663
  return this.ctx.tables[table];
3374
3664
  }
@@ -3572,13 +3862,13 @@ var OperationLowerer = class {
3572
3862
  });
3573
3863
  }
3574
3864
  lowerLimit(node) {
3575
- const base2 = { default: DEFAULT_LIMIT, max: MAX_LIMIT };
3865
+ const base2 = { default: DEFAULT_LIMIT, max: this.maxRows };
3576
3866
  if (!node) return base2;
3577
3867
  if (node.kind === Kind.VARIABLE) return { ...base2, variable: node.name.value };
3578
3868
  if (node.kind === Kind.INT) {
3579
3869
  const value = Number(node.value);
3580
3870
  if (value < 1) fail2("limit must be a positive integer", "invalid-limit");
3581
- return { ...base2, value: Math.min(value, MAX_LIMIT) };
3871
+ return { ...base2, value: Math.min(value, this.maxRows) };
3582
3872
  }
3583
3873
  fail2("limit must be an integer literal or a variable", "invalid-limit");
3584
3874
  }
@@ -4377,7 +4667,13 @@ var OperationLowerer = class {
4377
4667
  };
4378
4668
  function lowerOperation({ restricted, ctx }) {
4379
4669
  const lowerer = new OperationLowerer(ctx, restricted);
4380
- return lowerer.lowerRoots(restricted.definition, restricted.kind);
4670
+ const roots = lowerer.lowerRoots(restricted.definition, restricted.kind);
4671
+ if (restricted.readBudget === void 0) return roots;
4672
+ const root = roots[0];
4673
+ if (restricted.kind !== "query" || restricted.definition.selectionSet.selections.length !== 1 || roots.length !== 1 || root?.kind !== "select" || root.selection.relations.length > 0 || root.selection.aggregates.length > 0 || root.selection.cells !== void 0 || root.prefetch?.length) {
4674
+ fail2("@readBudget requires one flat select root without related selections, aggregates, cells, or prefetch", "invalid-read-budget");
4675
+ }
4676
+ return roots;
4381
4677
  }
4382
4678
  function isCellColumn(meta, name2) {
4383
4679
  if (!meta.cells) return false;
@@ -4436,6 +4732,19 @@ function parseDocuments({
4436
4732
  }
4437
4733
  return { documents: parsed, diagnostics };
4438
4734
  }
4735
+ function parseReadBudget(operation) {
4736
+ const directives = operation.directives?.filter((directive) => directive.name.value === "readBudget") ?? [];
4737
+ if (directives.length === 0) return void 0;
4738
+ const value = directives[0]?.arguments?.find((argument) => argument.name.value === "maxRows")?.value;
4739
+ if (operation.operation !== "query" || directives.length !== 1 || value?.kind !== Kind.INT) {
4740
+ throw new DocumentCompileError("@readBudget requires a literal maxRows on a query", "invalid-read-budget");
4741
+ }
4742
+ const maxRows = Number(value.value);
4743
+ if (!Number.isSafeInteger(maxRows) || maxRows < 1 || maxRows > MAX_PERSISTED_READ_ROWS) {
4744
+ throw new DocumentCompileError(`@readBudget(maxRows:) must be between 1 and ${MAX_PERSISTED_READ_ROWS}`, "invalid-read-budget");
4745
+ }
4746
+ return maxRows;
4747
+ }
4439
4748
  function unwrapType(node, variable) {
4440
4749
  let nullable = true;
4441
4750
  let list2 = false;
@@ -4596,6 +4905,7 @@ function restrictOperation({
4596
4905
  name: name2,
4597
4906
  kind: operation.operation === "mutation" ? "mutation" : "query",
4598
4907
  requires: parseRequires(operation),
4908
+ readBudget: parseReadBudget(operation),
4599
4909
  variables,
4600
4910
  definition: operation
4601
4911
  };
@@ -5636,6 +5946,118 @@ function bindNamedParameters({ sql, names }) {
5636
5946
  }
5637
5947
  return result;
5638
5948
  }
5949
+ var parser2;
5950
+ var functions = new Set(VIEW_QUERY_FUNCTION_ALLOWLIST);
5951
+ var scalarTypes = /* @__PURE__ */ new Set([
5952
+ "bool",
5953
+ "boolean",
5954
+ "int2",
5955
+ "int4",
5956
+ "int8",
5957
+ "integer",
5958
+ "bigint",
5959
+ "smallint",
5960
+ "numeric",
5961
+ "decimal",
5962
+ "float4",
5963
+ "float8",
5964
+ "real",
5965
+ "text",
5966
+ "varchar",
5967
+ "bpchar",
5968
+ "uuid",
5969
+ "date",
5970
+ "timestamp",
5971
+ "timestamptz",
5972
+ "time",
5973
+ "timetz",
5974
+ "interval",
5975
+ "json",
5976
+ "jsonb",
5977
+ "bytea"
5978
+ ]);
5979
+ var sqlValues = /* @__PURE__ */ new Set([
5980
+ "SVFOP_CURRENT_DATE",
5981
+ "SVFOP_CURRENT_TIME",
5982
+ "SVFOP_CURRENT_TIME_N",
5983
+ "SVFOP_CURRENT_TIMESTAMP",
5984
+ "SVFOP_CURRENT_TIMESTAMP_N",
5985
+ "SVFOP_LOCALTIME",
5986
+ "SVFOP_LOCALTIME_N",
5987
+ "SVFOP_LOCALTIMESTAMP",
5988
+ "SVFOP_LOCALTIMESTAMP_N",
5989
+ "SVFOP_CURRENT_ROLE",
5990
+ "SVFOP_CURRENT_USER",
5991
+ "SVFOP_USER",
5992
+ "SVFOP_SESSION_USER",
5993
+ "SVFOP_CURRENT_CATALOG",
5994
+ "SVFOP_CURRENT_SCHEMA"
5995
+ ]);
5996
+ async function validateManagedViewQueries({ canonical }) {
5997
+ for (const definition of [canonical, ...canonical.imports ?? []]) {
5998
+ for (const view of definition.views ?? []) {
5999
+ const fail4 = (message) => {
6000
+ throw new OrmDefinitionError(`managed view '${definition.namespace}/${view.view}': ${message}`);
6001
+ };
6002
+ parser2 ??= new PgParser({ version: 17 });
6003
+ const parsed = await parser2.parse(view.query);
6004
+ if (parsed.error || !parsed.tree) fail4("invalid SELECT query");
6005
+ const statements = list(obj(parsed.tree).stmts);
6006
+ if (statements.length !== 1 || !obj(obj(statements[0]).stmt).SelectStmt) fail4("one SELECT query is required");
6007
+ validateTree({ tree: parsed.tree, schema: ormSchemaName(definition.namespace), enums: definition.enums.map((entry) => entry.name), fail: fail4 });
6008
+ }
6009
+ }
6010
+ }
6011
+ function pgCatalogName(parts) {
6012
+ if (parts.length === 1) return parts[0];
6013
+ if (parts.length === 2 && parts[0] === "pg_catalog") return parts[1];
6014
+ return void 0;
6015
+ }
6016
+ function reviewedFunctionName({ parts, format }) {
6017
+ return format === "COERCE_SQL_SYNTAX" && parts.length === 2 && parts[0] === "pg_catalog" && parts[1] === "position" ? "strpos" : pgCatalogName(parts);
6018
+ }
6019
+ function validateTree({ tree, ...scope }) {
6020
+ const pending = [tree];
6021
+ while (pending.length) {
6022
+ const value = pending.pop();
6023
+ if (Array.isArray(value)) {
6024
+ pending.push(...value);
6025
+ continue;
6026
+ }
6027
+ if (!value || typeof value !== "object") continue;
6028
+ const node = obj(value);
6029
+ for (const [kind, child] of Object.entries(node)) {
6030
+ validateNode({ kind, child, scope });
6031
+ pending.push(child);
6032
+ }
6033
+ }
6034
+ }
6035
+ function validateNode({ kind, child, scope }) {
6036
+ const { fail: fail4 } = scope;
6037
+ if (kind.endsWith("Stmt") && kind !== "SelectStmt") fail4("only SELECT statements are permitted");
6038
+ if (kind === "FuncCall") {
6039
+ const call = obj(child);
6040
+ const parts = strings(call.funcname);
6041
+ const name2 = reviewedFunctionName({ parts, format: call.funcformat });
6042
+ if (!name2 || !functions.has(name2)) fail4(`only explicitly allowlisted pg_catalog functions are permitted (found '${parts.join(".")}')`);
6043
+ }
6044
+ if (kind === "typeName" || kind === "TypeName") validateType({ node: obj(child), ...scope });
6045
+ if (kind === "A_Expr" && pgCatalogName(strings(obj(child).name)) === void 0) fail4("only pg_catalog operators are permitted");
6046
+ if (kind === "SortBy" && list(obj(child).useOp).length && pgCatalogName(strings(obj(child).useOp)) === void 0) fail4("only pg_catalog sort operators are permitted");
6047
+ if (kind === "SQLValueFunction" && !sqlValues.has(String(obj(child).op))) fail4("unsupported SQL value expression");
6048
+ if (kind === "ParamRef") fail4("view queries cannot contain parameters");
6049
+ if (kind === "A_Indirection" && list(obj(child).indirection).some((entry) => !obj(entry).A_Indices)) {
6050
+ fail4("composite field notation is not permitted in managed views");
6051
+ }
6052
+ }
6053
+ function validateType({ node, schema, enums, fail: fail4 }) {
6054
+ const parts = strings(node.names);
6055
+ const builtin = pgCatalogName(parts);
6056
+ const managedEnum = parts.length === 1 && enums.includes(parts[0]) || parts.length === 2 && parts[0] === schema && enums.includes(parts[1]);
6057
+ if (node.setof || node.pct_type || !managedEnum && (!builtin || !scalarTypes.has(builtin))) {
6058
+ fail4(`casts may only use supported pg_catalog scalar types or declared enums (found '${parts.join(".")}')`);
6059
+ }
6060
+ }
5639
6061
 
5640
6062
  // src/sql/operations.ts
5641
6063
  function isSqlOperationDocument(path, contents) {
@@ -5651,7 +6073,13 @@ function isSqlOperationDocument(path, contents) {
5651
6073
  async function compileOperationDocuments(input) {
5652
6074
  const sqlDocuments = input.documents.filter((d) => isSqlOperationDocument(d.path, d.contents));
5653
6075
  const result = compileNamespace({ ...input, documents: input.documents.filter((d) => !isSqlOperationDocument(d.path, d.contents)) });
5654
- if (!result.ok || !sqlDocuments.length) return result;
6076
+ if (!result.ok) return result;
6077
+ const viewDiagnostics = await managedViewDiagnostics(input.canonical);
6078
+ if (viewDiagnostics.length) return { ok: false, diagnostics: [...result.diagnostics, ...viewDiagnostics] };
6079
+ if (!sqlDocuments.length) return result;
6080
+ return compileSqlDocuments({ input, result, sqlDocuments });
6081
+ }
6082
+ async function compileSqlDocuments({ input, result, sqlDocuments }) {
5655
6083
  for (const document of sqlDocuments) {
5656
6084
  try {
5657
6085
  const definition = defineOperation(JSON.parse(document.contents));
@@ -5745,6 +6173,18 @@ async function compileOperationDocuments(input) {
5745
6173
  result.manifest.opsHash = result.artifact.opsHash;
5746
6174
  return { ...result, artifact: normalizeIr(result.artifact) };
5747
6175
  }
6176
+ async function managedViewDiagnostics(canonical) {
6177
+ try {
6178
+ await validateManagedViewQueries({ canonical });
6179
+ return [];
6180
+ } catch (error) {
6181
+ return [{
6182
+ severity: "error",
6183
+ code: "invalid-view-query",
6184
+ message: error instanceof Error ? error.message : "invalid managed view query"
6185
+ }];
6186
+ }
6187
+ }
5748
6188
  var parameterName = z.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/).max(63).refine((value) => !["__proto__", "prototype", "constructor"].includes(value), "reserved parameter name");
5749
6189
  var parameter = z.discriminatedUnion("type", [
5750
6190
  z.object({ type: z.literal("text"), value: z.string().nullable() }).strict(),
@@ -5826,6 +6266,6 @@ function compileDatasetPreviews(input) {
5826
6266
  return operations;
5827
6267
  }
5828
6268
 
5829
- export { COMPILER_MAJOR, CONST_TRUE, DATASET_PREVIEW_LIMIT, DEFAULT_LIMIT, DocumentCompileError, MAX_LIMIT, NamespaceCompileError, ORDER_BY_DIRECTIONS, OperationLowerer, PLATFORM_USER_TABLE, PLATFORM_USER_TYPENAME, POLICY_COMPARE_OPS, POLICY_MAX_LINK_DEPTH, PolicyCompileError, PolicyParseError, allowedBoolExpOperators, allowedOps, andPred, assertClaimsOnlyWhen, buildCompileContext, camelCase, canonicalOperationText, classifyInputType, collectPinnedColumns, compileDatasetPreviews, compileNamespace, compileNamespaceOrThrow, compileOperationDocuments, compilePolicy, compilePredicateV2, compileRuntimeSql, computeOpHash, computeOpsHash, computePinnedColumnsByTable, computeSchemaHash, defineOperation, enumTypeName, flattenOperation, injectPolicies, inputTypeName, isSqlOperationDocument, lowerOperation, mutationRootNames, parseDocuments, parsePolicy, parseSdl, pascalCase, platformUserMeta, predContains, predContainsExists, queryRootNames, restrictOperation, sqlOperationDefinitionSchema, sqlQueryInputSchema, typeNameForTable, validateAppendInput, validateBoolExpInput, validateInsertInput, validateOnConflictInput, validateOrderByInput, validateSelectColumns, validateSetInput, walkPolicy, walkPred };
6269
+ export { COMPILER_MAJOR, CONST_TRUE, DATASET_PREVIEW_LIMIT, DEFAULT_LIMIT, DocumentCompileError, MAX_LIMIT, NamespaceCompileError, ORDER_BY_DIRECTIONS, OperationLowerer, PLATFORM_USER_TABLE, PLATFORM_USER_TYPENAME, POLICY_COMPARE_OPS, POLICY_MAX_LINK_DEPTH, PolicyCompileError, PolicyParseError, allowedBoolExpOperators, allowedOps, andPred, assertClaimsOnlyWhen, buildCompileContext, camelCase, canonicalOperationText, classifyInputType, collectPinnedColumns, compileDatasetPreviews, compileNamespace, compileNamespaceOrThrow, compileOperationDocuments, compilePolicy, compilePredicateV2, compileRuntimeSql, computeOpHash, computeOpsHash, computePinnedColumnsByTable, computeSchemaHash, defineOperation, enumTypeName, flattenOperation, injectPolicies, inputTypeName, isSqlOperationDocument, lowerOperation, mutationRootNames, parseDocuments, parsePolicy, parseSdl, pascalCase, platformUserMeta, predContains, predContainsExists, queryRootNames, restrictOperation, sqlOperationDefinitionSchema, sqlQueryInputSchema, typeNameForTable, validateAppendInput, validateBoolExpInput, validateInsertInput, validateManagedViewQueries, validateOnConflictInput, validateOrderByInput, validateSelectColumns, validateSetInput, walkPolicy, walkPred };
5830
6270
  //# sourceMappingURL=compiler.js.map
5831
6271
  //# sourceMappingURL=compiler.js.map