@o3co/auth.policy-verifier.builtins 0.12.0 → 0.14.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 (54) hide show
  1. package/README.ja.md +26 -5
  2. package/README.md +41 -5
  3. package/dist/collectors/PayloadClaimAttributeCollector.d.mts.map +1 -1
  4. package/dist/collectors/PayloadScopeCollector.d.mts.map +1 -1
  5. package/dist/collectors/PayloadSubjectIdCollector.d.mts.map +1 -1
  6. package/dist/collectors/RequestContextAttributeCollector.d.mts.map +1 -1
  7. package/dist/collectors/StaticPermissionCollector.d.mts +15 -1
  8. package/dist/collectors/StaticPermissionCollector.d.mts.map +1 -1
  9. package/dist/collectors/StaticPermissionCollector.mjs +19 -1
  10. package/dist/collectors/StaticRoleCollector.d.mts +17 -1
  11. package/dist/collectors/StaticRoleCollector.d.mts.map +1 -1
  12. package/dist/collectors/StaticRoleCollector.mjs +40 -1
  13. package/dist/collectors/_attributeMapping.d.mts +10 -2
  14. package/dist/collectors/_attributeMapping.d.mts.map +1 -1
  15. package/dist/collectors/_attributeMapping.mjs +10 -2
  16. package/dist/collectors/_claims.d.mts.map +1 -1
  17. package/dist/collectors/_claims.mjs +7 -3
  18. package/dist/module.d.mts.map +1 -1
  19. package/dist/resource/DotNotationResourceParser.d.mts.map +1 -1
  20. package/dist/rules/AttrLiteralCompare.d.mts +11 -1
  21. package/dist/rules/AttrLiteralCompare.d.mts.map +1 -1
  22. package/dist/rules/AttrLiteralCompare.mjs +21 -9
  23. package/dist/rules/AttrLiteralEqual.d.mts +10 -1
  24. package/dist/rules/AttrLiteralEqual.d.mts.map +1 -1
  25. package/dist/rules/AttrLiteralEqual.mjs +19 -10
  26. package/dist/rules/AttrLiteralIn.d.mts +9 -1
  27. package/dist/rules/AttrLiteralIn.d.mts.map +1 -1
  28. package/dist/rules/AttrLiteralIn.mjs +14 -6
  29. package/dist/rules/AttrLiteralNotEqual.d.mts +15 -3
  30. package/dist/rules/AttrLiteralNotEqual.d.mts.map +1 -1
  31. package/dist/rules/AttrLiteralNotEqual.mjs +26 -12
  32. package/dist/rules/AttrLiteralNotIn.d.mts +14 -3
  33. package/dist/rules/AttrLiteralNotIn.d.mts.map +1 -1
  34. package/dist/rules/AttrLiteralNotIn.mjs +21 -8
  35. package/dist/rules/AttrMatchRule.d.mts +2 -1
  36. package/dist/rules/AttrMatchRule.d.mts.map +1 -1
  37. package/dist/rules/AttrMatchRule.mjs +6 -1
  38. package/dist/rules/AttrPairCompare.d.mts +11 -1
  39. package/dist/rules/AttrPairCompare.d.mts.map +1 -1
  40. package/dist/rules/AttrPairCompare.mjs +22 -10
  41. package/dist/rules/AttrPairEqual.d.mts +10 -1
  42. package/dist/rules/AttrPairEqual.d.mts.map +1 -1
  43. package/dist/rules/AttrPairEqual.mjs +18 -8
  44. package/dist/rules/AttrPairNotEqual.d.mts +10 -1
  45. package/dist/rules/AttrPairNotEqual.d.mts.map +1 -1
  46. package/dist/rules/AttrPairNotEqual.mjs +18 -8
  47. package/dist/rules/HasPermission.d.mts.map +1 -1
  48. package/dist/rules/HasScope.d.mts.map +1 -1
  49. package/dist/rules/collectors/ResourceActionPermissionRuleCollector.d.mts +1 -1
  50. package/dist/rules/collectors/ResourceActionPermissionRuleCollector.d.mts.map +1 -1
  51. package/dist/rules/collectors/ResourceActionPermissionRuleCollector.mjs +1 -1
  52. package/dist/rules/collectors/ResourceActionScopeRuleCollector.d.mts +5 -1
  53. package/dist/rules/collectors/ResourceActionScopeRuleCollector.d.mts.map +1 -1
  54. package/package.json +5 -5
@@ -21,25 +21,34 @@ import { requireAttrName, requireLiteralValue, requireOptionalGroup, } from "./_
21
21
  *
22
22
  * Pass a shared `group` string to two instances to opt into OR semantics
23
23
  * (e.g. "role is admin" OR "role is superuser" under one group).
24
+ *
25
+ * ## Configuration is copied at construction
26
+ *
27
+ * The constructor reads each field of `config` once, validates it, and keeps
28
+ * the validated value in a field of its own; the object is not retained (#255).
29
+ * A caller that mutates the config afterwards changes nothing: the rule answers
30
+ * from the values it validated, and `ruleType` and `message` keep describing
31
+ * them.
24
32
  */
25
33
  export class AttrLiteralEqual {
26
- config;
27
34
  ruleType;
28
35
  code = "attr_not_equal";
29
36
  message;
37
+ a;
38
+ v;
30
39
  constructor(config) {
31
- this.config = config;
32
- requireAttrName("AttrLiteralEqual", "a", config.a);
33
- requireLiteralValue("AttrLiteralEqual", "v", config.v);
40
+ const a = requireAttrName("AttrLiteralEqual", "a", config.a);
41
+ const v = requireLiteralValue("AttrLiteralEqual", "v", config.v);
34
42
  const group = requireOptionalGroup("AttrLiteralEqual", config.group);
35
- this.ruleType =
36
- group ?? `attr_literal_equal:${config.a}:${typeof config.v}:${String(config.v)}`;
37
- this.message = `Attribute constraint not satisfied: ${config.a} must equal ${String(config.v)}.`;
43
+ this.a = a;
44
+ this.v = v;
45
+ this.ruleType = group ?? `attr_literal_equal:${a}:${typeof v}:${String(v)}`;
46
+ this.message = `Attribute constraint not satisfied: ${a} must equal ${String(v)}.`;
38
47
  }
39
48
  verify(attrs) {
40
- const x = attrs.get(this.config.a);
41
- if (typeof x !== typeof this.config.v)
49
+ const x = attrs.get(this.a);
50
+ if (typeof x !== typeof this.v)
42
51
  return false;
43
- return x === this.config.v;
52
+ return x === this.v;
44
53
  }
45
54
  }
@@ -24,12 +24,20 @@ export interface AttrLiteralInConfig {
24
24
  * will share a ruleType and be OR-combined.
25
25
  *
26
26
  * Pass an explicit `group` string to override the default ruleType entirely.
27
+ *
28
+ * ## Configuration is copied at construction
29
+ *
30
+ * The constructor reads each field of `config` once, validates it, and keeps
31
+ * the validated value in a field of its own; the object is not retained (#255).
32
+ * A caller that mutates the config afterwards changes nothing: the rule answers
33
+ * from the values it validated, and `ruleType` and `message` keep describing
34
+ * them.
27
35
  */
28
36
  export declare class AttrLiteralIn implements Rule {
29
- private readonly config;
30
37
  readonly ruleType: string;
31
38
  readonly code = "attr_not_in_set";
32
39
  readonly message: string;
40
+ private readonly a;
33
41
  private readonly elementType;
34
42
  private readonly valuesSet;
35
43
  constructor(config: AttrLiteralInConfig);
@@ -1 +1 @@
1
- {"version":3,"file":"AttrLiteralIn.d.mts","sourceRoot":"","sources":["../../src/rules/AttrLiteralIn.mts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EAEN,KAAK,YAAY,EAIjB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,mBAAmB;IACnC,CAAC,EAAE,MAAM,CAAC;IACV,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,aAAc,YAAW,IAAI;IAQ7B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAPnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,qBAAqB;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;gBAEjB,MAAM,EAAE,mBAAmB;IAaxD,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;CAK1C"}
1
+ {"version":3,"file":"AttrLiteralIn.d.mts","sourceRoot":"","sources":["../../src/rules/AttrLiteralIn.mts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EAEN,KAAK,YAAY,EAIjB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,mBAAmB;IACnC,CAAC,EAAE,MAAM,CAAC;IACV,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,aAAc,YAAW,IAAI;IACzC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,qBAAqB;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;gBAElC,MAAM,EAAE,mBAAmB;IAcvC,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;CAK1C"}
@@ -20,27 +20,35 @@ import { computeValuesKey, requireAttrName, requireHomogeneousLiteralArray, requ
20
20
  * will share a ruleType and be OR-combined.
21
21
  *
22
22
  * Pass an explicit `group` string to override the default ruleType entirely.
23
+ *
24
+ * ## Configuration is copied at construction
25
+ *
26
+ * The constructor reads each field of `config` once, validates it, and keeps
27
+ * the validated value in a field of its own; the object is not retained (#255).
28
+ * A caller that mutates the config afterwards changes nothing: the rule answers
29
+ * from the values it validated, and `ruleType` and `message` keep describing
30
+ * them.
23
31
  */
24
32
  export class AttrLiteralIn {
25
- config;
26
33
  ruleType;
27
34
  code = "attr_not_in_set";
28
35
  message;
36
+ a;
29
37
  elementType;
30
38
  valuesSet;
31
39
  constructor(config) {
32
- this.config = config;
33
- requireAttrName("AttrLiteralIn", "a", config.a);
40
+ const a = requireAttrName("AttrLiteralIn", "a", config.a);
34
41
  const values = requireHomogeneousLiteralArray("AttrLiteralIn", config.values);
35
42
  const group = requireOptionalGroup("AttrLiteralIn", config.group);
43
+ this.a = a;
36
44
  this.elementType = typeof values[0];
37
45
  this.valuesSet = new Set(values);
38
46
  const valuesKey = computeValuesKey(values);
39
- this.ruleType = group ?? `attr_literal_in:${config.a}:${valuesKey}`;
40
- this.message = `Attribute constraint not satisfied: ${config.a} must be one of [${values.map(String).join(", ")}].`;
47
+ this.ruleType = group ?? `attr_literal_in:${a}:${valuesKey}`;
48
+ this.message = `Attribute constraint not satisfied: ${a} must be one of [${values.map(String).join(", ")}].`;
41
49
  }
42
50
  verify(attrs) {
43
- const x = attrs.get(this.config.a);
51
+ const x = attrs.get(this.a);
44
52
  if (typeof x !== this.elementType)
45
53
  return false;
46
54
  return this.valuesSet.has(x);
@@ -8,8 +8,11 @@ export interface AttrLiteralNotEqualConfig {
8
8
  /**
9
9
  * Rule that passes when a named attribute is present, matches the type of the
10
10
  * configured literal value, and is strictly NOT equal to it. No type coercion
11
- * is performed. If the attribute is missing, null, or of the wrong type the
12
- * rule returns false (safe-deny).
11
+ * is performed. If the attribute is missing, null, of the wrong type, or
12
+ * `NaN` the rule returns false (safe-deny). `NaN` is unequal to every number,
13
+ * so `!==` alone would pass it: a restriction that allows on an attribute
14
+ * that is not a number at all (#254). Construction refuses a `NaN` literal
15
+ * for the mirror reason.
13
16
  *
14
17
  * ## Grouping and the default ruleType
15
18
  *
@@ -24,12 +27,21 @@ export interface AttrLiteralNotEqualConfig {
24
27
  * of two independent constraints. See AttrLiteralEqual for the same rationale.
25
28
  *
26
29
  * Pass a shared `group` string to two instances to opt into OR semantics.
30
+ *
31
+ * ## Configuration is copied at construction
32
+ *
33
+ * The constructor reads each field of `config` once, validates it, and keeps
34
+ * the validated value in a field of its own; the object is not retained (#255).
35
+ * A caller that mutates the config afterwards changes nothing: the rule answers
36
+ * from the values it validated, and `ruleType` and `message` keep describing
37
+ * them.
27
38
  */
28
39
  export declare class AttrLiteralNotEqual implements Rule {
29
- private readonly config;
30
40
  readonly ruleType: string;
31
41
  readonly code = "attr_equal";
32
42
  readonly message: string;
43
+ private readonly a;
44
+ private readonly v;
33
45
  constructor(config: AttrLiteralNotEqualConfig);
34
46
  verify(attrs: ReadonlyAttributes): boolean;
35
47
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AttrLiteralNotEqual.d.mts","sourceRoot":"","sources":["../../src/rules/AttrLiteralNotEqual.mts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EACN,KAAK,YAAY,EAIjB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,yBAAyB;IACzC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,YAAY,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,mBAAoB,YAAW,IAAI;IAKnC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBAEI,MAAM,EAAE,yBAAyB;IAU9D,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;CAK1C"}
1
+ {"version":3,"file":"AttrLiteralNotEqual.d.mts","sourceRoot":"","sources":["../../src/rules/AttrLiteralNotEqual.mts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EACN,KAAK,YAAY,EAIjB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,yBAAyB;IACzC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,YAAY,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBAAa,mBAAoB,YAAW,IAAI;IAC/C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAe;gBAErB,MAAM,EAAE,yBAAyB;IAW7C,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;CAM1C"}
@@ -4,8 +4,11 @@ import { requireAttrName, requireLiteralValue, requireOptionalGroup, } from "./_
4
4
  /**
5
5
  * Rule that passes when a named attribute is present, matches the type of the
6
6
  * configured literal value, and is strictly NOT equal to it. No type coercion
7
- * is performed. If the attribute is missing, null, or of the wrong type the
8
- * rule returns false (safe-deny).
7
+ * is performed. If the attribute is missing, null, of the wrong type, or
8
+ * `NaN` the rule returns false (safe-deny). `NaN` is unequal to every number,
9
+ * so `!==` alone would pass it: a restriction that allows on an attribute
10
+ * that is not a number at all (#254). Construction refuses a `NaN` literal
11
+ * for the mirror reason.
9
12
  *
10
13
  * ## Grouping and the default ruleType
11
14
  *
@@ -20,25 +23,36 @@ import { requireAttrName, requireLiteralValue, requireOptionalGroup, } from "./_
20
23
  * of two independent constraints. See AttrLiteralEqual for the same rationale.
21
24
  *
22
25
  * Pass a shared `group` string to two instances to opt into OR semantics.
26
+ *
27
+ * ## Configuration is copied at construction
28
+ *
29
+ * The constructor reads each field of `config` once, validates it, and keeps
30
+ * the validated value in a field of its own; the object is not retained (#255).
31
+ * A caller that mutates the config afterwards changes nothing: the rule answers
32
+ * from the values it validated, and `ruleType` and `message` keep describing
33
+ * them.
23
34
  */
24
35
  export class AttrLiteralNotEqual {
25
- config;
26
36
  ruleType;
27
37
  code = "attr_equal";
28
38
  message;
39
+ a;
40
+ v;
29
41
  constructor(config) {
30
- this.config = config;
31
- requireAttrName("AttrLiteralNotEqual", "a", config.a);
32
- requireLiteralValue("AttrLiteralNotEqual", "v", config.v);
42
+ const a = requireAttrName("AttrLiteralNotEqual", "a", config.a);
43
+ const v = requireLiteralValue("AttrLiteralNotEqual", "v", config.v);
33
44
  const group = requireOptionalGroup("AttrLiteralNotEqual", config.group);
34
- this.ruleType =
35
- group ?? `attr_literal_not_equal:${config.a}:${typeof config.v}:${String(config.v)}`;
36
- this.message = `Attribute constraint not satisfied: ${config.a} must not equal ${String(config.v)}.`;
45
+ this.a = a;
46
+ this.v = v;
47
+ this.ruleType = group ?? `attr_literal_not_equal:${a}:${typeof v}:${String(v)}`;
48
+ this.message = `Attribute constraint not satisfied: ${a} must not equal ${String(v)}.`;
37
49
  }
38
50
  verify(attrs) {
39
- const x = attrs.get(this.config.a);
40
- if (typeof x !== typeof this.config.v)
51
+ const x = attrs.get(this.a);
52
+ if (typeof x !== typeof this.v)
53
+ return false;
54
+ if (Number.isNaN(x))
41
55
  return false;
42
- return x !== this.config.v;
56
+ return x !== this.v;
43
57
  }
44
58
  }
@@ -8,8 +8,11 @@ export interface AttrLiteralNotInConfig {
8
8
  /**
9
9
  * Rule that passes when a named attribute is present, matches the element type
10
10
  * of the configured values array, and is NOT included in that array. No type
11
- * coercion is performed. If the attribute is missing, null, or of the wrong
12
- * type the rule returns false (safe-deny).
11
+ * coercion is performed. If the attribute is missing, null, of the wrong
12
+ * type, or `NaN` the rule returns false (safe-deny). `NaN` is in no set of
13
+ * numbers — construction refuses one that holds it — so the membership test
14
+ * alone would pass it: a restriction that allows on an attribute that is not
15
+ * a number at all (#254).
13
16
  *
14
17
  * ## Grouping and the default ruleType
15
18
  *
@@ -19,12 +22,20 @@ export interface AttrLiteralNotInConfig {
19
22
  * `attr_literal_not_in:{a}:{valuesKey}`
20
23
  *
21
24
  * Pass an explicit `group` string to override the default ruleType entirely.
25
+ *
26
+ * ## Configuration is copied at construction
27
+ *
28
+ * The constructor reads each field of `config` once, validates it, and keeps
29
+ * the validated value in a field of its own; the object is not retained (#255).
30
+ * A caller that mutates the config afterwards changes nothing: the rule answers
31
+ * from the values it validated, and `ruleType` and `message` keep describing
32
+ * them.
22
33
  */
23
34
  export declare class AttrLiteralNotIn implements Rule {
24
- private readonly config;
25
35
  readonly ruleType: string;
26
36
  readonly code = "attr_in_set";
27
37
  readonly message: string;
38
+ private readonly a;
28
39
  private readonly elementType;
29
40
  private readonly valuesSet;
30
41
  constructor(config: AttrLiteralNotInConfig);
@@ -1 +1 @@
1
- {"version":3,"file":"AttrLiteralNotIn.d.mts","sourceRoot":"","sources":["../../src/rules/AttrLiteralNotIn.mts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EAEN,KAAK,YAAY,EAIjB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,sBAAsB;IACtC,CAAC,EAAE,MAAM,CAAC;IACV,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,gBAAiB,YAAW,IAAI;IAQhC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAPnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,iBAAiB;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;gBAEjB,MAAM,EAAE,sBAAsB;IAa3D,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;CAK1C"}
1
+ {"version":3,"file":"AttrLiteralNotIn.d.mts","sourceRoot":"","sources":["../../src/rules/AttrLiteralNotIn.mts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EAEN,KAAK,YAAY,EAIjB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,sBAAsB;IACtC,CAAC,EAAE,MAAM,CAAC;IACV,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBAAa,gBAAiB,YAAW,IAAI;IAC5C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,iBAAiB;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;gBAElC,MAAM,EAAE,sBAAsB;IAc1C,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;CAM1C"}
@@ -4,8 +4,11 @@ import { computeValuesKey, requireAttrName, requireHomogeneousLiteralArray, requ
4
4
  /**
5
5
  * Rule that passes when a named attribute is present, matches the element type
6
6
  * of the configured values array, and is NOT included in that array. No type
7
- * coercion is performed. If the attribute is missing, null, or of the wrong
8
- * type the rule returns false (safe-deny).
7
+ * coercion is performed. If the attribute is missing, null, of the wrong
8
+ * type, or `NaN` the rule returns false (safe-deny). `NaN` is in no set of
9
+ * numbers — construction refuses one that holds it — so the membership test
10
+ * alone would pass it: a restriction that allows on an attribute that is not
11
+ * a number at all (#254).
9
12
  *
10
13
  * ## Grouping and the default ruleType
11
14
  *
@@ -15,29 +18,39 @@ import { computeValuesKey, requireAttrName, requireHomogeneousLiteralArray, requ
15
18
  * `attr_literal_not_in:{a}:{valuesKey}`
16
19
  *
17
20
  * Pass an explicit `group` string to override the default ruleType entirely.
21
+ *
22
+ * ## Configuration is copied at construction
23
+ *
24
+ * The constructor reads each field of `config` once, validates it, and keeps
25
+ * the validated value in a field of its own; the object is not retained (#255).
26
+ * A caller that mutates the config afterwards changes nothing: the rule answers
27
+ * from the values it validated, and `ruleType` and `message` keep describing
28
+ * them.
18
29
  */
19
30
  export class AttrLiteralNotIn {
20
- config;
21
31
  ruleType;
22
32
  code = "attr_in_set";
23
33
  message;
34
+ a;
24
35
  elementType;
25
36
  valuesSet;
26
37
  constructor(config) {
27
- this.config = config;
28
- requireAttrName("AttrLiteralNotIn", "a", config.a);
38
+ const a = requireAttrName("AttrLiteralNotIn", "a", config.a);
29
39
  const values = requireHomogeneousLiteralArray("AttrLiteralNotIn", config.values);
30
40
  const group = requireOptionalGroup("AttrLiteralNotIn", config.group);
41
+ this.a = a;
31
42
  this.elementType = typeof values[0];
32
43
  this.valuesSet = new Set(values);
33
44
  const valuesKey = computeValuesKey(values);
34
- this.ruleType = group ?? `attr_literal_not_in:${config.a}:${valuesKey}`;
35
- this.message = `Attribute constraint not satisfied: ${config.a} must not be one of [${values.map(String).join(", ")}].`;
45
+ this.ruleType = group ?? `attr_literal_not_in:${a}:${valuesKey}`;
46
+ this.message = `Attribute constraint not satisfied: ${a} must not be one of [${values.map(String).join(", ")}].`;
36
47
  }
37
48
  verify(attrs) {
38
- const x = attrs.get(this.config.a);
49
+ const x = attrs.get(this.a);
39
50
  if (typeof x !== this.elementType)
40
51
  return false;
52
+ if (Number.isNaN(x))
53
+ return false;
41
54
  return !this.valuesSet.has(x);
42
55
  }
43
56
  }
@@ -1,11 +1,12 @@
1
1
  import { AttrPairEqual, type AttrPairEqualConfig } from "./AttrPairEqual.mjs";
2
2
  export type AttrMatchRuleConfig = AttrPairEqualConfig;
3
3
  /**
4
- * @deprecated Use {@link AttrPairEqual}. Scheduled for removal in a future major version.
4
+ * @deprecated since v0.3 — use {@link AttrPairEqual}.
5
5
  *
6
6
  * Kept as a thin wrapper that preserves the legacy `ruleType` (`attr_match:{a}:{b}`)
7
7
  * and legacy `message` wording. `verify()` semantics are inherited unchanged from
8
8
  * `AttrPairEqual`: both named attributes must be non-empty strings and equal.
9
+ * Its config is validated by `super`, so a refusal names `AttrPairEqual`.
9
10
  */
10
11
  export declare class AttrMatchRule extends AttrPairEqual {
11
12
  readonly ruleType: string;
@@ -1 +1 @@
1
- {"version":3,"file":"AttrMatchRule.d.mts","sourceRoot":"","sources":["../../src/rules/AttrMatchRule.mts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE9E,MAAM,MAAM,mBAAmB,GAAG,mBAAmB,CAAC;AAEtD;;;;;;GAMG;AACH,qBAAa,aAAc,SAAQ,aAAa;IAC/C,SAAkB,QAAQ,EAAE,MAAM,CAAC;IACnC,SAAkB,OAAO,EAAE,MAAM,CAAC;gBAEtB,MAAM,EAAE,mBAAmB;CAKvC"}
1
+ {"version":3,"file":"AttrMatchRule.d.mts","sourceRoot":"","sources":["../../src/rules/AttrMatchRule.mts"],"names":[],"mappings":"AAQA,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE9E,MAAM,MAAM,mBAAmB,GAAG,mBAAmB,CAAC;AAEtD;;;;;;;GAOG;AACH,qBAAa,aAAc,SAAQ,aAAa;IAC/C,SAAkB,QAAQ,EAAE,MAAM,CAAC;IACnC,SAAkB,OAAO,EAAE,MAAM,CAAC;gBAEtB,MAAM,EAAE,mBAAmB;CAKvC"}
@@ -1,12 +1,17 @@
1
1
  // SPDX-FileCopyrightText: 2026 1o1 Co. Ltd.
2
2
  // SPDX-License-Identifier: Apache-2.0
3
+ /*
4
+ * The deprecated `AttrMatchRule`: `AttrPairEqual` under its legacy `ruleType`
5
+ * and message, kept for existing configurations.
6
+ */
3
7
  import { AttrPairEqual } from "./AttrPairEqual.mjs";
4
8
  /**
5
- * @deprecated Use {@link AttrPairEqual}. Scheduled for removal in a future major version.
9
+ * @deprecated since v0.3 — use {@link AttrPairEqual}.
6
10
  *
7
11
  * Kept as a thin wrapper that preserves the legacy `ruleType` (`attr_match:{a}:{b}`)
8
12
  * and legacy `message` wording. `verify()` semantics are inherited unchanged from
9
13
  * `AttrPairEqual`: both named attributes must be non-empty strings and equal.
14
+ * Its config is validated by `super`, so a refusal names `AttrPairEqual`.
10
15
  */
11
16
  export class AttrMatchRule extends AttrPairEqual {
12
17
  ruleType;
@@ -23,12 +23,22 @@ export interface AttrPairCompareConfig {
23
23
  * `attr_pair_compare:{a}:{op}:{b}`
24
24
  *
25
25
  * Pass an explicit `group` string to override the default ruleType entirely.
26
+ *
27
+ * ## Configuration is copied at construction
28
+ *
29
+ * The constructor reads each field of `config` once, validates it, and keeps
30
+ * the validated value in a field of its own; the object is not retained (#255).
31
+ * A caller that mutates the config afterwards changes nothing: the rule answers
32
+ * from the values it validated, and `ruleType` and `message` keep describing
33
+ * them.
26
34
  */
27
35
  export declare class AttrPairCompare implements Rule {
28
- private readonly config;
29
36
  readonly ruleType: string;
30
37
  readonly code = "attr_compare_violated";
31
38
  readonly message: string;
39
+ private readonly a;
40
+ private readonly op;
41
+ private readonly b;
32
42
  constructor(config: AttrPairCompareConfig);
33
43
  verify(attrs: ReadonlyAttributes): boolean;
34
44
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AttrPairCompare.d.mts","sourceRoot":"","sources":["../../src/rules/AttrPairCompare.mts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EAEN,KAAK,SAAS,EAId,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,qBAAqB;IACrC,CAAC,EAAE,MAAM,CAAC;IACV,EAAE,EAAE,SAAS,CAAC;IACd,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,eAAgB,YAAW,IAAI;IAK/B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,2BAA2B;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBAEI,MAAM,EAAE,qBAAqB;IAU1D,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;CAO1C"}
1
+ {"version":3,"file":"AttrPairCompare.d.mts","sourceRoot":"","sources":["../../src/rules/AttrPairCompare.mts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EAEN,KAAK,SAAS,EAId,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,qBAAqB;IACrC,CAAC,EAAE,MAAM,CAAC;IACV,EAAE,EAAE,SAAS,CAAC;IACd,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBAAa,eAAgB,YAAW,IAAI;IAC3C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,2BAA2B;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAY;IAC/B,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAS;gBAEf,MAAM,EAAE,qBAAqB;IAazC,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;CAO1C"}
@@ -18,28 +18,40 @@ import { applyCompare, requireAttrName, requireCompareOp, requireOptionalGroup,
18
18
  * `attr_pair_compare:{a}:{op}:{b}`
19
19
  *
20
20
  * Pass an explicit `group` string to override the default ruleType entirely.
21
+ *
22
+ * ## Configuration is copied at construction
23
+ *
24
+ * The constructor reads each field of `config` once, validates it, and keeps
25
+ * the validated value in a field of its own; the object is not retained (#255).
26
+ * A caller that mutates the config afterwards changes nothing: the rule answers
27
+ * from the values it validated, and `ruleType` and `message` keep describing
28
+ * them.
21
29
  */
22
30
  export class AttrPairCompare {
23
- config;
24
31
  ruleType;
25
32
  code = "attr_compare_violated";
26
33
  message;
34
+ a;
35
+ op;
36
+ b;
27
37
  constructor(config) {
28
- this.config = config;
29
- requireAttrName("AttrPairCompare", "a", config.a);
30
- requireAttrName("AttrPairCompare", "b", config.b);
31
- requireCompareOp("AttrPairCompare", config.op);
38
+ const a = requireAttrName("AttrPairCompare", "a", config.a);
39
+ const b = requireAttrName("AttrPairCompare", "b", config.b);
40
+ const op = requireCompareOp("AttrPairCompare", config.op);
32
41
  const group = requireOptionalGroup("AttrPairCompare", config.group);
33
- this.ruleType = group ?? `attr_pair_compare:${config.a}:${config.op}:${config.b}`;
34
- this.message = `Attribute constraint not satisfied: ${config.a} must be ${config.op} ${config.b}.`;
42
+ this.a = a;
43
+ this.op = op;
44
+ this.b = b;
45
+ this.ruleType = group ?? `attr_pair_compare:${a}:${op}:${b}`;
46
+ this.message = `Attribute constraint not satisfied: ${a} must be ${op} ${b}.`;
35
47
  }
36
48
  verify(attrs) {
37
- const a = attrs.get(this.config.a);
38
- const b = attrs.get(this.config.b);
49
+ const a = attrs.get(this.a);
50
+ const b = attrs.get(this.b);
39
51
  if (typeof a !== "number")
40
52
  return false;
41
53
  if (typeof b !== "number")
42
54
  return false;
43
- return applyCompare(this.config.op, a, b);
55
+ return applyCompare(this.op, a, b);
44
56
  }
45
57
  }
@@ -23,12 +23,21 @@ export interface AttrPairEqualConfig {
23
23
  * `attr_pair_equal:{a}:{b}`
24
24
  *
25
25
  * Pass a shared `group` string to two instances to opt into OR semantics.
26
+ *
27
+ * ## Configuration is copied at construction
28
+ *
29
+ * The constructor reads each field of `config` once, validates it, and keeps
30
+ * the validated value in a field of its own; the object is not retained (#255).
31
+ * A caller that mutates the config afterwards changes nothing: the rule answers
32
+ * from the values it validated, and `ruleType` and `message` keep describing
33
+ * them.
26
34
  */
27
35
  export declare class AttrPairEqual implements Rule {
28
- private readonly config;
29
36
  readonly ruleType: string;
30
37
  readonly code = "attr_mismatch";
31
38
  readonly message: string;
39
+ private readonly a;
40
+ private readonly b;
32
41
  constructor(config: AttrPairEqualConfig);
33
42
  verify(attrs: ReadonlyAttributes): boolean;
34
43
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AttrPairEqual.d.mts","sourceRoot":"","sources":["../../src/rules/AttrPairEqual.mts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC;AAGhF,MAAM,WAAW,mBAAmB;IACnC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,aAAc,YAAW,IAAI;IAK7B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,mBAAmB;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBAEI,MAAM,EAAE,mBAAmB;IASxD,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;CAO1C"}
1
+ {"version":3,"file":"AttrPairEqual.d.mts","sourceRoot":"","sources":["../../src/rules/AttrPairEqual.mts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC;AAGhF,MAAM,WAAW,mBAAmB;IACnC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,aAAc,YAAW,IAAI;IACzC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,mBAAmB;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAS;gBAEf,MAAM,EAAE,mBAAmB;IAWvC,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;CAO1C"}
@@ -20,23 +20,33 @@ import { requireAttrName, requireOptionalGroup } from "./_sharedValidation.mjs";
20
20
  * `attr_pair_equal:{a}:{b}`
21
21
  *
22
22
  * Pass a shared `group` string to two instances to opt into OR semantics.
23
+ *
24
+ * ## Configuration is copied at construction
25
+ *
26
+ * The constructor reads each field of `config` once, validates it, and keeps
27
+ * the validated value in a field of its own; the object is not retained (#255).
28
+ * A caller that mutates the config afterwards changes nothing: the rule answers
29
+ * from the values it validated, and `ruleType` and `message` keep describing
30
+ * them.
23
31
  */
24
32
  export class AttrPairEqual {
25
- config;
26
33
  ruleType;
27
34
  code = "attr_mismatch";
28
35
  message;
36
+ a;
37
+ b;
29
38
  constructor(config) {
30
- this.config = config;
31
- requireAttrName("AttrPairEqual", "a", config.a);
32
- requireAttrName("AttrPairEqual", "b", config.b);
39
+ const a = requireAttrName("AttrPairEqual", "a", config.a);
40
+ const b = requireAttrName("AttrPairEqual", "b", config.b);
33
41
  const group = requireOptionalGroup("AttrPairEqual", config.group);
34
- this.ruleType = group ?? `attr_pair_equal:${config.a}:${config.b}`;
35
- this.message = `Attribute constraint not satisfied: ${config.a} must equal ${config.b}.`;
42
+ this.a = a;
43
+ this.b = b;
44
+ this.ruleType = group ?? `attr_pair_equal:${a}:${b}`;
45
+ this.message = `Attribute constraint not satisfied: ${a} must equal ${b}.`;
36
46
  }
37
47
  verify(attrs) {
38
- const a = attrs.get(this.config.a);
39
- const b = attrs.get(this.config.b);
48
+ const a = attrs.get(this.a);
49
+ const b = attrs.get(this.b);
40
50
  if (typeof a !== "string" || a.length === 0)
41
51
  return false;
42
52
  if (typeof b !== "string" || b.length === 0)
@@ -22,12 +22,21 @@ export interface AttrPairNotEqualConfig {
22
22
  * `attr_pair_not_equal:{a}:{b}`
23
23
  *
24
24
  * Pass a shared `group` string to two instances to opt into OR semantics.
25
+ *
26
+ * ## Configuration is copied at construction
27
+ *
28
+ * The constructor reads each field of `config` once, validates it, and keeps
29
+ * the validated value in a field of its own; the object is not retained (#255).
30
+ * A caller that mutates the config afterwards changes nothing: the rule answers
31
+ * from the values it validated, and `ruleType` and `message` keep describing
32
+ * them.
25
33
  */
26
34
  export declare class AttrPairNotEqual implements Rule {
27
- private readonly config;
28
35
  readonly ruleType: string;
29
36
  readonly code = "attr_match";
30
37
  readonly message: string;
38
+ private readonly a;
39
+ private readonly b;
31
40
  constructor(config: AttrPairNotEqualConfig);
32
41
  verify(attrs: ReadonlyAttributes): boolean;
33
42
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AttrPairNotEqual.d.mts","sourceRoot":"","sources":["../../src/rules/AttrPairNotEqual.mts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC;AAGhF,MAAM,WAAW,sBAAsB;IACtC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,gBAAiB,YAAW,IAAI;IAKhC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBAEI,MAAM,EAAE,sBAAsB;IAS3D,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;CAO1C"}
1
+ {"version":3,"file":"AttrPairNotEqual.d.mts","sourceRoot":"","sources":["../../src/rules/AttrPairNotEqual.mts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC;AAGhF,MAAM,WAAW,sBAAsB;IACtC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,gBAAiB,YAAW,IAAI;IAC5C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAS;gBAEf,MAAM,EAAE,sBAAsB;IAW1C,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;CAO1C"}
@@ -19,23 +19,33 @@ import { requireAttrName, requireOptionalGroup } from "./_sharedValidation.mjs";
19
19
  * `attr_pair_not_equal:{a}:{b}`
20
20
  *
21
21
  * Pass a shared `group` string to two instances to opt into OR semantics.
22
+ *
23
+ * ## Configuration is copied at construction
24
+ *
25
+ * The constructor reads each field of `config` once, validates it, and keeps
26
+ * the validated value in a field of its own; the object is not retained (#255).
27
+ * A caller that mutates the config afterwards changes nothing: the rule answers
28
+ * from the values it validated, and `ruleType` and `message` keep describing
29
+ * them.
22
30
  */
23
31
  export class AttrPairNotEqual {
24
- config;
25
32
  ruleType;
26
33
  code = "attr_match";
27
34
  message;
35
+ a;
36
+ b;
28
37
  constructor(config) {
29
- this.config = config;
30
- requireAttrName("AttrPairNotEqual", "a", config.a);
31
- requireAttrName("AttrPairNotEqual", "b", config.b);
38
+ const a = requireAttrName("AttrPairNotEqual", "a", config.a);
39
+ const b = requireAttrName("AttrPairNotEqual", "b", config.b);
32
40
  const group = requireOptionalGroup("AttrPairNotEqual", config.group);
33
- this.ruleType = group ?? `attr_pair_not_equal:${config.a}:${config.b}`;
34
- this.message = `Attribute constraint not satisfied: ${config.a} must not equal ${config.b}.`;
41
+ this.a = a;
42
+ this.b = b;
43
+ this.ruleType = group ?? `attr_pair_not_equal:${a}:${b}`;
44
+ this.message = `Attribute constraint not satisfied: ${a} must not equal ${b}.`;
35
45
  }
36
46
  verify(attrs) {
37
- const a = attrs.get(this.config.a);
38
- const b = attrs.get(this.config.b);
47
+ const a = attrs.get(this.a);
48
+ const b = attrs.get(this.b);
39
49
  if (typeof a !== "string" || a.length === 0)
40
50
  return false;
41
51
  if (typeof b !== "string" || b.length === 0)
@@ -1 +1 @@
1
- {"version":3,"file":"HasPermission.d.mts","sourceRoot":"","sources":["../../src/rules/HasPermission.mts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAQ,IAAI,EAAE,MAAM,iCAAiC,CAAC;AAGtF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,qBAAa,aAAc,YAAW,IAAI;IAK7B,OAAO,CAAC,UAAU;IAJ9B,QAAQ,CAAC,QAAQ,gBAAgB;IACjC,QAAQ,CAAC,IAAI,mBAAmB;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBAEL,UAAU,EAAE,MAAM;IAItC,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;IAoB1C,OAAO,CAAC,KAAK;CA0Bb"}
1
+ {"version":3,"file":"HasPermission.d.mts","sourceRoot":"","sources":["../../src/rules/HasPermission.mts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,kBAAkB,EAAQ,IAAI,EAAE,MAAM,iCAAiC,CAAC;AAGtF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,qBAAa,aAAc,YAAW,IAAI;IAK7B,OAAO,CAAC,UAAU;IAJ9B,QAAQ,CAAC,QAAQ,gBAAgB;IACjC,QAAQ,CAAC,IAAI,mBAAmB;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBAEL,UAAU,EAAE,MAAM;IAItC,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;IAoB1C,OAAO,CAAC,KAAK;CA0Bb"}
@@ -1 +1 @@
1
- {"version":3,"file":"HasScope.d.mts","sourceRoot":"","sources":["../../src/rules/HasScope.mts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC;AAGhF,sCAAsC;AACtC,MAAM,WAAW,eAAe;IAC/B;;;;;;;;OAQG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,QAAS,YAAW,IAAI;IAQnC,OAAO,CAAC,KAAK;IAPd,QAAQ,CAAC,QAAQ,WAAW;IAC5B,QAAQ,CAAC,IAAI,mBAAmB;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAU;gBAGvC,KAAK,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,eAAe;IAM1B,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;IAM1C,OAAO,CAAC,UAAU;CAYlB"}
1
+ {"version":3,"file":"HasScope.d.mts","sourceRoot":"","sources":["../../src/rules/HasScope.mts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC;AAGhF,sCAAsC;AACtC,MAAM,WAAW,eAAe;IAC/B;;;;;;;;OAQG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,QAAS,YAAW,IAAI;IAQnC,OAAO,CAAC,KAAK;IAPd,QAAQ,CAAC,QAAQ,WAAW;IAC5B,QAAQ,CAAC,IAAI,mBAAmB;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAU;gBAGvC,KAAK,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,eAAe;IAM1B,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;IAM1C,OAAO,CAAC,UAAU;CAYlB"}
@@ -1,7 +1,7 @@
1
1
  import type { CollectorContext, Rule, RuleCollector } from "@o3co/auth.policy-verifier.core";
2
2
  /**
3
3
  * Rule collector that emits a single `HasPermission` rule for the
4
- * `{resource}.perm:{action}` permission string. Use when the effective
4
+ * `{resource.raw}.perm:{action}` permission string. Use when the effective
5
5
  * permission is encoded directly into the token's permission attribute rather
6
6
  * than derived from scopes.
7
7
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ResourceActionPermissionRuleCollector.d.mts","sourceRoot":"","sources":["../../../src/rules/collectors/ResourceActionPermissionRuleCollector.mts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAG7F;;;;;GAKG;AACH,qBAAa,qCAAsC,YAAW,aAAa;IACpE,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;CAIzD"}
1
+ {"version":3,"file":"ResourceActionPermissionRuleCollector.d.mts","sourceRoot":"","sources":["../../../src/rules/collectors/ResourceActionPermissionRuleCollector.mts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAG7F;;;;;GAKG;AACH,qBAAa,qCAAsC,YAAW,aAAa;IACpE,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;CAIzD"}
@@ -3,7 +3,7 @@
3
3
  import { HasPermission } from "../HasPermission.mjs";
4
4
  /**
5
5
  * Rule collector that emits a single `HasPermission` rule for the
6
- * `{resource}.perm:{action}` permission string. Use when the effective
6
+ * `{resource.raw}.perm:{action}` permission string. Use when the effective
7
7
  * permission is encoded directly into the token's permission attribute rather
8
8
  * than derived from scopes.
9
9
  */