@nmnmcc/ability 2.0.7 → 2.1.2

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 (87) hide show
  1. package/README.md +52 -29
  2. package/dist/Authorizer.d.ts +21 -12
  3. package/dist/Authorizer.d.ts.map +1 -1
  4. package/dist/Authorizer.js.map +1 -1
  5. package/dist/Condition.d.ts +121 -19
  6. package/dist/Condition.d.ts.map +1 -1
  7. package/dist/Condition.js +32 -21
  8. package/dist/Condition.js.map +1 -1
  9. package/dist/Domain.d.ts +9 -0
  10. package/dist/Domain.d.ts.map +1 -1
  11. package/dist/Domain.js +5 -0
  12. package/dist/Domain.js.map +1 -1
  13. package/dist/Limits.d.ts +44 -13
  14. package/dist/Limits.d.ts.map +1 -1
  15. package/dist/Limits.js +52 -22
  16. package/dist/Limits.js.map +1 -1
  17. package/dist/Policy.d.ts +102 -18
  18. package/dist/Policy.d.ts.map +1 -1
  19. package/dist/Policy.js +7 -6
  20. package/dist/Policy.js.map +1 -1
  21. package/dist/index.d.ts +1 -1
  22. package/dist/internal/algebra.js +2 -2
  23. package/dist/internal/analysis.js +81 -75
  24. package/dist/internal/analysis.js.map +1 -1
  25. package/dist/internal/authorizer.d.ts.map +1 -1
  26. package/dist/internal/authorizer.js +11 -7
  27. package/dist/internal/authorizer.js.map +1 -1
  28. package/dist/internal/bind.js +86 -64
  29. package/dist/internal/bind.js.map +1 -1
  30. package/dist/internal/catalog.d.ts +33 -10
  31. package/dist/internal/catalog.d.ts.map +1 -1
  32. package/dist/internal/catalog.js +170 -77
  33. package/dist/internal/catalog.js.map +1 -1
  34. package/dist/internal/decide.js +27 -31
  35. package/dist/internal/decide.js.map +1 -1
  36. package/dist/internal/domain.js +19 -5
  37. package/dist/internal/domain.js.map +1 -1
  38. package/dist/internal/json.js +120 -76
  39. package/dist/internal/json.js.map +1 -1
  40. package/dist/internal/limits.d.ts +28 -0
  41. package/dist/internal/limits.d.ts.map +1 -1
  42. package/dist/internal/limits.js +75 -16
  43. package/dist/internal/limits.js.map +1 -1
  44. package/dist/internal/nodes.d.ts.map +1 -1
  45. package/dist/internal/nodes.js +53 -44
  46. package/dist/internal/nodes.js.map +1 -1
  47. package/dist/internal/patterns.js +50 -15
  48. package/dist/internal/patterns.js.map +1 -1
  49. package/dist/internal/policy-json.js +169 -127
  50. package/dist/internal/policy-json.js.map +1 -1
  51. package/dist/internal/policy-nodes.d.ts.map +1 -1
  52. package/dist/internal/policy-nodes.js +16 -13
  53. package/dist/internal/policy-nodes.js.map +1 -1
  54. package/dist/internal/policy.d.ts.map +1 -1
  55. package/dist/internal/policy.js +38 -22
  56. package/dist/internal/policy.js.map +1 -1
  57. package/dist/internal/resource.js +1 -1
  58. package/dist/internal/rule.d.ts.map +1 -1
  59. package/dist/internal/rule.js +6 -5
  60. package/dist/internal/rule.js.map +1 -1
  61. package/dist/internal/search.d.ts.map +1 -1
  62. package/dist/internal/search.js +106 -92
  63. package/dist/internal/search.js.map +1 -1
  64. package/dist/internal/trampoline.js +19 -5
  65. package/dist/internal/trampoline.js.map +1 -1
  66. package/package.json +1 -1
  67. package/src/Authorizer.ts +30 -20
  68. package/src/Condition.ts +317 -86
  69. package/src/Domain.ts +9 -0
  70. package/src/Limits.ts +69 -29
  71. package/src/Policy.ts +143 -21
  72. package/src/internal/analysis.ts +154 -124
  73. package/src/internal/authorizer.ts +29 -14
  74. package/src/internal/bind.ts +193 -136
  75. package/src/internal/catalog.ts +320 -118
  76. package/src/internal/decide.ts +61 -50
  77. package/src/internal/domain.ts +39 -3
  78. package/src/internal/json.ts +212 -117
  79. package/src/internal/limits.ts +101 -31
  80. package/src/internal/nodes.ts +65 -47
  81. package/src/internal/patterns.ts +79 -25
  82. package/src/internal/policy-json.ts +266 -197
  83. package/src/internal/policy-nodes.ts +31 -23
  84. package/src/internal/policy.ts +63 -23
  85. package/src/internal/rule.ts +16 -3
  86. package/src/internal/search.ts +186 -136
  87. package/src/internal/trampoline.ts +51 -4
package/dist/Limits.js CHANGED
@@ -1,12 +1,17 @@
1
1
  import { __exportAll } from "./_virtual/_rolldown/runtime.js";
2
- import { LimitExceeded as LimitExceeded$1, catalogFields as catalogFields$1, conditionNodes as conditionNodes$1, jsonNodes as jsonNodes$1, policyNodes as policyNodes$1, residualNodes as residualNodes$1, searchSteps as searchSteps$1 } from "./internal/limits.js";
2
+ import { LimitExceeded as LimitExceeded$1, catalogFields as catalogFields$1, ceilings as ceilings$1, conditionNodes as conditionNodes$1, defaults as defaults$1, fieldPathParts as fieldPathParts$1, jsonNodes as jsonNodes$1, patternParts as patternParts$1, policyNodes as policyNodes$1, residualNodes as residualNodes$1, searchFields as searchFields$1, searchSteps as searchSteps$1 } from "./internal/limits.js";
3
3
  // src/Limits.ts
4
4
  /**
5
- * The limits of the library. Each one keeps a walk, a decoder or a search
6
- * small, so no input can fill the stack or take a very long time. An input
5
+ * The limits of the library. Each one keeps a decoder, a walk or a search
6
+ * small, so no input can take a very long time or very much memory. An input
7
7
  * past a limit is an error, with one form of message, as in "A condition has
8
- * 100001 nodes. The most is 100000.". In an `Authorizer`, such an error is
9
- * never a "yes".
8
+ * 1000001 nodes and values. The most is 1000000.". In an `Authorizer`, such
9
+ * an error is never a "yes".
10
+ *
11
+ * The constants here are the defaults. A domain may set its own limits, up
12
+ * to the {@link ceilings}: see `Domain.make`. A walk does not fill the stack
13
+ * at any depth, and the levels of an input are at most its nodes, so there is
14
+ * no limit of levels.
10
15
  *
11
16
  * @stability stable
12
17
  * @since 2.0.0
@@ -14,8 +19,10 @@ import { LimitExceeded as LimitExceeded$1, catalogFields as catalogFields$1, con
14
19
  var Limits_exports = /* @__PURE__ */ __exportAll({
15
20
  LimitExceeded: () => LimitExceeded,
16
21
  catalogFields: () => catalogFields,
22
+ ceilings: () => ceilings,
17
23
  conditionDepth: () => conditionDepth,
18
24
  conditionNodes: () => conditionNodes,
25
+ defaults: () => defaults,
19
26
  fieldPathParts: () => fieldPathParts,
20
27
  jsonNodes: () => jsonNodes,
21
28
  patternParts: () => patternParts,
@@ -26,14 +33,30 @@ var Limits_exports = /* @__PURE__ */ __exportAll({
26
33
  searchSteps: () => searchSteps
27
34
  });
28
35
  /**
29
- * The most parts of a field path, as in `settings.model`. The types of the
30
- * field paths go to the same depth.
36
+ * The limits of a domain that sets none.
37
+ *
38
+ * @stability stable
39
+ * @category constants
40
+ * @since 2.1.0
41
+ */
42
+ const defaults = defaults$1;
43
+ /**
44
+ * The most that a domain may set for each limit.
45
+ *
46
+ * @stability stable
47
+ * @category constants
48
+ * @since 2.1.0
49
+ */
50
+ const ceilings = ceilings$1;
51
+ /**
52
+ * The most parts of a field path, as in `settings.model`, by default. The
53
+ * types check a path that you write up to about 1000 parts.
31
54
  *
32
55
  * @stability stable
33
56
  * @category constants
34
57
  * @since 2.0.0
35
58
  */
36
- const fieldPathParts = 5;
59
+ const fieldPathParts = fieldPathParts$1;
37
60
  /**
38
61
  * The most parts of a field pattern, as in `**.secret`.
39
62
  *
@@ -41,10 +64,10 @@ const fieldPathParts = 5;
41
64
  * @category constants
42
65
  * @since 2.0.0
43
66
  */
44
- const patternParts = 16;
67
+ const patternParts = patternParts$1;
45
68
  /**
46
- * The most nodes of one condition. A part that a condition uses in many
47
- * places counts for each place.
69
+ * The most nodes of one condition, with each value of an `In` or `Under`
70
+ * test. A part that a condition uses in many places counts for each place.
48
71
  *
49
72
  * @stability stable
50
73
  * @category constants
@@ -52,13 +75,16 @@ const patternParts = 16;
52
75
  */
53
76
  const conditionNodes = conditionNodes$1;
54
77
  /**
55
- * The most levels of one condition.
78
+ * There is no limit of the levels of a condition: a walk does not fill the
79
+ * stack, and the levels are at most the nodes, which `conditionNodes`
80
+ * limits.
56
81
  *
57
- * @stability stable
82
+ * @deprecated Since 2.1.0, there is no such limit. The value is `Infinity`.
83
+ * @stability deprecated
58
84
  * @category constants
59
85
  * @since 2.0.0
60
86
  */
61
- const conditionDepth = 500;
87
+ const conditionDepth = Number.POSITIVE_INFINITY;
62
88
  /**
63
89
  * The most nodes of one residual condition.
64
90
  *
@@ -68,16 +94,19 @@ const conditionDepth = 500;
68
94
  */
69
95
  const residualNodes = residualNodes$1;
70
96
  /**
71
- * The most levels of a policy tree.
97
+ * There is no limit of the levels of a policy tree: a walk does not fill the
98
+ * stack, and the levels are at most the nodes, which `policyNodes` limits.
72
99
  *
73
- * @stability stable
100
+ * @deprecated Since 2.1.0, there is no such limit. The value is `Infinity`.
101
+ * @stability deprecated
74
102
  * @category constants
75
103
  * @since 2.0.0
76
104
  */
77
- const policyDepth = 256;
105
+ const policyDepth = Number.POSITIVE_INFINITY;
78
106
  /**
79
- * The most nodes of a policy tree, with its rules and the nodes of their
80
- * conditions. A part that the tree uses in many places counts for each place.
107
+ * The most nodes of a policy tree, with its rules and the nodes and values
108
+ * of their conditions. A part that the tree uses in many places counts for
109
+ * each place.
81
110
  *
82
111
  * @stability stable
83
112
  * @category constants
@@ -94,7 +123,8 @@ const policyNodes = policyNodes$1;
94
123
  */
95
124
  const jsonNodes = jsonNodes$1;
96
125
  /**
97
- * The most fields in the catalog of one Schema.
126
+ * The most fields in the list of the fields of one Schema, as
127
+ * `Policy.permittedFields` reads it.
98
128
  *
99
129
  * @stability stable
100
130
  * @category constants
@@ -120,7 +150,7 @@ const searchSteps = searchSteps$1;
120
150
  * @category constants
121
151
  * @since 2.0.0
122
152
  */
123
- const searchFields = 256;
153
+ const searchFields = searchFields$1;
124
154
  /**
125
155
  * The error when an input goes past a limit.
126
156
  *
@@ -129,6 +159,6 @@ const searchFields = 256;
129
159
  * @since 2.0.0
130
160
  */
131
161
  const LimitExceeded = LimitExceeded$1;
132
- export { LimitExceeded, Limits_exports, catalogFields, conditionDepth, conditionNodes, fieldPathParts, jsonNodes, patternParts, policyDepth, policyNodes, residualNodes, searchFields, searchSteps };
162
+ export { LimitExceeded, Limits_exports, catalogFields, ceilings, conditionDepth, conditionNodes, defaults, fieldPathParts, jsonNodes, patternParts, policyDepth, policyNodes, residualNodes, searchFields, searchSteps };
133
163
 
134
164
  //# sourceMappingURL=Limits.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Limits.js","names":["Limits.conditionNodes","Limits.residualNodes","Limits.policyNodes","Limits.jsonNodes","Limits.catalogFields","Limits.searchSteps","Limits.LimitExceeded"],"sources":["../src/Limits.ts"],"sourcesContent":["/**\n * The limits of the library. Each one keeps a walk, a decoder or a search\n * small, so no input can fill the stack or take a very long time. An input\n * past a limit is an error, with one form of message, as in \"A condition has\n * 100001 nodes. The most is 100000.\". In an `Authorizer`, such an error is\n * never a \"yes\".\n *\n * @stability stable\n * @since 2.0.0\n */\nimport * as Limits from \"./internal/limits.ts\"\n\n/**\n * The most parts of a field path, as in `settings.model`. The types of the\n * field paths go to the same depth.\n *\n * @stability stable\n * @category constants\n * @since 2.0.0\n */\nexport const fieldPathParts: number = Limits.fieldPathParts\n\n/**\n * The most parts of a field pattern, as in `**.secret`.\n *\n * @stability stable\n * @category constants\n * @since 2.0.0\n */\nexport const patternParts: number = Limits.patternParts\n\n/**\n * The most nodes of one condition. A part that a condition uses in many\n * places counts for each place.\n *\n * @stability stable\n * @category constants\n * @since 2.0.0\n */\nexport const conditionNodes: number = Limits.conditionNodes\n\n/**\n * The most levels of one condition.\n *\n * @stability stable\n * @category constants\n * @since 2.0.0\n */\nexport const conditionDepth: number = Limits.conditionDepth\n\n/**\n * The most nodes of one residual condition.\n *\n * @stability stable\n * @category constants\n * @since 2.0.0\n */\nexport const residualNodes: number = Limits.residualNodes\n\n/**\n * The most levels of a policy tree.\n *\n * @stability stable\n * @category constants\n * @since 2.0.0\n */\nexport const policyDepth: number = Limits.policyDepth\n\n/**\n * The most nodes of a policy tree, with its rules and the nodes of their\n * conditions. A part that the tree uses in many places counts for each place.\n *\n * @stability stable\n * @category constants\n * @since 2.0.0\n */\nexport const policyNodes: number = Limits.policyNodes\n\n/**\n * The most objects and arrays in one input to the Schema of a policy or of a\n * condition.\n *\n * @stability stable\n * @category constants\n * @since 2.0.0\n */\nexport const jsonNodes: number = Limits.jsonNodes\n\n/**\n * The most fields in the catalog of one Schema.\n *\n * @stability stable\n * @category constants\n * @since 2.0.0\n */\nexport const catalogFields: number = Limits.catalogFields\n\n/**\n * The most steps of one search for a value, as in `Policy.coverage`. Past\n * it, the answer is `Unknown`. It is also the most steps of the checks of\n * the field patterns of one policy on every kind of their rules. Past it, the\n * policy does not load.\n *\n * @stability stable\n * @category constants\n * @since 2.0.0\n */\nexport const searchSteps: number = Limits.searchSteps\n\n/**\n * The most fields that one search for a value may test. Past it, the answer\n * is `Unknown`.\n *\n * @stability stable\n * @category constants\n * @since 2.0.0\n */\nexport const searchFields: number = Limits.searchFields\n\n/**\n * The error when an input goes past a limit.\n *\n * @stability stable\n * @category errors\n * @since 2.0.0\n */\nexport const LimitExceeded: typeof Limits.LimitExceeded = Limits.LimitExceeded\n\n/**\n * @stability stable\n * @category errors\n * @since 2.0.0\n */\nexport type LimitExceeded = Limits.LimitExceeded\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoBA,MAAa,iBAAyB;;;;;;;;AAStC,MAAa,eAAuB;;;;;;;;;AAUpC,MAAa,iBAAyBA;;;;;;;;AAStC,MAAa,iBAAyB;;;;;;;;AAStC,MAAa,gBAAwBC;;;;;;;;AASrC,MAAa,cAAsB;;;;;;;;;AAUnC,MAAa,cAAsBC;;;;;;;;;AAUnC,MAAa,YAAoBC;;;;;;;;AASjC,MAAa,gBAAwBC;;;;;;;;;;;AAYrC,MAAa,cAAsBC;;;;;;;;;AAUnC,MAAa,eAAuB;;;;;;;;AASpC,MAAa,gBAA6CC"}
1
+ {"version":3,"file":"Limits.js","names":["Internal.defaults","Internal.ceilings","Internal.fieldPathParts","Internal.patternParts","Internal.conditionNodes","Internal.residualNodes","Internal.policyNodes","Internal.jsonNodes","Internal.catalogFields","Internal.searchSteps","Internal.searchFields","Internal.LimitExceeded"],"sources":["../src/Limits.ts"],"sourcesContent":["/**\n * The limits of the library. Each one keeps a decoder, a walk or a search\n * small, so no input can take a very long time or very much memory. An input\n * past a limit is an error, with one form of message, as in \"A condition has\n * 1000001 nodes and values. The most is 1000000.\". In an `Authorizer`, such\n * an error is never a \"yes\".\n *\n * The constants here are the defaults. A domain may set its own limits, up\n * to the {@link ceilings}: see `Domain.make`. A walk does not fill the stack\n * at any depth, and the levels of an input are at most its nodes, so there is\n * no limit of levels.\n *\n * @stability stable\n * @since 2.0.0\n */\nimport * as Internal from \"./internal/limits.ts\"\n\n/**\n * The values of all the limits.\n *\n * @stability stable\n * @category models\n * @since 2.1.0\n */\nexport type Limits = Internal.Limits\n\n/**\n * The limits of a domain that sets none.\n *\n * @stability stable\n * @category constants\n * @since 2.1.0\n */\nexport const defaults: Limits = Internal.defaults\n\n/**\n * The most that a domain may set for each limit.\n *\n * @stability stable\n * @category constants\n * @since 2.1.0\n */\nexport const ceilings: Limits = Internal.ceilings\n\n/**\n * The most parts of a field path, as in `settings.model`, by default. The\n * types check a path that you write up to about 1000 parts.\n *\n * @stability stable\n * @category constants\n * @since 2.0.0\n */\nexport const fieldPathParts: number = Internal.fieldPathParts\n\n/**\n * The most parts of a field pattern, as in `**.secret`.\n *\n * @stability stable\n * @category constants\n * @since 2.0.0\n */\nexport const patternParts: number = Internal.patternParts\n\n/**\n * The most nodes of one condition, with each value of an `In` or `Under`\n * test. A part that a condition uses in many places counts for each place.\n *\n * @stability stable\n * @category constants\n * @since 2.0.0\n */\nexport const conditionNodes: number = Internal.conditionNodes\n\n/**\n * There is no limit of the levels of a condition: a walk does not fill the\n * stack, and the levels are at most the nodes, which `conditionNodes`\n * limits.\n *\n * @deprecated Since 2.1.0, there is no such limit. The value is `Infinity`.\n * @stability deprecated\n * @category constants\n * @since 2.0.0\n */\nexport const conditionDepth: number = Number.POSITIVE_INFINITY\n\n/**\n * The most nodes of one residual condition.\n *\n * @stability stable\n * @category constants\n * @since 2.0.0\n */\nexport const residualNodes: number = Internal.residualNodes\n\n/**\n * There is no limit of the levels of a policy tree: a walk does not fill the\n * stack, and the levels are at most the nodes, which `policyNodes` limits.\n *\n * @deprecated Since 2.1.0, there is no such limit. The value is `Infinity`.\n * @stability deprecated\n * @category constants\n * @since 2.0.0\n */\nexport const policyDepth: number = Number.POSITIVE_INFINITY\n\n/**\n * The most nodes of a policy tree, with its rules and the nodes and values\n * of their conditions. A part that the tree uses in many places counts for\n * each place.\n *\n * @stability stable\n * @category constants\n * @since 2.0.0\n */\nexport const policyNodes: number = Internal.policyNodes\n\n/**\n * The most objects and arrays in one input to the Schema of a policy or of a\n * condition.\n *\n * @stability stable\n * @category constants\n * @since 2.0.0\n */\nexport const jsonNodes: number = Internal.jsonNodes\n\n/**\n * The most fields in the list of the fields of one Schema, as\n * `Policy.permittedFields` reads it.\n *\n * @stability stable\n * @category constants\n * @since 2.0.0\n */\nexport const catalogFields: number = Internal.catalogFields\n\n/**\n * The most steps of one search for a value, as in `Policy.coverage`. Past\n * it, the answer is `Unknown`. It is also the most steps of the checks of\n * the field patterns of one policy on every kind of their rules. Past it, the\n * policy does not load.\n *\n * @stability stable\n * @category constants\n * @since 2.0.0\n */\nexport const searchSteps: number = Internal.searchSteps\n\n/**\n * The most fields that one search for a value may test. Past it, the answer\n * is `Unknown`.\n *\n * @stability stable\n * @category constants\n * @since 2.0.0\n */\nexport const searchFields: number = Internal.searchFields\n\n/**\n * The error when an input goes past a limit.\n *\n * @stability stable\n * @category errors\n * @since 2.0.0\n */\nexport const LimitExceeded: typeof Internal.LimitExceeded =\n\tInternal.LimitExceeded\n\n/**\n * @stability stable\n * @category errors\n * @since 2.0.0\n */\nexport type LimitExceeded = Internal.LimitExceeded\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,MAAa,WAAmBA;;;;;;;;AAShC,MAAa,WAAmBC;;;;;;;;;AAUhC,MAAa,iBAAyBC;;;;;;;;AAStC,MAAa,eAAuBC;;;;;;;;;AAUpC,MAAa,iBAAyBC;;;;;;;;;;;AAYtC,MAAa,iBAAyB,OAAO;;;;;;;;AAS7C,MAAa,gBAAwBC;;;;;;;;;;AAWrC,MAAa,cAAsB,OAAO;;;;;;;;;;AAW1C,MAAa,cAAsBC;;;;;;;;;AAUnC,MAAa,YAAoBC;;;;;;;;;AAUjC,MAAa,gBAAwBC;;;;;;;;;;;AAYrC,MAAa,cAAsBC;;;;;;;;;AAUnC,MAAa,eAAuBC;;;;;;;;AASpC,MAAa,gBACZC"}
package/dist/Policy.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Kind } from "./Resource.js";
2
- import { Any as Any$1, Builder as Builder$1, Condition, Encoded, ErrorOf, Example, FieldName, FieldSelector, OpaqueOf as OpaqueOf$1, Provided, Reads, ReadsOf, ServicesOf } from "./Condition.js";
2
+ import { Any as Any$1, Builder as Builder$1, Condition, Encoded, ErrorOf, Example, FieldName, FieldSelector, NamePath, OpaqueOf as OpaqueOf$1, Provided, Reads, ReadsOf, SelectPath, ServicesOf } from "./Condition.js";
3
3
  import { ActionOf, Any as Any$2, AnyAction, AnyValue, CommonAction, DataOf, Kind as Kind$1, Meta, Principal, Resources, ValueOf } from "./Domain.js";
4
4
  import { Rule as Rule$1 } from "./internal/rule.js";
5
5
  import { Algorithm as Algorithm$1, All, Any as Any$3, Ceiling, FirstOf, Node as Node$1, Rules } from "./internal/policy-nodes.js";
@@ -10,7 +10,7 @@ import * as Effect from "effect/Effect";
10
10
  import * as Schema from "effect/Schema";
11
11
  import * as Data from "effect/Data";
12
12
  declare namespace Policy_d_exports {
13
- export { ActionFor, ActionForTargets, Algorithm, AllNode, Any, AnyNode, AnyRequest, AnyRule, Builder, CeilingNode, ConditionFor, Coverage, DataFor, DomainOf, EncodedNode, EncodedRule, Explanation, FieldFor, FieldlessRequest, FieldlessTarget, FirstOfNode, KindOf, KindRequest, KindTarget, Node, OpaqueOf, Options, Policy, PolicyError, Request, ResidualReads, Rule, RuleOptions, RuleShape, RuleTarget, RulesNode, Scope, Step, Target, TargetOf, ValueFor, all, any, builder, ceiling, coverage, decide, decideSync, define, explain, firstOf, permittedFields, provideContext, residual, rule, schema };
13
+ export { ActionFor, ActionForTargets, Algorithm, AllNode, Any, AnyNode, AnyRequest, AnyRule, Builder, CeilingNode, CheckField, ConditionFor, Coverage, DataFor, DeepKindRequest, DeepKindTarget, DeepRequest, DeepTarget, DomainOf, EncodedNode, EncodedRule, Explanation, FieldFor, FieldlessRequest, FieldlessTarget, FieldsFor, FirstOfNode, KindOf, KindRequest, KindTarget, Node, OpaqueOf, Options, Policy, PolicyError, Request, ResidualReads, Rule, RuleOptions, RuleShape, RuleTarget, RulesNode, Scope, Step, Target, TargetOf, ValueFor, all, any, builder, ceiling, coverage, decide, decideSync, define, explain, firstOf, permittedFields, provideContext, residual, rule, schema };
14
14
  }
15
15
  /**
16
16
  * @stability stable
@@ -150,6 +150,58 @@ export type KindTarget<D> = { [K in Kind$1<D>]: {
150
150
  /** A target has a resource value or a kind, never both. */
151
151
  readonly resource?: never;
152
152
  }; }[Kind$1<D>];
153
+ /**
154
+ * A {@link Target} with a field of any length. A function that takes a
155
+ * target checks its field with {@link CheckField}, so a field of up to about
156
+ * 1000 parts is fine, and a field that is not a field of the kind is a type
157
+ * error.
158
+ *
159
+ * @stability stable
160
+ * @category models
161
+ * @since 2.1.0
162
+ */
163
+ export type DeepTarget<D> = { [K in Kind$1<D>]: {
164
+ readonly action: ActionOf<D, K>;
165
+ readonly resource: ValueOf<D, K>;
166
+ readonly field?: string;
167
+ readonly kind?: never;
168
+ }; }[Kind$1<D>];
169
+ /**
170
+ * A {@link KindTarget} with a field of any length. See {@link DeepTarget}.
171
+ *
172
+ * @stability stable
173
+ * @category models
174
+ * @since 2.1.0
175
+ */
176
+ export type DeepKindTarget<D> = { [K in Kind$1<D>]: {
177
+ readonly action: ActionOf<D, K>;
178
+ readonly kind: K;
179
+ readonly field?: string;
180
+ readonly within?: Scope<D, K>;
181
+ readonly resource?: never;
182
+ }; }[Kind$1<D>];
183
+ /** The kind of a target: its `kind`, or the `_tag` of its resource value. */
184
+ type KindOfTarget<T> = T extends {
185
+ readonly kind: infer K extends string;
186
+ } ? K : T extends {
187
+ readonly resource: {
188
+ readonly _tag: infer K extends string;
189
+ };
190
+ } ? K : never;
191
+ /**
192
+ * Checks the field of a target or a request: a field of its kind that a
193
+ * request may name, of any length up to about 1000 parts. See
194
+ * `Condition.SelectPath`. A target with no field needs no check.
195
+ *
196
+ * @stability stable
197
+ * @category utility types
198
+ * @since 2.1.0
199
+ */
200
+ export type CheckField<D, T> = T extends {
201
+ readonly field?: infer F;
202
+ } ? [Exclude<F, undefined>] extends [never] ? unknown : {
203
+ readonly field?: SelectPath<DataOf<D, KindOfTarget<T>>, Exclude<F, undefined> & string>;
204
+ } : unknown;
153
205
  /**
154
206
  * A request: a principal, an action, and a resource value.
155
207
  *
@@ -160,6 +212,16 @@ export type KindTarget<D> = { [K in Kind$1<D>]: {
160
212
  export type Request<D> = Target<D> & {
161
213
  readonly principal: Principal<D>;
162
214
  };
215
+ /**
216
+ * A {@link Request} with a field of any length. See {@link DeepTarget}.
217
+ *
218
+ * @stability stable
219
+ * @category models
220
+ * @since 2.1.0
221
+ */
222
+ export type DeepRequest<D> = DeepTarget<D> & {
223
+ readonly principal: Principal<D>;
224
+ };
163
225
  /**
164
226
  * A {@link Request} with no field.
165
227
  *
@@ -180,6 +242,16 @@ export type FieldlessRequest<D> = FieldlessTarget<D> & {
180
242
  export type KindRequest<D> = KindTarget<D> & {
181
243
  readonly principal: Principal<D>;
182
244
  };
245
+ /**
246
+ * A {@link KindRequest} with a field of any length. See {@link DeepTarget}.
247
+ *
248
+ * @stability stable
249
+ * @category models
250
+ * @since 2.1.0
251
+ */
252
+ export type DeepKindRequest<D> = DeepKindTarget<D> & {
253
+ readonly principal: Principal<D>;
254
+ };
183
255
  /**
184
256
  * A request with no types.
185
257
  *
@@ -341,16 +413,27 @@ export type FieldFor<D, K> = FieldName<DataFor<D, K>> | `${string}*${string}`;
341
413
  */
342
414
  export type ConditionFor<D, K> = Condition<Reads<ValueFor<D, K>, Principal<D>>, any>;
343
415
  /**
344
- * The options of a rule.
416
+ * Checks each field of a rule: a field pattern with a star, or a name of the
417
+ * kinds `K`, of any length up to about 1000 parts. A name that is not a field
418
+ * gives the names that may come next, so the type error names them. See
419
+ * `Condition.NamePath`.
420
+ *
421
+ * @stability stable
422
+ * @category utility types
423
+ * @since 2.1.0
424
+ */
425
+ export type FieldsFor<D, K, Fields extends ReadonlyArray<string>> = { readonly [I in keyof Fields]: Fields[I] extends `${string}*${string}` ? Fields[I] : NamePath<DataFor<D, K>, Fields[I] & string>; };
426
+ /**
427
+ * The options of a rule. `Fields` is the list of the fields of the rule.
345
428
  *
346
429
  * @stability stable
347
430
  * @category models
348
431
  * @since 0.3.0
349
432
  */
350
- export interface RuleOptions<D, K, C extends Any$1> {
433
+ export interface RuleOptions<D, K, C extends Any$1, Fields extends ReadonlyArray<string> = ReadonlyArray<FieldFor<D, K>>> {
351
434
  /** The condition. It gets a builder with the types of the resource. */
352
435
  readonly when?: (builder: Builder$1<DataFor<D, K>, ValueFor<D, K>, Principal<D>>) => C;
353
- readonly fields?: ReadonlyArray<FieldFor<D, K>>;
436
+ readonly fields?: Fields & FieldsFor<D, K, Fields>;
354
437
  readonly reason?: string;
355
438
  readonly id?: string;
356
439
  readonly meta?: Meta<D>;
@@ -364,8 +447,8 @@ type SingleOrArray<A> = A | ReadonlyArray<A>;
364
447
  * @since 0.3.0
365
448
  */
366
449
  export interface Builder<D> {
367
- readonly allow: <const Res extends SingleOrArray<RuleTarget<D>>, const A extends ActionForTargets<D, Res>, const C extends ConditionFor<D, KindOf<TargetOf<Res>>> = Condition>(action: SingleOrArray<A>, resource: Res, options?: RuleOptions<D, KindOf<TargetOf<Res>>, C>) => Rule<D, ReadsOf<C>, OpaqueOf$1<C>>;
368
- readonly deny: <const Res extends SingleOrArray<RuleTarget<D>>, const A extends ActionForTargets<D, Res>, const C extends ConditionFor<D, KindOf<TargetOf<Res>>> = Condition>(action: SingleOrArray<A>, resource: Res, options?: RuleOptions<D, KindOf<TargetOf<Res>>, C>) => Rule<D, ReadsOf<C>, OpaqueOf$1<C>>;
450
+ readonly allow: <const Res extends SingleOrArray<RuleTarget<D>>, const A extends ActionForTargets<D, Res>, const C extends ConditionFor<D, KindOf<TargetOf<Res>>> = Condition, const Fields extends ReadonlyArray<string> = readonly []>(action: SingleOrArray<A>, resource: Res, options?: RuleOptions<D, KindOf<TargetOf<Res>>, C, Fields>) => Rule<D, ReadsOf<C>, OpaqueOf$1<C>>;
451
+ readonly deny: <const Res extends SingleOrArray<RuleTarget<D>>, const A extends ActionForTargets<D, Res>, const C extends ConditionFor<D, KindOf<TargetOf<Res>>> = Condition, const Fields extends ReadonlyArray<string> = readonly []>(action: SingleOrArray<A>, resource: Res, options?: RuleOptions<D, KindOf<TargetOf<Res>>, C, Fields>) => Rule<D, ReadsOf<C>, OpaqueOf$1<C>>;
369
452
  }
370
453
  /**
371
454
  * Makes rules with the types of a domain. `Policy.define` gives one to its
@@ -507,7 +590,7 @@ export declare const provideContext: {
507
590
  * @category evaluation
508
591
  * @since 0.3.0
509
592
  */
510
- export declare const decide: <D extends Any$2, X>(policy: Policy<D, X>, request: Request<NoInfer<D>>) => Effect.Effect<Decision, ErrorOf<X>, ServicesOf<X>>;
593
+ export declare const decide: <D extends Any$2, X, const Req extends DeepRequest<NoInfer<D>>>(policy: Policy<D, X>, request: Req & CheckField<NoInfer<D>, Req>) => Effect.Effect<Decision, ErrorOf<X>, ServicesOf<X>>;
511
594
  /**
512
595
  * Gives the decision of a policy with no predicates, at once.
513
596
  *
@@ -515,7 +598,7 @@ export declare const decide: <D extends Any$2, X>(policy: Policy<D, X>, request:
515
598
  * @category evaluation
516
599
  * @since 0.3.0
517
600
  */
518
- export declare const decideSync: <D extends Any$2>(policy: Policy<D>, request: Request<NoInfer<D>>) => Decision;
601
+ export declare const decideSync: <D extends Any$2, const Req extends DeepRequest<NoInfer<D>>>(policy: Policy<D>, request: Req & CheckField<NoInfer<D>, Req>) => Decision;
519
602
  /**
520
603
  * Gives the decision of a policy and the rules that were tested to make it.
521
604
  *
@@ -526,7 +609,7 @@ export declare const decideSync: <D extends Any$2>(policy: Policy<D>, request: R
526
609
  * @category evaluation
527
610
  * @since 0.3.0
528
611
  */
529
- export declare const explain: <D extends Any$2, X>(policy: Policy<D, X>, request: Request<NoInfer<D>>) => Effect.Effect<Explanation, ErrorOf<X>, ServicesOf<X>>;
612
+ export declare const explain: <D extends Any$2, X, const Req extends DeepRequest<NoInfer<D>>>(policy: Policy<D, X>, request: Req & CheckField<NoInfer<D>, Req>) => Effect.Effect<Explanation, ErrorOf<X>, ServicesOf<X>>;
530
613
  /**
531
614
  * Gives the fields of a resource value that the policy lets a request use. It
532
615
  * tests each field that a list of fields shows: each scalar, record or array
@@ -573,14 +656,14 @@ export type ResidualReads<D, K> = Reads<(K extends unknown ? (value: ValueOf<D,
573
656
  *
574
657
  * A policy tree may use the condition of a child two times, so a small policy
575
658
  * may give a very large condition. When the condition would have more than
576
- * 10000 nodes, this function throws an error. In an `Authorizer`, the error
577
- * is a defect, so the check fails.
659
+ * the `residualNodes` of the domain, 100000 by default, this function throws
660
+ * an error. In an `Authorizer`, the error is a defect, so the check fails.
578
661
  *
579
662
  * @stability stable
580
663
  * @category evaluation
581
664
  * @since 0.3.0
582
665
  */
583
- export declare const residual: <D extends Any$2, X, const Req extends KindRequest<NoInfer<D>>>(policy: Policy<D, X>, request: Req) => Condition<ResidualReads<D, Req["kind"]>, X>;
666
+ export declare const residual: <D extends Any$2, X, const Req extends DeepKindRequest<NoInfer<D>>>(policy: Policy<D, X>, request: Req & CheckField<NoInfer<D>, Req>) => Condition<ResidualReads<D, Req["kind"]>, X>;
584
667
  /**
585
668
  * How much of a scope a policy allows. In each case, `condition` is the exact
586
669
  * condition on the values in the scope that the policy allows: give it to
@@ -636,7 +719,7 @@ export type Coverage<I = unknown, X = never> = Data.TaggedEnum<{
636
719
  * @category evaluation
637
720
  * @since 1.0.0
638
721
  */
639
- export declare const coverage: <D extends Any$2, X, const Req extends KindRequest<NoInfer<D>>>(policy: Policy<D, X>, request: Req) => Coverage<ResidualReads<D, Req["kind"]>, X>;
722
+ export declare const coverage: <D extends Any$2, X, const Req extends DeepKindRequest<NoInfer<D>>>(policy: Policy<D, X>, request: Req & CheckField<NoInfer<D>, Req>) => Coverage<ResidualReads<D, Req["kind"]>, X>;
640
723
  /**
641
724
  * The JSON form of a rule.
642
725
  *
@@ -678,10 +761,11 @@ export type EncodedNode = {
678
761
  * every kind, action, field and principal field against the domain, and the
679
762
  * `meta` of each rule against the `meta` Schema of the domain.
680
763
  *
681
- * The decoder takes at most 256 levels of policies and 500 levels of
682
- * conditions, and at most 1000000 objects and array items, with a shared
683
- * object counted for each place. It reads only the own data fields of the
684
- * input.
764
+ * The decoder takes the limits of the domain: at most `policyNodes` nodes
765
+ * of the tree, `conditionNodes` nodes of each condition, and `jsonNodes`
766
+ * objects and array items, with a shared object counted for each place. It
767
+ * stops at the first one past a limit. It takes any number of levels, and it
768
+ * reads only the own data fields of the input.
685
769
  *
686
770
  * @stability stable
687
771
  * @category schemas
@@ -1 +1 @@
1
- {"version":3,"file":"Policy.d.ts","names":["PolicyNodes.Algorithm","PolicyNodes.Rules","PolicyNodes.All","PolicyNodes.Any","PolicyNodes.FirstOf","PolicyNodes.Ceiling","PolicyNodes.Node","Domain.Any","Internal.PolicyData","Domain.Kind","Domain.ActionOf","Domain.ValueOf","Domain.DataOf","Condition.FieldSelector","Domain.Principal","Condition.Builder","Condition.Reads","Condition.Condition","Decision.Decision","RuleData.Rule","Domain.Resources","Resource.Kind","Domain.AnyAction","Domain.CommonAction","Domain.AnyValue","Condition.FieldName","Condition.Any","Domain.Meta","Condition.ReadsOf","Condition.OpaqueOf","Internal.PolicyError","Condition.ServicesOf","Condition.Provided","Condition.ErrorOf","Condition.Example","Condition.Encoded"],"sources":["../src/Policy.ts"],"mappings":"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"}
1
+ {"version":3,"file":"Policy.d.ts","names":["PolicyNodes.Algorithm","PolicyNodes.Rules","PolicyNodes.All","PolicyNodes.Any","PolicyNodes.FirstOf","PolicyNodes.Ceiling","PolicyNodes.Node","Domain.Any","Internal.PolicyData","Domain.Kind","Domain.ActionOf","Domain.ValueOf","Domain.DataOf","Condition.FieldSelector","Domain.Principal","Condition.Builder","Condition.Reads","Condition.Condition","Condition.SelectPath","Decision.Decision","RuleData.Rule","Domain.Resources","Resource.Kind","Domain.AnyAction","Domain.CommonAction","Domain.AnyValue","Condition.FieldName","Condition.NamePath","Condition.Any","Domain.Meta","Condition.ReadsOf","Condition.OpaqueOf","Internal.PolicyError","Condition.ServicesOf","Condition.Provided","Condition.ErrorOf","Condition.Example","Condition.Encoded"],"sources":["../src/Policy.ts"],"mappings":"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"}
package/dist/Policy.js CHANGED
@@ -189,8 +189,8 @@ const permittedFields = permittedFields$1;
189
189
  *
190
190
  * A policy tree may use the condition of a child two times, so a small policy
191
191
  * may give a very large condition. When the condition would have more than
192
- * 10000 nodes, this function throws an error. In an `Authorizer`, the error
193
- * is a defect, so the check fails.
192
+ * the `residualNodes` of the domain, 100000 by default, this function throws
193
+ * an error. In an `Authorizer`, the error is a defect, so the check fails.
194
194
  *
195
195
  * @stability stable
196
196
  * @category evaluation
@@ -222,10 +222,11 @@ const coverage = coverageAny;
222
222
  * every kind, action, field and principal field against the domain, and the
223
223
  * `meta` of each rule against the `meta` Schema of the domain.
224
224
  *
225
- * The decoder takes at most 256 levels of policies and 500 levels of
226
- * conditions, and at most 1000000 objects and array items, with a shared
227
- * object counted for each place. It reads only the own data fields of the
228
- * input.
225
+ * The decoder takes the limits of the domain: at most `policyNodes` nodes
226
+ * of the tree, `conditionNodes` nodes of each condition, and `jsonNodes`
227
+ * objects and array items, with a shared object counted for each place. It
228
+ * stops at the first one past a limit. It takes any number of levels, and it
229
+ * reads only the own data fields of the input.
229
230
  *
230
231
  * @stability stable
231
232
  * @category schemas
@@ -1 +1 @@
1
- {"version":3,"file":"Policy.js","names":["RuleData.builder","RuleData.makePlain","Internal.PolicyError","Internal.define","Internal.combine","Internal.ceiling","Internal.provideContext","Decide.decideAny","Decide.decideSync","Decide.explain","Decide.permittedFields","Analysis.residual","Analysis.coverageAny","Internal.schema"],"sources":["../src/Policy.ts"],"sourcesContent":["/**\n * A policy is a tree that gives a {@link Decision.Decision} for a request.\n *\n * The leaves of the tree are lists of rules. A combining algorithm decides\n * which rule gives the answer when more than one rule applies:\n * - `denyOverrides` (the default): a deny rule wins over every allow rule.\n * - `permitOverrides`: an allow rule wins over every deny rule.\n * - `firstApplicable`: the first rule that applies wins.\n * - `lastApplicable`: the last rule that applies wins.\n *\n * The branches put policies together:\n * - {@link all}: every policy must allow, and one deny is enough to deny. Use\n * it when a user token may never do more than its user.\n * - {@link any}: one allow is enough.\n * - {@link firstOf}: the first policy that gives an answer wins. Use it for\n * grants first, then rules.\n * - {@link ceiling}: the deny rules of a second policy are a limit for\n * everyone. Its allow rules do nothing.\n *\n * A policy gives three kinds of answers:\n * - {@link decide}: the decision for one resource value.\n * - {@link residual}: a condition on resource values. A value passes when the\n * policy allows the request for that value. Use it to make a database\n * query, or to ask \"may this principal do this act on some resource of\n * this kind?\"\n * - {@link permittedFields}: the fields that the policy lets a request use.\n *\n * Each of them takes the policy first and the request second, as in\n * `Policy.decide(policy, request)`. The policy gives the domain, so\n * TypeScript checks the request against it.\n *\n * A policy without predicates can become JSON with {@link schema}.\n *\n * @stability stable\n * @since 0.3.0\n */\nimport type * as Context from \"effect/Context\"\nimport type * as Data from \"effect/Data\"\nimport type * as Effect from \"effect/Effect\"\nimport type * as Schema from \"effect/Schema\"\nimport type * as Condition from \"./Condition.ts\"\nimport * as Analysis from \"./internal/analysis.ts\"\nimport * as Decide from \"./internal/decide.ts\"\nimport * as Internal from \"./internal/policy.ts\"\nimport type * as PolicyNodes from \"./internal/policy-nodes.ts\"\nimport * as RuleData from \"./internal/rule.ts\"\nimport type * as Decision from \"./Decision.ts\"\nimport type * as Domain from \"./Domain.ts\"\nimport type * as Resource from \"./Resource.ts\"\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Algorithm = PolicyNodes.Algorithm\n\n/**\n * A list of rules with a combining algorithm.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type RulesNode = PolicyNodes.Rules\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type AllNode = PolicyNodes.All\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type AnyNode = PolicyNodes.Any\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type FirstOfNode = PolicyNodes.FirstOf\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type CeilingNode = PolicyNodes.Ceiling\n\n/**\n * The nodes of a policy tree, without types. Each node is a class, and only\n * the functions of this module and the Schema make one.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Node = PolicyNodes.Node\n\n/**\n * A policy for the domain `D`. `X` is `Condition.Opaque` when a rule of the\n * policy has a predicate, and `never` when the policy is plain data. A plain\n * policy can become JSON, and `decideSync` takes it.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Policy<D extends Domain.Any, X = never> = Internal.PolicyData<D, X>\n\n/**\n * Any policy.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Any = Policy<any, any>\n\n/**\n * The domain of a policy.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type DomainOf<P> = P extends Policy<infer D, any> ? D : never\n\n/**\n * The mark of a policy or a rule: `Condition.Opaque` when it has a predicate.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type OpaqueOf<P> = P extends { readonly \"~Opaque\": () => infer X }\n\t? X\n\t: never\n\n/**\n * One act on one resource value, for each kind of the domain. The action must\n * be an action of the kind, and the field must be a field of the kind.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Target<D> = {\n\t[K in Domain.Kind<D>]: {\n\t\treadonly action: Domain.ActionOf<D, K>\n\t\treadonly resource: Domain.ValueOf<D, K>\n\t\treadonly field?: Condition.FieldSelector<Domain.DataOf<D, K>>\n\t\t/** A target has a resource value or a kind, never both. */\n\t\treadonly kind?: never\n\t}\n}[Domain.Kind<D>]\n\n/**\n * A {@link Target} with no field. Each kind keeps its own actions.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type FieldlessTarget<D> = {\n\t[K in Domain.Kind<D>]: {\n\t\treadonly action: Domain.ActionOf<D, K>\n\t\treadonly resource: Domain.ValueOf<D, K>\n\t\treadonly kind?: never\n\t}\n}[Domain.Kind<D>]\n\n/**\n * A scope: a part of a kind, as a condition on its values. It gets a builder\n * with the types of the kind and of the principal, like the condition of a\n * rule. A scope is plain data, so it can not have a predicate.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport type Scope<D, K extends string> = (\n\tbuilder: Condition.Builder<\n\t\tDomain.DataOf<D, K>,\n\t\tDomain.ValueOf<D, K>,\n\t\tDomain.Principal<D>\n\t>,\n) => Condition.Condition<\n\tCondition.Reads<Domain.ValueOf<D, K>, Domain.Principal<D>>\n>\n\n/**\n * One act on one kind of resource, with no value. With `within`, the target is\n * only the values of the kind in the scope. Without it, the target is every\n * value of the kind.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type KindTarget<D> = {\n\t[K in Domain.Kind<D>]: {\n\t\treadonly action: Domain.ActionOf<D, K>\n\t\treadonly kind: K\n\t\treadonly field?: Condition.FieldSelector<Domain.DataOf<D, K>>\n\t\t/** The part of the kind. See {@link Scope}. */\n\t\treadonly within?: Scope<D, K>\n\t\t/** A target has a resource value or a kind, never both. */\n\t\treadonly resource?: never\n\t}\n}[Domain.Kind<D>]\n\n/**\n * A request: a principal, an action, and a resource value.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Request<D> = Target<D> & { readonly principal: Domain.Principal<D> }\n\n/**\n * A {@link Request} with no field.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type FieldlessRequest<D> = FieldlessTarget<D> & {\n\treadonly principal: Domain.Principal<D>\n}\n\n/**\n * A request about a kind of resource, with no value.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type KindRequest<D> = KindTarget<D> & {\n\treadonly principal: Domain.Principal<D>\n}\n\n/**\n * A request with no types.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface AnyRequest {\n\treadonly principal: object\n\treadonly action: string\n\treadonly resource: object\n\treadonly field?: string | undefined\n}\n\n/**\n * One rule that a decision tested. `path` gives the place of the rule in the\n * policy tree: the index of each child, then the index of the rule.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Step {\n\treadonly path: ReadonlyArray<number>\n\treadonly rule: AnyRule\n\treadonly applies: boolean\n}\n\n/**\n * A decision, and the rules that were tested to make it, in order. Keep it in\n * an audit log.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Explanation {\n\treadonly decision: Decision.Decision\n\treadonly steps: ReadonlyArray<Step>\n}\n\n// Rules\n\n/**\n * A rule for the domain `D`. `I` is what the tests of its condition read, and\n * `X` is its mark: see `Condition.Condition`. A predicate reads the values and\n * the principal of its domain, so a rule may go only into a policy of its own\n * domain. A rule from {@link rule} has the domain `any`.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Rule<D = any, I = unknown, X = never> = RuleData.Rule<D, I, X>\n\n/**\n * The data of a rule.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport interface RuleShape<I = unknown, X = never> {\n\treadonly _tag: \"Allow\" | \"Deny\"\n\treadonly actions: ReadonlyArray<string>\n\treadonly resources: ReadonlyArray<string>\n\treadonly when?: Condition.Condition<I, X>\n\treadonly fields?: ReadonlyArray<string>\n\treadonly reason?: string\n\treadonly id?: string\n\treadonly meta?: unknown\n\t/**\n\t * The domain of the builder that made the rule. Two domains may have the\n\t * same types but other paths, so the types can not tell them apart. It is\n\t * not in the JSON form of a rule.\n\t */\n\treadonly domain?: Domain.Any\n}\n\n/**\n * Any rule.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\n// Every rule fits `never` as what it reads, and a condition taken from such a\n// rule fits no rule that reads a value or a principal.\nexport type AnyRule = Rule<any, never, any>\n\n/**\n * A resource in a rule: a kind name, a resource of the domain, or `\"*\"`.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type RuleTarget<D> = Domain.Kind<D> | Domain.Resources<D> | \"*\"\n\n/**\n * The kind name of a target.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type KindOf<T> = T extends string ? T : Resource.Kind<T>\n\n/**\n * The actions that a rule may use for the kinds `K`.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type ActionFor<D, K> =\n\t| \"*\"\n\t| (\"*\" extends K\n\t\t\t? Domain.AnyAction<D>\n\t\t\t: Domain.ActionOf<D, Extract<K, string>>)\n\n/**\n * The targets in the resource argument of a rule: the one target, or the\n * targets of a list.\n *\n * @stability stable\n * @category utility types\n * @since 1.0.0\n */\nexport type TargetOf<Res> = Res extends ReadonlyArray<infer X> ? X : Res\n\n/**\n * The actions that a rule may use for its resource argument. A list of\n * resources may use an action of any of them. One target with a union type\n * may use only an action of every kind in the union, because its value may be\n * any one of them. When the argument may be a list or one target, the rule\n * may use only an action that each of these shapes allows.\n *\n * @stability stable\n * @category utility types\n * @since 1.0.0\n */\nexport type ActionForTargets<D, Res> = (\n\tRes extends ReadonlyArray<infer X>\n\t\t? (action: ActionFor<D, KindOf<X>>) => void\n\t\t: (action: ActionForTarget<D, Res>) => void\n) extends (action: infer A) => void\n\t? A\n\t: never\n\n/** The actions for one target that is not a list. */\ntype ActionForTarget<D, Res> =\n\t| \"*\"\n\t| (\"*\" extends KindOf<Res>\n\t\t\t? Domain.AnyAction<D>\n\t\t\t: Domain.CommonAction<D, Extract<KindOf<Res>, string>>)\n\n/**\n * The data type of the kinds `K`. For `\"*\"` it has no fields.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type DataFor<D, K> = \"*\" extends K\n\t? {}\n\t: Domain.DataOf<D, Extract<K, string>>\n\n/**\n * The value type of the kinds `K`.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type ValueFor<D, K> = \"*\" extends K\n\t? Domain.AnyValue<D>\n\t: Domain.ValueOf<D, Extract<K, string>>\n\n/**\n * A field name or a field pattern of the kinds `K`.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type FieldFor<D, K> =\n\tCondition.FieldName<DataFor<D, K>> | `${string}*${string}`\n\n/**\n * A condition that a rule for the kinds `K` may have. Its predicates may read\n * only the values of these kinds and the principal of the domain.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport type ConditionFor<D, K> = Condition.Condition<\n\tCondition.Reads<ValueFor<D, K>, Domain.Principal<D>>,\n\tany\n>\n\n/**\n * The options of a rule.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface RuleOptions<D, K, C extends Condition.Any> {\n\t/** The condition. It gets a builder with the types of the resource. */\n\treadonly when?: (\n\t\tbuilder: Condition.Builder<\n\t\t\tDataFor<D, K>,\n\t\t\tValueFor<D, K>,\n\t\t\tDomain.Principal<D>\n\t\t>,\n\t) => C\n\treadonly fields?: ReadonlyArray<FieldFor<D, K>>\n\treadonly reason?: string\n\treadonly id?: string\n\treadonly meta?: Domain.Meta<D>\n}\n\ntype SingleOrArray<A> = A | ReadonlyArray<A>\n\n/**\n * Makes rules with the types of a domain.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Builder<D> {\n\treadonly allow: <\n\t\tconst Res extends SingleOrArray<RuleTarget<D>>,\n\t\tconst A extends ActionForTargets<D, Res>,\n\t\tconst C extends ConditionFor<D, KindOf<TargetOf<Res>>> =\n\t\t\tCondition.Condition,\n\t>(\n\t\taction: SingleOrArray<A>,\n\t\tresource: Res,\n\t\toptions?: RuleOptions<D, KindOf<TargetOf<Res>>, C>,\n\t) => Rule<D, Condition.ReadsOf<C>, Condition.OpaqueOf<C>>\n\treadonly deny: <\n\t\tconst Res extends SingleOrArray<RuleTarget<D>>,\n\t\tconst A extends ActionForTargets<D, Res>,\n\t\tconst C extends ConditionFor<D, KindOf<TargetOf<Res>>> =\n\t\t\tCondition.Condition,\n\t>(\n\t\taction: SingleOrArray<A>,\n\t\tresource: Res,\n\t\toptions?: RuleOptions<D, KindOf<TargetOf<Res>>, C>,\n\t) => Rule<D, Condition.ReadsOf<C>, Condition.OpaqueOf<C>>\n}\n\n/**\n * Makes rules with the types of a domain. `Policy.define` gives one to its\n * generator. Use this one to make rules outside of a generator.\n *\n * @example\n * ```ts\n * const _ = Policy.builder(App)\n * const rule = _.allow(\"read\", Document, {\n * when: ($) => $.eq(\"ownerId\", $.principal(\"id\")),\n * })\n * ```\n *\n * @stability stable\n * @category constructors\n * @since 2.0.0\n */\nexport const builder = <D extends Domain.Any>(domain: D): Builder<D> =>\n\tRuleData.builder(domain) as never\n\n/**\n * Makes a rule from its data, with no types. It does not check the data\n * against a domain: a policy does that when the rule goes into it. Use\n * {@link builder} for rules with types, or {@link schema} for rules from JSON.\n *\n * The condition may not have a predicate. A policy checks the fields of a\n * condition against the resources of its rule, but it can not check what\n * the code of a predicate reads. A rule from the builder keeps that in its\n * types; this one could give a predicate of one kind to another kind.\n *\n * @stability stable\n * @category constructors\n * @since 2.0.0\n */\nexport const rule: <I = unknown>(\n\tdata: RuleShape<I, never>,\n\t// The types come from the data only, not from where the rule goes.\n) => Rule<any, NoInfer<I>> = RuleData.makePlain as never\n\n/**\n * The options of a list of rules.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Options {\n\t/** The default is `denyOverrides`. */\n\treadonly algorithm?: Algorithm\n}\n\n/**\n * The error when a rule does not fit its domain: it names a kind, an action,\n * a field or a field of the principal that the domain does not have, or it\n * tests a field with a value that the field can not hold. It has one issue\n * for each problem, with its path, and a suggestion when a name has a mistake.\n *\n * @stability stable\n * @category errors\n * @since 2.0.0\n */\nexport const PolicyError: typeof Internal.PolicyError = Internal.PolicyError\n\n/**\n * @stability stable\n * @category errors\n * @since 2.0.0\n */\nexport type PolicyError = Internal.PolicyError\n\n/** The mark of a union of rules: `Condition.Opaque` when one has a predicate. */\ntype RulesOpaque<Rules> = Rules extends { readonly \"~Opaque\": () => infer X }\n\t? X\n\t: never\n\n/**\n * Makes a policy from a generator function that gives rules. It is pure and it\n * gives its result at once.\n *\n * @example\n * ```ts\n * const policy = Policy.define(App)(function* (_) {\n * yield* _.allow(\"read\", Document)\n * yield* _.allow([\"update\", \"delete\"], Document, {\n * when: ($) => $.eq(\"ownerId\", $.principal(\"id\")),\n * })\n * })\n * ```\n *\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const define: <D extends Domain.Any>(\n\tdomain: D,\n\toptions?: Options,\n) => <Rules extends Rule<D, never, any>, A>(\n\tbody: (builder: Builder<D>) => Generator<Rules, A, unknown>,\n) => Policy<D, RulesOpaque<Rules>> = Internal.define as never\n\ntype Combined<D extends Domain.Any, Ps extends ReadonlyArray<Any>> = Policy<\n\tD,\n\tOpaqueOf<Ps[number]>\n>\n\n/**\n * Every policy must allow, and one deny is enough to deny. With some policies\n * not applicable and none that deny, the result is not applicable.\n *\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const all: <const Ps extends readonly [Any, ...Array<Any>]>(\n\tpolicies: Ps,\n) => Combined<DomainOf<Ps[0]>, Ps> = Internal.combine(\"All\")\n\n/**\n * One allow is enough. Without an allow, one deny gives a deny.\n *\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const any: <const Ps extends readonly [Any, ...Array<Any>]>(\n\tpolicies: Ps,\n) => Combined<DomainOf<Ps[0]>, Ps> = Internal.combine(\"Any\")\n\n/**\n * The first policy that allows or denies gives the answer.\n *\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const firstOf: <const Ps extends readonly [Any, ...Array<Any>]>(\n\tpolicies: Ps,\n) => Combined<DomainOf<Ps[0]>, Ps> = Internal.combine(\"FirstOf\")\n\n/**\n * Puts a limit on a policy. A deny from `cap` always wins. An allow from `cap`\n * does nothing.\n *\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const ceiling: {\n\t<D extends Domain.Any, X2>(\n\t\tcap: Policy<D, X2>,\n\t): <X>(policy: Policy<D, X>) => Policy<D, X | X2>\n\t<D extends Domain.Any, X, X2>(\n\t\tpolicy: Policy<D, X>,\n\t\tcap: Policy<D, X2>,\n\t): Policy<D, X | X2>\n} = Internal.ceiling as never\n\n/**\n * Gives the services in `context` to every predicate of a policy, so the\n * policy needs no services when it runs.\n *\n * @stability stable\n * @category services\n * @since 1.0.0\n */\nexport const provideContext: {\n\t<R>(\n\t\tcontext: Context.Context<R>,\n\t): <D extends Domain.Any, X>(\n\t\tpolicy: Policy<D, X> &\n\t\t\t([Condition.ServicesOf<X>] extends [R] ? unknown : never),\n\t) => Policy<D, Condition.Provided<X>>\n\t<D extends Domain.Any, X>(\n\t\tpolicy: Policy<D, X>,\n\t\tcontext: Context.Context<Condition.ServicesOf<X>>,\n\t): Policy<D, Condition.Provided<X>>\n} = Internal.provideContext as never\n\n// Decisions\n\n/**\n * Gives the decision of a policy for a request.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const decide: <D extends Domain.Any, X>(\n\tpolicy: Policy<D, X>,\n\trequest: Request<NoInfer<D>>,\n) => Effect.Effect<\n\tDecision.Decision,\n\tCondition.ErrorOf<X>,\n\tCondition.ServicesOf<X>\n> = Decide.decideAny as never\n\n/**\n * Gives the decision of a policy with no predicates, at once.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const decideSync: <D extends Domain.Any>(\n\tpolicy: Policy<D>,\n\trequest: Request<NoInfer<D>>,\n) => Decision.Decision = Decide.decideSync\n\n/**\n * Gives the decision of a policy and the rules that were tested to make it.\n *\n * One node may be a child of many nodes. Its rules are tested, and are in the\n * steps, each time that the decision comes to it.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const explain: <D extends Domain.Any, X>(\n\tpolicy: Policy<D, X>,\n\trequest: Request<NoInfer<D>>,\n) => Effect.Effect<Explanation, Condition.ErrorOf<X>, Condition.ServicesOf<X>> =\n\tDecide.explain as never\n\n/**\n * Gives the fields of a resource value that the policy lets a request use. It\n * tests each field that a list of fields shows: each scalar, record or array\n * of the resource Schema, with dots for nested fields.\n *\n * A field that holds more than one value, such as a record, is left out when a\n * deny rule names a part of it. The list can not name that part, and the whole\n * field would show it.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const permittedFields: <D extends Domain.Any, X>(\n\tpolicy: Policy<D, X>,\n\trequest: FieldlessRequest<NoInfer<D>>,\n) => Effect.Effect<\n\tReadonlyArray<string>,\n\tCondition.ErrorOf<X>,\n\tCondition.ServicesOf<X>\n> = Decide.permittedFields as never\n\n// Residual conditions\n\n/**\n * What a residual condition reads: a value of the kind `K`. The principal is\n * already in it. A residual is for one kind, so when `K` is a union of kinds,\n * the value must be a value of each of them. No value is, so such a residual\n * can not be evaluated on a value of the wrong kind.\n *\n * @stability stable\n * @category utility types\n * @since 1.0.0\n */\nexport type ResidualReads<D, K> = Condition.Reads<\n\t(\n\t\tK extends unknown ? (value: Domain.ValueOf<D, K & string>) => void : never\n\t) extends (value: infer V) => void\n\t\t? V\n\t\t: never,\n\tunknown\n>\n\n/**\n * Gives the condition on resource values for which the policy allows a\n * request. It has no principal fields and no `Under` nodes, so you can give it\n * to `Condition.fold`. It is made smaller, so it is often `True` or `False`\n * when the answer does not depend on the value, but it does no search: a\n * condition that is true for every value may stay a test. To know if the\n * policy allows every value, or some value, use {@link coverage}.\n *\n * With a scope (`within`), the condition is the scope and the residual\n * together, so it is false for every value outside the scope. Give the policy\n * first to use a scope. The condition comes from its parts, with no search. To\n * know if it allows all of the scope or none of it, use {@link coverage}.\n *\n * When a rule that the request may use has a predicate, the condition is one\n * predicate with the name `\"policy\"`. It runs the whole policy for each value,\n * so its answers and its failures are the same as those of {@link decide}. It\n * takes the principal with it. Give it resource values with their `_tag`. It\n * is false for a value of another kind.\n *\n * A policy tree may use the condition of a child two times, so a small policy\n * may give a very large condition. When the condition would have more than\n * 10000 nodes, this function throws an error. In an `Authorizer`, the error\n * is a defect, so the check fails.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const residual: <\n\tD extends Domain.Any,\n\tX,\n\tconst Req extends KindRequest<NoInfer<D>>,\n>(\n\tpolicy: Policy<D, X>,\n\trequest: Req,\n) => Condition.Condition<ResidualReads<D, Req[\"kind\"]>, X> =\n\tAnalysis.residual as never\n\n/**\n * How much of a scope a policy allows. In each case, `condition` is the exact\n * condition on the values in the scope that the policy allows: give it to\n * `Condition.fold` for a list query.\n * - `All`: the policy allows every value in the scope. `condition` is the\n * scope (`True` with no scope).\n * - `None`: the policy allows no value in the scope. `condition` is `False`.\n * An empty scope is `None` too, so a check on a scope that has a mistake,\n * such as a principal field with no value, never passes.\n * - `Some`: the policy allows some values in the scope and not others.\n * `allowed` is an example of a value that it allows, and `refused` of a\n * value in the scope that it does not allow.\n * - `Unknown`: the answer needs a predicate, or the search went past its\n * budget.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport type Coverage<I = unknown, X = never> = Data.TaggedEnum<{\n\tAll: { readonly condition: Condition.Condition<I, X> }\n\tNone: { readonly condition: Condition.Condition<I, X> }\n\tSome: {\n\t\treadonly condition: Condition.Condition<I, X>\n\t\treadonly allowed: Condition.Example\n\t\treadonly refused: Condition.Example\n\t}\n\tUnknown: {\n\t\treadonly condition: Condition.Condition<I, X>\n\t\treadonly reason: \"predicate\" | \"budget\"\n\t}\n}>\n\n/**\n * Tells how much of a scope the policy allows: all of it, none of it, or some\n * of it. See {@link Coverage}. With no scope (`within`), the scope is every\n * value of the kind.\n *\n * The answer comes from {@link Condition.satisfiable} with the shape of the\n * Schema of the resource. `All` and `None` hold for every value of the\n * Schema. `Some` means that, by the shape of the Schema, a value may get\n * either answer: a check such as a minimum length may still stop one of the\n * examples. `Unknown` comes only from a predicate or from the budget of the\n * search.\n *\n * `Some` does not mean that such a value is in your database. To know that,\n * run `condition` as a query.\n *\n * @stability stable\n * @category evaluation\n * @since 1.0.0\n */\nexport const coverage: <\n\tD extends Domain.Any,\n\tX,\n\tconst Req extends KindRequest<NoInfer<D>>,\n>(\n\tpolicy: Policy<D, X>,\n\trequest: Req,\n) => Coverage<ResidualReads<D, Req[\"kind\"]>, X> = Analysis.coverageAny as never\n\n// Schema\n\n/**\n * The JSON form of a rule.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface EncodedRule {\n\treadonly _tag: \"Allow\" | \"Deny\"\n\treadonly actions: ReadonlyArray<string>\n\treadonly resources: ReadonlyArray<string>\n\treadonly when?: Condition.Encoded\n\treadonly fields?: ReadonlyArray<string>\n\treadonly reason?: string\n\treadonly id?: string\n\treadonly meta?: unknown\n}\n\n/**\n * The JSON form of a policy.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type EncodedNode =\n\t| {\n\t\t\treadonly _tag: \"Rules\"\n\t\t\treadonly algorithm: Algorithm\n\t\t\treadonly rules: ReadonlyArray<EncodedRule>\n\t }\n\t| {\n\t\t\treadonly _tag: \"All\" | \"Any\" | \"FirstOf\"\n\t\t\treadonly policies: ReadonlyArray<EncodedNode>\n\t }\n\t| {\n\t\t\treadonly _tag: \"Ceiling\"\n\t\t\treadonly cap: EncodedNode\n\t\t\treadonly policy: EncodedNode\n\t }\n\n/**\n * The Schema of the policies of a domain with no predicates. Decoding checks\n * every kind, action, field and principal field against the domain, and the\n * `meta` of each rule against the `meta` Schema of the domain.\n *\n * The decoder takes at most 256 levels of policies and 500 levels of\n * conditions, and at most 1000000 objects and array items, with a shared\n * object counted for each place. It reads only the own data fields of the\n * input.\n *\n * @stability stable\n * @category schemas\n * @since 0.3.0\n */\nexport const schema: <D extends Domain.Any>(\n\tdomain: D,\n) => Schema.Codec<Policy<D>, EncodedNode> = Internal.schema as never\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwgBA,MAAa,WAAiC,WAC7CA,UAAiB,MAAM;;;;;;;;;;;;;;;AAgBxB,MAAa,OAGgBC;;;;;;;;;;;AAwB7B,MAAa,cAA2CC;;;;;;;;;;;;;;;;;;;AAgCxD,MAAa,SAKwBC;;;;;;;;;AAerC,MAAa,MAEwBC,QAAiB,KAAK;;;;;;;;AAS3D,MAAa,MAEwBA,QAAiB,KAAK;;;;;;;;AAS3D,MAAa,UAEwBA,QAAiB,SAAS;;;;;;;;;AAU/D,MAAa,UAQTC;;;;;;;;;AAUJ,MAAa,iBAWTC;;;;;;;;AAWJ,MAAa,SAOTC;;;;;;;;AASJ,MAAa,aAGYC;;;;;;;;;;;AAYzB,MAAa,UAIZC;;;;;;;;;;;;;;AAeD,MAAa,kBAOTC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDJ,MAAa,WAQZC;;;;;;;;;;;;;;;;;;;;AAsDD,MAAa,WAOqCC;;;;;;;;;;;;;;;AA2DlD,MAAa,SAE+BC"}
1
+ {"version":3,"file":"Policy.js","names":["RuleData.builder","RuleData.makePlain","Internal.PolicyError","Internal.define","Internal.combine","Internal.ceiling","Internal.provideContext","Decide.decideAny","Decide.decideSync","Decide.explain","Decide.permittedFields","Analysis.residual","Analysis.coverageAny","Internal.schema"],"sources":["../src/Policy.ts"],"sourcesContent":["/**\n * A policy is a tree that gives a {@link Decision.Decision} for a request.\n *\n * The leaves of the tree are lists of rules. A combining algorithm decides\n * which rule gives the answer when more than one rule applies:\n * - `denyOverrides` (the default): a deny rule wins over every allow rule.\n * - `permitOverrides`: an allow rule wins over every deny rule.\n * - `firstApplicable`: the first rule that applies wins.\n * - `lastApplicable`: the last rule that applies wins.\n *\n * The branches put policies together:\n * - {@link all}: every policy must allow, and one deny is enough to deny. Use\n * it when a user token may never do more than its user.\n * - {@link any}: one allow is enough.\n * - {@link firstOf}: the first policy that gives an answer wins. Use it for\n * grants first, then rules.\n * - {@link ceiling}: the deny rules of a second policy are a limit for\n * everyone. Its allow rules do nothing.\n *\n * A policy gives three kinds of answers:\n * - {@link decide}: the decision for one resource value.\n * - {@link residual}: a condition on resource values. A value passes when the\n * policy allows the request for that value. Use it to make a database\n * query, or to ask \"may this principal do this act on some resource of\n * this kind?\"\n * - {@link permittedFields}: the fields that the policy lets a request use.\n *\n * Each of them takes the policy first and the request second, as in\n * `Policy.decide(policy, request)`. The policy gives the domain, so\n * TypeScript checks the request against it.\n *\n * A policy without predicates can become JSON with {@link schema}.\n *\n * @stability stable\n * @since 0.3.0\n */\nimport type * as Context from \"effect/Context\"\nimport type * as Data from \"effect/Data\"\nimport type * as Effect from \"effect/Effect\"\nimport type * as Schema from \"effect/Schema\"\nimport type * as Condition from \"./Condition.ts\"\nimport * as Analysis from \"./internal/analysis.ts\"\nimport * as Decide from \"./internal/decide.ts\"\nimport * as Internal from \"./internal/policy.ts\"\nimport type * as PolicyNodes from \"./internal/policy-nodes.ts\"\nimport * as RuleData from \"./internal/rule.ts\"\nimport type * as Decision from \"./Decision.ts\"\nimport type * as Domain from \"./Domain.ts\"\nimport type * as Resource from \"./Resource.ts\"\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Algorithm = PolicyNodes.Algorithm\n\n/**\n * A list of rules with a combining algorithm.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type RulesNode = PolicyNodes.Rules\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type AllNode = PolicyNodes.All\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type AnyNode = PolicyNodes.Any\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type FirstOfNode = PolicyNodes.FirstOf\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type CeilingNode = PolicyNodes.Ceiling\n\n/**\n * The nodes of a policy tree, without types. Each node is a class, and only\n * the functions of this module and the Schema make one.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Node = PolicyNodes.Node\n\n/**\n * A policy for the domain `D`. `X` is `Condition.Opaque` when a rule of the\n * policy has a predicate, and `never` when the policy is plain data. A plain\n * policy can become JSON, and `decideSync` takes it.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Policy<D extends Domain.Any, X = never> = Internal.PolicyData<D, X>\n\n/**\n * Any policy.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Any = Policy<any, any>\n\n/**\n * The domain of a policy.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type DomainOf<P> = P extends Policy<infer D, any> ? D : never\n\n/**\n * The mark of a policy or a rule: `Condition.Opaque` when it has a predicate.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type OpaqueOf<P> = P extends { readonly \"~Opaque\": () => infer X }\n\t? X\n\t: never\n\n/**\n * One act on one resource value, for each kind of the domain. The action must\n * be an action of the kind, and the field must be a field of the kind.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Target<D> = {\n\t[K in Domain.Kind<D>]: {\n\t\treadonly action: Domain.ActionOf<D, K>\n\t\treadonly resource: Domain.ValueOf<D, K>\n\t\treadonly field?: Condition.FieldSelector<Domain.DataOf<D, K>>\n\t\t/** A target has a resource value or a kind, never both. */\n\t\treadonly kind?: never\n\t}\n}[Domain.Kind<D>]\n\n/**\n * A {@link Target} with no field. Each kind keeps its own actions.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type FieldlessTarget<D> = {\n\t[K in Domain.Kind<D>]: {\n\t\treadonly action: Domain.ActionOf<D, K>\n\t\treadonly resource: Domain.ValueOf<D, K>\n\t\treadonly kind?: never\n\t}\n}[Domain.Kind<D>]\n\n/**\n * A scope: a part of a kind, as a condition on its values. It gets a builder\n * with the types of the kind and of the principal, like the condition of a\n * rule. A scope is plain data, so it can not have a predicate.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport type Scope<D, K extends string> = (\n\tbuilder: Condition.Builder<\n\t\tDomain.DataOf<D, K>,\n\t\tDomain.ValueOf<D, K>,\n\t\tDomain.Principal<D>\n\t>,\n) => Condition.Condition<\n\tCondition.Reads<Domain.ValueOf<D, K>, Domain.Principal<D>>\n>\n\n/**\n * One act on one kind of resource, with no value. With `within`, the target is\n * only the values of the kind in the scope. Without it, the target is every\n * value of the kind.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type KindTarget<D> = {\n\t[K in Domain.Kind<D>]: {\n\t\treadonly action: Domain.ActionOf<D, K>\n\t\treadonly kind: K\n\t\treadonly field?: Condition.FieldSelector<Domain.DataOf<D, K>>\n\t\t/** The part of the kind. See {@link Scope}. */\n\t\treadonly within?: Scope<D, K>\n\t\t/** A target has a resource value or a kind, never both. */\n\t\treadonly resource?: never\n\t}\n}[Domain.Kind<D>]\n\n/**\n * A {@link Target} with a field of any length. A function that takes a\n * target checks its field with {@link CheckField}, so a field of up to about\n * 1000 parts is fine, and a field that is not a field of the kind is a type\n * error.\n *\n * @stability stable\n * @category models\n * @since 2.1.0\n */\nexport type DeepTarget<D> = {\n\t[K in Domain.Kind<D>]: {\n\t\treadonly action: Domain.ActionOf<D, K>\n\t\treadonly resource: Domain.ValueOf<D, K>\n\t\treadonly field?: string\n\t\treadonly kind?: never\n\t}\n}[Domain.Kind<D>]\n\n/**\n * A {@link KindTarget} with a field of any length. See {@link DeepTarget}.\n *\n * @stability stable\n * @category models\n * @since 2.1.0\n */\nexport type DeepKindTarget<D> = {\n\t[K in Domain.Kind<D>]: {\n\t\treadonly action: Domain.ActionOf<D, K>\n\t\treadonly kind: K\n\t\treadonly field?: string\n\t\treadonly within?: Scope<D, K>\n\t\treadonly resource?: never\n\t}\n}[Domain.Kind<D>]\n\n/** The kind of a target: its `kind`, or the `_tag` of its resource value. */\ntype KindOfTarget<T> = T extends { readonly kind: infer K extends string }\n\t? K\n\t: T extends { readonly resource: { readonly _tag: infer K extends string } }\n\t\t? K\n\t\t: never\n\n/**\n * Checks the field of a target or a request: a field of its kind that a\n * request may name, of any length up to about 1000 parts. See\n * `Condition.SelectPath`. A target with no field needs no check.\n *\n * @stability stable\n * @category utility types\n * @since 2.1.0\n */\nexport type CheckField<D, T> = T extends { readonly field?: infer F }\n\t? [Exclude<F, undefined>] extends [never]\n\t\t? unknown\n\t\t: {\n\t\t\t\t// A field that the target may leave out is checked too, when it is\n\t\t\t\t// there.\n\t\t\t\treadonly field?: Condition.SelectPath<\n\t\t\t\t\tDomain.DataOf<D, KindOfTarget<T>>,\n\t\t\t\t\tExclude<F, undefined> & string\n\t\t\t\t>\n\t\t\t}\n\t: unknown\n\n/**\n * A request: a principal, an action, and a resource value.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Request<D> = Target<D> & { readonly principal: Domain.Principal<D> }\n\n/**\n * A {@link Request} with a field of any length. See {@link DeepTarget}.\n *\n * @stability stable\n * @category models\n * @since 2.1.0\n */\nexport type DeepRequest<D> = DeepTarget<D> & {\n\treadonly principal: Domain.Principal<D>\n}\n\n/**\n * A {@link Request} with no field.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type FieldlessRequest<D> = FieldlessTarget<D> & {\n\treadonly principal: Domain.Principal<D>\n}\n\n/**\n * A request about a kind of resource, with no value.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type KindRequest<D> = KindTarget<D> & {\n\treadonly principal: Domain.Principal<D>\n}\n\n/**\n * A {@link KindRequest} with a field of any length. See {@link DeepTarget}.\n *\n * @stability stable\n * @category models\n * @since 2.1.0\n */\nexport type DeepKindRequest<D> = DeepKindTarget<D> & {\n\treadonly principal: Domain.Principal<D>\n}\n\n/**\n * A request with no types.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface AnyRequest {\n\treadonly principal: object\n\treadonly action: string\n\treadonly resource: object\n\treadonly field?: string | undefined\n}\n\n/**\n * One rule that a decision tested. `path` gives the place of the rule in the\n * policy tree: the index of each child, then the index of the rule.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Step {\n\treadonly path: ReadonlyArray<number>\n\treadonly rule: AnyRule\n\treadonly applies: boolean\n}\n\n/**\n * A decision, and the rules that were tested to make it, in order. Keep it in\n * an audit log.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Explanation {\n\treadonly decision: Decision.Decision\n\treadonly steps: ReadonlyArray<Step>\n}\n\n// Rules\n\n/**\n * A rule for the domain `D`. `I` is what the tests of its condition read, and\n * `X` is its mark: see `Condition.Condition`. A predicate reads the values and\n * the principal of its domain, so a rule may go only into a policy of its own\n * domain. A rule from {@link rule} has the domain `any`.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Rule<D = any, I = unknown, X = never> = RuleData.Rule<D, I, X>\n\n/**\n * The data of a rule.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport interface RuleShape<I = unknown, X = never> {\n\treadonly _tag: \"Allow\" | \"Deny\"\n\treadonly actions: ReadonlyArray<string>\n\treadonly resources: ReadonlyArray<string>\n\treadonly when?: Condition.Condition<I, X>\n\treadonly fields?: ReadonlyArray<string>\n\treadonly reason?: string\n\treadonly id?: string\n\treadonly meta?: unknown\n\t/**\n\t * The domain of the builder that made the rule. Two domains may have the\n\t * same types but other paths, so the types can not tell them apart. It is\n\t * not in the JSON form of a rule.\n\t */\n\treadonly domain?: Domain.Any\n}\n\n/**\n * Any rule.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\n// Every rule fits `never` as what it reads, and a condition taken from such a\n// rule fits no rule that reads a value or a principal.\nexport type AnyRule = Rule<any, never, any>\n\n/**\n * A resource in a rule: a kind name, a resource of the domain, or `\"*\"`.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type RuleTarget<D> = Domain.Kind<D> | Domain.Resources<D> | \"*\"\n\n/**\n * The kind name of a target.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type KindOf<T> = T extends string ? T : Resource.Kind<T>\n\n/**\n * The actions that a rule may use for the kinds `K`.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type ActionFor<D, K> =\n\t| \"*\"\n\t| (\"*\" extends K\n\t\t\t? Domain.AnyAction<D>\n\t\t\t: Domain.ActionOf<D, Extract<K, string>>)\n\n/**\n * The targets in the resource argument of a rule: the one target, or the\n * targets of a list.\n *\n * @stability stable\n * @category utility types\n * @since 1.0.0\n */\nexport type TargetOf<Res> = Res extends ReadonlyArray<infer X> ? X : Res\n\n/**\n * The actions that a rule may use for its resource argument. A list of\n * resources may use an action of any of them. One target with a union type\n * may use only an action of every kind in the union, because its value may be\n * any one of them. When the argument may be a list or one target, the rule\n * may use only an action that each of these shapes allows.\n *\n * @stability stable\n * @category utility types\n * @since 1.0.0\n */\nexport type ActionForTargets<D, Res> = (\n\tRes extends ReadonlyArray<infer X>\n\t\t? (action: ActionFor<D, KindOf<X>>) => void\n\t\t: (action: ActionForTarget<D, Res>) => void\n) extends (action: infer A) => void\n\t? A\n\t: never\n\n/** The actions for one target that is not a list. */\ntype ActionForTarget<D, Res> =\n\t| \"*\"\n\t| (\"*\" extends KindOf<Res>\n\t\t\t? Domain.AnyAction<D>\n\t\t\t: Domain.CommonAction<D, Extract<KindOf<Res>, string>>)\n\n/**\n * The data type of the kinds `K`. For `\"*\"` it has no fields.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type DataFor<D, K> = \"*\" extends K\n\t? {}\n\t: Domain.DataOf<D, Extract<K, string>>\n\n/**\n * The value type of the kinds `K`.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type ValueFor<D, K> = \"*\" extends K\n\t? Domain.AnyValue<D>\n\t: Domain.ValueOf<D, Extract<K, string>>\n\n/**\n * A field name or a field pattern of the kinds `K`.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type FieldFor<D, K> =\n\tCondition.FieldName<DataFor<D, K>> | `${string}*${string}`\n\n/**\n * A condition that a rule for the kinds `K` may have. Its predicates may read\n * only the values of these kinds and the principal of the domain.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport type ConditionFor<D, K> = Condition.Condition<\n\tCondition.Reads<ValueFor<D, K>, Domain.Principal<D>>,\n\tany\n>\n\n/**\n * Checks each field of a rule: a field pattern with a star, or a name of the\n * kinds `K`, of any length up to about 1000 parts. A name that is not a field\n * gives the names that may come next, so the type error names them. See\n * `Condition.NamePath`.\n *\n * @stability stable\n * @category utility types\n * @since 2.1.0\n */\nexport type FieldsFor<D, K, Fields extends ReadonlyArray<string>> = {\n\treadonly [I in keyof Fields]: Fields[I] extends `${string}*${string}`\n\t\t? Fields[I]\n\t\t: Condition.NamePath<DataFor<D, K>, Fields[I] & string>\n}\n\n/**\n * The options of a rule. `Fields` is the list of the fields of the rule.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface RuleOptions<\n\tD,\n\tK,\n\tC extends Condition.Any,\n\tFields extends ReadonlyArray<string> = ReadonlyArray<FieldFor<D, K>>,\n> {\n\t/** The condition. It gets a builder with the types of the resource. */\n\treadonly when?: (\n\t\tbuilder: Condition.Builder<\n\t\t\tDataFor<D, K>,\n\t\t\tValueFor<D, K>,\n\t\t\tDomain.Principal<D>\n\t\t>,\n\t) => C\n\treadonly fields?: Fields & FieldsFor<D, K, Fields>\n\treadonly reason?: string\n\treadonly id?: string\n\treadonly meta?: Domain.Meta<D>\n}\n\ntype SingleOrArray<A> = A | ReadonlyArray<A>\n\n/**\n * Makes rules with the types of a domain.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Builder<D> {\n\treadonly allow: <\n\t\tconst Res extends SingleOrArray<RuleTarget<D>>,\n\t\tconst A extends ActionForTargets<D, Res>,\n\t\tconst C extends ConditionFor<D, KindOf<TargetOf<Res>>> =\n\t\t\tCondition.Condition,\n\t\tconst Fields extends ReadonlyArray<string> = readonly [],\n\t>(\n\t\taction: SingleOrArray<A>,\n\t\tresource: Res,\n\t\toptions?: RuleOptions<D, KindOf<TargetOf<Res>>, C, Fields>,\n\t) => Rule<D, Condition.ReadsOf<C>, Condition.OpaqueOf<C>>\n\treadonly deny: <\n\t\tconst Res extends SingleOrArray<RuleTarget<D>>,\n\t\tconst A extends ActionForTargets<D, Res>,\n\t\tconst C extends ConditionFor<D, KindOf<TargetOf<Res>>> =\n\t\t\tCondition.Condition,\n\t\tconst Fields extends ReadonlyArray<string> = readonly [],\n\t>(\n\t\taction: SingleOrArray<A>,\n\t\tresource: Res,\n\t\toptions?: RuleOptions<D, KindOf<TargetOf<Res>>, C, Fields>,\n\t) => Rule<D, Condition.ReadsOf<C>, Condition.OpaqueOf<C>>\n}\n\n/**\n * Makes rules with the types of a domain. `Policy.define` gives one to its\n * generator. Use this one to make rules outside of a generator.\n *\n * @example\n * ```ts\n * const _ = Policy.builder(App)\n * const rule = _.allow(\"read\", Document, {\n * when: ($) => $.eq(\"ownerId\", $.principal(\"id\")),\n * })\n * ```\n *\n * @stability stable\n * @category constructors\n * @since 2.0.0\n */\nexport const builder = <D extends Domain.Any>(domain: D): Builder<D> =>\n\tRuleData.builder(domain) as never\n\n/**\n * Makes a rule from its data, with no types. It does not check the data\n * against a domain: a policy does that when the rule goes into it. Use\n * {@link builder} for rules with types, or {@link schema} for rules from JSON.\n *\n * The condition may not have a predicate. A policy checks the fields of a\n * condition against the resources of its rule, but it can not check what\n * the code of a predicate reads. A rule from the builder keeps that in its\n * types; this one could give a predicate of one kind to another kind.\n *\n * @stability stable\n * @category constructors\n * @since 2.0.0\n */\nexport const rule: <I = unknown>(\n\tdata: RuleShape<I, never>,\n\t// The types come from the data only, not from where the rule goes.\n) => Rule<any, NoInfer<I>> = RuleData.makePlain as never\n\n/**\n * The options of a list of rules.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Options {\n\t/** The default is `denyOverrides`. */\n\treadonly algorithm?: Algorithm\n}\n\n/**\n * The error when a rule does not fit its domain: it names a kind, an action,\n * a field or a field of the principal that the domain does not have, or it\n * tests a field with a value that the field can not hold. It has one issue\n * for each problem, with its path, and a suggestion when a name has a mistake.\n *\n * @stability stable\n * @category errors\n * @since 2.0.0\n */\nexport const PolicyError: typeof Internal.PolicyError = Internal.PolicyError\n\n/**\n * @stability stable\n * @category errors\n * @since 2.0.0\n */\nexport type PolicyError = Internal.PolicyError\n\n/** The mark of a union of rules: `Condition.Opaque` when one has a predicate. */\ntype RulesOpaque<Rules> = Rules extends { readonly \"~Opaque\": () => infer X }\n\t? X\n\t: never\n\n/**\n * Makes a policy from a generator function that gives rules. It is pure and it\n * gives its result at once.\n *\n * @example\n * ```ts\n * const policy = Policy.define(App)(function* (_) {\n * yield* _.allow(\"read\", Document)\n * yield* _.allow([\"update\", \"delete\"], Document, {\n * when: ($) => $.eq(\"ownerId\", $.principal(\"id\")),\n * })\n * })\n * ```\n *\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const define: <D extends Domain.Any>(\n\tdomain: D,\n\toptions?: Options,\n) => <Rules extends Rule<D, never, any>, A>(\n\tbody: (builder: Builder<D>) => Generator<Rules, A, unknown>,\n) => Policy<D, RulesOpaque<Rules>> = Internal.define as never\n\ntype Combined<D extends Domain.Any, Ps extends ReadonlyArray<Any>> = Policy<\n\tD,\n\tOpaqueOf<Ps[number]>\n>\n\n/**\n * Every policy must allow, and one deny is enough to deny. With some policies\n * not applicable and none that deny, the result is not applicable.\n *\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const all: <const Ps extends readonly [Any, ...Array<Any>]>(\n\tpolicies: Ps,\n) => Combined<DomainOf<Ps[0]>, Ps> = Internal.combine(\"All\")\n\n/**\n * One allow is enough. Without an allow, one deny gives a deny.\n *\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const any: <const Ps extends readonly [Any, ...Array<Any>]>(\n\tpolicies: Ps,\n) => Combined<DomainOf<Ps[0]>, Ps> = Internal.combine(\"Any\")\n\n/**\n * The first policy that allows or denies gives the answer.\n *\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const firstOf: <const Ps extends readonly [Any, ...Array<Any>]>(\n\tpolicies: Ps,\n) => Combined<DomainOf<Ps[0]>, Ps> = Internal.combine(\"FirstOf\")\n\n/**\n * Puts a limit on a policy. A deny from `cap` always wins. An allow from `cap`\n * does nothing.\n *\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const ceiling: {\n\t<D extends Domain.Any, X2>(\n\t\tcap: Policy<D, X2>,\n\t): <X>(policy: Policy<D, X>) => Policy<D, X | X2>\n\t<D extends Domain.Any, X, X2>(\n\t\tpolicy: Policy<D, X>,\n\t\tcap: Policy<D, X2>,\n\t): Policy<D, X | X2>\n} = Internal.ceiling as never\n\n/**\n * Gives the services in `context` to every predicate of a policy, so the\n * policy needs no services when it runs.\n *\n * @stability stable\n * @category services\n * @since 1.0.0\n */\nexport const provideContext: {\n\t<R>(\n\t\tcontext: Context.Context<R>,\n\t): <D extends Domain.Any, X>(\n\t\tpolicy: Policy<D, X> &\n\t\t\t([Condition.ServicesOf<X>] extends [R] ? unknown : never),\n\t) => Policy<D, Condition.Provided<X>>\n\t<D extends Domain.Any, X>(\n\t\tpolicy: Policy<D, X>,\n\t\tcontext: Context.Context<Condition.ServicesOf<X>>,\n\t): Policy<D, Condition.Provided<X>>\n} = Internal.provideContext as never\n\n// Decisions\n\n/**\n * Gives the decision of a policy for a request.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const decide: <\n\tD extends Domain.Any,\n\tX,\n\tconst Req extends DeepRequest<NoInfer<D>>,\n>(\n\tpolicy: Policy<D, X>,\n\trequest: Req & CheckField<NoInfer<D>, Req>,\n) => Effect.Effect<\n\tDecision.Decision,\n\tCondition.ErrorOf<X>,\n\tCondition.ServicesOf<X>\n> = Decide.decideAny as never\n\n/**\n * Gives the decision of a policy with no predicates, at once.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const decideSync: <\n\tD extends Domain.Any,\n\tconst Req extends DeepRequest<NoInfer<D>>,\n>(\n\tpolicy: Policy<D>,\n\trequest: Req & CheckField<NoInfer<D>, Req>,\n) => Decision.Decision = Decide.decideSync\n\n/**\n * Gives the decision of a policy and the rules that were tested to make it.\n *\n * One node may be a child of many nodes. Its rules are tested, and are in the\n * steps, each time that the decision comes to it.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const explain: <\n\tD extends Domain.Any,\n\tX,\n\tconst Req extends DeepRequest<NoInfer<D>>,\n>(\n\tpolicy: Policy<D, X>,\n\trequest: Req & CheckField<NoInfer<D>, Req>,\n) => Effect.Effect<Explanation, Condition.ErrorOf<X>, Condition.ServicesOf<X>> =\n\tDecide.explain as never\n\n/**\n * Gives the fields of a resource value that the policy lets a request use. It\n * tests each field that a list of fields shows: each scalar, record or array\n * of the resource Schema, with dots for nested fields.\n *\n * A field that holds more than one value, such as a record, is left out when a\n * deny rule names a part of it. The list can not name that part, and the whole\n * field would show it.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const permittedFields: <D extends Domain.Any, X>(\n\tpolicy: Policy<D, X>,\n\trequest: FieldlessRequest<NoInfer<D>>,\n) => Effect.Effect<\n\tReadonlyArray<string>,\n\tCondition.ErrorOf<X>,\n\tCondition.ServicesOf<X>\n> = Decide.permittedFields as never\n\n// Residual conditions\n\n/**\n * What a residual condition reads: a value of the kind `K`. The principal is\n * already in it. A residual is for one kind, so when `K` is a union of kinds,\n * the value must be a value of each of them. No value is, so such a residual\n * can not be evaluated on a value of the wrong kind.\n *\n * @stability stable\n * @category utility types\n * @since 1.0.0\n */\nexport type ResidualReads<D, K> = Condition.Reads<\n\t(\n\t\tK extends unknown ? (value: Domain.ValueOf<D, K & string>) => void : never\n\t) extends (value: infer V) => void\n\t\t? V\n\t\t: never,\n\tunknown\n>\n\n/**\n * Gives the condition on resource values for which the policy allows a\n * request. It has no principal fields and no `Under` nodes, so you can give it\n * to `Condition.fold`. It is made smaller, so it is often `True` or `False`\n * when the answer does not depend on the value, but it does no search: a\n * condition that is true for every value may stay a test. To know if the\n * policy allows every value, or some value, use {@link coverage}.\n *\n * With a scope (`within`), the condition is the scope and the residual\n * together, so it is false for every value outside the scope. Give the policy\n * first to use a scope. The condition comes from its parts, with no search. To\n * know if it allows all of the scope or none of it, use {@link coverage}.\n *\n * When a rule that the request may use has a predicate, the condition is one\n * predicate with the name `\"policy\"`. It runs the whole policy for each value,\n * so its answers and its failures are the same as those of {@link decide}. It\n * takes the principal with it. Give it resource values with their `_tag`. It\n * is false for a value of another kind.\n *\n * A policy tree may use the condition of a child two times, so a small policy\n * may give a very large condition. When the condition would have more than\n * the `residualNodes` of the domain, 100000 by default, this function throws\n * an error. In an `Authorizer`, the error is a defect, so the check fails.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const residual: <\n\tD extends Domain.Any,\n\tX,\n\tconst Req extends DeepKindRequest<NoInfer<D>>,\n>(\n\tpolicy: Policy<D, X>,\n\trequest: Req & CheckField<NoInfer<D>, Req>,\n) => Condition.Condition<ResidualReads<D, Req[\"kind\"]>, X> =\n\tAnalysis.residual as never\n\n/**\n * How much of a scope a policy allows. In each case, `condition` is the exact\n * condition on the values in the scope that the policy allows: give it to\n * `Condition.fold` for a list query.\n * - `All`: the policy allows every value in the scope. `condition` is the\n * scope (`True` with no scope).\n * - `None`: the policy allows no value in the scope. `condition` is `False`.\n * An empty scope is `None` too, so a check on a scope that has a mistake,\n * such as a principal field with no value, never passes.\n * - `Some`: the policy allows some values in the scope and not others.\n * `allowed` is an example of a value that it allows, and `refused` of a\n * value in the scope that it does not allow.\n * - `Unknown`: the answer needs a predicate, or the search went past its\n * budget.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport type Coverage<I = unknown, X = never> = Data.TaggedEnum<{\n\tAll: { readonly condition: Condition.Condition<I, X> }\n\tNone: { readonly condition: Condition.Condition<I, X> }\n\tSome: {\n\t\treadonly condition: Condition.Condition<I, X>\n\t\treadonly allowed: Condition.Example\n\t\treadonly refused: Condition.Example\n\t}\n\tUnknown: {\n\t\treadonly condition: Condition.Condition<I, X>\n\t\treadonly reason: \"predicate\" | \"budget\"\n\t}\n}>\n\n/**\n * Tells how much of a scope the policy allows: all of it, none of it, or some\n * of it. See {@link Coverage}. With no scope (`within`), the scope is every\n * value of the kind.\n *\n * The answer comes from {@link Condition.satisfiable} with the shape of the\n * Schema of the resource. `All` and `None` hold for every value of the\n * Schema. `Some` means that, by the shape of the Schema, a value may get\n * either answer: a check such as a minimum length may still stop one of the\n * examples. `Unknown` comes only from a predicate or from the budget of the\n * search.\n *\n * `Some` does not mean that such a value is in your database. To know that,\n * run `condition` as a query.\n *\n * @stability stable\n * @category evaluation\n * @since 1.0.0\n */\nexport const coverage: <\n\tD extends Domain.Any,\n\tX,\n\tconst Req extends DeepKindRequest<NoInfer<D>>,\n>(\n\tpolicy: Policy<D, X>,\n\trequest: Req & CheckField<NoInfer<D>, Req>,\n) => Coverage<ResidualReads<D, Req[\"kind\"]>, X> = Analysis.coverageAny as never\n\n// Schema\n\n/**\n * The JSON form of a rule.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface EncodedRule {\n\treadonly _tag: \"Allow\" | \"Deny\"\n\treadonly actions: ReadonlyArray<string>\n\treadonly resources: ReadonlyArray<string>\n\treadonly when?: Condition.Encoded\n\treadonly fields?: ReadonlyArray<string>\n\treadonly reason?: string\n\treadonly id?: string\n\treadonly meta?: unknown\n}\n\n/**\n * The JSON form of a policy.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type EncodedNode =\n\t| {\n\t\t\treadonly _tag: \"Rules\"\n\t\t\treadonly algorithm: Algorithm\n\t\t\treadonly rules: ReadonlyArray<EncodedRule>\n\t }\n\t| {\n\t\t\treadonly _tag: \"All\" | \"Any\" | \"FirstOf\"\n\t\t\treadonly policies: ReadonlyArray<EncodedNode>\n\t }\n\t| {\n\t\t\treadonly _tag: \"Ceiling\"\n\t\t\treadonly cap: EncodedNode\n\t\t\treadonly policy: EncodedNode\n\t }\n\n/**\n * The Schema of the policies of a domain with no predicates. Decoding checks\n * every kind, action, field and principal field against the domain, and the\n * `meta` of each rule against the `meta` Schema of the domain.\n *\n * The decoder takes the limits of the domain: at most `policyNodes` nodes\n * of the tree, `conditionNodes` nodes of each condition, and `jsonNodes`\n * objects and array items, with a shared object counted for each place. It\n * stops at the first one past a limit. It takes any number of levels, and it\n * reads only the own data fields of the input.\n *\n * @stability stable\n * @category schemas\n * @since 0.3.0\n */\nexport const schema: <D extends Domain.Any>(\n\tdomain: D,\n) => Schema.Codec<Policy<D>, EncodedNode> = Internal.schema as never\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsnBA,MAAa,WAAiC,WAC7CA,UAAiB,MAAM;;;;;;;;;;;;;;;AAgBxB,MAAa,OAGgBC;;;;;;;;;;;AAwB7B,MAAa,cAA2CC;;;;;;;;;;;;;;;;;;;AAgCxD,MAAa,SAKwBC;;;;;;;;;AAerC,MAAa,MAEwBC,QAAiB,KAAK;;;;;;;;AAS3D,MAAa,MAEwBA,QAAiB,KAAK;;;;;;;;AAS3D,MAAa,UAEwBA,QAAiB,SAAS;;;;;;;;;AAU/D,MAAa,UAQTC;;;;;;;;;AAUJ,MAAa,iBAWTC;;;;;;;;AAWJ,MAAa,SAWTC;;;;;;;;AASJ,MAAa,aAMYC;;;;;;;;;;;AAYzB,MAAa,UAQZC;;;;;;;;;;;;;;AAeD,MAAa,kBAOTC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDJ,MAAa,WAQZC;;;;;;;;;;;;;;;;;;;;AAsDD,MAAa,WAOqCC;;;;;;;;;;;;;;;;AA4DlD,MAAa,SAE+BC"}
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { Resource_d_exports } from "./Resource.js";
2
2
  import { Condition_d_exports } from "./Condition.js";
3
+ import { Limits_d_exports } from "./Limits.js";
3
4
  import { Domain_d_exports } from "./Domain.js";
4
5
  import { Policy_d_exports } from "./Policy.js";
5
6
  import { Decision_d_exports } from "./Decision.js";
6
7
  import { Authorizer_d_exports } from "./Authorizer.js";
7
- import { Limits_d_exports } from "./Limits.js";
8
8
  export { Authorizer_d_exports as Authorizer, Condition_d_exports as Condition, Decision_d_exports as Decision, Domain_d_exports as Domain, Limits_d_exports as Limits, Policy_d_exports as Policy, Resource_d_exports as Resource };