@nmnmcc/ability 1.0.1 → 2.0.1

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 (127) hide show
  1. package/README.md +112 -69
  2. package/dist/Authorizer.d.ts +43 -47
  3. package/dist/Authorizer.d.ts.map +1 -1
  4. package/dist/Authorizer.js +5 -290
  5. package/dist/Authorizer.js.map +1 -1
  6. package/dist/Condition.d.ts +164 -332
  7. package/dist/Condition.d.ts.map +1 -1
  8. package/dist/Condition.js +75 -890
  9. package/dist/Condition.js.map +1 -1
  10. package/dist/Decision.d.ts +13 -13
  11. package/dist/Decision.d.ts.map +1 -1
  12. package/dist/Decision.js.map +1 -1
  13. package/dist/Domain.d.ts +10 -21
  14. package/dist/Domain.d.ts.map +1 -1
  15. package/dist/Domain.js +4 -62
  16. package/dist/Domain.js.map +1 -1
  17. package/dist/HttpApi.d.ts +31 -7
  18. package/dist/HttpApi.d.ts.map +1 -1
  19. package/dist/HttpApi.js +25 -8
  20. package/dist/HttpApi.js.map +1 -1
  21. package/dist/Limits.d.ts +114 -0
  22. package/dist/Limits.d.ts.map +1 -0
  23. package/dist/Limits.js +132 -0
  24. package/dist/Limits.js.map +1 -0
  25. package/dist/Policy.d.ts +276 -269
  26. package/dist/Policy.d.ts.map +1 -1
  27. package/dist/Policy.js +73 -1177
  28. package/dist/Policy.js.map +1 -1
  29. package/dist/Resource.d.ts +4 -177
  30. package/dist/Resource.d.ts.map +1 -1
  31. package/dist/Resource.js +4 -803
  32. package/dist/Resource.js.map +1 -1
  33. package/dist/index.d.ts +3 -4
  34. package/dist/index.js +4 -5
  35. package/dist/internal/algebra.js +267 -0
  36. package/dist/internal/algebra.js.map +1 -0
  37. package/dist/internal/analysis.js +245 -0
  38. package/dist/internal/analysis.js.map +1 -0
  39. package/dist/internal/authorizer.d.ts +30 -0
  40. package/dist/internal/authorizer.d.ts.map +1 -0
  41. package/dist/internal/authorizer.js +221 -0
  42. package/dist/internal/authorizer.js.map +1 -0
  43. package/dist/internal/bind.js +311 -0
  44. package/dist/internal/bind.js.map +1 -0
  45. package/dist/internal/catalog.d.ts +56 -0
  46. package/dist/internal/catalog.d.ts.map +1 -0
  47. package/dist/internal/catalog.js +292 -0
  48. package/dist/internal/catalog.js.map +1 -0
  49. package/dist/internal/decide.js +166 -0
  50. package/dist/internal/decide.js.map +1 -0
  51. package/dist/internal/domain.js +32 -0
  52. package/dist/internal/domain.js.map +1 -0
  53. package/dist/internal/json.js +134 -0
  54. package/dist/internal/json.js.map +1 -0
  55. package/dist/internal/limits.d.ts +14 -0
  56. package/dist/internal/limits.d.ts.map +1 -0
  57. package/dist/internal/limits.js +43 -0
  58. package/dist/internal/limits.js.map +1 -0
  59. package/dist/internal/nodes.d.ts +121 -0
  60. package/dist/internal/nodes.d.ts.map +1 -0
  61. package/dist/internal/nodes.js +277 -0
  62. package/dist/internal/nodes.js.map +1 -0
  63. package/dist/internal/patterns.js +110 -0
  64. package/dist/internal/patterns.js.map +1 -0
  65. package/dist/internal/policy-json.js +265 -0
  66. package/dist/internal/policy-json.js.map +1 -0
  67. package/dist/internal/policy-nodes.d.ts +61 -0
  68. package/dist/internal/policy-nodes.d.ts.map +1 -0
  69. package/dist/internal/policy-nodes.js +146 -0
  70. package/dist/internal/policy-nodes.js.map +1 -0
  71. package/dist/internal/policy.d.ts +42 -0
  72. package/dist/internal/policy.d.ts.map +1 -0
  73. package/dist/internal/policy.js +124 -0
  74. package/dist/internal/policy.js.map +1 -0
  75. package/dist/internal/read.js +39 -0
  76. package/dist/internal/read.js.map +1 -0
  77. package/dist/internal/resource.js +115 -0
  78. package/dist/internal/resource.js.map +1 -0
  79. package/dist/internal/rule.d.ts +26 -0
  80. package/dist/internal/rule.d.ts.map +1 -0
  81. package/dist/internal/rule.js +103 -0
  82. package/dist/internal/rule.js.map +1 -0
  83. package/dist/internal/search.d.ts +22 -0
  84. package/dist/internal/search.d.ts.map +1 -0
  85. package/dist/internal/search.js +274 -0
  86. package/dist/internal/search.js.map +1 -0
  87. package/dist/internal/suggest.js +46 -0
  88. package/dist/internal/suggest.js.map +1 -0
  89. package/package.json +3 -4
  90. package/src/Authorizer.ts +67 -583
  91. package/src/Condition.ts +339 -2095
  92. package/src/Decision.ts +6 -5
  93. package/src/Domain.ts +12 -69
  94. package/src/HttpApi.ts +72 -10
  95. package/src/Limits.ts +132 -0
  96. package/src/Policy.ts +391 -2772
  97. package/src/Resource.ts +7 -1548
  98. package/src/index.ts +3 -9
  99. package/src/internal/algebra.ts +482 -0
  100. package/src/internal/analysis.ts +478 -0
  101. package/src/internal/authorizer.ts +418 -0
  102. package/src/internal/bind.ts +648 -0
  103. package/src/internal/catalog.ts +534 -0
  104. package/src/internal/decide.ts +402 -0
  105. package/src/internal/domain.ts +66 -0
  106. package/src/internal/json.ts +260 -0
  107. package/src/internal/limits.ts +78 -0
  108. package/src/internal/nodes.ts +404 -0
  109. package/src/internal/patterns.ts +211 -0
  110. package/src/internal/policy-json.ts +487 -0
  111. package/src/internal/policy-nodes.ts +207 -0
  112. package/src/internal/policy.ts +264 -0
  113. package/src/internal/read.ts +55 -0
  114. package/src/internal/resource.ts +180 -0
  115. package/src/internal/rule.ts +196 -0
  116. package/src/internal/search.ts +541 -0
  117. package/src/internal/suggest.ts +104 -0
  118. package/dist/Principal.d.ts +0 -35
  119. package/dist/Principal.d.ts.map +0 -1
  120. package/dist/Principal.js +0 -37
  121. package/dist/Principal.js.map +0 -1
  122. package/dist/Rule.d.ts +0 -275
  123. package/dist/Rule.d.ts.map +0 -1
  124. package/dist/Rule.js +0 -257
  125. package/dist/Rule.js.map +0 -1
  126. package/src/Principal.ts +0 -41
  127. package/src/Rule.ts +0 -683
@@ -1 +1 @@
1
- {"version":3,"file":"Policy.js","names":["Condition.toJsonValue","Rule.isRule","Rule.domainOf","Rule.builder","Condition.hasPredicate","Rule.make","Condition.provideContext","Rule.matchesTarget","Condition.evaluate","Decision.Allow","Decision.Deny","Decision.NotApplicable","Resource.hasPath","Resource.hasGetter","Resource.kindOf","Domain.descriptorOf","Rule.matchesInside","Condition.always","Condition.never","Condition.simplifier","Condition.andAll","Condition.orAll","Condition.not","Condition.partial","Condition.fields","Condition.builder","Resource.isPlainField","Condition.satisfiable","Condition.simplify","Condition.and","Condition.schema","Resource.domainOf","Resource.fieldPaths","Condition.isAst"],"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 also takes the request first and the policy later. In a `pipe`,\n * the policy gives the domain. Outside a `pipe`, give the domain by hand, as\n * in `Policy.decide<typeof App>(request)`. Without it the request has the type\n * `never`, so TypeScript can still check it.\n *\n * A policy without predicates can become JSON with {@link schema}.\n *\n * @stability stable\n * @since 0.3.0\n */\n// A policy keeps the error type and the service type of its predicates in the\n// public types. The code below works on the nodes with no types, where they\n// are `unknown`, so the language service check for `unknown` in an Effect is\n// off here.\n// @effect-diagnostics anyUnknownInErrorContext:off\nimport type * as Context from \"effect/Context\"\nimport * as Data from \"effect/Data\"\nimport * as Arr from \"effect/Array\"\nimport * as Chunk from \"effect/Chunk\"\nimport * as Effect from \"effect/Effect\"\nimport { dual } from \"effect/Function\"\nimport * as HashMap from \"effect/HashMap\"\nimport * as HashSet from \"effect/HashSet\"\nimport * as Option from \"effect/Option\"\nimport { hasProperty } from \"effect/Predicate\"\nimport type * as Pipeable from \"effect/Pipeable\"\nimport * as Ref from \"effect/Ref\"\nimport * as Schema from \"effect/Schema\"\nimport * as SchemaIssue from \"effect/SchemaIssue\"\nimport * as SchemaTransformation from \"effect/SchemaTransformation\"\nimport * as Condition from \"./Condition.ts\"\nimport * as Decision from \"./Decision.ts\"\nimport * as Domain from \"./Domain.ts\"\nimport * as Resource from \"./Resource.ts\"\nimport * as Rule from \"./Rule.ts\"\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Algorithm =\n\t\"denyOverrides\" | \"permitOverrides\" | \"firstApplicable\" | \"lastApplicable\"\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface RulesNode {\n\treadonly _tag: \"Rules\"\n\treadonly algorithm: Algorithm\n\treadonly rules: ReadonlyArray<Rule.Any>\n}\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface AllNode {\n\treadonly _tag: \"All\"\n\treadonly policies: ReadonlyArray<Node>\n}\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface AnyNode {\n\treadonly _tag: \"Any\"\n\treadonly policies: ReadonlyArray<Node>\n}\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface FirstOfNode {\n\treadonly _tag: \"FirstOf\"\n\treadonly policies: ReadonlyArray<Node>\n}\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface CeilingNode {\n\treadonly _tag: \"Ceiling\"\n\treadonly cap: Node\n\treadonly policy: Node\n}\n\n/**\n * The nodes of a policy tree.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Node = RulesNode | AllNode | AnyNode | FirstOfNode | CeilingNode\n\n/**\n * The tree of a policy with the types of its predicates and its domain `D`.\n * Each rule and each child has the types too, and `\"~Node\"` is only in the types. A node made by\n * hand does not have it. So the node of one policy, or a part of it, can not\n * go into a policy with other types.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport type TypedNode<E = never, R = never, O = never, D = any> = (\n\t| {\n\t\t\treadonly _tag: \"Rules\"\n\t\t\treadonly algorithm: Algorithm\n\t\t\t// The rules may read different values, so a node keeps no one type of\n\t\t\t// what they read. With `never`, a condition taken from a node fits no\n\t\t\t// rule that reads a value or a principal.\n\t\t\treadonly rules: ReadonlyArray<Rule.Rule<E, R, O, D, never>>\n\t }\n\t| {\n\t\t\treadonly _tag: \"All\" | \"Any\" | \"FirstOf\"\n\t\t\treadonly policies: ReadonlyArray<TypedNode<E, R, O, D>>\n\t }\n\t| {\n\t\t\treadonly _tag: \"Ceiling\"\n\t\t\treadonly cap: TypedNode<E, R, O, D>\n\t\t\treadonly policy: TypedNode<E, R, O, D>\n\t }\n) & {\n\treadonly \"~Node\": Condition.Variance<E, R, O>\n}\n\n/**\n * A policy for the domain `D`. `E`, `R` and `O` come from the conditions of\n * its rules. See `Condition.Condition`.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Policy<D extends Domain.Any, E = never, R = never, O = never>\n\textends Pipeable.Pipeable {\n\treadonly domain: D\n\treadonly node: TypedNode<E, R, O, D>\n\treadonly \"~Policy\": Condition.Variance<E, R, O>\n\t/**\n\t * Only in the types. A policy reads the values and the principal of its\n\t * domain, so a policy of one domain is not a policy of a wider domain.\n\t */\n\treadonly \"~Domain\": (domain: D) => D\n}\n\n/**\n * Any policy.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Any = Policy<any, any, 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, any, any> ? D : never\n\n/**\n * The error type of a policy.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type Error<P> = P extends {\n\treadonly \"~Policy\"?: Condition.Variance<infer E, infer _R, infer _O>\n}\n\t? E\n\t: never\n\n/**\n * The service type of a policy.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type Services<P> = P extends {\n\treadonly \"~Policy\"?: Condition.Variance<infer _E, infer R, infer _O>\n}\n\t? R\n\t: never\n\n/**\n * `Condition.Opaque` when a policy has a predicate.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type OpaqueOf<P> = P extends {\n\treadonly \"~Policy\"?: Condition.Variance<infer _E, infer _R, infer O>\n}\n\t? O\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\tnever,\n\tnever,\n\tnever,\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: Rule.Any\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/**\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\nconst nodes = Data.taggedEnum<Node>()\n\n/**\n * The most nodes that the JSON form of a policy may have. A tree may use one\n * child in many places, and the JSON form writes it out each time, so a small\n * tree may have a very large JSON form.\n */\nconst maxEncodedNodes = 100_000\n\n/**\n * The number of nodes of the JSON form of a condition. A shared child counts\n * one time for each place, as the JSON form writes it out each time.\n */\nconst conditionSize = (ast: Ast, memo: Map<Ast, number>): number =>\n\tremember(memo, ast, () => {\n\t\tswitch (ast._tag) {\n\t\t\tcase \"And\":\n\t\t\tcase \"Or\":\n\t\t\t\treturn Arr.reduce(\n\t\t\t\t\tast.conditions,\n\t\t\t\t\t1,\n\t\t\t\t\t(size, child) => size + conditionSize(child, memo),\n\t\t\t\t)\n\t\t\tcase \"Not\":\n\t\t\t\treturn 1 + conditionSize(ast.condition, memo)\n\t\t\tdefault:\n\t\t\t\treturn 1\n\t\t}\n\t})\n\n/**\n * The number of nodes of the JSON form of a tree, with the conditions of its\n * rules.\n */\nconst encodedSize = (\n\tnode: Node,\n\tmemo: Map<Node, number> = new Map(),\n\tconditions: Map<Ast, number> = new Map(),\n): number =>\n\tremember(memo, node, () => {\n\t\tswitch (node._tag) {\n\t\t\tcase \"Rules\":\n\t\t\t\treturn Arr.reduce(\n\t\t\t\t\tnode.rules,\n\t\t\t\t\t1,\n\t\t\t\t\t(size, value) =>\n\t\t\t\t\t\tsize +\n\t\t\t\t\t\t1 +\n\t\t\t\t\t\t(value.when === undefined\n\t\t\t\t\t\t\t? 0\n\t\t\t\t\t\t\t: conditionSize(value.when as Ast, conditions)),\n\t\t\t\t)\n\t\t\tcase \"All\":\n\t\t\tcase \"Any\":\n\t\t\tcase \"FirstOf\":\n\t\t\t\treturn Arr.reduce(\n\t\t\t\t\tnode.policies,\n\t\t\t\t\t1,\n\t\t\t\t\t(size, child) => size + encodedSize(child, memo, conditions),\n\t\t\t\t)\n\t\t\tcase \"Ceiling\":\n\t\t\t\treturn (\n\t\t\t\t\t1 +\n\t\t\t\t\tencodedSize(node.cap, memo, conditions) +\n\t\t\t\t\tencodedSize(node.policy, memo, conditions)\n\t\t\t\t)\n\t\t}\n\t})\n\n/** Gives the JSON form of a tree, when it is not too large. */\nconst encodeTree = (node: Node): EncodedNode => {\n\tif (encodedSize(node) > maxEncodedNodes) {\n\t\tthrow new globalThis.Error(tooLargeMessage)\n\t}\n\treturn encodeNode(node)\n}\n\nconst tooLargeMessage = `The JSON form of this policy would have more than ${String(maxEncodedNodes)} nodes`\n\nconst encodeNode = (node: Node): EncodedNode => {\n\tswitch (node._tag) {\n\t\tcase \"Rules\":\n\t\t\treturn {\n\t\t\t\t_tag: \"Rules\",\n\t\t\t\talgorithm: node.algorithm,\n\t\t\t\t// The domain of a rule is not in its JSON form.\n\t\t\t\trules: node.rules.map(\n\t\t\t\t\t({ domain: _domain, ...value }) => ({ ...value }) as EncodedRule,\n\t\t\t\t),\n\t\t\t}\n\t\tcase \"All\":\n\t\tcase \"Any\":\n\t\tcase \"FirstOf\":\n\t\t\treturn { _tag: node._tag, policies: node.policies.map(encodeNode) }\n\t\tcase \"Ceiling\":\n\t\t\treturn {\n\t\t\t\t_tag: \"Ceiling\",\n\t\t\t\tcap: encodeNode(node.cap),\n\t\t\t\tpolicy: encodeNode(node.policy),\n\t\t\t}\n\t}\n}\n\n/**\n * The tree of a policy as a value that `JSON.stringify` keeps with no loss.\n * See `Condition.toJsonValue`.\n */\nconst jsonNode = (node: EncodedNode, meta: Schema.Top | undefined): unknown => {\n\tconst json = (child: EncodedNode) => jsonNode(child, meta)\n\tswitch (node._tag) {\n\t\tcase \"Rules\":\n\t\t\treturn {\n\t\t\t\t...node,\n\t\t\t\trules: Arr.map(node.rules, (value) => ({\n\t\t\t\t\t...value,\n\t\t\t\t\t...(value.when === undefined\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: { when: Condition.toJsonValue(value.when as Ast) }),\n\t\t\t\t\t// The `meta` of a rule is a decoded value. Its JSON form comes\n\t\t\t\t\t// from the `meta` Schema of the domain, as in `schema`.\n\t\t\t\t\t...(value.meta === undefined || meta === undefined\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\tmeta: Schema.encodeUnknownSync(\n\t\t\t\t\t\t\t\t\tmeta as Schema.Codec<unknown, unknown>,\n\t\t\t\t\t\t\t\t)(value.meta),\n\t\t\t\t\t\t\t}),\n\t\t\t\t})),\n\t\t\t}\n\t\tcase \"All\":\n\t\tcase \"Any\":\n\t\tcase \"FirstOf\":\n\t\t\treturn { ...node, policies: Arr.map(node.policies, json) }\n\t\tcase \"Ceiling\":\n\t\t\treturn { ...node, cap: json(node.cap), policy: json(node.policy) }\n\t}\n}\n\n/**\n * The class of every policy value. Two policies of one domain with the same\n * tree are equal. As JSON, a policy is its tree.\n */\nclass PolicyData extends Data.Class<{\n\treadonly domain: Domain.Any\n\treadonly node: Node\n}> {\n\ttoJSON(): unknown {\n\t\treturn jsonNode(encodeTree(this.node), this.domain.meta)\n\t}\n}\n\n/** The node of a policy, with no types, for the code below. */\nconst nodeOf = (policy: Any): Node => policy.node as Node\n\nconst fromNode = (domain: Domain.Any, node: Node): any =>\n\tnew PolicyData({ domain, node })\n\n/**\n * Makes a policy from a list of rules.\n *\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const rules: <\n\tD extends Domain.Any,\n\tRules extends Rule.Rule<any, any, any, D, never>,\n>(\n\tdomain: D,\n\trules: Iterable<Rules>,\n\toptions?: Options,\n) => Policy<\n\tD,\n\tRule.Error<Rules>,\n\tRule.Services<Rules>,\n\tRule.OpaqueOf<Rules>\n> = (domain, values, options) => {\n\tconst node = nodes.Rules({\n\t\talgorithm: options?.algorithm ?? \"denyOverrides\",\n\t\trules: Array.from(values),\n\t})\n\t// A value that is not a rule, such as a copy of a rule made with a spread,\n\t// may keep the type fields of another rule, and it does not work in a\n\t// generator. It is a mistake in the code, so it is a defect.\n\tif (!Arr.every(node.rules, Rule.isRule)) {\n\t\tthrow new globalThis.Error(\"A value in the list is not a rule\")\n\t}\n\t// A rule from a builder of another domain is a mistake in the code, so it\n\t// is a defect. Two domains may have the same types, so the types do not\n\t// find it.\n\tif (\n\t\tArr.some(node.rules, (value) => {\n\t\t\tconst origin = Rule.domainOf(value)\n\t\t\treturn origin !== undefined && origin !== domain\n\t\t})\n\t) {\n\t\tthrow new globalThis.Error(\n\t\t\t\"A rule comes from the builder of another domain\",\n\t\t)\n\t}\n\t// A rule from `Rule.make` keeps no domain, so its names are checked here.\n\tconst issues = validate(domain, encodeNode(node))\n\tif (issues.length > 0) {\n\t\tthrow new globalThis.Error(\n\t\t\t`A rule does not fit the domain: ${issues.map((issue) => issue.issue).join(\"; \")}`,\n\t\t)\n\t}\n\treturn fromNode(domain, node)\n}\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 =\n\t<D extends Domain.Any>(domain: D, options?: Options) =>\n\t<Rules extends Rule.Rule<any, any, any, D, never>, A>(\n\t\tbody: (builder: Rule.Builder<D>) => Generator<Rules, A, unknown>,\n\t): Policy<\n\t\tD,\n\t\tRule.Error<Rules>,\n\t\tRule.Services<Rules>,\n\t\tRule.OpaqueOf<Rules>\n\t> => {\n\t\tconst iterator = body(Rule.builder(domain))\n\t\t// Each rule goes back into the generator, as `yield*` gives it.\n\t\tconst collected = Arr.unfold(iterator.next(), (state) =>\n\t\t\tstate.done === true\n\t\t\t\t? Option.none()\n\t\t\t\t: Option.some([state.value, iterator.next(state.value)] as const),\n\t\t)\n\t\treturn rules(domain, collected, options)\n\t}\n\n/**\n * A policy with no rules. It is not applicable to any request.\n *\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const empty = <D extends Domain.Any>(domain: D): Policy<D> =>\n\trules(domain, [])\n\ntype Combined<D extends Domain.Any, Ps extends ReadonlyArray<Any>> = Policy<\n\tD,\n\tError<Ps[number]>,\n\tServices<Ps[number]>,\n\tOpaqueOf<Ps[number]>\n>\n\nconst sameDomain = (policies: ReadonlyArray<Any>): Domain.Any => {\n\t// A copy of a policy made with a spread may keep the type fields of another\n\t// policy. Only a policy value goes into a tree.\n\tif (!Arr.every(policies, isPolicy)) {\n\t\tthrow new globalThis.Error(\"A value in the list is not a policy\")\n\t}\n\tconst domain = policies[0]!.domain\n\tif (!Arr.every(policies, (policy) => policy.domain === domain)) {\n\t\tthrow new globalThis.Error(\n\t\t\t\"Policies from two domains can not be put together\",\n\t\t)\n\t}\n\treturn domain\n}\n\n/**\n * The most levels in a policy tree. A walk over a tree calls itself for each\n * level, so a much deeper tree could fill the stack and stop a check.\n */\nconst maxDepth = 256\n\n/** The number of levels of a policy tree. */\nconst heightOf = (node: Node, memo: Map<Node, number> = new Map()): number =>\n\tremember(memo, node, () => {\n\t\tconst height = (child: Node) => heightOf(child, memo)\n\t\tswitch (node._tag) {\n\t\t\tcase \"Rules\":\n\t\t\t\treturn 1\n\t\t\tcase \"All\":\n\t\t\tcase \"Any\":\n\t\t\tcase \"FirstOf\":\n\t\t\t\treturn (\n\t\t\t\t\t1 +\n\t\t\t\t\tArr.reduce(node.policies, 0, (top, child) =>\n\t\t\t\t\t\tMath.max(top, height(child)),\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\tcase \"Ceiling\":\n\t\t\t\treturn 1 + Math.max(height(node.cap), height(node.policy))\n\t\t}\n\t})\n\n/**\n * Makes a policy from a new node. Its children come from policies, so each\n * has at most `maxDepth` levels, and the walk of `heightOf` is safe.\n */\nconst fromCombined = (domain: Domain.Any, node: Node): any => {\n\tif (heightOf(node) > maxDepth) {\n\t\tthrow new globalThis.Error(\n\t\t\t`A policy tree may have at most ${maxDepth} levels`,\n\t\t)\n\t}\n\treturn fromNode(domain, node)\n}\n\nconst combine =\n\t(tag: \"All\" | \"Any\" | \"FirstOf\") =>\n\t(policies: ReadonlyArray<Any>): any =>\n\t\tfromCombined(\n\t\t\tsameDomain(policies),\n\t\t\tnodes[tag]({ policies: policies.map(nodeOf) }),\n\t\t)\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: <\n\tconst Ps extends readonly [Policy<any, any, any, any>, ...Array<Any>],\n>(\n\tpolicies: Ps,\n) => Combined<DomainOf<Ps[0]>, Ps> = 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: <\n\tconst Ps extends readonly [Policy<any, any, any, any>, ...Array<Any>],\n>(\n\tpolicies: Ps,\n) => Combined<DomainOf<Ps[0]>, Ps> = 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: <\n\tconst Ps extends readonly [Policy<any, any, any, any>, ...Array<Any>],\n>(\n\tpolicies: Ps,\n) => Combined<DomainOf<Ps[0]>, Ps> = 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, E2, R2, O2>(\n\t\tcap: Policy<D, E2, R2, O2>,\n\t): <E, R, O>(policy: Policy<D, E, R, O>) => Policy<D, E | E2, R | R2, O | O2>\n\t<D extends Domain.Any, E, R, O, E2, R2, O2>(\n\t\tpolicy: Policy<D, E, R, O>,\n\t\tcap: Policy<D, E2, R2, O2>,\n\t): Policy<D, E | E2, R | R2, O | O2>\n} = dual(2, (policy: Any, cap: Any): any =>\n\tfromCombined(\n\t\tsameDomain([policy, cap]),\n\t\tnodes.Ceiling({ cap: nodeOf(cap), policy: nodeOf(policy) }),\n\t),\n)\n\n/**\n * Gives the answer for a key from a memo, or works it out and keeps it. One\n * node may be a child of many nodes, so each walk over a tree keeps its work\n * on a node in a memo that the walk makes for itself. No memo lives longer\n * than one call.\n *\n * The memo is a native `Map`, because it must find a node by the node itself.\n * An Effect `HashMap` finds a key by `Equal`, and the nodes are Effect data,\n * so it would hash the whole structure of a node, and a shared child again for\n * each path to it.\n */\nconst remember = <K, A>(memo: Map<K, A>, key: K, work: () => A): A => {\n\t// A result may be `undefined`, as the result of a fold may be, so the test\n\t// asks for the key.\n\tif (memo.has(key)) {\n\t\treturn memo.get(key) as A\n\t}\n\tconst result = work()\n\tmemo.set(key, result)\n\treturn result\n}\n\n/** The memos of one walk over a policy tree. */\ninterface TreeMemo {\n\treadonly done: Map<Node, Node>\n\treadonly predicates: Map<Node, boolean>\n}\n\nconst provideNode = (\n\tnode: Node,\n\tcontext: Context.Context<never>,\n\tmemo: TreeMemo = { done: new Map(), predicates: new Map() },\n): Node =>\n\t// A node with no predicate needs no services, and it stays the same node.\n\t// One node may be a child of many nodes, and it gives one new node.\n\t!nodeHasPredicate(node, memo.predicates)\n\t\t? node\n\t\t: remember(memo.done, node, () => provideOnce(node, context, memo))\n\nconst provideOnce = (\n\tnode: Node,\n\tcontext: Context.Context<never>,\n\tmemo: TreeMemo,\n): Node => {\n\tswitch (node._tag) {\n\t\tcase \"Rules\":\n\t\t\treturn nodes.Rules({\n\t\t\t\talgorithm: node.algorithm,\n\t\t\t\trules: node.rules.map((value) =>\n\t\t\t\t\tvalue.when === undefined || !Condition.hasPredicate(value.when)\n\t\t\t\t\t\t? value\n\t\t\t\t\t\t: Rule.make({\n\t\t\t\t\t\t\t\t...value,\n\t\t\t\t\t\t\t\twhen: Condition.provideContext(value.when, context as never),\n\t\t\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t})\n\t\tcase \"All\":\n\t\tcase \"Any\":\n\t\tcase \"FirstOf\":\n\t\t\treturn nodes[node._tag]({\n\t\t\t\tpolicies: Arr.map(node.policies, (child) =>\n\t\t\t\t\tprovideNode(child, context, memo),\n\t\t\t\t),\n\t\t\t})\n\t\tcase \"Ceiling\":\n\t\t\treturn nodes.Ceiling({\n\t\t\t\tcap: provideNode(node.cap, context, memo),\n\t\t\t\tpolicy: provideNode(node.policy, context, memo),\n\t\t\t})\n\t}\n}\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, E, O>(\n\t\tpolicy: Policy<D, E, R, O>,\n\t) => Policy<D, E, never, O>\n\t<D extends Domain.Any, E, R, O>(\n\t\tpolicy: Policy<D, E, R, O>,\n\t\tcontext: Context.Context<R>,\n\t): Policy<D, E, never, O>\n} = dual(2, (policy: Any, context: Context.Context<never>): any =>\n\tfromNode(policy.domain, provideNode(nodeOf(policy), context)),\n)\n\n// Decisions\n\ninterface DecideContext {\n\treadonly action: string\n\treadonly kind: string\n\treadonly field: string | undefined\n\treadonly input: Condition.Input\n\t/** The resource of the kind, for the fields that a rule may grant. */\n\treadonly descriptor: Resource.Descriptor\n\t/** The rules that were tested, for {@link explain}. */\n\treadonly trace: Ref.Ref<Chunk.Chunk<Step>> | undefined\n\treadonly predicates: Map<Node, boolean>\n\t/**\n\t * The decisions of nodes with no predicates. One node may be a child of\n\t * many nodes, and its decision is the same each time, so it is made only\n\t * one time. A tree with shared nodes may have very many paths.\n\t */\n\treadonly decisions: Map<Node, Decision.Decision>\n}\n\nconst ruleApplies = (\n\tvalue: Rule.Any,\n\tcontext: DecideContext,\n\tpath: ReadonlyArray<number>,\n): Effect.Effect<boolean, unknown, unknown> => {\n\tif (!Rule.matchesTarget(value, context)) {\n\t\treturn Effect.succeed(false)\n\t}\n\tconst test =\n\t\tvalue.when === undefined\n\t\t\t? Effect.succeed(true)\n\t\t\t: // A rule of a node keeps no type of what it reads. The decision gives\n\t\t\t\t// it the value and the principal of the request.\n\t\t\t\tCondition.evaluate(value.when as Condition.Any, context.input)\n\tconst trace = context.trace\n\treturn trace === undefined\n\t\t? test\n\t\t: Effect.tap(test, (applies) =>\n\t\t\t\t// A chunk adds a step with no copy of the steps before.\n\t\t\t\tRef.update(trace, Chunk.append({ path, rule: value, applies })),\n\t\t\t)\n}\n\nconst fromRule = (value: Rule.Any): Decision.Decision =>\n\tvalue._tag === \"Allow\"\n\t\t? Decision.Allow({ rule: value })\n\t\t: value.reason === undefined\n\t\t\t? Decision.Deny({ rule: value })\n\t\t\t: Decision.Deny({ rule: value, reason: value.reason })\n\n/** Gives the first rule that applies, in order. */\nconst firstApplying = (\n\tcandidates: ReadonlyArray<readonly [Rule.Any, number]>,\n\tcontext: DecideContext,\n\tpath: ReadonlyArray<number>,\n): Effect.Effect<Option.Option<Rule.Any>, unknown, unknown> =>\n\tEffect.map(\n\t\tEffect.findFirst(candidates, ([value, index]) =>\n\t\t\truleApplies(value, context, [...path, index]),\n\t\t),\n\t\tOption.map(([value]) => value),\n\t)\n\n/** Gives the first result that is found, and tests `next` only when none is. */\nconst orElse = <A, E, R>(\n\tfirst: Effect.Effect<Option.Option<A>, E, R>,\n\tnext: () => Effect.Effect<Option.Option<A>, E, R>,\n): Effect.Effect<Option.Option<A>, E, R> =>\n\tEffect.filterOrElse(first, Option.isSome, next)\n\nconst decideRules = (\n\tnode: RulesNode,\n\tcontext: DecideContext,\n\tpath: ReadonlyArray<number>,\n): Effect.Effect<Decision.Decision, unknown, unknown> => {\n\tconst indexed = Arr.map(node.rules, (value, index) => [value, index] as const)\n\tconst denies = Arr.filter(indexed, ([value]) => value._tag === \"Deny\")\n\tconst allows = Arr.filter(indexed, ([value]) => value._tag === \"Allow\")\n\tconst first = (candidates: ReadonlyArray<readonly [Rule.Any, number]>) =>\n\t\tfirstApplying(candidates, context, path)\n\tconst found = (() => {\n\t\tswitch (node.algorithm) {\n\t\t\tcase \"denyOverrides\":\n\t\t\t\treturn orElse(first(denies), () => first(allows))\n\t\t\tcase \"permitOverrides\":\n\t\t\t\treturn orElse(first(allows), () => first(denies))\n\t\t\tcase \"firstApplicable\":\n\t\t\t\treturn first(indexed)\n\t\t\tcase \"lastApplicable\":\n\t\t\t\treturn first(Arr.reverse(indexed))\n\t\t}\n\t})()\n\treturn Effect.map(\n\t\tfound,\n\t\tOption.match({ onNone: () => Decision.NotApplicable, onSome: fromRule }),\n\t)\n}\n\nconst decideNode = (\n\tnode: Node,\n\tcontext: DecideContext,\n\tpath: ReadonlyArray<number>,\n): Effect.Effect<Decision.Decision, unknown, unknown> => {\n\t// A predicate that the request may use must run each time. A predicate of\n\t// a rule for another action, kind or field never runs, so the decision may\n\t// be kept. A trace keeps the steps of a node only the first time, so a\n\t// shared tree does not give a step for each path to a node.\n\tif (usesPredicate(node, context)) {\n\t\treturn decideOnce(node, context, path)\n\t}\n\tconst cached = context.decisions.get(node)\n\treturn cached !== undefined\n\t\t? Effect.succeed(cached)\n\t\t: Effect.tap(decideOnce(node, context, path), (decision) =>\n\t\t\t\tEffect.sync(() => context.decisions.set(node, decision)),\n\t\t\t)\n}\n\n/** The next step of a walk over children: stop with a decision, or go on. */\ntype WalkStep<S> =\n\t| { readonly _tag: \"Stop\"; readonly decision: Decision.Decision }\n\t| { readonly _tag: \"Next\"; readonly state: S }\n\n/**\n * Decides the children in order. After each child, `step` stops with a\n * decision, or gives the state for the next child. After the last child,\n * `end` gives the decision. A child after a stop is not decided, so its\n * predicates do not run.\n */\nconst walkChildren = <S>(\n\tchildren: ReadonlyArray<Node>,\n\tcontext: DecideContext,\n\tpath: ReadonlyArray<number>,\n\tstart: S,\n\tstep: (state: S, decision: Decision.Decision) => WalkStep<S>,\n\tend: (state: S) => Decision.Decision,\n): Effect.Effect<Decision.Decision, unknown, unknown> => {\n\tconst go = (\n\t\tindex: number,\n\t\tstate: S,\n\t): Effect.Effect<Decision.Decision, unknown, unknown> =>\n\t\tindex === children.length\n\t\t\t? Effect.succeed(end(state))\n\t\t\t: Effect.flatMap(\n\t\t\t\t\tdecideNode(children[index]!, context, [...path, index]),\n\t\t\t\t\t(decision) => {\n\t\t\t\t\t\tconst next = step(state, decision)\n\t\t\t\t\t\treturn next._tag === \"Stop\"\n\t\t\t\t\t\t\t? Effect.succeed(next.decision)\n\t\t\t\t\t\t\t: go(index + 1, next.state)\n\t\t\t\t\t},\n\t\t\t\t)\n\treturn go(0, start)\n}\n\nconst stop = (decision: Decision.Decision): WalkStep<never> => ({\n\t_tag: \"Stop\",\n\tdecision,\n})\n\nconst next = <S>(state: S): WalkStep<S> => ({ _tag: \"Next\", state })\n\nconst decideOnce = (\n\tnode: Node,\n\tcontext: DecideContext,\n\tpath: ReadonlyArray<number>,\n): Effect.Effect<Decision.Decision, unknown, unknown> => {\n\tswitch (node._tag) {\n\t\tcase \"Rules\":\n\t\t\treturn decideRules(node, context, path)\n\t\tcase \"All\":\n\t\t\t// One deny is enough to deny. Every child must allow.\n\t\t\treturn walkChildren(\n\t\t\t\tnode.policies,\n\t\t\t\tcontext,\n\t\t\t\tpath,\n\t\t\t\t{\n\t\t\t\t\tfirstAllow: Option.none<Decision.Decision>(),\n\t\t\t\t\tallAllow: node.policies.length > 0,\n\t\t\t\t},\n\t\t\t\t(state, decision) =>\n\t\t\t\t\tdecision._tag === \"Deny\"\n\t\t\t\t\t\t? stop(decision)\n\t\t\t\t\t\t: next({\n\t\t\t\t\t\t\t\tfirstAllow: Option.orElse(state.firstAllow, () =>\n\t\t\t\t\t\t\t\t\tdecision._tag === \"Allow\"\n\t\t\t\t\t\t\t\t\t\t? Option.some(decision)\n\t\t\t\t\t\t\t\t\t\t: Option.none(),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tallAllow: state.allAllow && decision._tag === \"Allow\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t(state) =>\n\t\t\t\t\tstate.allAllow\n\t\t\t\t\t\t? Option.getOrElse(state.firstAllow, () => Decision.NotApplicable)\n\t\t\t\t\t\t: Decision.NotApplicable,\n\t\t\t)\n\t\tcase \"Any\":\n\t\t\t// One allow is enough. Without one, the first deny denies.\n\t\t\treturn walkChildren(\n\t\t\t\tnode.policies,\n\t\t\t\tcontext,\n\t\t\t\tpath,\n\t\t\t\tOption.none<Decision.Decision>(),\n\t\t\t\t(firstDeny, decision) =>\n\t\t\t\t\tdecision._tag === \"Allow\"\n\t\t\t\t\t\t? stop(decision)\n\t\t\t\t\t\t: next(\n\t\t\t\t\t\t\t\tOption.orElse(firstDeny, () =>\n\t\t\t\t\t\t\t\t\tdecision._tag === \"Deny\"\n\t\t\t\t\t\t\t\t\t\t? Option.some(decision)\n\t\t\t\t\t\t\t\t\t\t: Option.none(),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t),\n\t\t\t\t(firstDeny) =>\n\t\t\t\t\tOption.getOrElse(firstDeny, () => Decision.NotApplicable),\n\t\t\t)\n\t\tcase \"FirstOf\":\n\t\t\treturn walkChildren(\n\t\t\t\tnode.policies,\n\t\t\t\tcontext,\n\t\t\t\tpath,\n\t\t\t\tundefined,\n\t\t\t\t(_, decision) =>\n\t\t\t\t\tdecision._tag === \"NotApplicable\" ? next(undefined) : stop(decision),\n\t\t\t\t() => Decision.NotApplicable,\n\t\t\t)\n\t\tcase \"Ceiling\":\n\t\t\t// A deny of the cap wins. Else the policy decides.\n\t\t\treturn Effect.filterOrElse(\n\t\t\t\tdecideNode(node.cap, context, [...path, 0]),\n\t\t\t\t(capped) => capped._tag === \"Deny\",\n\t\t\t\t() => decideNode(node.policy, context, [...path, 1]),\n\t\t\t)\n\t}\n}\n\n/**\n * Tests if a request fits its kind: the action is an action of the kind, and\n * the field, if there is one, is a field of the kind. The types check this,\n * but a value with a union type, or a value from outside, may get past them.\n * A rule for every action (`\"*\"`) must not cover an action that the kind does\n * not have, so such a request is not applicable.\n *\n * @stability stable\n * @category predicates\n * @since 1.0.0\n */\nexport const fitsKind = (\n\tdescriptor: Resource.Descriptor,\n\trequest: { readonly action: string; readonly field?: string | undefined },\n): boolean =>\n\tdescriptor.actions.includes(request.action) &&\n\t(request.field === undefined ||\n\t\tdescriptor.fieldPaths.includes(request.field) ||\n\t\tResource.hasPath(descriptor.schema, request.field) ||\n\t\tResource.hasGetter(descriptor.schema, request.field))\n\nconst makeContext = (\n\tdomain: Domain.Any,\n\trequest: AnyRequest,\n\ttrace: Ref.Ref<Chunk.Chunk<Step>> | undefined,\n): DecideContext | undefined => {\n\tconst kind = Resource.kindOf(request.resource)\n\tconst descriptor =\n\t\tkind === undefined ? undefined : Domain.descriptorOf(domain, kind)\n\tif (\n\t\tkind === undefined ||\n\t\tdescriptor === undefined ||\n\t\t!fitsKind(descriptor, request)\n\t) {\n\t\treturn undefined\n\t}\n\treturn {\n\t\taction: request.action,\n\t\tkind,\n\t\tfield: request.field,\n\t\tinput: {\n\t\t\tvalue: request.resource,\n\t\t\tprincipal: request.principal,\n\t\t\tpath: descriptor.path,\n\t\t},\n\t\tdescriptor,\n\t\ttrace,\n\t\tpredicates: new Map(),\n\t\tdecisions: new Map(),\n\t}\n}\n\nconst decideAny = (\n\tpolicy: Any,\n\trequest: AnyRequest,\n): Effect.Effect<Decision.Decision, unknown, unknown> =>\n\t// Each run of the Effect needs its own store of decisions, because the\n\t// resource value may change between two runs.\n\tEffect.suspend(() => {\n\t\tconst context = makeContext(policy.domain, request, undefined)\n\t\treturn context === undefined\n\t\t\t? Effect.succeed(Decision.NotApplicable)\n\t\t\t: decideNode(nodeOf(policy), context, [])\n\t})\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\t<D extends Domain.Any = never>(\n\t\trequest: Request<D>,\n\t): <E, R, O>(\n\t\tpolicy: Policy<D, E, R, O>,\n\t) => Effect.Effect<Decision.Decision, E, R>\n\t<D extends Domain.Any, E, R, O>(\n\t\tpolicy: Policy<D, E, R, O>,\n\t\trequest: Request<NoInfer<D>>,\n\t): Effect.Effect<Decision.Decision, E, R>\n} = dual(2, 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\t<D extends Domain.Any = never>(\n\t\trequest: Request<D>,\n\t): (policy: Policy<D>) => Decision.Decision\n\t<D extends Domain.Any>(\n\t\tpolicy: Policy<D>,\n\t\trequest: Request<NoInfer<D>>,\n\t): Decision.Decision\n} = dual(2, (policy: Any, request: AnyRequest): Decision.Decision =>\n\tEffect.runSync(\n\t\t// The public type of `decideSync` takes only policies with no\n\t\t// predicates, so this Effect has no error and needs no services.\n\t\t// @effect-diagnostics-next-line unsafeEffectTypeAssertion:off\n\t\tdecideAny(policy, request) as Effect.Effect<Decision.Decision>,\n\t),\n)\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. A node with no predicate that the\n * request may use gives the same decision each time, so its rules are tested,\n * and are in the steps, only the first time. So a small tree with many shared\n * nodes gives a short list of steps.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const explain: {\n\t<D extends Domain.Any = never>(\n\t\trequest: Request<D>,\n\t): <E, R, O>(policy: Policy<D, E, R, O>) => Effect.Effect<Explanation, E, R>\n\t<D extends Domain.Any, E, R, O>(\n\t\tpolicy: Policy<D, E, R, O>,\n\t\trequest: Request<NoInfer<D>>,\n\t): Effect.Effect<Explanation, E, R>\n} = dual(\n\t2,\n\t(\n\t\tpolicy: Any,\n\t\trequest: AnyRequest,\n\t): Effect.Effect<Explanation, unknown, unknown> =>\n\t\t// Each run of the Effect needs its own trace, so the trace is made inside\n\t\t// the Effect.\n\t\tEffect.gen(function* () {\n\t\t\tconst trace = yield* Ref.make(Chunk.empty<Step>())\n\t\t\tconst context = makeContext(policy.domain, request, trace)\n\t\t\tif (context === undefined) {\n\t\t\t\treturn { decision: Decision.NotApplicable, steps: [] }\n\t\t\t}\n\t\t\tconst decision = yield* decideNode(nodeOf(policy), context, [])\n\t\t\treturn { decision, steps: Chunk.toReadonlyArray(yield* Ref.get(trace)) }\n\t\t}),\n) as never\n\n/**\n * Tests if a deny rule of the request names a part inside `field`.\n */\nconst deniesInside = (\n\tnode: Node,\n\ttarget: { readonly action: string; readonly kind: string },\n\tfield: string,\n\t// A native set: it must find a node by the node itself. See `remember`.\n\tseen: Set<Node> = new Set(),\n): boolean => {\n\t// One node may be a child of many nodes. It is tested one time.\n\tif (seen.has(node)) {\n\t\treturn false\n\t}\n\tseen.add(node)\n\tswitch (node._tag) {\n\t\tcase \"Rules\":\n\t\t\treturn node.rules.some(\n\t\t\t\t(value) =>\n\t\t\t\t\tvalue._tag === \"Deny\" &&\n\t\t\t\t\tvalue.fields !== undefined &&\n\t\t\t\t\tvalue.fields.some((pattern) => Rule.matchesInside(pattern, field)) &&\n\t\t\t\t\t(value.actions.includes(\"*\") ||\n\t\t\t\t\t\tvalue.actions.includes(target.action)) &&\n\t\t\t\t\t(value.resources.includes(\"*\") ||\n\t\t\t\t\t\tvalue.resources.includes(target.kind)),\n\t\t\t)\n\t\tcase \"All\":\n\t\tcase \"Any\":\n\t\tcase \"FirstOf\":\n\t\t\treturn node.policies.some((child) =>\n\t\t\t\tdeniesInside(child, target, field, seen),\n\t\t\t)\n\t\tcase \"Ceiling\":\n\t\t\treturn (\n\t\t\t\tdeniesInside(node.cap, target, field, seen) ||\n\t\t\t\tdeniesInside(node.policy, target, field, seen)\n\t\t\t)\n\t}\n}\n\n/**\n * Gives the fields of a resource value that the policy lets a request use. It\n * tests each field 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: {\n\t<D extends Domain.Any = never>(\n\t\trequest: FieldlessRequest<D>,\n\t): <E, R, O>(\n\t\tpolicy: Policy<D, E, R, O>,\n\t) => Effect.Effect<ReadonlyArray<string>, E, R>\n\t<D extends Domain.Any, E, R, O>(\n\t\tpolicy: Policy<D, E, R, O>,\n\t\trequest: FieldlessRequest<NoInfer<D>>,\n\t): Effect.Effect<ReadonlyArray<string>, E, R>\n} = dual(\n\t2,\n\t(\n\t\tpolicy: Any,\n\t\trequest: Omit<AnyRequest, \"field\">,\n\t): Effect.Effect<ReadonlyArray<string>, unknown, unknown> => {\n\t\tconst kind = Resource.kindOf(request.resource)\n\t\tconst descriptor: Resource.Descriptor | undefined =\n\t\t\tkind === undefined ? undefined : Domain.descriptorOf(policy.domain, kind)\n\t\tif (descriptor === undefined) {\n\t\t\treturn Effect.succeed([])\n\t\t}\n\t\treturn Effect.filter(descriptor.fieldPaths, (field) =>\n\t\t\tEffect.map(\n\t\t\t\tdecideAny(policy, { ...request, field }),\n\t\t\t\t(result) =>\n\t\t\t\t\tresult._tag === \"Allow\" &&\n\t\t\t\t\t!(\n\t\t\t\t\t\tdescriptor.openPaths.includes(field) &&\n\t\t\t\t\t\tdeniesInside(\n\t\t\t\t\t\t\tnodeOf(policy),\n\t\t\t\t\t\t\t{ ...request, kind: descriptor.kind },\n\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t)\n\t\t\t\t\t),\n\t\t\t),\n\t\t)\n\t},\n) as never\n\n// Residual conditions\n\ntype Ast = Condition.Ast\n\n/**\n * The two residual conditions of a request. See {@link residuals}.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport interface Residuals<E = never, R = never, O = never, I = unknown> {\n\t/** The condition on resource values for which the policy allows. */\n\treadonly allow: Condition.Condition<E, R, O, I>\n\t/** The condition on resource values for which the policy denies. */\n\treadonly deny: Condition.Condition<E, R, O, I>\n}\n\n/**\n * A request about a kind of resource, with no types.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport interface AnyKindRequest {\n\treadonly principal: object\n\treadonly action: string\n\treadonly kind: string\n\treadonly field?: string | undefined\n\t/**\n\t * A scope needs the types of the domain for its builder. With the request\n\t * first, the domain is not known yet, so give the policy first.\n\t */\n\treadonly within?: never\n}\n\n/**\n * `unknown` when the request `Req` is a request of the type `T`, and `never`\n * when it is not. With the request first and the policy later, the request is\n * checked when the policy, and so the domain, is known. For a union, each\n * member must be such a request.\n */\ntype Fits<Req, T> = [Req] extends [T] ? unknown : never\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\nconst always: Ast = Condition.always\nconst never: Ast = Condition.never\n\n/**\n * The most nodes that a residual condition may have. A policy tree may use a\n * condition of a child two times, in its allow condition and in its deny\n * condition, so a small policy may give a very large condition. Past this\n * size, `residual` throws an error.\n */\nconst maxResidualSize = 10_000\n\n/**\n * The most levels that a residual condition may have. The rules of an ordered\n * algorithm, such as `firstApplicable`, give one level for each run of rules\n * with one tag. A walk over a condition calls itself for each level, so a much\n * deeper condition could fill the stack. Past this depth, `residual` throws an\n * error.\n */\nconst maxResidualDepth = 500\n\n/**\n * A residual condition is too large. See {@link maxResidualSize} and\n * {@link maxResidualDepth}.\n */\nclass TooLarge {}\n\n/**\n * Makes conditions for one residual, with no types. Each step simplifies the\n * condition, and it stops the work when the condition is too large. The\n * steps keep their work for the parts they have seen, for this residual only.\n */\ninterface Build {\n\t// A list goes in as an array, not as arguments: a call may take only so\n\t// many arguments, and a policy may have more rules.\n\treadonly and: (values: ReadonlyArray<Ast>) => Ast\n\treadonly or: (values: ReadonlyArray<Ast>) => Ast\n\treadonly not: (value: Ast) => Ast\n}\n\nconst makeBuild = (): Build => {\n\tconst simplify = Condition.simplifier()\n\tconst sizes = new Map<Ast, number>()\n\t/** Gives the number of nodes in a condition, as JSON would have them. */\n\tconst sizeOf = (ast: Ast): number =>\n\t\tremember(sizes, ast, () => {\n\t\t\tswitch (ast._tag) {\n\t\t\t\tcase \"And\":\n\t\t\t\tcase \"Or\":\n\t\t\t\t\treturn Arr.reduce(\n\t\t\t\t\t\tast.conditions,\n\t\t\t\t\t\t1,\n\t\t\t\t\t\t(size, child) => size + sizeOf(child),\n\t\t\t\t\t)\n\t\t\t\tcase \"Not\":\n\t\t\t\t\treturn 1 + sizeOf(ast.condition)\n\t\t\t\tdefault:\n\t\t\t\t\treturn 1\n\t\t\t}\n\t\t})\n\tconst depths = new Map<Ast, number>()\n\t/**\n\t * Gives the number of levels in a condition. Each child went through\n\t * `limit`, so this walk is not deeper than `maxResidualDepth`.\n\t */\n\tconst depthOf = (ast: Ast): number =>\n\t\tremember(depths, ast, () => {\n\t\t\tswitch (ast._tag) {\n\t\t\t\tcase \"And\":\n\t\t\t\tcase \"Or\":\n\t\t\t\t\treturn (\n\t\t\t\t\t\t1 +\n\t\t\t\t\t\tArr.reduce(ast.conditions, 0, (top, child) =>\n\t\t\t\t\t\t\tMath.max(top, depthOf(child)),\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\tcase \"Not\":\n\t\t\t\t\treturn 1 + depthOf(ast.condition)\n\t\t\t\tdefault:\n\t\t\t\t\treturn 1\n\t\t\t}\n\t\t})\n\tconst limit = (ast: Ast): Ast => {\n\t\tif (sizeOf(ast) > maxResidualSize || depthOf(ast) > maxResidualDepth) {\n\t\t\tthrow new TooLarge()\n\t\t}\n\t\treturn ast\n\t}\n\t// These steps work on nodes with no types, so they leave out the type\n\t// field of a condition.\n\treturn {\n\t\tand: (values) =>\n\t\t\tlimit(simplify(Condition.andAll(values as ReadonlyArray<never>))),\n\t\tor: (values) =>\n\t\t\tlimit(simplify(Condition.orAll(values as ReadonlyArray<never>))),\n\t\tnot: (value) => limit(simplify(Condition.not(value as never))),\n\t}\n}\n\n/** The two residual conditions of a node, with no types. */\ninterface Pair {\n\treadonly allow: Ast\n\treadonly deny: Ast\n}\n\ninterface ResidualContext {\n\treadonly action: string\n\treadonly kind: string\n\treadonly field: string | undefined\n\treadonly input: {\n\t\treadonly principal: object\n\t\treadonly path: Condition.Input[\"path\"]\n\t}\n\t/** The resource of the kind, for the fields that a rule may grant. */\n\treadonly descriptor: Resource.Descriptor\n\t/**\n\t * The work done on each node. One node may be a child of many nodes, so\n\t * the work on it is done only one time.\n\t */\n\treadonly pairs: Map<Node, Pair>\n\treadonly predicates: Map<Node, boolean>\n\treadonly build: Build\n}\n\nconst ruleCondition = (value: Rule.Any, context: ResidualContext): Ast =>\n\t!Rule.matchesTarget(value, context)\n\t\t? never\n\t\t: value.when === undefined\n\t\t\t? always\n\t\t\t: Condition.partial(value.when as Condition.Any, context.input)\n\n/**\n * Gives the conditions for \"the first rule that applies is an allow rule\" and\n * \"the first rule that applies is a deny rule\".\n */\nconst firstApplicableResidual = (\n\tvalues: ReadonlyArray<Rule.Any>,\n\tcontext: ResidualContext,\n): Pair => {\n\tconst { and, not, or } = context.build\n\t// The rules go in runs of one tag, from the last run to the first. The\n\t// conditions of a run go into one node at once. With one node for each\n\t// rule, each step would flatten the whole condition again.\n\tconst runs = Arr.isReadonlyArrayNonEmpty(values)\n\t\t? Arr.groupWith(values, (a, b) => a._tag === b._tag)\n\t\t: []\n\treturn Arr.reduceRight(\n\t\truns,\n\t\t{ allow: never, deny: never },\n\t\t(rest: Pair, run): Pair => {\n\t\t\tconst applies = or(Arr.map(run, (value) => ruleCondition(value, context)))\n\t\t\treturn run[0]._tag === \"Allow\"\n\t\t\t\t? {\n\t\t\t\t\t\tallow: or([applies, rest.allow]),\n\t\t\t\t\t\tdeny: and([not(applies), rest.deny]),\n\t\t\t\t\t}\n\t\t\t\t: {\n\t\t\t\t\t\tallow: and([not(applies), rest.allow]),\n\t\t\t\t\t\tdeny: or([applies, rest.deny]),\n\t\t\t\t\t}\n\t\t},\n\t)\n}\n\nconst residualNode = (node: Node, context: ResidualContext): Pair =>\n\tremember(context.pairs, node, () => residualOnce(node, context))\n\nconst residualOnce = (node: Node, context: ResidualContext): Pair => {\n\tconst { and, not, or } = context.build\n\tswitch (node._tag) {\n\t\tcase \"Rules\": {\n\t\t\tswitch (node.algorithm) {\n\t\t\t\tcase \"denyOverrides\": {\n\t\t\t\t\tconst deny = or(\n\t\t\t\t\t\tnode.rules\n\t\t\t\t\t\t\t.filter((value) => value._tag === \"Deny\")\n\t\t\t\t\t\t\t.map((value) => ruleCondition(value, context)),\n\t\t\t\t\t)\n\t\t\t\t\tconst allow = and([\n\t\t\t\t\t\tnot(deny),\n\t\t\t\t\t\tor(\n\t\t\t\t\t\t\tnode.rules\n\t\t\t\t\t\t\t\t.filter((value) => value._tag === \"Allow\")\n\t\t\t\t\t\t\t\t.map((value) => ruleCondition(value, context)),\n\t\t\t\t\t\t),\n\t\t\t\t\t])\n\t\t\t\t\treturn { allow, deny }\n\t\t\t\t}\n\t\t\t\tcase \"permitOverrides\": {\n\t\t\t\t\tconst allow = or(\n\t\t\t\t\t\tnode.rules\n\t\t\t\t\t\t\t.filter((value) => value._tag === \"Allow\")\n\t\t\t\t\t\t\t.map((value) => ruleCondition(value, context)),\n\t\t\t\t\t)\n\t\t\t\t\tconst deny = and([\n\t\t\t\t\t\tnot(allow),\n\t\t\t\t\t\tor(\n\t\t\t\t\t\t\tnode.rules\n\t\t\t\t\t\t\t\t.filter((value) => value._tag === \"Deny\")\n\t\t\t\t\t\t\t\t.map((value) => ruleCondition(value, context)),\n\t\t\t\t\t\t),\n\t\t\t\t\t])\n\t\t\t\t\treturn { allow, deny }\n\t\t\t\t}\n\t\t\t\tcase \"firstApplicable\":\n\t\t\t\t\treturn firstApplicableResidual(node.rules, context)\n\t\t\t\tcase \"lastApplicable\":\n\t\t\t\t\treturn firstApplicableResidual(node.rules.slice().reverse(), context)\n\t\t\t}\n\t\t}\n\t\t// falls through: every algorithm returns above\n\t\tcase \"All\": {\n\t\t\tif (node.policies.length === 0) {\n\t\t\t\treturn { allow: never, deny: never }\n\t\t\t}\n\t\t\tconst pairs = node.policies.map((child) => residualNode(child, context))\n\t\t\tconst deny = or(pairs.map((pair) => pair.deny))\n\t\t\tconst allow = and([...pairs.map((pair) => pair.allow), not(deny)])\n\t\t\treturn { allow, deny }\n\t\t}\n\t\tcase \"Any\": {\n\t\t\tconst pairs = node.policies.map((child) => residualNode(child, context))\n\t\t\tconst allow = or(pairs.map((pair) => pair.allow))\n\t\t\tconst deny = and([not(allow), or(pairs.map((pair) => pair.deny))])\n\t\t\treturn { allow, deny }\n\t\t}\n\t\tcase \"FirstOf\": {\n\t\t\t// The first child that gives an answer wins.\n\t\t\treturn Arr.reduceRight(\n\t\t\t\tnode.policies,\n\t\t\t\t{ allow: never, deny: never },\n\t\t\t\t(rest: Pair, child): Pair => {\n\t\t\t\t\tconst pair = residualNode(child, context)\n\t\t\t\t\treturn {\n\t\t\t\t\t\tallow: or([pair.allow, and([not(pair.deny), rest.allow])]),\n\t\t\t\t\t\tdeny: or([pair.deny, and([not(pair.allow), rest.deny])]),\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\t\tcase \"Ceiling\": {\n\t\t\tconst cap = residualNode(node.cap, context)\n\t\t\tconst inner = residualNode(node.policy, context)\n\t\t\treturn {\n\t\t\t\tallow: and([not(cap.deny), inner.allow]),\n\t\t\t\tdeny: or([cap.deny, inner.deny]),\n\t\t\t}\n\t\t}\n\t}\n}\n\n/** The name of the predicate of a residual condition that runs `decide`. */\nconst policyPredicate = \"policy\"\n\n/** Tests if a rule of a policy tree has a predicate. */\nconst nodeHasPredicate = (\n\tnode: Node,\n\tmemo: Map<Node, boolean> = new Map(),\n): boolean =>\n\tremember(memo, node, () => {\n\t\tconst test = (child: Node) => nodeHasPredicate(child, memo)\n\t\tswitch (node._tag) {\n\t\t\tcase \"Rules\":\n\t\t\t\treturn Arr.some(\n\t\t\t\t\tnode.rules,\n\t\t\t\t\t(value) =>\n\t\t\t\t\t\tvalue.when !== undefined && Condition.hasPredicate(value.when),\n\t\t\t\t)\n\t\t\tcase \"All\":\n\t\t\tcase \"Any\":\n\t\t\tcase \"FirstOf\":\n\t\t\t\treturn Arr.some(node.policies, test)\n\t\t\tcase \"Ceiling\":\n\t\t\t\treturn test(node.cap) || test(node.policy)\n\t\t}\n\t})\n\n/** Tests if a rule that the request may use has a predicate. */\n/** What {@link usesPredicate} needs: the request and a memo. */\ninterface PredicateContext {\n\treadonly action: string\n\treadonly kind: string\n\treadonly field: string | undefined\n\treadonly descriptor: Resource.Descriptor\n\treadonly predicates: Map<Node, boolean>\n}\n\nconst usesPredicate = (node: Node, context: PredicateContext): boolean =>\n\tremember(context.predicates, node, () => usesPredicateOnce(node, context))\n\nconst usesPredicateOnce = (node: Node, context: PredicateContext): boolean => {\n\tswitch (node._tag) {\n\t\tcase \"Rules\":\n\t\t\treturn node.rules.some(\n\t\t\t\t(value) =>\n\t\t\t\t\tvalue.when !== undefined &&\n\t\t\t\t\tCondition.hasPredicate(value.when) &&\n\t\t\t\t\tRule.matchesTarget(value, context),\n\t\t\t)\n\t\tcase \"All\":\n\t\tcase \"Any\":\n\t\tcase \"FirstOf\":\n\t\t\treturn node.policies.some((child) => usesPredicate(child, context))\n\t\tcase \"Ceiling\":\n\t\t\treturn (\n\t\t\t\tusesPredicate(node.cap, context) || usesPredicate(node.policy, context)\n\t\t\t)\n\t}\n}\n\nconst isScopeValue = (operand: Condition.Operand): boolean =>\n\toperand._tag === \"Principal\" ||\n\toperand.value === null ||\n\ttypeof operand.value === \"string\" ||\n\ttypeof operand.value === \"number\" ||\n\ttypeof operand.value === \"boolean\"\n\n/**\n * Gives the problem of a scope that is not plain data, or `undefined` when it\n * is plain data. A predicate, or a value that a condition can not hold, such\n * as `undefined` from a route parameter, is a defect: such a scope could make\n * a check pass on the wrong values. A shared node is tested one time.\n */\nconst scopeProblem = (\n\tast: Ast,\n\tmemo: Map<Ast, string | null> = new Map(),\n): string | undefined =>\n\tremember(memo, ast, (): string | null => {\n\t\tswitch (ast._tag) {\n\t\t\tcase \"Predicate\":\n\t\t\t\treturn \"can not have a predicate\"\n\t\t\tcase \"Compare\":\n\t\t\t\treturn isScopeValue(ast.value)\n\t\t\t\t\t? null\n\t\t\t\t\t: `has a value for \"${ast.field}\" that is not a scalar`\n\t\t\tcase \"In\":\n\t\t\t\treturn Arr.every(ast.values, isScopeValue)\n\t\t\t\t\t? null\n\t\t\t\t\t: `has a value for \"${ast.field}\" that is not a scalar`\n\t\t\tcase \"Under\":\n\t\t\t\treturn Arr.every(ast.prefix, isScopeValue)\n\t\t\t\t\t? null\n\t\t\t\t\t: \"has a path part that is not a scalar\"\n\t\t\tcase \"And\":\n\t\t\tcase \"Or\":\n\t\t\t\treturn (\n\t\t\t\t\tOption.getOrNull(\n\t\t\t\t\t\tArr.findFirst(\n\t\t\t\t\t\t\tArr.map(ast.conditions, (child) => scopeProblem(child, memo)),\n\t\t\t\t\t\t\t(problem) => problem !== undefined,\n\t\t\t\t\t\t),\n\t\t\t\t\t) ?? null\n\t\t\t\t)\n\t\t\tcase \"Not\":\n\t\t\t\treturn scopeProblem(ast.condition, memo) ?? null\n\t\t\tdefault:\n\t\t\t\treturn null\n\t\t}\n\t}) ?? undefined\n\n/**\n * Gives the condition of a scope, with the principal and the path in it.\n * With no scope, it is `True`.\n */\n/**\n * The fields that a scope reads, before it is made smaller. A smaller scope\n * may leave out a read that fails, such as a getter.\n */\nconst scopeFields = (within: unknown): ReadonlyArray<string> =>\n\twithin === undefined\n\t\t? []\n\t\t: Condition.fields(\n\t\t\t\t(within as (builder: unknown) => Ast)(Condition.builder()),\n\t\t\t)\n\nconst scopeOf = (within: unknown, input: ResidualContext[\"input\"]): Ast => {\n\tif (within === undefined) {\n\t\treturn always\n\t}\n\tconst ast = (within as (builder: unknown) => Ast)(Condition.builder())\n\tconst problem = scopeProblem(ast)\n\tif (problem !== undefined) {\n\t\tthrow new globalThis.Error(`A scope ${problem}`)\n\t}\n\treturn Condition.partial(ast as Condition.Condition, input)\n}\n\n/** A request about a kind with no types, with the scope of a target. */\ninterface ScopedRequest {\n\treadonly principal: object\n\treadonly action: string\n\treadonly kind: string\n\treadonly field?: string | undefined\n\treadonly within?: unknown\n}\n\n/** The scope of a request, and the residual conditions inside it. */\ninterface Scoped extends Pair {\n\treadonly scope: Ast\n\treadonly schema: Schema.Top | undefined\n}\n\nconst residualsAny = (policy: Any, request: ScopedRequest): Pair =>\n\tscopedResiduals(policy, request)\n\nconst scopedResiduals = (policy: Any, request: ScopedRequest): Scoped => {\n\tconst descriptor = Domain.descriptorOf(policy.domain, request.kind)\n\tif (descriptor === undefined || !fitsKind(descriptor, request)) {\n\t\treturn { scope: never, allow: never, deny: never, schema: undefined }\n\t}\n\t// A scope is made smaller below, and that may leave out a read of a\n\t// getter that fails. So such a scope has no residual.\n\tif (scopeReadsGetter(request, descriptor)) {\n\t\tthrow new globalThis.Error(\n\t\t\t\"The scope of this request reads a getter, so it has no residual condition\",\n\t\t)\n\t}\n\tconst input = { principal: request.principal, path: descriptor.path }\n\tconst scope = scopeOf(request.within, input)\n\tconst build = makeBuild()\n\tconst and = build.and\n\tconst inScope = (pair: Pair): Scoped => ({\n\t\tscope,\n\t\tallow: and([scope, pair.allow]),\n\t\tdeny: and([scope, pair.deny]),\n\t\tschema: descriptor.schema,\n\t})\n\tif (scope._tag === \"False\") {\n\t\treturn inScope({ allow: never, deny: never })\n\t}\n\tconst context: ResidualContext = {\n\t\taction: request.action,\n\t\tkind: request.kind,\n\t\tfield: request.field,\n\t\tinput,\n\t\tdescriptor,\n\t\tpairs: new Map(),\n\t\tpredicates: new Map(),\n\t\tbuild,\n\t}\n\tif (!usesPredicate(nodeOf(policy), context)) {\n\t\t// A read of a getter may fail when `decide` runs, and a smaller\n\t\t// condition may leave the read out. So a plain residual can not agree\n\t\t// with `decide`, and there is none.\n\t\tif (readsGetter(policy, request, descriptor)) {\n\t\t\tthrow new globalThis.Error(\n\t\t\t\t\"A rule of this request reads a getter, so it has no residual condition\",\n\t\t\t)\n\t\t}\n\t\ttry {\n\t\t\treturn inScope(residualNode(nodeOf(policy), context))\n\t\t} catch (error) {\n\t\t\t// The type of the residual of a plain policy says that it has no\n\t\t\t// predicate, so it can not be the predicate below. The policy is too\n\t\t\t// large for a residual, and that is a defect.\n\t\t\tif (error instanceof TooLarge) {\n\t\t\t\tthrow new globalThis.Error(\n\t\t\t\t\t`The residual condition of this request would have more than ${String(maxResidualSize)} nodes or ${String(maxResidualDepth)} levels`,\n\t\t\t\t)\n\t\t\t}\n\t\t\tthrow error\n\t\t}\n\t}\n\t// A predicate may fail, and it may give another answer each time it runs.\n\t// A tree of `And` and `Or` nodes can not run the predicates in the same\n\t// order and the same number of times as `decide`. So the residual is one\n\t// predicate that runs `decide` for each value.\n\tconst decision = (value: object) =>\n\t\tdecideNode(\n\t\t\tpolicy.node,\n\t\t\t{\n\t\t\t\taction: request.action,\n\t\t\t\tkind: request.kind,\n\t\t\t\tfield: request.field,\n\t\t\t\tinput: {\n\t\t\t\t\tvalue,\n\t\t\t\t\tprincipal: request.principal,\n\t\t\t\t\tpath: descriptor.path,\n\t\t\t\t},\n\t\t\t\tdescriptor,\n\t\t\t\ttrace: undefined,\n\t\t\t\tpredicates: new Map(),\n\t\t\t\tdecisions: new Map(),\n\t\t\t},\n\t\t\t[],\n\t\t)\n\t// A value of another kind is not a value that the residual is about, so\n\t// the rules of this kind must not run on it.\n\tconst test = (tag: Decision.Decision[\"_tag\"]): Ast =>\n\t\tCondition.builder<any, any, any>().predicate(policyPredicate, (value) =>\n\t\t\tResource.kindOf(value) === request.kind\n\t\t\t\t? Effect.map(decision(value), (result) => result._tag === tag)\n\t\t\t\t: Effect.succeed(false),\n\t\t)\n\t// The scope comes first in each `And`, so the policy runs only on values\n\t// in the scope.\n\treturn inScope({ allow: test(\"Allow\"), deny: test(\"Deny\") })\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 `True` when the policy allows every value of the\n * kind, and `False` when it allows none.\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 or 500 levels, this function throws an error. In an\n * `Authorizer`, the error is\n * a defect, so the check fails.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const residual: {\n\t<const Req extends AnyKindRequest>(\n\t\trequest: Req,\n\t): <D extends Domain.Any, E, R, O>(\n\t\tpolicy: Policy<D, E, R, O> & Fits<Req, KindRequest<D>>,\n\t) => Condition.Condition<E, R, O, ResidualReads<D, Req[\"kind\"]>>\n\t<D extends Domain.Any, E, R, O, const Req extends KindRequest<NoInfer<D>>>(\n\t\tpolicy: Policy<D, E, R, O>,\n\t\trequest: Req,\n\t): Condition.Condition<E, R, O, ResidualReads<D, Req[\"kind\"]>>\n} = dual(\n\t2,\n\t(policy: Any, request: KindRequest<Domain.Any>): Ast =>\n\t\tresidualsAny(policy, request).allow,\n) as never\n\n/**\n * Gives both residual conditions of a request: the values that the policy\n * allows, and the values that it denies. A value in neither is not\n * applicable. See {@link residual}.\n *\n * @stability stable\n * @category evaluation\n * @since 1.0.0\n */\nexport const residuals: {\n\t<const Req extends AnyKindRequest>(\n\t\trequest: Req,\n\t): <D extends Domain.Any, E, R, O>(\n\t\tpolicy: Policy<D, E, R, O> & Fits<Req, KindRequest<D>>,\n\t) => Residuals<E, R, O, ResidualReads<D, Req[\"kind\"]>>\n\t<D extends Domain.Any, E, R, O, const Req extends KindRequest<NoInfer<D>>>(\n\t\tpolicy: Policy<D, E, R, O>,\n\t\trequest: Req,\n\t): Residuals<E, R, O, ResidualReads<D, Req[\"kind\"]>>\n} = dual(2, residualsAny) 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<\n\tE = never,\n\tR = never,\n\tO = never,\n\tI = unknown,\n> = Data.TaggedEnum<{\n\tAll: { readonly condition: Condition.Condition<E, R, O, I> }\n\tNone: { readonly condition: Condition.Condition<E, R, O, I> }\n\tSome: {\n\t\treadonly condition: Condition.Condition<E, R, O, I>\n\t\treadonly allowed: Condition.Example\n\t\treadonly refused: Condition.Example\n\t}\n\tUnknown: {\n\t\treadonly condition: Condition.Condition<E, R, O, I>\n\t\treadonly reason: \"predicate\" | \"budget\" | \"schema\"\n\t}\n}>\n\n/** A {@link Coverage} with no types. */\ntype AnyCoverage = Data.TaggedEnum<{\n\tAll: { readonly condition: Ast }\n\tNone: { readonly condition: Ast }\n\tSome: {\n\t\treadonly condition: Ast\n\t\treadonly allowed: Condition.Example\n\t\treadonly refused: Condition.Example\n\t}\n\tUnknown: {\n\t\treadonly condition: Ast\n\t\treadonly reason: \"predicate\" | \"budget\" | \"schema\"\n\t}\n}>\n\nconst coverages = Data.taggedEnum<AnyCoverage>()\n\n/**\n * Tests if a rule that the request may use, or its scope, reads a getter of\n * a class, in any branch of a union.\n */\nconst readsGetter = (\n\tpolicy: Any,\n\trequest: ScopedRequest,\n\tdescriptor: Resource.Descriptor,\n): boolean =>\n\tscopeReadsGetter(request, descriptor) ||\n\t!readsOnly(\n\t\tnodeOf(policy),\n\t\ttargetOf(request, descriptor),\n\t\t(field) => !readsGetterAt(descriptor.schema, field),\n\t\tnew Map(),\n\t)\n\n/**\n * Tests if a read of a field may read a getter of a class: at the field, or\n * at a field on the way to it, in any branch of a union.\n */\nconst readsGetterAt = (schema: Schema.Top, field: string): boolean => {\n\tconst parts = field.split(\".\")\n\treturn Arr.some(Arr.range(1, parts.length), (count) =>\n\t\tResource.hasGetter(schema, parts.slice(0, count).join(\".\")),\n\t)\n}\n\n/**\n * Tests if the scope of a request reads a getter of a class. A scope is made\n * smaller in each residual, also next to a predicate that runs `decide`, so\n * such a scope has no residual.\n */\nconst scopeReadsGetter = (\n\trequest: ScopedRequest,\n\tdescriptor: Resource.Descriptor,\n): boolean =>\n\t!Arr.every(\n\t\tscopeFields(request.within),\n\t\t(field) => !readsGetterAt(descriptor.schema, field),\n\t)\n\n/**\n * Tests if a request has no residual: its scope reads a getter, or it has a\n * plain residual and a rule that it may use reads a getter. A residual with\n * a predicate runs `decide`, so the reads of its rules stay.\n */\nconst hasNoResidual = (\n\tpolicy: Any,\n\trequest: ScopedRequest,\n\tdescriptor: Resource.Descriptor,\n): boolean =>\n\tscopeReadsGetter(request, descriptor) ||\n\t(!usesPredicate(nodeOf(policy), targetOf(request, descriptor)) &&\n\t\treadsGetter(policy, request, descriptor))\n\n/** The parts of a request that tell which rules it may use. */\nconst targetOf = (\n\trequest: ScopedRequest,\n\tdescriptor: Resource.Descriptor,\n): PredicateContext => ({\n\taction: request.action,\n\tkind: request.kind,\n\tfield: request.field,\n\tdescriptor,\n\tpredicates: new Map(),\n})\n\n/**\n * Tests if each field that a rule that the request may use reads passes\n * `test`. It looks at the conditions before they are made smaller. A smaller\n * condition may leave out a field, but a read of that field, such as a\n * getter, may fail when `decide` runs. A shared node is visited one time.\n */\nconst readsOnly = (\n\tnode: Node,\n\ttarget: PredicateContext,\n\ttest: (field: string) => boolean,\n\tmemo: Map<Node, boolean>,\n): boolean =>\n\tremember(memo, node, () => {\n\t\tswitch (node._tag) {\n\t\t\tcase \"Rules\":\n\t\t\t\treturn Arr.every(\n\t\t\t\t\tnode.rules,\n\t\t\t\t\t(value) =>\n\t\t\t\t\t\tvalue.when === undefined ||\n\t\t\t\t\t\t!Rule.matchesTarget(value, target) ||\n\t\t\t\t\t\tArr.every(Condition.fields(value.when as Ast), test),\n\t\t\t\t)\n\t\t\tcase \"All\":\n\t\t\tcase \"Any\":\n\t\t\tcase \"FirstOf\":\n\t\t\t\treturn Arr.every(node.policies, (child) =>\n\t\t\t\t\treadsOnly(child, target, test, memo),\n\t\t\t\t)\n\t\t\tcase \"Ceiling\":\n\t\t\t\treturn (\n\t\t\t\t\treadsOnly(node.cap, target, test, memo) &&\n\t\t\t\t\treadsOnly(node.policy, target, test, memo)\n\t\t\t\t)\n\t\t}\n\t})\n\nconst coverageAny = (policy: Any, request: ScopedRequest): AnyCoverage => {\n\tconst descriptor = Domain.descriptorOf(policy.domain, request.kind)\n\t// A request with no residual has the condition `False`.\n\tif (descriptor !== undefined && hasNoResidual(policy, request, descriptor)) {\n\t\treturn coverages.Unknown({ condition: never, reason: \"schema\" })\n\t}\n\tconst scoped = scopedResiduals(policy, request)\n\tconst allowed = scoped.allow\n\t// Each field that a rule or the scope reads must be plain, also a field\n\t// that a smaller condition leaves out. The condition is the residual.\n\tif (descriptor !== undefined) {\n\t\tconst plain = (field: string) =>\n\t\t\tResource.isPlainField(descriptor.schema, field)\n\t\tif (\n\t\t\treadsGetter(policy, request, descriptor) ||\n\t\t\t!Arr.every(scopeFields(request.within), plain) ||\n\t\t\t!readsOnly(\n\t\t\t\tnodeOf(policy),\n\t\t\t\ttargetOf(request, descriptor),\n\t\t\t\tplain,\n\t\t\t\tnew Map(),\n\t\t\t)\n\t\t) {\n\t\t\treturn coverages.Unknown({ condition: allowed, reason: \"schema\" })\n\t\t}\n\t}\n\n\tconst options = { schema: scoped.schema }\n\tconst some =\n\t\tallowed._tag === \"False\"\n\t\t\t? undefined\n\t\t\t: Condition.satisfiable(allowed as Condition.Condition, options)\n\tif (some === undefined || some._tag === \"Unsatisfiable\") {\n\t\treturn coverages.None({ condition: never })\n\t}\n\tif (some._tag === \"Unknown\") {\n\t\treturn coverages.Unknown({ condition: allowed, reason: some.reason })\n\t}\n\t// Only two nodes more than `allowed`, so it needs no size limit.\n\tconst refused: Ast = Condition.simplify(\n\t\tCondition.and(\n\t\t\tscoped.scope as Condition.Condition,\n\t\t\tCondition.not(allowed as Condition.Condition),\n\t\t),\n\t)\n\tconst missing =\n\t\trefused._tag === \"False\"\n\t\t\t? undefined\n\t\t\t: Condition.satisfiable(refused as Condition.Condition, options)\n\tif (missing === undefined || missing._tag === \"Unsatisfiable\") {\n\t\treturn coverages.All({ condition: scoped.scope })\n\t}\n\tif (missing._tag === \"Unknown\") {\n\t\treturn coverages.Unknown({ condition: allowed, reason: missing.reason })\n\t}\n\treturn coverages.Some({\n\t\tcondition: allowed,\n\t\tallowed: some.example,\n\t\trefused: missing.example,\n\t})\n}\n\n/**\n * Tests if the scope of a request has a value of the Schema of its kind. The\n * answer is `true` only when the search finds such a value. When the search\n * can not say, the answer is `false`. So a \"yes\" from it is safe to act on,\n * as for the question \"may the decider answer for this scope?\".\n *\n * @stability stable\n * @category evaluation\n * @since 1.0.0\n */\nexport const scopeHasValue = (policy: Any, request: ScopedRequest): boolean => {\n\tconst scoped = scopedResiduals(policy, request)\n\treturn (\n\t\tCondition.satisfiable(scoped.scope as Condition.Any, {\n\t\t\tschema: scoped.schema,\n\t\t})._tag === \"Satisfiable\"\n\t)\n}\n\n/**\n * Tests if the scope of a request has no value of the Schema of its kind. A\n * scope with a mistake, such as two values for one field, is empty. With no\n * scope, the answer is `false` when the kind has a value. When the search can\n * not say, the answer is `false`.\n *\n * @stability stable\n * @category evaluation\n * @since 1.0.0\n */\nexport const scopeIsEmpty = (policy: Any, request: ScopedRequest): boolean => {\n\tconst scoped = scopedResiduals(policy, request)\n\treturn (\n\t\tCondition.satisfiable(scoped.scope as Condition.Any, {\n\t\t\tschema: scoped.schema,\n\t\t})._tag === \"Unsatisfiable\"\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 Schema of the\n * resource, so it is exact for the values of the Schema. When a condition\n * tests a field that is not a plain scalar (see `Resource.isPlainField`),\n * such as a field with a check other than a finite or integer check, the\n * answer is `Unknown`, and a check on the kind says no.\n *\n * `Some` means that some value of the Schema is allowed. It does not mean that\n * such a value is in your database. To know that, run `condition` as a query.\n *\n * @stability stable\n * @category evaluation\n * @since 1.0.0\n */\nexport const coverage: {\n\t<const Req extends AnyKindRequest>(\n\t\trequest: Req,\n\t): <D extends Domain.Any, E, R, O>(\n\t\tpolicy: Policy<D, E, R, O> & Fits<Req, KindRequest<D>>,\n\t) => Coverage<E, R, O, ResidualReads<D, Req[\"kind\"]>>\n\t<D extends Domain.Any, E, R, O, const Req extends KindRequest<NoInfer<D>>>(\n\t\tpolicy: Policy<D, E, R, O>,\n\t\trequest: Req,\n\t): Coverage<E, R, O, ResidualReads<D, Req[\"kind\"]>>\n} = dual(2, 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\nconst AlgorithmSchema = Schema.Literals([\n\t\"denyOverrides\",\n\t\"permitOverrides\",\n\t\"firstApplicable\",\n\t\"lastApplicable\",\n])\n\nconst encodedRuleSchema = (meta: Schema.Top | undefined) =>\n\tSchema.Struct({\n\t\t_tag: Schema.Literals([\"Allow\", \"Deny\"]),\n\t\tactions: Schema.Array(Schema.String),\n\t\tresources: Schema.Array(Schema.String),\n\t\twhen: Schema.optionalKey(Condition.schema),\n\t\tfields: Schema.String.pipe(Schema.Array, Schema.optionalKey),\n\t\treason: Schema.optionalKey(Schema.String),\n\t\tid: Schema.optionalKey(Schema.String),\n\t\tmeta: Schema.optionalKey(\n\t\t\t(meta ?? Schema.Never) as Schema.Codec<unknown, unknown>,\n\t\t),\n\t})\n\n/**\n * The most levels of objects and arrays in the JSON form of a policy. The\n * Schema of a policy calls itself for each level, so a much deeper input\n * could fill the stack before the checks of the policy run. A policy tree of\n * `maxDepth` levels with deep conditions stays well below this.\n */\nconst maxJsonDepth = 1000\n\n/**\n * The most objects and arrays in the JSON form of an input, with a shared one\n * counted for each place. The decoder writes out a shared one each time, so\n * an input with few objects may give a very large tree.\n */\nconst maxInputNodes = 1_000_000\n\n/** The size and the height of a value, in objects and arrays. */\ninterface Measure {\n\treadonly size: number\n\treadonly height: number\n}\n\n/**\n * Measures a value, or gives `undefined` when it is higher than `levels`. A\n * shared object is measured one time. The walk stops at that height, so it\n * does not fill the stack itself. The memo is a native `Map`, because it\n * must find an object by the object itself.\n */\nconst measure = (\n\tinput: unknown,\n\tlevels: number,\n\tmemo: Map<object, Measure | { readonly failed: number }>,\n): Measure | undefined => {\n\tif (typeof input !== \"object\" || input === null) {\n\t\treturn { size: 0, height: 0 }\n\t}\n\tconst cached = memo.get(input)\n\t// A value that was too high for some levels is too high for fewer.\n\tif (\n\t\tcached !== undefined &&\n\t\t(\"failed\" in cached ? levels <= cached.failed : true)\n\t) {\n\t\treturn \"failed\" in cached || cached.height > levels ? undefined : cached\n\t}\n\t// After the first child that is too high, the fold measures no more\n\t// children. The walk has few frames for each level, so it does not fill\n\t// the stack at the most levels.\n\t// An input with a key that a loop over the keys does not see, or with a\n\t// getter, may give the decoder more than the measure sees. Such an input\n\t// is not plain data, so it fails.\n\tconst result =\n\t\tlevels === 0 || !isPlainData(input)\n\t\t\t? undefined\n\t\t\t: Arr.reduce(\n\t\t\t\t\tObject.values(input),\n\t\t\t\t\t{ size: 1, height: 1 } as Measure | undefined,\n\t\t\t\t\t(total, child) => {\n\t\t\t\t\t\tconst measured =\n\t\t\t\t\t\t\ttotal === undefined ? undefined : measure(child, levels - 1, memo)\n\t\t\t\t\t\treturn total === undefined || measured === undefined\n\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\tsize: total.size + measured.size,\n\t\t\t\t\t\t\t\t\theight: Math.max(total.height, 1 + measured.height),\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t)\n\tmemo.set(input, result ?? { failed: levels })\n\treturn result\n}\n\n/**\n * Tests if each own key of an object is a plain data key that a loop over the\n * keys sees. The `length` of an array is the one key that is not seen. The\n * decoder reads keys of the prototypes too, so a prototype other than the\n * one of a plain object or an array may have only methods, as the prototype\n * of a class has.\n */\nconst isPlainData = (input: object): boolean =>\n\tArr.every(Reflect.ownKeys(input), (key) => {\n\t\tconst property = Object.getOwnPropertyDescriptor(input, key)\n\t\treturn (\n\t\t\tproperty !== undefined &&\n\t\t\t\"value\" in property &&\n\t\t\t(property.enumerable === true ||\n\t\t\t\t(Array.isArray(input) && key === \"length\"))\n\t\t)\n\t}) && hasOnlyMethods(Object.getPrototypeOf(input))\n\n/** Tests if the prototypes from `prototype` up have only methods. */\nconst hasOnlyMethods = (prototype: unknown): boolean =>\n\tprototype === null ||\n\tprototype === Object.prototype ||\n\tprototype === Array.prototype ||\n\t(typeof prototype === \"object\" &&\n\t\tArr.every(Reflect.ownKeys(prototype), (key) => {\n\t\t\tconst property = Object.getOwnPropertyDescriptor(prototype, key)\n\t\t\treturn (\n\t\t\t\ttypeof key === \"symbol\" ||\n\t\t\t\tkey === \"constructor\" ||\n\t\t\t\t(property !== undefined &&\n\t\t\t\t\t\"value\" in property &&\n\t\t\t\t\ttypeof property.value === \"function\")\n\t\t\t)\n\t\t}) &&\n\t\thasOnlyMethods(Object.getPrototypeOf(prototype)))\n\n/** Tests if a value is low and small enough to decode. */\nconst fitsLimits = (input: unknown): string | true => {\n\tconst measured = measure(input, maxJsonDepth, new Map())\n\treturn measured === undefined\n\t\t? `A policy may have at most ${String(maxJsonDepth)} levels of JSON`\n\t\t: measured.size > maxInputNodes\n\t\t\t? `A policy may have at most ${String(maxInputNodes)} objects and arrays in JSON`\n\t\t\t: true\n}\n\nconst encodedNodeSchema = (\n\tmeta: Schema.Top | undefined,\n): Schema.Codec<EncodedNode> => {\n\tconst self: Schema.Codec<EncodedNode> = Schema.Union([\n\t\tSchema.TaggedStruct(\"Rules\", {\n\t\t\talgorithm: AlgorithmSchema,\n\t\t\trules: Schema.Array(encodedRuleSchema(meta)),\n\t\t}),\n\t\tSchema.TaggedStruct(\"All\", {\n\t\t\tpolicies: Schema.Array(Schema.suspend(() => self)),\n\t\t}),\n\t\tSchema.TaggedStruct(\"Any\", {\n\t\t\tpolicies: Schema.Array(Schema.suspend(() => self)),\n\t\t}),\n\t\tSchema.TaggedStruct(\"FirstOf\", {\n\t\t\tpolicies: Schema.Array(Schema.suspend(() => self)),\n\t\t}),\n\t\tSchema.TaggedStruct(\"Ceiling\", {\n\t\t\tcap: Schema.suspend(() => self),\n\t\t\tpolicy: Schema.suspend(() => self),\n\t\t}),\n\t]) as never\n\treturn self\n}\n\ntype ConditionNode = Condition.Encoded | Ast\n\nconst principalRefs = (ast: ConditionNode): ReadonlyArray<string> =>\n\tArray.from(refsIn(ast, new Map()))\n\n/** The principal fields of a node. A shared node is visited one time. */\nconst refsIn = (\n\tnode: ConditionNode,\n\tmemo: Map<ConditionNode, HashSet.HashSet<string>>,\n): HashSet.HashSet<string> =>\n\tremember(memo, node, () => {\n\t\tconst refs = (operands: ReadonlyArray<Condition.Operand>) =>\n\t\t\tHashSet.fromIterable(\n\t\t\t\tArr.flatMap(operands, (operand) =>\n\t\t\t\t\toperand._tag === \"Principal\" ? [operand.path] : [],\n\t\t\t\t),\n\t\t\t)\n\t\tswitch (node._tag) {\n\t\t\tcase \"Compare\":\n\t\t\t\treturn refs([node.value])\n\t\t\tcase \"In\":\n\t\t\t\treturn refs(node.values)\n\t\t\tcase \"Under\":\n\t\t\t\treturn refs(node.prefix)\n\t\t\tcase \"And\":\n\t\t\tcase \"Or\":\n\t\t\t\treturn Arr.reduce(\n\t\t\t\t\tnode.conditions as ReadonlyArray<ConditionNode>,\n\t\t\t\t\tHashSet.empty<string>(),\n\t\t\t\t\t(all, child) => HashSet.union(all, refsIn(child, memo)),\n\t\t\t\t)\n\t\t\tcase \"Not\":\n\t\t\t\treturn refsIn(node.condition, memo)\n\t\t\tdefault:\n\t\t\t\treturn HashSet.empty()\n\t\t}\n\t})\n\ninterface Issue {\n\treadonly path: ReadonlyArray<PropertyKey>\n\treadonly issue: string\n}\n\n/** A test of a field with a fixed value, as in `eq(\"level\", 3)`. */\ntype LiteralTest = readonly [field: string, value: Condition.Scalar]\n\nconst literalTests = (node: ConditionNode): ReadonlyArray<LiteralTest> =>\n\tArr.map(Array.from(literalTestsIn(node, new Map())), (text) => {\n\t\tconst [field, value] = JSON.parse(text) as readonly [string, unknown]\n\t\treturn [\n\t\t\tfield,\n\t\t\thasProperty(value, \"number\") ? Number(value.number) : value,\n\t\t] as LiteralTest\n\t})\n\n/**\n * The JSON text of a test. JSON has no `Infinity`, `-Infinity` or `NaN`, so\n * such a number goes in as its text.\n */\nconst literalText = (field: string, value: Condition.Scalar): string =>\n\tJSON.stringify([\n\t\tfield,\n\t\ttypeof value === \"number\" && !Number.isFinite(value)\n\t\t\t? { number: String(value) }\n\t\t\t: value,\n\t])\n\n/**\n * The tests of fields with fixed values in a node, each as the JSON text of a\n * {@link LiteralTest}. A set of texts keeps each test one time, so a node\n * with many shared parts gives a small set. A shared node is visited one time.\n */\nconst literalTestsIn = (\n\tnode: ConditionNode,\n\tmemo: Map<ConditionNode, HashSet.HashSet<string>>,\n): HashSet.HashSet<string> =>\n\tremember(memo, node, () => {\n\t\tconst tests = (\n\t\t\tfield: string,\n\t\t\toperands: ReadonlyArray<Condition.Operand>,\n\t\t): HashSet.HashSet<string> =>\n\t\t\tHashSet.fromIterable(\n\t\t\t\tArr.flatMap(operands, (operand) =>\n\t\t\t\t\toperand._tag === \"Literal\" ? [literalText(field, operand.value)] : [],\n\t\t\t\t),\n\t\t\t)\n\t\tswitch (node._tag) {\n\t\t\tcase \"Compare\":\n\t\t\t\treturn tests(node.field, [node.value])\n\t\t\tcase \"In\":\n\t\t\t\treturn tests(node.field, node.values)\n\t\t\tcase \"And\":\n\t\t\tcase \"Or\":\n\t\t\t\treturn Arr.reduce(\n\t\t\t\t\tnode.conditions as ReadonlyArray<ConditionNode>,\n\t\t\t\t\tHashSet.empty<string>(),\n\t\t\t\t\t(all, child) => HashSet.union(all, literalTestsIn(child, memo)),\n\t\t\t\t)\n\t\t\tcase \"Not\":\n\t\t\t\treturn literalTestsIn(node.condition, memo)\n\t\t\tdefault:\n\t\t\t\treturn HashSet.empty()\n\t\t}\n\t})\n\n/** A test of a field with a field of the principal, as in `eq(\"ownerId\", $.principal(\"id\"))`. */\ntype PrincipalTest = readonly [field: string, ref: string]\n\nconst principalTests = (node: ConditionNode): ReadonlyArray<PrincipalTest> =>\n\tArr.map(\n\t\tArray.from(principalTestsIn(node, new Map())),\n\t\t(text) => JSON.parse(text) as PrincipalTest,\n\t)\n\n/**\n * The tests of fields with principal fields in a node, each as the JSON text\n * of a {@link PrincipalTest}. See {@link literalTestsIn}.\n */\nconst principalTestsIn = (\n\tnode: ConditionNode,\n\tmemo: Map<ConditionNode, HashSet.HashSet<string>>,\n): HashSet.HashSet<string> =>\n\tremember(memo, node, () => {\n\t\tconst tests = (\n\t\t\tfield: string,\n\t\t\toperands: ReadonlyArray<Condition.Operand>,\n\t\t): HashSet.HashSet<string> =>\n\t\t\tHashSet.fromIterable(\n\t\t\t\tArr.flatMap(operands, (operand) =>\n\t\t\t\t\toperand._tag === \"Principal\"\n\t\t\t\t\t\t? [JSON.stringify([field, operand.path])]\n\t\t\t\t\t\t: [],\n\t\t\t\t),\n\t\t\t)\n\t\tswitch (node._tag) {\n\t\t\tcase \"Compare\":\n\t\t\t\treturn tests(node.field, [node.value])\n\t\t\tcase \"In\":\n\t\t\t\treturn tests(node.field, node.values)\n\t\t\tcase \"And\":\n\t\t\tcase \"Or\":\n\t\t\t\treturn Arr.reduce(\n\t\t\t\t\tnode.conditions as ReadonlyArray<ConditionNode>,\n\t\t\t\t\tHashSet.empty<string>(),\n\t\t\t\t\t(all, child) => HashSet.union(all, principalTestsIn(child, memo)),\n\t\t\t\t)\n\t\t\tcase \"Not\":\n\t\t\t\treturn principalTestsIn(node.condition, memo)\n\t\t\tdefault:\n\t\t\t\treturn HashSet.empty()\n\t\t}\n\t})\n\n/**\n * Tests if a node has a fixed value that is not a {@link Condition.Scalar},\n * such as `undefined`. A shared node is visited one time.\n */\nconst hasBadLiteralIn = (\n\tnode: ConditionNode,\n\tmemo: Map<ConditionNode, boolean>,\n): boolean =>\n\tremember(memo, node, () => {\n\t\tconst bad = (operands: ReadonlyArray<Condition.Operand>) =>\n\t\t\tArr.some(\n\t\t\t\toperands,\n\t\t\t\t(operand) =>\n\t\t\t\t\toperand._tag === \"Literal\" &&\n\t\t\t\t\toperand.value !== null &&\n\t\t\t\t\ttypeof operand.value !== \"string\" &&\n\t\t\t\t\ttypeof operand.value !== \"number\" &&\n\t\t\t\t\ttypeof operand.value !== \"boolean\",\n\t\t\t)\n\t\tswitch (node._tag) {\n\t\t\tcase \"Compare\":\n\t\t\t\treturn bad([node.value])\n\t\t\tcase \"In\":\n\t\t\t\treturn bad(node.values)\n\t\t\tcase \"Under\":\n\t\t\t\treturn bad(node.prefix)\n\t\t\tcase \"And\":\n\t\t\tcase \"Or\":\n\t\t\t\treturn Arr.some(\n\t\t\t\t\tnode.conditions as ReadonlyArray<ConditionNode>,\n\t\t\t\t\t(child) => hasBadLiteralIn(child, memo),\n\t\t\t\t)\n\t\t\tcase \"Not\":\n\t\t\t\treturn hasBadLiteralIn(node.condition, memo)\n\t\t\tdefault:\n\t\t\t\treturn false\n\t\t}\n\t})\n\n/**\n * The principal fields in the prefixes of `Under` nodes, each as the JSON text\n * of the place in the prefix and the path of the field. See\n * {@link literalTestsIn}.\n */\n/**\n * The fixed values in the prefixes of `Under` nodes, each as the JSON text of\n * the place in the prefix, the value, and the fixed strings of the whole\n * prefix. A number that JSON can not hold is left out: it fits no field\n * that a path names. See {@link underRefsIn}.\n */\nconst underLiteralsIn = (\n\tnode: ConditionNode,\n\tmemo: Map<ConditionNode, HashSet.HashSet<string>>,\n): HashSet.HashSet<string> =>\n\tremember(memo, node, () => {\n\t\tswitch (node._tag) {\n\t\t\tcase \"Under\": {\n\t\t\t\tconst strings = Arr.map(node.prefix, (operand) =>\n\t\t\t\t\toperand._tag === \"Literal\" && typeof operand.value === \"string\"\n\t\t\t\t\t\t? operand.value\n\t\t\t\t\t\t: null,\n\t\t\t\t)\n\t\t\t\treturn HashSet.fromIterable(\n\t\t\t\t\tArr.flatMap(node.prefix, (operand, index) =>\n\t\t\t\t\t\toperand._tag === \"Literal\" &&\n\t\t\t\t\t\t(operand.value === null ||\n\t\t\t\t\t\t\ttypeof operand.value === \"string\" ||\n\t\t\t\t\t\t\ttypeof operand.value === \"boolean\" ||\n\t\t\t\t\t\t\tNumber.isFinite(operand.value))\n\t\t\t\t\t\t\t? [JSON.stringify([index, operand.value, strings])]\n\t\t\t\t\t\t\t: [],\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t}\n\t\t\tcase \"And\":\n\t\t\tcase \"Or\":\n\t\t\t\treturn Arr.reduce(\n\t\t\t\t\tnode.conditions as ReadonlyArray<ConditionNode>,\n\t\t\t\t\tHashSet.empty<string>(),\n\t\t\t\t\t(all, child) => HashSet.union(all, underLiteralsIn(child, memo)),\n\t\t\t\t)\n\t\t\tcase \"Not\":\n\t\t\t\treturn underLiteralsIn(node.condition, memo)\n\t\t\tdefault:\n\t\t\t\treturn HashSet.empty()\n\t\t}\n\t})\n\n/** A fixed value in a path test. See {@link underLiteralsIn}. */\ntype UnderLiteral = readonly [\n\tindex: number,\n\tvalue: Condition.Scalar,\n\tstrings: ReadonlyArray<string | null>,\n]\n\nconst underLiterals = (node: ConditionNode): ReadonlyArray<UnderLiteral> =>\n\tArr.map(\n\t\tArray.from(underLiteralsIn(node, new Map())),\n\t\t(text) => JSON.parse(text) as UnderLiteral,\n\t)\n\nconst underRefsIn = (\n\tnode: ConditionNode,\n\tmemo: Map<ConditionNode, HashSet.HashSet<string>>,\n): HashSet.HashSet<string> =>\n\tremember(memo, node, () => {\n\t\tswitch (node._tag) {\n\t\t\tcase \"Under\": {\n\t\t\t\t// The fixed strings of the prefix, so the check can leave out a\n\t\t\t\t// resource whose path can not match them.\n\t\t\t\tconst strings = Arr.map(node.prefix, (operand) =>\n\t\t\t\t\toperand._tag === \"Literal\" && typeof operand.value === \"string\"\n\t\t\t\t\t\t? operand.value\n\t\t\t\t\t\t: null,\n\t\t\t\t)\n\t\t\t\treturn HashSet.fromIterable(\n\t\t\t\t\tArr.flatMap(node.prefix, (operand, index) =>\n\t\t\t\t\t\toperand._tag === \"Principal\"\n\t\t\t\t\t\t\t? [JSON.stringify([index, operand.path, strings])]\n\t\t\t\t\t\t\t: [],\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t}\n\t\t\tcase \"And\":\n\t\t\tcase \"Or\":\n\t\t\t\treturn Arr.reduce(\n\t\t\t\t\tnode.conditions as ReadonlyArray<ConditionNode>,\n\t\t\t\t\tHashSet.empty<string>(),\n\t\t\t\t\t(all, child) => HashSet.union(all, underRefsIn(child, memo)),\n\t\t\t\t)\n\t\t\tcase \"Not\":\n\t\t\t\treturn underRefsIn(node.condition, memo)\n\t\t\tdefault:\n\t\t\t\treturn HashSet.empty()\n\t\t}\n\t})\n\n/**\n * A principal field in a path test: its place in the prefix, its path, and\n * the fixed strings of the whole prefix, or `null` for another part.\n */\ntype UnderRef = readonly [\n\tindex: number,\n\tref: string,\n\tstrings: ReadonlyArray<string | null>,\n]\n\nconst underRefs = (node: ConditionNode): ReadonlyArray<UnderRef> =>\n\tArr.map(\n\t\tArray.from(underRefsIn(node, new Map())),\n\t\t(text) => JSON.parse(text) as UnderRef,\n\t)\n\n/**\n * Tests if the path of a resource may start with a prefix: it is as long as\n * the prefix, and each fixed string of the prefix is the string of the path\n * at its place, when the path has a string there.\n */\nconst mayStartWith = (\n\tdescriptor: Resource.Descriptor,\n\tstrings: ReadonlyArray<string | null>,\n): boolean =>\n\t// A path shorter than the prefix never matches.\n\t(descriptor.path?.length ?? 0) >= strings.length &&\n\tArr.every(strings, (string, index) => {\n\t\tconst segment = descriptor.path?.[index]\n\t\treturn string === null || typeof segment !== \"string\" || segment === string\n\t})\n\n/**\n * Tests if a principal field may hold the part of a path at `index`: a string\n * of the path, or a value of the field that the path names there.\n */\nconst fitsPathPart = (\n\tdescriptor: Resource.Descriptor,\n\tindex: number,\n\tprincipal: Resource.FieldDomain,\n): boolean => {\n\tconst segment = descriptor.path?.[index]\n\treturn segment === undefined\n\t\t? false\n\t\t: typeof segment === \"string\"\n\t\t\t? fitsDomain(principal, segment)\n\t\t\t: domainsMeet(\n\t\t\t\t\tResource.domainOf(descriptor.schema, segment.field),\n\t\t\t\t\tprincipal,\n\t\t\t\t)\n}\n\n/**\n * The fields of ordered tests (`lt`, `lte`, `gt`, `gte`) in a node, each as\n * the JSON text of the field and the operand. See {@link literalTestsIn}.\n */\nconst orderedTestsIn = (\n\tnode: ConditionNode,\n\tmemo: Map<ConditionNode, HashSet.HashSet<string>>,\n): HashSet.HashSet<string> =>\n\tremember(memo, node, () => {\n\t\tswitch (node._tag) {\n\t\t\tcase \"Compare\":\n\t\t\t\treturn node.op === \"eq\" || node.op === \"ne\"\n\t\t\t\t\t? HashSet.empty()\n\t\t\t\t\t: HashSet.make(\n\t\t\t\t\t\t\tJSON.stringify([\n\t\t\t\t\t\t\t\tnode.field,\n\t\t\t\t\t\t\t\t// The type of a fixed value, not the value: JSON has no\n\t\t\t\t\t\t\t\t// `Infinity`.\n\t\t\t\t\t\t\t\tnode.value._tag === \"Literal\"\n\t\t\t\t\t\t\t\t\t? { _tag: \"Literal\", type: typeof node.value.value }\n\t\t\t\t\t\t\t\t\t: node.value,\n\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t)\n\t\t\tcase \"And\":\n\t\t\tcase \"Or\":\n\t\t\t\treturn Arr.reduce(\n\t\t\t\t\tnode.conditions as ReadonlyArray<ConditionNode>,\n\t\t\t\t\tHashSet.empty<string>(),\n\t\t\t\t\t(all, child) => HashSet.union(all, orderedTestsIn(child, memo)),\n\t\t\t\t)\n\t\t\tcase \"Not\":\n\t\t\t\treturn orderedTestsIn(node.condition, memo)\n\t\t\tdefault:\n\t\t\t\treturn HashSet.empty()\n\t\t}\n\t})\n\n/** The operand of an ordered test: the type of a fixed value, or a principal field. */\ntype OrderedOperand =\n\t| { readonly _tag: \"Literal\"; readonly type: string }\n\t| { readonly _tag: \"Principal\"; readonly path: string }\n\nconst orderedTests = (\n\tnode: ConditionNode,\n): ReadonlyArray<readonly [field: string, operand: OrderedOperand]> =>\n\tArr.map(\n\t\tArray.from(orderedTestsIn(node, new Map())),\n\t\t(text) =>\n\t\t\tJSON.parse(text) as readonly [field: string, operand: OrderedOperand],\n\t)\n\n/**\n * Tests if a field may hold a value with an order: a number or a string. An\n * ordered test is false for any other value.\n */\nconst isOrdered = (domain: Resource.FieldDomain): boolean =>\n\tdomain.string ||\n\tdomain.number !== \"none\" ||\n\tArr.some(\n\t\tdomain.literals,\n\t\t(value) => typeof value === \"string\" || typeof value === \"number\",\n\t)\n\n/**\n * Tests if two fields may hold values of one ordered type: two strings or two\n * numbers. An ordered test of two values of other types is false.\n */\nconst orderedMeet = (\n\tleft: Resource.FieldDomain,\n\tright: Resource.FieldDomain,\n): boolean => {\n\tconst strings = (domain: Resource.FieldDomain) =>\n\t\tdomain.string ||\n\t\tArr.some(domain.literals, (value) => typeof value === \"string\")\n\tconst numbers = (domain: Resource.FieldDomain) =>\n\t\tdomain.number !== \"none\" ||\n\t\tArr.some(domain.literals, (value) => typeof value === \"number\")\n\treturn (strings(left) && strings(right)) || (numbers(left) && numbers(right))\n}\n\n/**\n * Tests if two fields may hold one value: a value of one type, or a single\n * value that the other field may hold.\n */\nconst domainsMeet = (\n\tleft: Resource.FieldDomain,\n\tright: Resource.FieldDomain,\n): boolean =>\n\t// A principal field that is `null` is a missing value, and a test with a\n\t// missing value is false. A principal field that holds an object is not a\n\t// scalar, and it is a missing value too. So only scalars can be shared.\n\t(left.string && right.string) ||\n\t(left.boolean && right.boolean) ||\n\t(left.number !== \"none\" && right.number !== \"none\") ||\n\tArr.some(left.literals, (value) => fitsDomain(right, value)) ||\n\tArr.some(right.literals, (value) => fitsDomain(left, value))\n\n/**\n * Tests if a field with this domain may hold a value of the type of `value`.\n * `null` always fits: a test with `null` is a test that the field is missing.\n */\nconst fitsDomain = (\n\tdomain: Resource.FieldDomain,\n\tvalue: Condition.Scalar,\n): boolean =>\n\tvalue === null ||\n\tdomain.literals.includes(value) ||\n\t(typeof value === \"string\" && domain.string) ||\n\t(typeof value === \"boolean\" && domain.boolean) ||\n\t(typeof value === \"number\" && domain.number !== \"none\")\n\n/**\n * Checks the names in an encoded policy against the domain. It gives one\n * message for each problem.\n */\nconst validate = (\n\tdomain: Domain.Any,\n\troot: EncodedNode,\n): ReadonlyArray<Issue> => {\n\tconst principalPaths = domain.principal.pipe(\n\t\tResource.fieldPaths,\n\t\tHashSet.fromIterable,\n\t)\n\tconst ruleIssues = (\n\t\tvalue: EncodedRule,\n\t\tat: ReadonlyArray<PropertyKey>,\n\t): ReadonlyArray<Issue> => {\n\t\tconst all = value.resources.includes(\"*\")\n\t\t// Each kind is checked one time, also when the list names it again. The\n\t\t// order of the kinds does not change the issues, so a set is enough.\n\t\tconst named = Array.from(\n\t\t\tHashSet.fromIterable(Arr.filter(value.resources, (kind) => kind !== \"*\")),\n\t\t)\n\t\tconst descriptors = Arr.flatMap(named, (kind) => {\n\t\t\tconst descriptor = Domain.descriptorOf(domain, kind)\n\t\t\treturn descriptor === undefined ? [] : [descriptor]\n\t\t})\n\t\tconst known = all\n\t\t\t? Array.from(HashMap.values(domain.resources))\n\t\t\t: descriptors\n\t\t// The kinds of the rule with one of its actions. The rule never runs on\n\t\t// another kind, so the types of its tests are checked only on these.\n\t\tconst applicable = Arr.filter(\n\t\t\tdescriptors,\n\t\t\t(descriptor) =>\n\t\t\t\tvalue.actions.includes(\"*\") ||\n\t\t\t\tArr.some(value.actions, (action) =>\n\t\t\t\t\tdescriptor.actions.includes(action),\n\t\t\t\t),\n\t\t)\n\t\tconst usedFields = [\n\t\t\t...Arr.filter(value.fields ?? [], (field) => !field.includes(\"*\")),\n\t\t\t...(value.when === undefined ? [] : Condition.fields(value.when as Ast)),\n\t\t]\n\t\treturn [\n\t\t\t...Arr.map(\n\t\t\t\tArr.filter(named, (kind) => !HashMap.has(domain.resources, kind)),\n\t\t\t\t(kind): Issue => ({\n\t\t\t\t\tpath: [...at, \"resources\"],\n\t\t\t\t\tissue: `There is no resource with the kind \"${kind}\"`,\n\t\t\t\t}),\n\t\t\t),\n\t\t\t...Arr.map(\n\t\t\t\tArr.filter(\n\t\t\t\t\tvalue.actions,\n\t\t\t\t\t(action) =>\n\t\t\t\t\t\taction !== \"*\" &&\n\t\t\t\t\t\t!Arr.some(known, (descriptor) =>\n\t\t\t\t\t\t\tdescriptor.actions.includes(action),\n\t\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\t(action): Issue => ({\n\t\t\t\t\tpath: [...at, \"actions\"],\n\t\t\t\t\tissue: `The action \"${action}\" is not an action of these resources`,\n\t\t\t\t}),\n\t\t\t),\n\t\t\t...Arr.map(\n\t\t\t\tArr.filter(\n\t\t\t\t\tusedFields,\n\t\t\t\t\t(field) =>\n\t\t\t\t\t\tall ||\n\t\t\t\t\t\tdescriptors.length === 0 ||\n\t\t\t\t\t\t!Arr.every(\n\t\t\t\t\t\t\tdescriptors,\n\t\t\t\t\t\t\t(descriptor) =>\n\t\t\t\t\t\t\t\tdescriptor.fieldPaths.includes(field) ||\n\t\t\t\t\t\t\t\t// A key of a record, or a field deep in a recursive\n\t\t\t\t\t\t\t\t// Schema, or a getter of a nested class.\n\t\t\t\t\t\t\t\tResource.hasPath(descriptor.schema, field) ||\n\t\t\t\t\t\t\t\tResource.hasGetter(descriptor.schema, field),\n\t\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\t(field): Issue => ({\n\t\t\t\t\tpath: at,\n\t\t\t\t\tissue: `The field \"${field}\" is not a field of every resource of the rule`,\n\t\t\t\t}),\n\t\t\t),\n\t\t\t...Arr.map(\n\t\t\t\tArr.filter(\n\t\t\t\t\tvalue.when === undefined ? [] : principalRefs(value.when),\n\t\t\t\t\t(ref) =>\n\t\t\t\t\t\t!HashSet.has(principalPaths, ref) &&\n\t\t\t\t\t\t!Resource.hasPath(domain.principal, ref) &&\n\t\t\t\t\t\t!Resource.hasGetter(domain.principal, ref),\n\t\t\t\t),\n\t\t\t\t(ref): Issue => ({\n\t\t\t\t\tpath: [...at, \"when\"],\n\t\t\t\t\tissue: `The principal has no field \"${ref}\"`,\n\t\t\t\t}),\n\t\t\t),\n\t\t\t// A test with a value of another type than the field never matches.\n\t\t\t// The types stop it in a typed rule, so here it is a mistake, and in\n\t\t\t// a deny rule it would let values through.\n\t\t\t...Arr.map(\n\t\t\t\tArr.filter(\n\t\t\t\t\tvalue.when === undefined ? [] : literalTests(value.when),\n\t\t\t\t\t([field, literal]) =>\n\t\t\t\t\t\tArr.some(\n\t\t\t\t\t\t\tapplicable,\n\t\t\t\t\t\t\t(descriptor) =>\n\t\t\t\t\t\t\t\t!fitsDomain(\n\t\t\t\t\t\t\t\t\tResource.domainOf(descriptor.schema, field),\n\t\t\t\t\t\t\t\t\tliteral,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\t([field, literal]): Issue => ({\n\t\t\t\t\tpath: [...at, \"when\"],\n\t\t\t\t\tissue: `The field \"${field}\" can not hold the value ${JSON.stringify(literal)}`,\n\t\t\t\t}),\n\t\t\t),\n\t\t\t...Arr.map(\n\t\t\t\tArr.filter(\n\t\t\t\t\tvalue.when === undefined ? [] : principalTests(value.when),\n\t\t\t\t\t([field, ref]) =>\n\t\t\t\t\t\tArr.some(\n\t\t\t\t\t\t\tapplicable,\n\t\t\t\t\t\t\t(descriptor) =>\n\t\t\t\t\t\t\t\t!domainsMeet(\n\t\t\t\t\t\t\t\t\tResource.domainOf(descriptor.schema, field),\n\t\t\t\t\t\t\t\t\tResource.domainOf(domain.principal, ref),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\t([field, ref]): Issue => ({\n\t\t\t\t\tpath: [...at, \"when\"],\n\t\t\t\t\tissue: `The field \"${field}\" can not hold a value of the principal field \"${ref}\"`,\n\t\t\t\t}),\n\t\t\t),\n\t\t\t// A condition with a node that is not known would be skipped when it\n\t\t\t// runs, so it is not taken.\n\t\t\t...(value.when !== undefined && !Condition.isAst(value.when)\n\t\t\t\t? [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpath: [...at, \"when\"],\n\t\t\t\t\t\t\tissue: \"The condition is not a whole condition tree\",\n\t\t\t\t\t\t} satisfies Issue,\n\t\t\t\t\t]\n\t\t\t\t: []),\n\t\t\t// A fixed value such as `undefined` is not a value of a test. Its\n\t\t\t// JSON text would be `null`, and the test would mean another thing.\n\t\t\t...(value.when !== undefined && hasBadLiteralIn(value.when, new Map())\n\t\t\t\t? [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpath: [...at, \"when\"],\n\t\t\t\t\t\t\tissue:\n\t\t\t\t\t\t\t\t\"A test has a fixed value that is not a string, a number, a boolean or null\",\n\t\t\t\t\t\t} satisfies Issue,\n\t\t\t\t\t]\n\t\t\t\t: []),\n\t\t\t// A principal field in a path test must hold a value that the path\n\t\t\t// may have at that place. Else the test is always false.\n\t\t\t...Arr.map(\n\t\t\t\tArr.filter(\n\t\t\t\t\tvalue.when === undefined ? [] : underRefs(value.when),\n\t\t\t\t\t([index, ref, strings]) =>\n\t\t\t\t\t\t// A rule for every resource may run on each of them that has a\n\t\t\t\t\t\t// part of its path at this place.\n\t\t\t\t\t\tArr.some(\n\t\t\t\t\t\t\t// The rule runs only on a kind with one of its actions, and\n\t\t\t\t\t\t\t// the test can match only a path that starts with the fixed\n\t\t\t\t\t\t\t// strings of the prefix.\n\t\t\t\t\t\t\tArr.filter(\n\t\t\t\t\t\t\t\tall\n\t\t\t\t\t\t\t\t\t? Arr.filter(\n\t\t\t\t\t\t\t\t\t\t\tknown,\n\t\t\t\t\t\t\t\t\t\t\t(descriptor) =>\n\t\t\t\t\t\t\t\t\t\t\t\tdescriptor.path?.[index] !== undefined &&\n\t\t\t\t\t\t\t\t\t\t\t\t(value.actions.includes(\"*\") ||\n\t\t\t\t\t\t\t\t\t\t\t\t\tArr.some(value.actions, (action) =>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescriptor.actions.includes(action),\n\t\t\t\t\t\t\t\t\t\t\t\t\t)),\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t: applicable,\n\t\t\t\t\t\t\t\t(descriptor) => mayStartWith(descriptor, strings),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t(descriptor) =>\n\t\t\t\t\t\t\t\t!fitsPathPart(\n\t\t\t\t\t\t\t\t\tdescriptor,\n\t\t\t\t\t\t\t\t\tindex,\n\t\t\t\t\t\t\t\t\tResource.domainOf(domain.principal, ref),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\t([, ref]): Issue => ({\n\t\t\t\t\tpath: [...at, \"when\"],\n\t\t\t\t\tissue: `The principal field \"${ref}\" can not hold a part of the path of the resource`,\n\t\t\t\t}),\n\t\t\t),\n\t\t\t// A fixed value in a path test at the place of a field of the path\n\t\t\t// must be a value of that field. Else the test is always false.\n\t\t\t...Arr.map(\n\t\t\t\tArr.filter(\n\t\t\t\t\tvalue.when === undefined ? [] : underLiterals(value.when),\n\t\t\t\t\t([index, literal, strings]) =>\n\t\t\t\t\t\tArr.some(\n\t\t\t\t\t\t\tArr.filter(\n\t\t\t\t\t\t\t\tall\n\t\t\t\t\t\t\t\t\t? Arr.filter(\n\t\t\t\t\t\t\t\t\t\t\tknown,\n\t\t\t\t\t\t\t\t\t\t\t(descriptor) =>\n\t\t\t\t\t\t\t\t\t\t\t\tvalue.actions.includes(\"*\") ||\n\t\t\t\t\t\t\t\t\t\t\t\tArr.some(value.actions, (action) =>\n\t\t\t\t\t\t\t\t\t\t\t\t\tdescriptor.actions.includes(action),\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t: applicable,\n\t\t\t\t\t\t\t\t(descriptor) => mayStartWith(descriptor, strings),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t(descriptor) => {\n\t\t\t\t\t\t\t\tconst segment = descriptor.path?.[index]\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\tsegment !== undefined &&\n\t\t\t\t\t\t\t\t\ttypeof segment !== \"string\" &&\n\t\t\t\t\t\t\t\t\t!fitsDomain(\n\t\t\t\t\t\t\t\t\t\tResource.domainOf(descriptor.schema, segment.field),\n\t\t\t\t\t\t\t\t\t\tliteral,\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\t([index, literal]): Issue => ({\n\t\t\t\t\tpath: [...at, \"when\"],\n\t\t\t\t\tissue: `The path part ${String(index)} can not hold the value ${JSON.stringify(literal)}`,\n\t\t\t\t}),\n\t\t\t),\n\t\t\t// An ordered test compares numbers with numbers and strings with\n\t\t\t// strings. With another value it is always false.\n\t\t\t...Arr.map(\n\t\t\t\tArr.filter(\n\t\t\t\t\tvalue.when === undefined ? [] : orderedTests(value.when),\n\t\t\t\t\t([field, operand]) =>\n\t\t\t\t\t\t(operand._tag === \"Literal\" &&\n\t\t\t\t\t\t\toperand.type !== \"string\" &&\n\t\t\t\t\t\t\toperand.type !== \"number\") ||\n\t\t\t\t\t\tArr.some(applicable, (descriptor) => {\n\t\t\t\t\t\t\tconst fieldDomain = Resource.domainOf(descriptor.schema, field)\n\t\t\t\t\t\t\t// A principal field must share an ordered type with the\n\t\t\t\t\t\t\t// field: a string and a number never compare.\n\t\t\t\t\t\t\treturn operand._tag === \"Literal\"\n\t\t\t\t\t\t\t\t? !isOrdered(fieldDomain)\n\t\t\t\t\t\t\t\t: !orderedMeet(\n\t\t\t\t\t\t\t\t\t\tfieldDomain,\n\t\t\t\t\t\t\t\t\t\tResource.domainOf(domain.principal, operand.path),\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\t([field]): Issue => ({\n\t\t\t\t\tpath: [...at, \"when\"],\n\t\t\t\t\tissue: `The field \"${field}\" has an ordered test with a value that has no order`,\n\t\t\t\t}),\n\t\t\t),\n\t\t]\n\t}\n\tconst issuesOf = (\n\t\tnode: EncodedNode,\n\t\tpath: ReadonlyArray<PropertyKey>,\n\t\tlevel: number,\n\t): ReadonlyArray<Issue> => {\n\t\tif (level > maxDepth) {\n\t\t\treturn [\n\t\t\t\t{ path, issue: `A policy tree may have at most ${maxDepth} levels` },\n\t\t\t]\n\t\t}\n\t\tswitch (node._tag) {\n\t\t\tcase \"Rules\":\n\t\t\t\treturn Arr.flatMap(node.rules, (value, index) =>\n\t\t\t\t\truleIssues(value, [...path, \"rules\", index]),\n\t\t\t\t)\n\t\t\tcase \"All\":\n\t\t\tcase \"Any\":\n\t\t\tcase \"FirstOf\":\n\t\t\t\treturn Arr.flatMap(node.policies, (child, index) =>\n\t\t\t\t\tissuesOf(child, [...path, \"policies\", index], level + 1),\n\t\t\t\t)\n\t\t\tcase \"Ceiling\":\n\t\t\t\treturn [\n\t\t\t\t\t...issuesOf(node.cap, [...path, \"cap\"], level + 1),\n\t\t\t\t\t...issuesOf(node.policy, [...path, \"policy\"], level + 1),\n\t\t\t\t]\n\t\t}\n\t}\n\treturn issuesOf(root, [], 1)\n}\n\n/**\n * Makes a policy tree from its JSON form. Each rule gets the domain of the\n * Schema, as a rule from the builder of the domain has it.\n */\nconst decodeNode = (node: EncodedNode, domain: Domain.Any): Node => {\n\tswitch (node._tag) {\n\t\tcase \"Rules\":\n\t\t\treturn nodes.Rules({\n\t\t\t\talgorithm: node.algorithm,\n\t\t\t\trules: node.rules.map((value) =>\n\t\t\t\t\tRule.make({ ...(value as Rule.Shape), domain }),\n\t\t\t\t),\n\t\t\t})\n\t\tcase \"All\":\n\t\tcase \"Any\":\n\t\tcase \"FirstOf\":\n\t\t\treturn nodes[node._tag]({\n\t\t\t\tpolicies: node.policies.map((child) => decodeNode(child, domain)),\n\t\t\t})\n\t\tcase \"Ceiling\":\n\t\t\treturn nodes.Ceiling({\n\t\t\t\tcap: decodeNode(node.cap, domain),\n\t\t\t\tpolicy: decodeNode(node.policy, domain),\n\t\t\t})\n\t}\n}\n\n/**\n * Tests if a value is a policy.\n *\n * @stability stable\n * @category guards\n * @since 0.3.0\n */\nexport const isPolicy = (u: unknown): u is Any => u instanceof PolicyData\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 * @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> =>\n\t// The input is any value until the checks of `encodedNodeSchema` run, so\n\t// this guard says yes to every object.\n\tSchema.declare(\n\t\t(input): input is EncodedNode =>\n\t\t\ttypeof input === \"object\" && input !== null,\n\t).pipe(\n\t\tSchema.check(Schema.makeFilter(fitsLimits)),\n\t\tSchema.decodeTo(\n\t\t\tencodedNodeSchema(domain.meta),\n\t\t\tSchemaTransformation.passthrough(),\n\t\t),\n\t\tSchema.check(Schema.makeFilter((node) => validate(domain, node))),\n\t\tSchema.decodeTo(\n\t\t\t// A policy with a predicate is not a plain policy, and it can not\n\t\t\t// become JSON.\n\t\t\tSchema.declare(\n\t\t\t\t(u): u is Policy<D> =>\n\t\t\t\t\tisPolicy(u) && u.domain === domain && !nodeHasPredicate(u.node),\n\t\t\t),\n\t\t\tSchemaTransformation.transformEffect({\n\t\t\t\tdecode: (node: EncodedNode) =>\n\t\t\t\t\tEffect.succeed(fromNode(domain, decodeNode(node, domain))),\n\t\t\t\t// A tree whose JSON form is too large fails as a Schema issue.\n\t\t\t\tencode: (policy: Policy<D>, options) =>\n\t\t\t\t\tencodedSize(policy.node) > maxEncodedNodes\n\t\t\t\t\t\t? Effect.fail(\n\t\t\t\t\t\t\t\tnew SchemaIssue.InvalidValue(\n\t\t\t\t\t\t\t\t\t{ message: tooLargeMessage },\n\t\t\t\t\t\t\t\t\tpolicy,\n\t\t\t\t\t\t\t\t\toptions,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: Effect.succeed(encodeNode(policy.node)),\n\t\t\t}),\n\t\t),\n\t)\n"],"mappings":"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"}
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 Pipeable from \"effect/Pipeable\"\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 =\n\t\"denyOverrides\" | \"permitOverrides\" | \"firstApplicable\" | \"lastApplicable\"\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 interface Rule<D = any, I = unknown, X = never>\n\textends RuleShape<I, X>, Pipeable.Pipeable {\n\treadonly \"~Opaque\": () => X\n\treadonly \"~Domain\": (domain: D) => D\n\t[Symbol.iterator](): Generator<Rule<D, I, X>, Rule<D, I, X>, unknown>\n}\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 `True` when the policy allows every value of the\n * kind, and `False` when it allows none.\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+gBA,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;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDJ,MAAa,WAQZC;;;;;;;;;;;;;;;;;;;;AAsDD,MAAa,WAOqCC;;;;;;;;;;;;;;;AA2DlD,MAAa,SAE+BC"}