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