@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/cli.cjs +38 -1
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +38 -1
- package/dist/cli.js.map +1 -1
- package/dist/compiler.cjs +38 -1
- package/dist/compiler.cjs.map +1 -1
- package/dist/compiler.js +38 -1
- package/dist/compiler.js.map +1 -1
- package/dist/index.cjs +9 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/ir.cjs +9 -1
- package/dist/ir.cjs.map +1 -1
- package/dist/ir.d.cts +89 -3
- package/dist/ir.d.ts +89 -3
- package/dist/ir.js +8 -2
- package/dist/ir.js.map +1 -1
- package/dist/predicate-v2.cjs +38 -1
- package/dist/predicate-v2.cjs.map +1 -1
- package/dist/predicate-v2.d.cts +10 -2
- package/dist/predicate-v2.d.ts +10 -2
- package/dist/predicate-v2.js +38 -1
- package/dist/predicate-v2.js.map +1 -1
- package/dist/sdl.cjs +2 -1
- package/dist/sdl.cjs.map +1 -1
- package/dist/sdl.js +2 -1
- package/dist/sdl.js.map +1 -1
- package/package.json +1 -1
package/dist/predicate-v2.d.cts
CHANGED
|
@@ -11,7 +11,7 @@ type PolicyOperand =
|
|
|
11
11
|
kind: 'path';
|
|
12
12
|
segments: readonly string[];
|
|
13
13
|
}
|
|
14
|
-
/** `claim('sub')` / `claim('org')`
|
|
14
|
+
/** `claim('sub')` / `claim('org')` / `claim('ext_subject')` / `claim('ext_email')` — the scalar keys in CLAIMS_CONTRACT. */
|
|
15
15
|
| {
|
|
16
16
|
kind: 'claim';
|
|
17
17
|
key: ClaimKey;
|
|
@@ -63,7 +63,7 @@ declare class PolicyParseError extends Error {
|
|
|
63
63
|
readonly name = "PolicyParseError";
|
|
64
64
|
constructor(message: string, position: number);
|
|
65
65
|
}
|
|
66
|
-
type PolicyCompileErrorCode = 'unknown-table' | 'unknown-column' | 'unknown-link' | 'not-to-one' | 'link-depth-exceeded' | 'unsupported-comparison' | 'invalid-null-comparison' | 'when-not-claims-only';
|
|
66
|
+
type PolicyCompileErrorCode = 'unknown-table' | 'unknown-column' | 'unknown-link' | 'not-to-one' | 'link-depth-exceeded' | 'unsupported-comparison' | 'invalid-null-comparison' | 'when-not-claims-only' | 'claim-type-mismatch';
|
|
67
67
|
/**
|
|
68
68
|
* Compile-time failure — the parsed policy references something the table
|
|
69
69
|
* doesn't declare, or uses a shape the v2.0 IR cannot represent. Carries
|
|
@@ -90,6 +90,9 @@ declare function parsePolicy(source: string): ParsedPolicy;
|
|
|
90
90
|
* - a comparison must reference exactly ONE column side (column↔column and
|
|
91
91
|
* claims↔literal comparisons have no PredIr shape in v2.0);
|
|
92
92
|
* - `col = null` / `col != null` normalize to the isNull operator;
|
|
93
|
+
* - verified-borrower claims (`claim('ext_subject')`, `claim('ext_email')`)
|
|
94
|
+
* are text: they compare to a text column with `=` only, never under
|
|
95
|
+
* not(), so no negation, ordering or pattern can widen a borrower's rows;
|
|
93
96
|
* - variant `when` guards are claims-only: capability()/role() under
|
|
94
97
|
* and/or/not. (claim() comparisons in `when` are not representable in the
|
|
95
98
|
* v2.0 IR — a targeted error says so.)
|
|
@@ -99,6 +102,11 @@ declare const POLICY_MAX_LINK_DEPTH = 3;
|
|
|
99
102
|
interface PolicyColumnInfo {
|
|
100
103
|
readonly name: string;
|
|
101
104
|
readonly columnName: string;
|
|
105
|
+
/**
|
|
106
|
+
* The column's IR type when the resolver knows it (TableMetaIr always does).
|
|
107
|
+
* Required for a verified-borrower claim comparison: unknown is refused.
|
|
108
|
+
*/
|
|
109
|
+
readonly type?: unknown;
|
|
102
110
|
}
|
|
103
111
|
interface PolicyLinkInfo {
|
|
104
112
|
readonly name: string;
|
package/dist/predicate-v2.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ type PolicyOperand =
|
|
|
11
11
|
kind: 'path';
|
|
12
12
|
segments: readonly string[];
|
|
13
13
|
}
|
|
14
|
-
/** `claim('sub')` / `claim('org')`
|
|
14
|
+
/** `claim('sub')` / `claim('org')` / `claim('ext_subject')` / `claim('ext_email')` — the scalar keys in CLAIMS_CONTRACT. */
|
|
15
15
|
| {
|
|
16
16
|
kind: 'claim';
|
|
17
17
|
key: ClaimKey;
|
|
@@ -63,7 +63,7 @@ declare class PolicyParseError extends Error {
|
|
|
63
63
|
readonly name = "PolicyParseError";
|
|
64
64
|
constructor(message: string, position: number);
|
|
65
65
|
}
|
|
66
|
-
type PolicyCompileErrorCode = 'unknown-table' | 'unknown-column' | 'unknown-link' | 'not-to-one' | 'link-depth-exceeded' | 'unsupported-comparison' | 'invalid-null-comparison' | 'when-not-claims-only';
|
|
66
|
+
type PolicyCompileErrorCode = 'unknown-table' | 'unknown-column' | 'unknown-link' | 'not-to-one' | 'link-depth-exceeded' | 'unsupported-comparison' | 'invalid-null-comparison' | 'when-not-claims-only' | 'claim-type-mismatch';
|
|
67
67
|
/**
|
|
68
68
|
* Compile-time failure — the parsed policy references something the table
|
|
69
69
|
* doesn't declare, or uses a shape the v2.0 IR cannot represent. Carries
|
|
@@ -90,6 +90,9 @@ declare function parsePolicy(source: string): ParsedPolicy;
|
|
|
90
90
|
* - a comparison must reference exactly ONE column side (column↔column and
|
|
91
91
|
* claims↔literal comparisons have no PredIr shape in v2.0);
|
|
92
92
|
* - `col = null` / `col != null` normalize to the isNull operator;
|
|
93
|
+
* - verified-borrower claims (`claim('ext_subject')`, `claim('ext_email')`)
|
|
94
|
+
* are text: they compare to a text column with `=` only, never under
|
|
95
|
+
* not(), so no negation, ordering or pattern can widen a borrower's rows;
|
|
93
96
|
* - variant `when` guards are claims-only: capability()/role() under
|
|
94
97
|
* and/or/not. (claim() comparisons in `when` are not representable in the
|
|
95
98
|
* v2.0 IR — a targeted error says so.)
|
|
@@ -99,6 +102,11 @@ declare const POLICY_MAX_LINK_DEPTH = 3;
|
|
|
99
102
|
interface PolicyColumnInfo {
|
|
100
103
|
readonly name: string;
|
|
101
104
|
readonly columnName: string;
|
|
105
|
+
/**
|
|
106
|
+
* The column's IR type when the resolver knows it (TableMetaIr always does).
|
|
107
|
+
* Required for a verified-borrower claim comparison: unknown is refused.
|
|
108
|
+
*/
|
|
109
|
+
readonly type?: unknown;
|
|
102
110
|
}
|
|
103
111
|
interface PolicyLinkInfo {
|
|
104
112
|
readonly name: string;
|
package/dist/predicate-v2.js
CHANGED
|
@@ -1056,14 +1056,20 @@ z.object({ irVersion: irVersionSchema });
|
|
|
1056
1056
|
var CLAIMS_CONTRACT = {
|
|
1057
1057
|
sub: "string",
|
|
1058
1058
|
org: "string?",
|
|
1059
|
+
ext_subject: "string?",
|
|
1060
|
+
ext_email: "string?",
|
|
1059
1061
|
roles: "string[]",
|
|
1060
1062
|
capabilities: "string[]"
|
|
1061
1063
|
};
|
|
1064
|
+
var EXTERNAL_POLICY_CLAIM_KEYS = ["ext_subject", "ext_email"];
|
|
1065
|
+
function isExternalPolicyClaimKey(key) {
|
|
1066
|
+
return EXTERNAL_POLICY_CLAIM_KEYS.includes(key);
|
|
1067
|
+
}
|
|
1062
1068
|
var scalarLiteral = z.union([z.string(), z.number(), z.boolean(), z.null()]);
|
|
1063
1069
|
var valueIrSchema = z.discriminatedUnion("kind", [
|
|
1064
1070
|
z.object({ kind: z.literal("literal"), value: z.union([scalarLiteral, z.array(scalarLiteral)]) }),
|
|
1065
1071
|
z.object({ kind: z.literal("variable"), name: z.string() }),
|
|
1066
|
-
z.object({ kind: z.literal("claim"), key: z.enum(["sub", "org"]) })
|
|
1072
|
+
z.object({ kind: z.literal("claim"), key: z.enum(["sub", "org", ...EXTERNAL_POLICY_CLAIM_KEYS]) })
|
|
1067
1073
|
]);
|
|
1068
1074
|
var CMP_OPS = [
|
|
1069
1075
|
"eq",
|
|
@@ -1813,6 +1819,7 @@ var PolicyCompiler = class {
|
|
|
1813
1819
|
case "or":
|
|
1814
1820
|
return { kind: node.kind, operands: node.operands.map((operand) => this.compile(operand, table, depth)) };
|
|
1815
1821
|
case "not":
|
|
1822
|
+
assertNoNegatedExternalClaim(node.operand);
|
|
1816
1823
|
return { kind: "not", operand: this.compile(node.operand, table, depth) };
|
|
1817
1824
|
case "capability":
|
|
1818
1825
|
return { kind: "capability", key: node.key };
|
|
@@ -1892,6 +1899,9 @@ var PolicyCompiler = class {
|
|
|
1892
1899
|
columnCandidates(info)
|
|
1893
1900
|
);
|
|
1894
1901
|
}
|
|
1902
|
+
if (valueSide.kind === "claim" && isExternalPolicyClaimKey(valueSide.key)) {
|
|
1903
|
+
assertExternalClaimComparison({ op, key: valueSide.key, column: info.columns.find((c) => c.name === column) });
|
|
1904
|
+
}
|
|
1895
1905
|
let cmp = this.buildCmp(op, column, valueSide);
|
|
1896
1906
|
for (let i = links.length - 1; i >= 0; i -= 1) {
|
|
1897
1907
|
cmp = { kind: "exists", link: links[i].name, where: cmp };
|
|
@@ -1912,6 +1922,33 @@ var PolicyCompiler = class {
|
|
|
1912
1922
|
return { kind: "cmp", op: CMP_BY_OP[op], column, value };
|
|
1913
1923
|
}
|
|
1914
1924
|
};
|
|
1925
|
+
function assertExternalClaimComparison({ op, key, column }) {
|
|
1926
|
+
if (op !== "=") {
|
|
1927
|
+
throw new PolicyCompileError(
|
|
1928
|
+
`claim('${key}') supports = comparisons only, got '${op}'`,
|
|
1929
|
+
"unsupported-comparison"
|
|
1930
|
+
);
|
|
1931
|
+
}
|
|
1932
|
+
if (column?.type !== "text") {
|
|
1933
|
+
const actual = column?.type === void 0 ? "of unknown type" : typeof column.type === "string" ? column.type : "an enum";
|
|
1934
|
+
throw new PolicyCompileError(
|
|
1935
|
+
`claim('${key}') is text and compares to a text column only \u2014 '${column?.name ?? "?"}' is ${actual}`,
|
|
1936
|
+
"claim-type-mismatch"
|
|
1937
|
+
);
|
|
1938
|
+
}
|
|
1939
|
+
}
|
|
1940
|
+
function assertNoNegatedExternalClaim(operand) {
|
|
1941
|
+
walkPolicy(operand, (node) => {
|
|
1942
|
+
if (node.kind !== "compare") return;
|
|
1943
|
+
const claim = [node.left, node.right].find((side) => side.kind === "claim" && isExternalPolicyClaimKey(side.key));
|
|
1944
|
+
if (claim?.kind === "claim") {
|
|
1945
|
+
throw new PolicyCompileError(
|
|
1946
|
+
`claim('${claim.key}') cannot appear under not(): a negated borrower comparison admits other borrowers' rows`,
|
|
1947
|
+
"unsupported-comparison"
|
|
1948
|
+
);
|
|
1949
|
+
}
|
|
1950
|
+
});
|
|
1951
|
+
}
|
|
1915
1952
|
function compilePredicateV2({ expression, table, resolver, maxLinkDepth }) {
|
|
1916
1953
|
const parsed = typeof expression === "string" ? parsePolicy(expression) : expression;
|
|
1917
1954
|
const compiler = new PolicyCompiler({ resolver, maxLinkDepth: maxLinkDepth ?? POLICY_MAX_LINK_DEPTH });
|