@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.
package/dist/compiler.cjs CHANGED
@@ -1123,14 +1123,20 @@ function requiredArtifactIrVersion(operations) {
1123
1123
  var CLAIMS_CONTRACT = {
1124
1124
  sub: "string",
1125
1125
  org: "string?",
1126
+ ext_subject: "string?",
1127
+ ext_email: "string?",
1126
1128
  roles: "string[]",
1127
1129
  capabilities: "string[]"
1128
1130
  };
1131
+ var EXTERNAL_POLICY_CLAIM_KEYS = ["ext_subject", "ext_email"];
1132
+ function isExternalPolicyClaimKey(key) {
1133
+ return EXTERNAL_POLICY_CLAIM_KEYS.includes(key);
1134
+ }
1129
1135
  var scalarLiteral = zod.z.union([zod.z.string(), zod.z.number(), zod.z.boolean(), zod.z.null()]);
1130
1136
  var valueIrSchema = zod.z.discriminatedUnion("kind", [
1131
1137
  zod.z.object({ kind: zod.z.literal("literal"), value: zod.z.union([scalarLiteral, zod.z.array(scalarLiteral)]) }),
1132
1138
  zod.z.object({ kind: zod.z.literal("variable"), name: zod.z.string() }),
1133
- zod.z.object({ kind: zod.z.literal("claim"), key: zod.z.enum(["sub", "org"]) })
1139
+ zod.z.object({ kind: zod.z.literal("claim"), key: zod.z.enum(["sub", "org", ...EXTERNAL_POLICY_CLAIM_KEYS]) })
1134
1140
  ]);
1135
1141
  var CMP_OPS = [
1136
1142
  "eq",
@@ -2029,6 +2035,7 @@ var PolicyCompiler = class {
2029
2035
  case "or":
2030
2036
  return { kind: node.kind, operands: node.operands.map((operand) => this.compile(operand, table, depth)) };
2031
2037
  case "not":
2038
+ assertNoNegatedExternalClaim(node.operand);
2032
2039
  return { kind: "not", operand: this.compile(node.operand, table, depth) };
2033
2040
  case "capability":
2034
2041
  return { kind: "capability", key: node.key };
@@ -2108,6 +2115,9 @@ var PolicyCompiler = class {
2108
2115
  columnCandidates(info)
2109
2116
  );
2110
2117
  }
2118
+ if (valueSide.kind === "claim" && isExternalPolicyClaimKey(valueSide.key)) {
2119
+ assertExternalClaimComparison({ op, key: valueSide.key, column: info.columns.find((c) => c.name === column) });
2120
+ }
2111
2121
  let cmp = this.buildCmp(op, column, valueSide);
2112
2122
  for (let i = links.length - 1; i >= 0; i -= 1) {
2113
2123
  cmp = { kind: "exists", link: links[i].name, where: cmp };
@@ -2128,6 +2138,33 @@ var PolicyCompiler = class {
2128
2138
  return { kind: "cmp", op: CMP_BY_OP[op], column, value };
2129
2139
  }
2130
2140
  };
2141
+ function assertExternalClaimComparison({ op, key, column }) {
2142
+ if (op !== "=") {
2143
+ throw new PolicyCompileError(
2144
+ `claim('${key}') supports = comparisons only, got '${op}'`,
2145
+ "unsupported-comparison"
2146
+ );
2147
+ }
2148
+ if (column?.type !== "text") {
2149
+ const actual = column?.type === void 0 ? "of unknown type" : typeof column.type === "string" ? column.type : "an enum";
2150
+ throw new PolicyCompileError(
2151
+ `claim('${key}') is text and compares to a text column only \u2014 '${column?.name ?? "?"}' is ${actual}`,
2152
+ "claim-type-mismatch"
2153
+ );
2154
+ }
2155
+ }
2156
+ function assertNoNegatedExternalClaim(operand) {
2157
+ walkPolicy(operand, (node) => {
2158
+ if (node.kind !== "compare") return;
2159
+ const claim = [node.left, node.right].find((side) => side.kind === "claim" && isExternalPolicyClaimKey(side.key));
2160
+ if (claim?.kind === "claim") {
2161
+ throw new PolicyCompileError(
2162
+ `claim('${claim.key}') cannot appear under not(): a negated borrower comparison admits other borrowers' rows`,
2163
+ "unsupported-comparison"
2164
+ );
2165
+ }
2166
+ });
2167
+ }
2131
2168
  function compilePredicateV2({ expression, table, resolver, maxLinkDepth }) {
2132
2169
  const parsed = typeof expression === "string" ? parsePolicy(expression) : expression;
2133
2170
  const compiler = new PolicyCompiler({ resolver, maxLinkDepth: maxLinkDepth ?? POLICY_MAX_LINK_DEPTH });