@sequenceholdings/orm 2.2.0 → 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.
@@ -1058,14 +1058,20 @@ zod.z.object({ irVersion: irVersionSchema });
1058
1058
  var CLAIMS_CONTRACT = {
1059
1059
  sub: "string",
1060
1060
  org: "string?",
1061
+ ext_subject: "string?",
1062
+ ext_email: "string?",
1061
1063
  roles: "string[]",
1062
1064
  capabilities: "string[]"
1063
1065
  };
1066
+ var EXTERNAL_POLICY_CLAIM_KEYS = ["ext_subject", "ext_email"];
1067
+ function isExternalPolicyClaimKey(key) {
1068
+ return EXTERNAL_POLICY_CLAIM_KEYS.includes(key);
1069
+ }
1064
1070
  var scalarLiteral = zod.z.union([zod.z.string(), zod.z.number(), zod.z.boolean(), zod.z.null()]);
1065
1071
  var valueIrSchema = zod.z.discriminatedUnion("kind", [
1066
1072
  zod.z.object({ kind: zod.z.literal("literal"), value: zod.z.union([scalarLiteral, zod.z.array(scalarLiteral)]) }),
1067
1073
  zod.z.object({ kind: zod.z.literal("variable"), name: zod.z.string() }),
1068
- zod.z.object({ kind: zod.z.literal("claim"), key: zod.z.enum(["sub", "org"]) })
1074
+ zod.z.object({ kind: zod.z.literal("claim"), key: zod.z.enum(["sub", "org", ...EXTERNAL_POLICY_CLAIM_KEYS]) })
1069
1075
  ]);
1070
1076
  var CMP_OPS = [
1071
1077
  "eq",
@@ -1815,6 +1821,7 @@ var PolicyCompiler = class {
1815
1821
  case "or":
1816
1822
  return { kind: node.kind, operands: node.operands.map((operand) => this.compile(operand, table, depth)) };
1817
1823
  case "not":
1824
+ assertNoNegatedExternalClaim(node.operand);
1818
1825
  return { kind: "not", operand: this.compile(node.operand, table, depth) };
1819
1826
  case "capability":
1820
1827
  return { kind: "capability", key: node.key };
@@ -1894,6 +1901,9 @@ var PolicyCompiler = class {
1894
1901
  columnCandidates(info)
1895
1902
  );
1896
1903
  }
1904
+ if (valueSide.kind === "claim" && isExternalPolicyClaimKey(valueSide.key)) {
1905
+ assertExternalClaimComparison({ op, key: valueSide.key, column: info.columns.find((c) => c.name === column) });
1906
+ }
1897
1907
  let cmp = this.buildCmp(op, column, valueSide);
1898
1908
  for (let i = links.length - 1; i >= 0; i -= 1) {
1899
1909
  cmp = { kind: "exists", link: links[i].name, where: cmp };
@@ -1914,6 +1924,33 @@ var PolicyCompiler = class {
1914
1924
  return { kind: "cmp", op: CMP_BY_OP[op], column, value };
1915
1925
  }
1916
1926
  };
1927
+ function assertExternalClaimComparison({ op, key, column }) {
1928
+ if (op !== "=") {
1929
+ throw new PolicyCompileError(
1930
+ `claim('${key}') supports = comparisons only, got '${op}'`,
1931
+ "unsupported-comparison"
1932
+ );
1933
+ }
1934
+ if (column?.type !== "text") {
1935
+ const actual = column?.type === void 0 ? "of unknown type" : typeof column.type === "string" ? column.type : "an enum";
1936
+ throw new PolicyCompileError(
1937
+ `claim('${key}') is text and compares to a text column only \u2014 '${column?.name ?? "?"}' is ${actual}`,
1938
+ "claim-type-mismatch"
1939
+ );
1940
+ }
1941
+ }
1942
+ function assertNoNegatedExternalClaim(operand) {
1943
+ walkPolicy(operand, (node) => {
1944
+ if (node.kind !== "compare") return;
1945
+ const claim = [node.left, node.right].find((side) => side.kind === "claim" && isExternalPolicyClaimKey(side.key));
1946
+ if (claim?.kind === "claim") {
1947
+ throw new PolicyCompileError(
1948
+ `claim('${claim.key}') cannot appear under not(): a negated borrower comparison admits other borrowers' rows`,
1949
+ "unsupported-comparison"
1950
+ );
1951
+ }
1952
+ });
1953
+ }
1917
1954
  function compilePredicateV2({ expression, table, resolver, maxLinkDepth }) {
1918
1955
  const parsed = typeof expression === "string" ? parsePolicy(expression) : expression;
1919
1956
  const compiler = new PolicyCompiler({ resolver, maxLinkDepth: maxLinkDepth ?? POLICY_MAX_LINK_DEPTH });