@o3co/auth.policy-verifier.builtins 0.15.0 → 0.16.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 (85) hide show
  1. package/README.ja.md +45 -7
  2. package/README.md +47 -8
  3. package/dist/collectors/DelegationRangeCollector.d.mts +29 -0
  4. package/dist/collectors/DelegationRangeCollector.d.mts.map +1 -0
  5. package/dist/collectors/DelegationRangeCollector.mjs +29 -0
  6. package/dist/collectors/PayloadClaimAttributeCollector.d.mts +24 -39
  7. package/dist/collectors/PayloadClaimAttributeCollector.d.mts.map +1 -1
  8. package/dist/collectors/PayloadClaimAttributeCollector.mjs +26 -41
  9. package/dist/collectors/PayloadScopeCollector.d.mts +1 -1
  10. package/dist/collectors/PayloadSubjectIdCollector.d.mts +1 -1
  11. package/dist/collectors/PayloadSubjectIdCollector.mjs +1 -1
  12. package/dist/collectors/RequestContextAttributeCollector.d.mts +24 -62
  13. package/dist/collectors/RequestContextAttributeCollector.d.mts.map +1 -1
  14. package/dist/collectors/RequestContextAttributeCollector.mjs +33 -74
  15. package/dist/collectors/StaticPermissionCollector.d.mts +7 -9
  16. package/dist/collectors/StaticPermissionCollector.d.mts.map +1 -1
  17. package/dist/collectors/StaticPermissionCollector.mjs +7 -9
  18. package/dist/collectors/StaticRoleCollector.d.mts +9 -10
  19. package/dist/collectors/StaticRoleCollector.d.mts.map +1 -1
  20. package/dist/collectors/StaticRoleCollector.mjs +10 -11
  21. package/dist/collectors/_attributeMapping.d.mts +1 -0
  22. package/dist/collectors/_attributeMapping.d.mts.map +1 -1
  23. package/dist/collectors/_attributeMapping.mjs +3 -0
  24. package/dist/collectors/_claims.d.mts +2 -3
  25. package/dist/collectors/_claims.d.mts.map +1 -1
  26. package/dist/collectors/_claims.mjs +3 -4
  27. package/dist/delegation/range.d.mts +48 -0
  28. package/dist/delegation/range.d.mts.map +1 -0
  29. package/dist/delegation/range.mjs +108 -0
  30. package/dist/index.d.mts +5 -0
  31. package/dist/index.d.mts.map +1 -1
  32. package/dist/index.mjs +7 -0
  33. package/dist/keys.d.mts +9 -0
  34. package/dist/keys.d.mts.map +1 -0
  35. package/dist/keys.mjs +31 -0
  36. package/dist/module.d.mts.map +1 -1
  37. package/dist/module.mjs +4 -0
  38. package/dist/resource/DotNotationResourceParser.d.mts +16 -19
  39. package/dist/resource/DotNotationResourceParser.d.mts.map +1 -1
  40. package/dist/resource/DotNotationResourceParser.mjs +20 -25
  41. package/dist/rules/AttrLiteralCompare.d.mts +3 -5
  42. package/dist/rules/AttrLiteralCompare.d.mts.map +1 -1
  43. package/dist/rules/AttrLiteralCompare.mjs +3 -5
  44. package/dist/rules/AttrLiteralEqual.d.mts +3 -5
  45. package/dist/rules/AttrLiteralEqual.d.mts.map +1 -1
  46. package/dist/rules/AttrLiteralEqual.mjs +3 -5
  47. package/dist/rules/AttrLiteralIn.d.mts +3 -5
  48. package/dist/rules/AttrLiteralIn.d.mts.map +1 -1
  49. package/dist/rules/AttrLiteralIn.mjs +3 -5
  50. package/dist/rules/AttrLiteralNotEqual.d.mts +6 -8
  51. package/dist/rules/AttrLiteralNotEqual.d.mts.map +1 -1
  52. package/dist/rules/AttrLiteralNotEqual.mjs +6 -8
  53. package/dist/rules/AttrLiteralNotIn.d.mts +4 -6
  54. package/dist/rules/AttrLiteralNotIn.d.mts.map +1 -1
  55. package/dist/rules/AttrLiteralNotIn.mjs +4 -6
  56. package/dist/rules/AttrMatchRule.d.mts +1 -1
  57. package/dist/rules/AttrMatchRule.mjs +1 -1
  58. package/dist/rules/AttrPairCompare.d.mts +3 -5
  59. package/dist/rules/AttrPairCompare.d.mts.map +1 -1
  60. package/dist/rules/AttrPairCompare.mjs +3 -5
  61. package/dist/rules/AttrPairEqual.d.mts +6 -9
  62. package/dist/rules/AttrPairEqual.d.mts.map +1 -1
  63. package/dist/rules/AttrPairEqual.mjs +6 -9
  64. package/dist/rules/AttrPairNotEqual.d.mts +3 -5
  65. package/dist/rules/AttrPairNotEqual.d.mts.map +1 -1
  66. package/dist/rules/AttrPairNotEqual.mjs +3 -5
  67. package/dist/rules/HasPermission.d.mts +9 -10
  68. package/dist/rules/HasPermission.d.mts.map +1 -1
  69. package/dist/rules/HasPermission.mjs +16 -20
  70. package/dist/rules/HasScope.d.mts +11 -14
  71. package/dist/rules/HasScope.d.mts.map +1 -1
  72. package/dist/rules/HasScope.mjs +8 -11
  73. package/dist/rules/WithinDelegationRange.d.mts +22 -0
  74. package/dist/rules/WithinDelegationRange.d.mts.map +1 -0
  75. package/dist/rules/WithinDelegationRange.mjs +38 -0
  76. package/dist/rules/_sharedValidation.d.mts +12 -19
  77. package/dist/rules/_sharedValidation.d.mts.map +1 -1
  78. package/dist/rules/_sharedValidation.mjs +17 -25
  79. package/dist/rules/collectors/DelegationRangeRuleCollector.d.mts +36 -0
  80. package/dist/rules/collectors/DelegationRangeRuleCollector.d.mts.map +1 -0
  81. package/dist/rules/collectors/DelegationRangeRuleCollector.mjs +36 -0
  82. package/dist/rules/collectors/ResourceActionScopeRuleCollector.d.mts +19 -28
  83. package/dist/rules/collectors/ResourceActionScopeRuleCollector.d.mts.map +1 -1
  84. package/dist/rules/collectors/ResourceActionScopeRuleCollector.mjs +21 -30
  85. package/package.json +5 -5
package/dist/index.d.mts CHANGED
@@ -1,9 +1,12 @@
1
+ export { DelegationRangeCollector, type DelegationRangeCollectorConfig, } from "./collectors/DelegationRangeCollector.mjs";
1
2
  export { PayloadClaimAttributeCollector, type PayloadClaimAttributeCollectorConfig, type PayloadClaimAttributeMapping, type PayloadClaimAttributeType, } from "./collectors/PayloadClaimAttributeCollector.mjs";
2
3
  export { PayloadScopeCollector, type PayloadScopeCollectorConfig, } from "./collectors/PayloadScopeCollector.mjs";
3
4
  export { PayloadSubjectIdCollector } from "./collectors/PayloadSubjectIdCollector.mjs";
4
5
  export { RequestContextAttributeCollector, type RequestContextAttributeCollectorConfig, type RequestContextAttributeMapping, type RequestContextAttributeType, } from "./collectors/RequestContextAttributeCollector.mjs";
5
6
  export { StaticPermissionCollector } from "./collectors/StaticPermissionCollector.mjs";
6
7
  export { StaticRoleCollector } from "./collectors/StaticRoleCollector.mjs";
8
+ export { parseRangePath, type RangeElement, rangeContains, } from "./delegation/range.mjs";
9
+ export { ATTR_DELEGATION_RANGE, BUILTINS_ATTRIBUTE_KEY_OWNER } from "./keys.mjs";
7
10
  export { builtinCollectorsModule } from "./module.mjs";
8
11
  export { DotNotationResourceParser } from "./resource/DotNotationResourceParser.mjs";
9
12
  export { AttrLiteralCompare, type AttrLiteralCompareConfig } from "./rules/AttrLiteralCompare.mjs";
@@ -15,8 +18,10 @@ export { AttrMatchRule, type AttrMatchRuleConfig } from "./rules/AttrMatchRule.m
15
18
  export { AttrPairCompare, type AttrPairCompareConfig } from "./rules/AttrPairCompare.mjs";
16
19
  export { AttrPairEqual, type AttrPairEqualConfig } from "./rules/AttrPairEqual.mjs";
17
20
  export { AttrPairNotEqual, type AttrPairNotEqualConfig } from "./rules/AttrPairNotEqual.mjs";
21
+ export { DelegationRangeRuleCollector, type DelegationRangeRuleCollectorConfig, } from "./rules/collectors/DelegationRangeRuleCollector.mjs";
18
22
  export { ResourceActionPermissionRuleCollector } from "./rules/collectors/ResourceActionPermissionRuleCollector.mjs";
19
23
  export { ResourceActionScopeRuleCollector, type ResourceActionScopeRuleCollectorConfig, type ScopelessPolicy, } from "./rules/collectors/ResourceActionScopeRuleCollector.mjs";
20
24
  export { HasPermission } from "./rules/HasPermission.mjs";
21
25
  export { HasScope, type HasScopeOptions } from "./rules/HasScope.mjs";
26
+ export { WithinDelegationRange } from "./rules/WithinDelegationRange.mjs";
22
27
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.mts"],"names":[],"mappings":"AAIA,OAAO,EACN,8BAA8B,EAC9B,KAAK,oCAAoC,EACzC,KAAK,4BAA4B,EACjC,KAAK,yBAAyB,GAC9B,MAAM,iDAAiD,CAAC;AACzD,OAAO,EACN,qBAAqB,EACrB,KAAK,2BAA2B,GAChC,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AACvF,OAAO,EACN,gCAAgC,EAChC,KAAK,sCAAsC,EAC3C,KAAK,8BAA8B,EACnC,KAAK,2BAA2B,GAChC,MAAM,mDAAmD,CAAC;AAC3D,OAAO,EAAE,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AACvF,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAE3E,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAEvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AAErF,OAAO,EAAE,kBAAkB,EAAE,KAAK,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AACnG,OAAO,EAAE,gBAAgB,EAAE,KAAK,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC7F,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACpF,OAAO,EACN,mBAAmB,EACnB,KAAK,yBAAyB,GAC9B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,KAAK,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC7F,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACpF,OAAO,EAAE,eAAe,EAAE,KAAK,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAC1F,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACpF,OAAO,EAAE,gBAAgB,EAAE,KAAK,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC7F,OAAO,EAAE,qCAAqC,EAAE,MAAM,8DAA8D,CAAC;AACrH,OAAO,EACN,gCAAgC,EAChC,KAAK,sCAAsC,EAC3C,KAAK,eAAe,GACpB,MAAM,yDAAyD,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.mts"],"names":[],"mappings":"AAIA,OAAO,EACN,wBAAwB,EACxB,KAAK,8BAA8B,GACnC,MAAM,2CAA2C,CAAC;AACnD,OAAO,EACN,8BAA8B,EAC9B,KAAK,oCAAoC,EACzC,KAAK,4BAA4B,EACjC,KAAK,yBAAyB,GAC9B,MAAM,iDAAiD,CAAC;AACzD,OAAO,EACN,qBAAqB,EACrB,KAAK,2BAA2B,GAChC,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AACvF,OAAO,EACN,gCAAgC,EAChC,KAAK,sCAAsC,EAC3C,KAAK,8BAA8B,EACnC,KAAK,2BAA2B,GAChC,MAAM,mDAAmD,CAAC;AAC3D,OAAO,EAAE,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AACvF,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAE3E,OAAO,EACN,cAAc,EACd,KAAK,YAAY,EACjB,aAAa,GACb,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,qBAAqB,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAEjF,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAEvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AAErF,OAAO,EAAE,kBAAkB,EAAE,KAAK,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AACnG,OAAO,EAAE,gBAAgB,EAAE,KAAK,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC7F,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACpF,OAAO,EACN,mBAAmB,EACnB,KAAK,yBAAyB,GAC9B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,KAAK,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC7F,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACpF,OAAO,EAAE,eAAe,EAAE,KAAK,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAC1F,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACpF,OAAO,EAAE,gBAAgB,EAAE,KAAK,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC7F,OAAO,EACN,4BAA4B,EAC5B,KAAK,kCAAkC,GACvC,MAAM,qDAAqD,CAAC;AAC7D,OAAO,EAAE,qCAAqC,EAAE,MAAM,8DAA8D,CAAC;AACrH,OAAO,EACN,gCAAgC,EAChC,KAAK,sCAAsC,EAC3C,KAAK,eAAe,GACpB,MAAM,yDAAyD,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC"}
package/dist/index.mjs CHANGED
@@ -1,12 +1,17 @@
1
1
  // SPDX-FileCopyrightText: 2026 1o1 Co. Ltd.
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
  // Collectors
4
+ export { DelegationRangeCollector, } from "./collectors/DelegationRangeCollector.mjs";
4
5
  export { PayloadClaimAttributeCollector, } from "./collectors/PayloadClaimAttributeCollector.mjs";
5
6
  export { PayloadScopeCollector, } from "./collectors/PayloadScopeCollector.mjs";
6
7
  export { PayloadSubjectIdCollector } from "./collectors/PayloadSubjectIdCollector.mjs";
7
8
  export { RequestContextAttributeCollector, } from "./collectors/RequestContextAttributeCollector.mjs";
8
9
  export { StaticPermissionCollector } from "./collectors/StaticPermissionCollector.mjs";
9
10
  export { StaticRoleCollector } from "./collectors/StaticRoleCollector.mjs";
11
+ // Delegation range
12
+ export { parseRangePath, rangeContains, } from "./delegation/range.mjs";
13
+ // Attribute keys
14
+ export { ATTR_DELEGATION_RANGE, BUILTINS_ATTRIBUTE_KEY_OWNER } from "./keys.mjs";
10
15
  // Module
11
16
  export { builtinCollectorsModule } from "./module.mjs";
12
17
  // Resource
@@ -21,7 +26,9 @@ export { AttrMatchRule } from "./rules/AttrMatchRule.mjs";
21
26
  export { AttrPairCompare } from "./rules/AttrPairCompare.mjs";
22
27
  export { AttrPairEqual } from "./rules/AttrPairEqual.mjs";
23
28
  export { AttrPairNotEqual } from "./rules/AttrPairNotEqual.mjs";
29
+ export { DelegationRangeRuleCollector, } from "./rules/collectors/DelegationRangeRuleCollector.mjs";
24
30
  export { ResourceActionPermissionRuleCollector } from "./rules/collectors/ResourceActionPermissionRuleCollector.mjs";
25
31
  export { ResourceActionScopeRuleCollector, } from "./rules/collectors/ResourceActionScopeRuleCollector.mjs";
26
32
  export { HasPermission } from "./rules/HasPermission.mjs";
27
33
  export { HasScope } from "./rules/HasScope.mjs";
34
+ export { WithinDelegationRange } from "./rules/WithinDelegationRange.mjs";
@@ -0,0 +1,9 @@
1
+ /**
2
+ * The paths of a delegated token's range, as a `string[]`. The delegation
3
+ * range is not core vocabulary — its grammar and containment rule are this
4
+ * stack's, not a standard's — so the builtins own the key.
5
+ */
6
+ export declare const ATTR_DELEGATION_RANGE: "delegationRange";
7
+ /** The npm package name this vocabulary is reserved under. */
8
+ export declare const BUILTINS_ATTRIBUTE_KEY_OWNER: "@o3co/auth.policy-verifier.builtins";
9
+ //# sourceMappingURL=keys.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.d.mts","sourceRoot":"","sources":["../src/keys.mts"],"names":[],"mappings":"AAaA;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAG,iBAA0B,CAAC;AAEhE,8DAA8D;AAC9D,eAAO,MAAM,4BAA4B,EAAG,qCAA8C,CAAC"}
package/dist/keys.mjs ADDED
@@ -0,0 +1,31 @@
1
+ // SPDX-FileCopyrightText: 2026 1o1 Co. Ltd.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /*
4
+ * This package's own attribute keys and their reservation in core's key
5
+ * registry, made when this module is imported. The builtins write core's keys
6
+ * (`scopes`, `userId`, …) and the operator's; the keys here are the ones whose
7
+ * meaning is this package's — not core vocabulary (AGENTS.md "Core Vocabulary
8
+ * Scope"), and not the operator's to write with a mapping.
9
+ */
10
+ import { reserveAttributeKeys } from "@o3co/auth.policy-verifier.core";
11
+ /**
12
+ * The paths of a delegated token's range, as a `string[]`. The delegation
13
+ * range is not core vocabulary — its grammar and containment rule are this
14
+ * stack's, not a standard's — so the builtins own the key.
15
+ */
16
+ export const ATTR_DELEGATION_RANGE = "delegationRange";
17
+ /** The npm package name this vocabulary is reserved under. */
18
+ export const BUILTINS_ATTRIBUTE_KEY_OWNER = "@o3co/auth.policy-verifier.builtins";
19
+ /*
20
+ * Reserved at module scope, beside the constant, so that the reservation is
21
+ * in place before any collector can be constructed. With it,
22
+ * `RequestContextAttributeCollector` and `PayloadClaimAttributeCollector`
23
+ * refuse a mapping onto the key: `AttributePipeline` unions list keys, so a
24
+ * mapping would add paths of its own to the range `DelegationRangeCollector`
25
+ * read, and a narrowing would become a widening.
26
+ */
27
+ reserveAttributeKeys({
28
+ owner: BUILTINS_ATTRIBUTE_KEY_OWNER,
29
+ keys: [ATTR_DELEGATION_RANGE],
30
+ reason: "a delegated token's range, written by DelegationRangeCollector from the authenticated subject and read by WithinDelegationRange",
31
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"module.d.mts","sourceRoot":"","sources":["../src/module.mts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAC;AAW9D;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,EAAE,MA6CrC,CAAC"}
1
+ {"version":3,"file":"module.d.mts","sourceRoot":"","sources":["../src/module.mts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAC;AAa9D;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAqDrC,CAAC"}
package/dist/module.mjs CHANGED
@@ -1,5 +1,6 @@
1
1
  // SPDX-FileCopyrightText: 2026 1o1 Co. Ltd.
2
2
  // SPDX-License-Identifier: Apache-2.0
3
+ import { DelegationRangeCollector } from "./collectors/DelegationRangeCollector.mjs";
3
4
  import { PayloadClaimAttributeCollector } from "./collectors/PayloadClaimAttributeCollector.mjs";
4
5
  import { PayloadScopeCollector } from "./collectors/PayloadScopeCollector.mjs";
5
6
  import { PayloadSubjectIdCollector } from "./collectors/PayloadSubjectIdCollector.mjs";
@@ -7,6 +8,7 @@ import { RequestContextAttributeCollector } from "./collectors/RequestContextAtt
7
8
  import { StaticPermissionCollector } from "./collectors/StaticPermissionCollector.mjs";
8
9
  import { StaticRoleCollector } from "./collectors/StaticRoleCollector.mjs";
9
10
  import { DotNotationResourceParser } from "./resource/DotNotationResourceParser.mjs";
11
+ import { DelegationRangeRuleCollector } from "./rules/collectors/DelegationRangeRuleCollector.mjs";
10
12
  import { ResourceActionPermissionRuleCollector } from "./rules/collectors/ResourceActionPermissionRuleCollector.mjs";
11
13
  import { ResourceActionScopeRuleCollector } from "./rules/collectors/ResourceActionScopeRuleCollector.mjs";
12
14
  /**
@@ -24,9 +26,11 @@ export const builtinCollectorsModule = {
24
26
  context.attributeCollectorRegistry.register("StaticRoleCollector", (config) => new StaticRoleCollector(config));
25
27
  context.attributeCollectorRegistry.register("RequestContextAttributeCollector", (config) => new RequestContextAttributeCollector(config));
26
28
  context.attributeCollectorRegistry.register("PayloadClaimAttributeCollector", (config) => new PayloadClaimAttributeCollector(config));
29
+ context.attributeCollectorRegistry.register("DelegationRangeCollector", (config) => new DelegationRangeCollector(config));
27
30
  // Rule collector factories
28
31
  context.ruleCollectorRegistry.register("ResourceActionScopeRuleCollector", (config) => new ResourceActionScopeRuleCollector(config));
29
32
  context.ruleCollectorRegistry.register("ResourceActionPermissionRuleCollector", () => new ResourceActionPermissionRuleCollector());
33
+ context.ruleCollectorRegistry.register("DelegationRangeRuleCollector", (config) => new DelegationRangeRuleCollector(config));
30
34
  // Resource parser factories
31
35
  context.resourceParserRegistry.register("DotNotationResourceParser", () => new DotNotationResourceParser());
32
36
  },
@@ -23,25 +23,22 @@ import type { Resource, ResourceParser } from "@o3co/auth.policy-verifier.core";
23
23
  * `resourceType` is the authorization namespace: scope rules authorize it, so
24
24
  * two distinct resources that parse to the same type are authorized
25
25
  * identically, and a caller can reach resource A through a grant written for
26
- * resource B. Every rewrite the parser could perform is a way for that to
27
- * happen, so it performs none:
28
- *
29
- * - **The `.` separator is preserved.** Joining types with `_` collapsed the
30
- * nested type `a.b` and the flat type literally named `a_b` onto one string.
31
- * `.` is reserved as the separator and cannot occur inside a type, so the
32
- * sequence of types round-trips: distinct type sequences are distinct
33
- * `resourceType`s. `_` is now an ordinary type character.
34
- * - **Empty segments are refused.** `a..b` used to parse, and every input with
35
- * a repeated `.` landed in whatever namespace the empty types produced.
36
- * - **Extra `:` components are refused, not truncated.** `a:1:2` used to be
37
- * read as `a:1` with the tail silently dropped, so a deliberately narrowed
38
- * identifier widened into the broader one.
39
- * - **Whitespace is refused, not trimmed.** Trimming made `project : 1` and
40
- * `project:1` one resource for scope rules while
41
- * `ResourceActionPermissionRuleCollector`, which reads `raw`, still saw two.
42
- *
43
- * This is the same principle `HasScope` applies to scope values: compare what
44
- * was written, never a normalized guess at what was meant.
26
+ * resource B. Every rewrite is a way for that to happen, so the parser
27
+ * performs none:
28
+ *
29
+ * - **The `.` separator is preserved.** `.` cannot occur inside a type, so
30
+ * distinct type sequences are distinct `resourceType`s; `_` is an ordinary
31
+ * type character, and the nested type `a.b` stays apart from `a_b`.
32
+ * - **Empty segments are refused** (`a..b`): no input lands in a namespace
33
+ * produced by empty types.
34
+ * - **Extra `:` components are refused, not truncated:** `a:1:2` read as
35
+ * `a:1` would widen a deliberately narrowed identifier.
36
+ * - **Whitespace is refused, not trimmed:** trimmed, `project : 1` and
37
+ * `project:1` would be one resource for scope rules while
38
+ * `ResourceActionPermissionRuleCollector`, which reads `raw`, sees two.
39
+ *
40
+ * This is the principle `HasScope` applies to scope values: compare what was
41
+ * written, never a normalized guess at what was meant.
45
42
  *
46
43
  * An id that needs `.`, `:` or a character outside the set must be encoded by
47
44
  * the caller (percent-encoding round-trips through this grammar) or handled by
@@ -1 +1 @@
1
- {"version":3,"file":"DotNotationResourceParser.d.mts","sourceRoot":"","sources":["../../src/resource/DotNotationResourceParser.mts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAqBhF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,qBAAa,yBAA0B,YAAW,cAAc;IAC/D,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ;CAY5B"}
1
+ {"version":3,"file":"DotNotationResourceParser.d.mts","sourceRoot":"","sources":["../../src/resource/DotNotationResourceParser.mts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAmBhF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,qBAAa,yBAA0B,YAAW,cAAc;IAC/D,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ;CAY5B"}
@@ -2,14 +2,12 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
  import { ResourceParseError } from "@o3co/auth.policy-verifier.core";
4
4
  /**
5
- * Characters a segment type or id may carry.
6
- *
7
- * The set is RFC 6749 §3.3 `NQCHAR` (`%x21 / %x23-5B / %x5D-7E` — printable
8
- * ASCII minus space, `"` and `\`) less the two structural characters `.` and
9
- * `:`. Anchoring it there is not arbitrary: `resourceType` is concatenated into
10
- * the `{action}:{resourceType}` scope that `ResourceActionScopeRuleCollector`
11
- * requires, so a type that cannot appear in a scope value is a type no issuer
12
- * could ever grant.
5
+ * Characters a segment type or id may carry: those of an RFC 6749 §3.3
6
+ * `scope-token` (`%x21 / %x23-5B / %x5D-7E`, which its Appendix A names
7
+ * `NQCHAR` — printable ASCII minus space, `"` and `\`) less the structural `.`
8
+ * and `:`. `resourceType` is concatenated into the `{action}:{resourceType}`
9
+ * scope `ResourceActionScopeRuleCollector` requires, so a type that cannot
10
+ * appear in a scope value is one no issuer could grant.
13
11
  */
14
12
  const SEGMENT_TOKEN = /^[\x21\x23-\x2D\x2F-\x39\x3B-\x5B\x5D-\x7E]+$/;
15
13
  /**
@@ -36,25 +34,22 @@ const SEGMENT_TOKEN = /^[\x21\x23-\x2D\x2F-\x39\x3B-\x5B\x5D-\x7E]+$/;
36
34
  * `resourceType` is the authorization namespace: scope rules authorize it, so
37
35
  * two distinct resources that parse to the same type are authorized
38
36
  * identically, and a caller can reach resource A through a grant written for
39
- * resource B. Every rewrite the parser could perform is a way for that to
40
- * happen, so it performs none:
37
+ * resource B. Every rewrite is a way for that to happen, so the parser
38
+ * performs none:
41
39
  *
42
- * - **The `.` separator is preserved.** Joining types with `_` collapsed the
43
- * nested type `a.b` and the flat type literally named `a_b` onto one string.
44
- * `.` is reserved as the separator and cannot occur inside a type, so the
45
- * sequence of types round-trips: distinct type sequences are distinct
46
- * `resourceType`s. `_` is now an ordinary type character.
47
- * - **Empty segments are refused.** `a..b` used to parse, and every input with
48
- * a repeated `.` landed in whatever namespace the empty types produced.
49
- * - **Extra `:` components are refused, not truncated.** `a:1:2` used to be
50
- * read as `a:1` with the tail silently dropped, so a deliberately narrowed
51
- * identifier widened into the broader one.
52
- * - **Whitespace is refused, not trimmed.** Trimming made `project : 1` and
53
- * `project:1` one resource for scope rules while
54
- * `ResourceActionPermissionRuleCollector`, which reads `raw`, still saw two.
40
+ * - **The `.` separator is preserved.** `.` cannot occur inside a type, so
41
+ * distinct type sequences are distinct `resourceType`s; `_` is an ordinary
42
+ * type character, and the nested type `a.b` stays apart from `a_b`.
43
+ * - **Empty segments are refused** (`a..b`): no input lands in a namespace
44
+ * produced by empty types.
45
+ * - **Extra `:` components are refused, not truncated:** `a:1:2` read as
46
+ * `a:1` would widen a deliberately narrowed identifier.
47
+ * - **Whitespace is refused, not trimmed:** trimmed, `project : 1` and
48
+ * `project:1` would be one resource for scope rules while
49
+ * `ResourceActionPermissionRuleCollector`, which reads `raw`, sees two.
55
50
  *
56
- * This is the same principle `HasScope` applies to scope values: compare what
57
- * was written, never a normalized guess at what was meant.
51
+ * This is the principle `HasScope` applies to scope values: compare what was
52
+ * written, never a normalized guess at what was meant.
58
53
  *
59
54
  * An id that needs `.`, `:` or a character outside the set must be encoded by
60
55
  * the caller (percent-encoding round-trips through this grammar) or handled by
@@ -22,11 +22,9 @@ export interface AttrLiteralCompareConfig {
22
22
  *
23
23
  * ## Configuration is copied at construction
24
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.
25
+ * The constructor validates each field of `config` once and keeps the
26
+ * validated value; the object is not retained, so mutating it afterwards
27
+ * changes neither the rule's answers nor its `ruleType` and `message`.
30
28
  */
31
29
  export declare class AttrLiteralCompare implements Rule {
32
30
  readonly ruleType: string;
@@ -1 +1 @@
1
- {"version":3,"file":"AttrLiteralCompare.d.mts","sourceRoot":"","sources":["../../src/rules/AttrLiteralCompare.mts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EAEN,KAAK,SAAS,EAKd,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,wBAAwB;IACxC,CAAC,EAAE,MAAM,CAAC;IACV,EAAE,EAAE,SAAS,CAAC;IACd,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,kBAAmB,YAAW,IAAI;IAC9C,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,wBAAwB;IAa5C,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;CAK1C"}
1
+ {"version":3,"file":"AttrLiteralCompare.d.mts","sourceRoot":"","sources":["../../src/rules/AttrLiteralCompare.mts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EAEN,KAAK,SAAS,EAKd,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,wBAAwB;IACxC,CAAC,EAAE,MAAM,CAAC;IACV,EAAE,EAAE,SAAS,CAAC;IACd,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,kBAAmB,YAAW,IAAI;IAC9C,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,wBAAwB;IAa5C,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;CAK1C"}
@@ -17,11 +17,9 @@ import { applyCompare, requireAttrName, requireCompareOp, requireNumber, require
17
17
  *
18
18
  * ## Configuration is copied at construction
19
19
  *
20
- * The constructor reads each field of `config` once, validates it, and keeps
21
- * the validated value in a field of its own; the object is not retained (#255).
22
- * A caller that mutates the config afterwards changes nothing: the rule answers
23
- * from the values it validated, and `ruleType` and `message` keep describing
24
- * them.
20
+ * The constructor validates each field of `config` once and keeps the
21
+ * validated value; the object is not retained, so mutating it afterwards
22
+ * changes neither the rule's answers nor its `ruleType` and `message`.
25
23
  */
26
24
  export class AttrLiteralCompare {
27
25
  ruleType;
@@ -28,11 +28,9 @@ export interface AttrLiteralEqualConfig {
28
28
  *
29
29
  * ## Configuration is copied at construction
30
30
  *
31
- * The constructor reads each field of `config` once, validates it, and keeps
32
- * the validated value in a field of its own; the object is not retained (#255).
33
- * A caller that mutates the config afterwards changes nothing: the rule answers
34
- * from the values it validated, and `ruleType` and `message` keep describing
35
- * them.
31
+ * The constructor validates each field of `config` once and keeps the
32
+ * validated value; the object is not retained, so mutating it afterwards
33
+ * changes neither the rule's answers nor its `ruleType` and `message`.
36
34
  */
37
35
  export declare class AttrLiteralEqual implements Rule {
38
36
  readonly ruleType: string;
@@ -1 +1 @@
1
- {"version":3,"file":"AttrLiteralEqual.d.mts","sourceRoot":"","sources":["../../src/rules/AttrLiteralEqual.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,sBAAsB;IACtC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,YAAY,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,gBAAiB,YAAW,IAAI;IAC5C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,oBAAoB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAe;gBAErB,MAAM,EAAE,sBAAsB;IAW1C,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;CAK1C"}
1
+ {"version":3,"file":"AttrLiteralEqual.d.mts","sourceRoot":"","sources":["../../src/rules/AttrLiteralEqual.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,sBAAsB;IACtC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,YAAY,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,gBAAiB,YAAW,IAAI;IAC5C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,oBAAoB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAe;gBAErB,MAAM,EAAE,sBAAsB;IAW1C,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;CAK1C"}
@@ -24,11 +24,9 @@ import { requireAttrName, requireLiteralValue, requireOptionalGroup, } from "./_
24
24
  *
25
25
  * ## Configuration is copied at construction
26
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.
27
+ * The constructor validates each field of `config` once and keeps the
28
+ * validated value; the object is not retained, so mutating it afterwards
29
+ * changes neither the rule's answers nor its `ruleType` and `message`.
32
30
  */
33
31
  export class AttrLiteralEqual {
34
32
  ruleType;
@@ -27,11 +27,9 @@ export interface AttrLiteralInConfig {
27
27
  *
28
28
  * ## Configuration is copied at construction
29
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.
30
+ * The constructor validates each field of `config` once and keeps the
31
+ * validated value; the object is not retained, so mutating it afterwards
32
+ * changes neither the rule's answers nor its `ruleType` and `message`.
35
33
  */
36
34
  export declare class AttrLiteralIn implements Rule {
37
35
  readonly ruleType: string;
@@ -1 +1 @@
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"}
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;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;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"}
@@ -23,11 +23,9 @@ import { computeValuesKey, requireAttrName, requireHomogeneousLiteralArray, requ
23
23
  *
24
24
  * ## Configuration is copied at construction
25
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.
26
+ * The constructor validates each field of `config` once and keeps the
27
+ * validated value; the object is not retained, so mutating it afterwards
28
+ * changes neither the rule's answers nor its `ruleType` and `message`.
31
29
  */
32
30
  export class AttrLiteralIn {
33
31
  ruleType;
@@ -11,8 +11,8 @@ export interface AttrLiteralNotEqualConfig {
11
11
  * is performed. If the attribute is missing, null, of the wrong type, or
12
12
  * `NaN` the rule returns false (safe-deny). `NaN` is unequal to every number,
13
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.
14
+ * that is not a number at all. Construction refuses a `NaN` literal for the
15
+ * mirror reason.
16
16
  *
17
17
  * ## Grouping and the default ruleType
18
18
  *
@@ -24,17 +24,15 @@ export interface AttrLiteralNotEqualConfig {
24
24
  * The `typeof v` segment prevents silent `ruleType` collisions between
25
25
  * different-type literals that stringify the same way (e.g. `1` vs `"1"`),
26
26
  * which would otherwise be OR-combined by the evaluator against the intent
27
- * of two independent constraints. See AttrLiteralEqual for the same rationale.
27
+ * of two independent constraints.
28
28
  *
29
29
  * Pass a shared `group` string to two instances to opt into OR semantics.
30
30
  *
31
31
  * ## Configuration is copied at construction
32
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.
33
+ * The constructor validates each field of `config` once and keeps the
34
+ * validated value; the object is not retained, so mutating it afterwards
35
+ * changes neither the rule's answers nor its `ruleType` and `message`.
38
36
  */
39
37
  export declare class AttrLiteralNotEqual implements Rule {
40
38
  readonly ruleType: string;
@@ -1 +1 @@
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"}
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;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"}
@@ -7,8 +7,8 @@ import { requireAttrName, requireLiteralValue, requireOptionalGroup, } from "./_
7
7
  * is performed. If the attribute is missing, null, of the wrong type, or
8
8
  * `NaN` the rule returns false (safe-deny). `NaN` is unequal to every number,
9
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.
10
+ * that is not a number at all. Construction refuses a `NaN` literal for the
11
+ * mirror reason.
12
12
  *
13
13
  * ## Grouping and the default ruleType
14
14
  *
@@ -20,17 +20,15 @@ import { requireAttrName, requireLiteralValue, requireOptionalGroup, } from "./_
20
20
  * The `typeof v` segment prevents silent `ruleType` collisions between
21
21
  * different-type literals that stringify the same way (e.g. `1` vs `"1"`),
22
22
  * which would otherwise be OR-combined by the evaluator against the intent
23
- * of two independent constraints. See AttrLiteralEqual for the same rationale.
23
+ * of two independent constraints.
24
24
  *
25
25
  * Pass a shared `group` string to two instances to opt into OR semantics.
26
26
  *
27
27
  * ## Configuration is copied at construction
28
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.
29
+ * The constructor validates each field of `config` once and keeps the
30
+ * validated value; the object is not retained, so mutating it afterwards
31
+ * changes neither the rule's answers nor its `ruleType` and `message`.
34
32
  */
35
33
  export class AttrLiteralNotEqual {
36
34
  ruleType;
@@ -12,7 +12,7 @@ export interface AttrLiteralNotInConfig {
12
12
  * type, or `NaN` the rule returns false (safe-deny). `NaN` is in no set of
13
13
  * numbers — construction refuses one that holds it — so the membership test
14
14
  * alone would pass it: a restriction that allows on an attribute that is not
15
- * a number at all (#254).
15
+ * a number at all.
16
16
  *
17
17
  * ## Grouping and the default ruleType
18
18
  *
@@ -25,11 +25,9 @@ export interface AttrLiteralNotInConfig {
25
25
  *
26
26
  * ## Configuration is copied at construction
27
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.
28
+ * The constructor validates each field of `config` once and keeps the
29
+ * validated value; the object is not retained, so mutating it afterwards
30
+ * changes neither the rule's answers nor its `ruleType` and `message`.
33
31
  */
34
32
  export declare class AttrLiteralNotIn implements Rule {
35
33
  readonly ruleType: string;
@@ -1 +1 @@
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"}
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;;;;;;;;;;;;;;;;;;;;;;;GAuBG;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"}
@@ -8,7 +8,7 @@ import { computeValuesKey, requireAttrName, requireHomogeneousLiteralArray, requ
8
8
  * type, or `NaN` the rule returns false (safe-deny). `NaN` is in no set of
9
9
  * numbers — construction refuses one that holds it — so the membership test
10
10
  * alone would pass it: a restriction that allows on an attribute that is not
11
- * a number at all (#254).
11
+ * a number at all.
12
12
  *
13
13
  * ## Grouping and the default ruleType
14
14
  *
@@ -21,11 +21,9 @@ import { computeValuesKey, requireAttrName, requireHomogeneousLiteralArray, requ
21
21
  *
22
22
  * ## Configuration is copied at construction
23
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.
24
+ * The constructor validates each field of `config` once and keeps the
25
+ * validated value; the object is not retained, so mutating it afterwards
26
+ * changes neither the rule's answers nor its `ruleType` and `message`.
29
27
  */
30
28
  export class AttrLiteralNotIn {
31
29
  ruleType;
@@ -1,7 +1,7 @@
1
1
  import { AttrPairEqual, type AttrPairEqualConfig } from "./AttrPairEqual.mjs";
2
2
  export type AttrMatchRuleConfig = AttrPairEqualConfig;
3
3
  /**
4
- * @deprecated since v0.3 — use {@link AttrPairEqual}.
4
+ * @deprecated 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
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import { AttrPairEqual } from "./AttrPairEqual.mjs";
8
8
  /**
9
- * @deprecated since v0.3 — use {@link AttrPairEqual}.
9
+ * @deprecated Use {@link AttrPairEqual}.
10
10
  *
11
11
  * Kept as a thin wrapper that preserves the legacy `ruleType` (`attr_match:{a}:{b}`)
12
12
  * and legacy `message` wording. `verify()` semantics are inherited unchanged from
@@ -26,11 +26,9 @@ export interface AttrPairCompareConfig {
26
26
  *
27
27
  * ## Configuration is copied at construction
28
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.
29
+ * The constructor validates each field of `config` once and keeps the
30
+ * validated value; the object is not retained, so mutating it afterwards
31
+ * changes neither the rule's answers nor its `ruleType` and `message`.
34
32
  */
35
33
  export declare class AttrPairCompare implements Rule {
36
34
  readonly ruleType: string;
@@ -1 +1 @@
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"}
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;;;;;;;;;;;;;;;;;;;;;;;GAuBG;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"}
@@ -21,11 +21,9 @@ import { applyCompare, requireAttrName, requireCompareOp, requireOptionalGroup,
21
21
  *
22
22
  * ## Configuration is copied at construction
23
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.
24
+ * The constructor validates each field of `config` once and keeps the
25
+ * validated value; the object is not retained, so mutating it afterwards
26
+ * changes neither the rule's answers nor its `ruleType` and `message`.
29
27
  */
30
28
  export class AttrPairCompare {
31
29
  ruleType;
@@ -9,11 +9,10 @@ export interface AttrPairEqualConfig {
9
9
  * strings, and are strictly equal. No type coercion is performed: both
10
10
  * attribute values must be non-empty strings.
11
11
  *
12
- * ## Backward compatibility
12
+ * ## String-only
13
13
  *
14
- * AttrPairEqual deliberately retains the string-only semantic of the legacy
15
- * AttrMatchRule. Do not widen verify() to accept numbers or booleans — the
16
- * Phase 4 AttrMatchRule alias depends on this invariant.
14
+ * The deprecated `AttrMatchRule` inherits verify() from this rule and must stay
15
+ * string-only: do not widen verify() to accept numbers or booleans.
17
16
  *
18
17
  * ## Grouping and the default ruleType
19
18
  *
@@ -26,11 +25,9 @@ export interface AttrPairEqualConfig {
26
25
  *
27
26
  * ## Configuration is copied at construction
28
27
  *
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.
28
+ * The constructor validates each field of `config` once and keeps the
29
+ * validated value; the object is not retained, so mutating it afterwards
30
+ * changes neither the rule's answers nor its `ruleType` and `message`.
34
31
  */
35
32
  export declare class AttrPairEqual implements Rule {
36
33
  readonly ruleType: string;