@nmnmcc/ability 2.0.6 → 2.1.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 (89) hide show
  1. package/README.md +56 -32
  2. package/dist/Authorizer.d.ts +21 -12
  3. package/dist/Authorizer.d.ts.map +1 -1
  4. package/dist/Authorizer.js.map +1 -1
  5. package/dist/Condition.d.ts +118 -18
  6. package/dist/Condition.d.ts.map +1 -1
  7. package/dist/Condition.js +27 -18
  8. package/dist/Condition.js.map +1 -1
  9. package/dist/Domain.d.ts +9 -0
  10. package/dist/Domain.d.ts.map +1 -1
  11. package/dist/Domain.js +5 -0
  12. package/dist/Domain.js.map +1 -1
  13. package/dist/Limits.d.ts +44 -13
  14. package/dist/Limits.d.ts.map +1 -1
  15. package/dist/Limits.js +52 -22
  16. package/dist/Limits.js.map +1 -1
  17. package/dist/Policy.d.ts +95 -12
  18. package/dist/Policy.d.ts.map +1 -1
  19. package/dist/Policy.js.map +1 -1
  20. package/dist/index.d.ts +1 -1
  21. package/dist/internal/algebra.js +101 -74
  22. package/dist/internal/algebra.js.map +1 -1
  23. package/dist/internal/analysis.js +81 -75
  24. package/dist/internal/analysis.js.map +1 -1
  25. package/dist/internal/authorizer.d.ts.map +1 -1
  26. package/dist/internal/authorizer.js +16 -11
  27. package/dist/internal/authorizer.js.map +1 -1
  28. package/dist/internal/bind.js +119 -80
  29. package/dist/internal/bind.js.map +1 -1
  30. package/dist/internal/catalog.d.ts +33 -10
  31. package/dist/internal/catalog.d.ts.map +1 -1
  32. package/dist/internal/catalog.js +153 -78
  33. package/dist/internal/catalog.js.map +1 -1
  34. package/dist/internal/decide.js +25 -29
  35. package/dist/internal/decide.js.map +1 -1
  36. package/dist/internal/domain.js +19 -5
  37. package/dist/internal/domain.js.map +1 -1
  38. package/dist/internal/json.js +120 -76
  39. package/dist/internal/json.js.map +1 -1
  40. package/dist/internal/limits.d.ts +28 -0
  41. package/dist/internal/limits.d.ts.map +1 -1
  42. package/dist/internal/limits.js +75 -16
  43. package/dist/internal/limits.js.map +1 -1
  44. package/dist/internal/nodes.d.ts +7 -0
  45. package/dist/internal/nodes.d.ts.map +1 -1
  46. package/dist/internal/nodes.js +86 -47
  47. package/dist/internal/nodes.js.map +1 -1
  48. package/dist/internal/patterns.js +50 -15
  49. package/dist/internal/patterns.js.map +1 -1
  50. package/dist/internal/policy-json.js +169 -127
  51. package/dist/internal/policy-json.js.map +1 -1
  52. package/dist/internal/policy-nodes.d.ts.map +1 -1
  53. package/dist/internal/policy-nodes.js +17 -14
  54. package/dist/internal/policy-nodes.js.map +1 -1
  55. package/dist/internal/policy.d.ts.map +1 -1
  56. package/dist/internal/policy.js +38 -22
  57. package/dist/internal/policy.js.map +1 -1
  58. package/dist/internal/resource.js +1 -1
  59. package/dist/internal/rule.d.ts.map +1 -1
  60. package/dist/internal/rule.js +6 -5
  61. package/dist/internal/rule.js.map +1 -1
  62. package/dist/internal/search.d.ts.map +1 -1
  63. package/dist/internal/search.js +106 -92
  64. package/dist/internal/search.js.map +1 -1
  65. package/dist/internal/trampoline.js +89 -0
  66. package/dist/internal/trampoline.js.map +1 -0
  67. package/package.json +1 -1
  68. package/src/Authorizer.ts +30 -20
  69. package/src/Condition.ts +308 -83
  70. package/src/Domain.ts +9 -0
  71. package/src/Limits.ts +69 -29
  72. package/src/Policy.ts +131 -15
  73. package/src/internal/algebra.ts +218 -135
  74. package/src/internal/analysis.ts +154 -122
  75. package/src/internal/authorizer.ts +34 -16
  76. package/src/internal/bind.ts +279 -148
  77. package/src/internal/catalog.ts +307 -133
  78. package/src/internal/decide.ts +58 -49
  79. package/src/internal/domain.ts +39 -3
  80. package/src/internal/json.ts +212 -117
  81. package/src/internal/limits.ts +101 -31
  82. package/src/internal/nodes.ts +101 -59
  83. package/src/internal/patterns.ts +72 -26
  84. package/src/internal/policy-json.ts +266 -197
  85. package/src/internal/policy-nodes.ts +33 -24
  86. package/src/internal/policy.ts +63 -23
  87. package/src/internal/rule.ts +16 -3
  88. package/src/internal/search.ts +186 -136
  89. package/src/internal/trampoline.ts +194 -0
package/README.md CHANGED
@@ -213,11 +213,12 @@ A condition reads only the data fields of a value: an own field that a loop over
213
213
  the keys sees. A rule that names a getter of a class is a `PolicyError`. Use a
214
214
  predicate for a value that comes from code. A condition may not read a field, of
215
215
  a resource or of the principal, below a value that may not be plain data: a
216
- class in a union that does not have the field, a list, a date, or a value of
217
- `Schema.Unknown`. Such a rule is a `PolicyError` too. A struct without the field
218
- is fine: a decode or a `make` copies it into a plain object, so the field reads
219
- `null`. A test reads only the fields that the simple form of its condition
220
- needs, as the residual does: in `x AND False`, it does not read `x`.
216
+ union with a struct or a class that does not have the field, a list, a date, or
217
+ a value of `Schema.Unknown`. A decision may get a value made by hand, and such a
218
+ value may have the field with any value, as a list. Such a rule is a
219
+ `PolicyError` too. A string in a union is fine: the field reads `null` for it. A
220
+ test reads only the fields that the simple form of its condition needs, as the
221
+ residual does: in `x AND False`, it does not read `x`.
221
222
 
222
223
  ## Conditions
223
224
 
@@ -234,6 +235,11 @@ The builder in `when` has these functions:
234
235
  | `principal(field)` | Not a test. It gives a field of the principal. |
235
236
  | `predicate(name, test)` | The test function says yes. It may be an Effect. |
236
237
 
238
+ The types check each field path that you write, part by part, up to about 1000
239
+ parts, as `link.next.next.value` of a list of links. A path that is not a field
240
+ is a type error, and the error names the paths that may come next. The same
241
+ check is in the fields of a rule and in the field of a request.
242
+
237
243
  A missing field of a resource has the value `null`. A field of the principal
238
244
  that is `null` or missing is different: a test with it is always false, also
239
245
  with `ne`. So a guest with no `userId` never matches a document with no owner.
@@ -249,9 +255,11 @@ So a predicate for a Document can not go into a rule for a Comment. Make
249
255
  conditions with the builder: a node made by hand, or a spread of a node, is not
250
256
  a condition, in the types or when the code runs.
251
257
 
252
- A condition may have at most 100000 nodes and 500 levels, with a shared part
253
- counted for each place. The builder throws an error for a larger condition. So
254
- no condition can make a check slow or fill the stack.
258
+ A condition of a domain may have at most `conditionNodes` nodes, 1000000 by
259
+ default, with each value of an `In` test, and a shared part counted for each
260
+ place. A larger condition is a `PolicyError`, so no condition can make a check
261
+ slow. A condition may have any number of levels: no walk fills the stack. See
262
+ [Limits](#limits).
255
263
 
256
264
  ## Policies
257
265
 
@@ -282,12 +290,13 @@ Put policies together:
282
290
  | `Policy.firstOf([a, b])` | The first policy that allows or denies. |
283
291
  | `Policy.ceiling(policy, cap)` | A deny from `cap` always wins. An allow from `cap` does nothing. |
284
292
 
285
- A policy tree may have at most 256 levels and 100000 nodes, with its rules and
286
- the nodes of their conditions, and a shared part counted for each place. A
287
- combinator throws an error for a larger tree, and the policy Schema does not
288
- decode one. The decoder reads at most 1000000 objects and array items, so no
289
- input can fill the stack or take a very long time. A field path may have at most
290
- 5 parts.
293
+ A policy tree of a domain may have at most `policyNodes` nodes, 1000000 by
294
+ default, with its rules and the nodes and values of their conditions, and a
295
+ shared part counted for each place. A combinator throws an error for a larger
296
+ tree, and the policy Schema does not decode one. The decoder reads at most
297
+ `jsonNodes` objects and array items, so no input can take a very long time. A
298
+ field path may have at most `fieldPathParts` parts, 1000 by default. A tree may
299
+ have any number of levels. See [Limits](#limits).
291
300
 
292
301
  A shared part of a tree is decided again for each place, so its predicates run
293
302
  each time, and `Policy.explain` lists its rules each time.
@@ -613,24 +622,39 @@ status codes: 403, 503, and 409.
613
622
 
614
623
  ## Limits
615
624
 
616
- Each limit keeps a walk, a decoder or a search small, so no input can fill the
617
- stack or take a very long time. An input past a limit is an error, as in "A
618
- condition has 100001 nodes. The most is 100000.". In an `Authorizer`, such an
619
- error is never a "yes". The `Limits` module gives each value.
620
-
621
- | Limit | Value | What it limits |
622
- | ---------------- | ------- | ------------------------------------------------------------------------------------------------------ |
623
- | `fieldPathParts` | 5 | The parts of a field path, as in `settings.model`. |
624
- | `patternParts` | 16 | The parts of a field pattern. |
625
- | `conditionNodes` | 100000 | The nodes of a condition, a shared part for each place. |
626
- | `conditionDepth` | 500 | The levels of a condition. |
627
- | `residualNodes` | 10000 | The nodes of a residual condition. |
628
- | `policyDepth` | 256 | The levels of a policy tree. |
629
- | `policyNodes` | 100000 | The nodes of a policy tree, with its rules. |
630
- | `jsonNodes` | 1000000 | The objects and items that a decoder reads. |
631
- | `catalogFields` | 10000 | The fields of the Schema of a resource. |
632
- | `searchSteps` | 1000000 | The steps of one search, as in `Policy.coverage`, and of the checks of the field patterns of a policy. |
633
- | `searchFields` | 256 | The fields that one search may test. |
625
+ Each limit keeps a decoder, a walk or a search small, so no input can take a
626
+ very long time or very much memory. An input past a limit is an error, as in "A
627
+ condition has 1000001 nodes and values. The most is 1000000.". In an
628
+ `Authorizer`, such an error is never a "yes". The `Limits` module gives each
629
+ default, and `Limits.ceilings` gives the most that a domain may set.
630
+
631
+ A walk does not fill the stack at any depth: it runs on the stack for an input
632
+ with few levels, and in the run loop of an Effect for a deeper one. The levels
633
+ of an input are at most its nodes, so there is no limit of levels. Note that
634
+ `JSON.stringify` of the JSON form of a very deep policy, with many thousands of
635
+ levels, may fail: the engine writes JSON text with a walk of its own.
636
+
637
+ A domain may set its own limits:
638
+
639
+ ```ts
640
+ const Deep = Domain.make({
641
+ principal: User,
642
+ resources: [Post],
643
+ limits: { fieldPathParts: 2000, searchSteps: 5_000_000 },
644
+ })
645
+ ```
646
+
647
+ | Limit | Default | Ceiling | What it limits |
648
+ | ---------------- | -------- | ---------- | ------------------------------------------------------------------------------------------------------ |
649
+ | `fieldPathParts` | 1000 | 10000 | The parts of a field path, as in `settings.model`. |
650
+ | `patternParts` | 1000 | 10000 | The parts of a field pattern. |
651
+ | `conditionNodes` | 1000000 | 100000000 | The nodes of a condition, with each value of an `In` test, and a shared part for each place. |
652
+ | `residualNodes` | 100000 | 100000000 | The nodes of a residual condition. |
653
+ | `policyNodes` | 1000000 | 100000000 | The nodes of a policy tree, with its rules and the nodes and values of their conditions. |
654
+ | `jsonNodes` | 10000000 | 1000000000 | The objects and items that a decoder reads. |
655
+ | `catalogFields` | 100000 | 10000000 | The fields in the list of the fields of the Schema of a resource or of the principal. |
656
+ | `searchSteps` | 1000000 | 1000000000 | The steps of one search, as in `Policy.coverage`, and of the checks of the field patterns of a policy. |
657
+ | `searchFields` | 1000 | 100000 | The fields that one search may test. |
634
658
 
635
659
  ## Examples
636
660
 
@@ -1,6 +1,6 @@
1
1
  import { Condition, Opaque } from "./Condition.js";
2
2
  import { Any, CommonAction, Kind, Principal } from "./Domain.js";
3
- import { Coverage, FieldlessTarget, KindRequest, KindTarget, Policy, Request, ResidualReads, Target as Target$1 } from "./Policy.js";
3
+ import { CheckField, Coverage, DeepKindTarget, DeepTarget as DeepTarget$1, FieldlessTarget, KindRequest, KindTarget, Policy, Request, ResidualReads, Target as Target$1 } from "./Policy.js";
4
4
  import { Decision } from "./Decision.js";
5
5
  import { Forbidden as Forbidden$1, Pending as Pending$1, PolicyUnavailable as PolicyUnavailable$1 } from "./internal/authorizer.js";
6
6
  import * as Context from "effect/Context";
@@ -8,7 +8,7 @@ import * as Effect from "effect/Effect";
8
8
  import * as Layer from "effect/Layer";
9
9
  import * as Duration from "effect/Duration";
10
10
  declare namespace Authorizer_d_exports {
11
- export { AnyServiceClass, Authorizer, DeciderRequest, Forbidden, GuardOptions, Options, Pending, PolicyUnavailable, Service, ServiceClass, Target, layer };
11
+ export { AnyServiceClass, Authorizer, DeciderRequest, DeepTarget, Forbidden, GuardOptions, Options, Pending, PolicyUnavailable, Service, ServiceClass, Target, layer };
12
12
  }
13
13
  /**
14
14
  * The error when a policy says no.
@@ -65,6 +65,15 @@ export type Pending = Pending$1;
65
65
  * @since 0.3.0
66
66
  */
67
67
  export type Target<D> = Target$1<D> | KindTarget<D>;
68
+ /**
69
+ * A {@link Target} with a field of any length, which a check checks with
70
+ * `Policy.CheckField`.
71
+ *
72
+ * @stability stable
73
+ * @category models
74
+ * @since 2.1.0
75
+ */
76
+ export type DeepTarget<D> = DeepTarget$1<D> | DeepKindTarget<D>;
68
77
  /**
69
78
  * A request to the decider.
70
79
  *
@@ -114,29 +123,29 @@ export interface Authorizer<D extends Any, E, R> {
114
123
  */
115
124
  readonly policy: Effect.Effect<Policy<D, Opaque<E>>, PolicyUnavailable | E, R>;
116
125
  /** Gives the decision of the policy. It does not ask the decider. */
117
- readonly decide: (target: Target$1<D>) => Effect.Effect<Decision, PolicyUnavailable | E, R>;
126
+ readonly decide: <const T extends DeepTarget$1<D>>(target: T & CheckField<D, T>) => Effect.Effect<Decision, PolicyUnavailable | E, R>;
118
127
  /** Succeeds when the principal may do the act, and fails when it may not. */
119
- readonly check: (target: Target<D>) => Effect.Effect<void, Forbidden | Pending | PolicyUnavailable | E, R>;
128
+ readonly check: <const T extends DeepTarget<D>>(target: T & CheckField<D, T>) => Effect.Effect<void, Forbidden | Pending | PolicyUnavailable | E, R>;
120
129
  /**
121
130
  * Checks the read action first, and fails with the error of `hide` when the
122
131
  * principal may not see the resource. Then it checks the act. Use it to
123
132
  * answer "not found" to a principal that may not know that a resource
124
133
  * exists.
125
134
  */
126
- readonly guard: <const T extends Target$1<D>, E2>(target: T, options: GuardOptions<D, E2, T["resource"]["_tag"]>) => Effect.Effect<void, E2 | Forbidden | Pending | PolicyUnavailable | E, R>;
135
+ readonly guard: <const T extends DeepTarget$1<D>, E2>(target: T & CheckField<D, T>, options: GuardOptions<D, E2, T["resource"]["_tag"]>) => Effect.Effect<void, E2 | Forbidden | Pending | PolicyUnavailable | E, R>;
127
136
  /**
128
137
  * Gives the condition on resource values that the principal may act on,
129
138
  * inside the scope of the target when it has one. Change it into a query
130
139
  * with `Condition.fold`. It is `False` when the principal may act on no
131
140
  * value, so the list is empty: it is not an error.
132
141
  */
133
- readonly filter: <const T extends KindTarget<D>>(target: T) => Effect.Effect<Condition<ResidualReads<D, T["kind"]>, Opaque<E>>, PolicyUnavailable | E, R>;
142
+ readonly filter: <const T extends DeepKindTarget<D>>(target: T & CheckField<D, T>) => Effect.Effect<Condition<ResidualReads<D, T["kind"]>, Opaque<E>>, PolicyUnavailable | E, R>;
134
143
  /**
135
144
  * Tells if the principal may act on all, none or some of the values in
136
145
  * the scope of the target. See `Policy.coverage`. Use it to show a button
137
146
  * only when the answer is not `None`.
138
147
  */
139
- readonly coverage: <const T extends KindTarget<D>>(target: T) => Effect.Effect<Coverage<ResidualReads<D, T["kind"]>, Opaque<E>>, PolicyUnavailable | E, R>;
148
+ readonly coverage: <const T extends DeepKindTarget<D>>(target: T & CheckField<D, T>) => Effect.Effect<Coverage<ResidualReads<D, T["kind"]>, Opaque<E>>, PolicyUnavailable | E, R>;
140
149
  /** Gives the fields of a value that the principal may use. */
141
150
  readonly permittedFields: (target: FieldlessTarget<D>) => Effect.Effect<ReadonlyArray<string>, PolicyUnavailable | E, R>;
142
151
  /**
@@ -157,11 +166,11 @@ export interface ServiceClass<Self, Id extends string, D extends Any, E, R> exte
157
166
  readonly domain: D;
158
167
  /** The Effect that gives the principal of the current request. */
159
168
  readonly principal: Effect.Effect<Principal<D>, E, R>;
160
- readonly decide: (target: Target$1<D>) => Effect.Effect<Decision, PolicyUnavailable | E, R | Self>;
161
- readonly check: (target: Target<D>) => Effect.Effect<void, Forbidden | Pending | PolicyUnavailable | E, R | Self>;
162
- readonly guard: <const T extends Target$1<D>, E2>(target: T, options: GuardOptions<D, E2, T["resource"]["_tag"]>) => Effect.Effect<void, E2 | Forbidden | Pending | PolicyUnavailable | E, R | Self>;
163
- readonly filter: <const T extends KindTarget<D>>(target: T) => Effect.Effect<Condition<ResidualReads<D, T["kind"]>, Opaque<E>>, PolicyUnavailable | E, R | Self>;
164
- readonly coverage: <const T extends KindTarget<D>>(target: T) => Effect.Effect<Coverage<ResidualReads<D, T["kind"]>, Opaque<E>>, PolicyUnavailable | E, R | Self>;
169
+ readonly decide: <const T extends DeepTarget$1<D>>(target: T & CheckField<D, T>) => Effect.Effect<Decision, PolicyUnavailable | E, R | Self>;
170
+ readonly check: <const T extends DeepTarget<D>>(target: T & CheckField<D, T>) => Effect.Effect<void, Forbidden | Pending | PolicyUnavailable | E, R | Self>;
171
+ readonly guard: <const T extends DeepTarget$1<D>, E2>(target: T & CheckField<D, T>, options: GuardOptions<D, E2, T["resource"]["_tag"]>) => Effect.Effect<void, E2 | Forbidden | Pending | PolicyUnavailable | E, R | Self>;
172
+ readonly filter: <const T extends DeepKindTarget<D>>(target: T & CheckField<D, T>) => Effect.Effect<Condition<ResidualReads<D, T["kind"]>, Opaque<E>>, PolicyUnavailable | E, R | Self>;
173
+ readonly coverage: <const T extends DeepKindTarget<D>>(target: T & CheckField<D, T>) => Effect.Effect<Coverage<ResidualReads<D, T["kind"]>, Opaque<E>>, PolicyUnavailable | E, R | Self>;
165
174
  readonly permittedFields: (target: FieldlessTarget<D>) => Effect.Effect<ReadonlyArray<string>, PolicyUnavailable | E, R | Self>;
166
175
  }
167
176
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"Authorizer.d.ts","names":["Internal.Forbidden","Internal.PolicyUnavailable","Internal.Pending","Policy.Target","Policy.KindTarget","Policy.Request","Policy.KindRequest","Domain.Kind","Domain.CommonAction","Domain.Any","Domain.Principal","Condition.Opaque","Policy.Policy","Decision.Decision","Policy.ResidualReads","Condition.Condition","Policy.Coverage","Policy.FieldlessTarget"],"sources":["../src/Authorizer.ts"],"mappings":"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"}
1
+ {"version":3,"file":"Authorizer.d.ts","names":["Internal.Forbidden","Internal.PolicyUnavailable","Internal.Pending","Policy.Target","Policy.KindTarget","Policy.DeepTarget","Policy.DeepKindTarget","Policy.Request","Policy.KindRequest","Domain.Kind","Domain.CommonAction","Domain.Any","Domain.Principal","Condition.Opaque","Policy.Policy","Policy.CheckField","Decision.Decision","Policy.ResidualReads","Condition.Condition","Policy.Coverage","Policy.FieldlessTarget"],"sources":["../src/Authorizer.ts"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Authorizer.js","names":["Internal.Forbidden","Internal.PolicyUnavailable","Internal.Pending","Internal.Service","Internal.makeLayer"],"sources":["../src/Authorizer.ts"],"sourcesContent":["/**\n * An authorizer is an Effect service that makes decisions for the principal\n * of the current request.\n *\n * You make the service class, in the same way as `Context.Service`. Give the\n * domain, and the Effect that gives the principal of the current request. The\n * error type and the service type of the checks come from that Effect:\n *\n * ```ts\n * class Auth extends Authorizer.Service<Auth>()(\"app/Auth\", {\n * domain: App,\n * principal: Identity,\n * }) {}\n * ```\n *\n * Then give a layer with {@link layer}. It says how to load the policy of a\n * principal. The policy of each principal is loaded once and kept in a cache\n * for a short time.\n *\n * Then use the service in a handler:\n *\n * ```ts\n * yield* Auth.check({ action: \"update\", resource: document })\n * ```\n *\n * A \"no\" answer goes into the error channel as {@link Forbidden}. When the\n * policy can not be loaded, the check fails with {@link PolicyUnavailable}.\n * So the check fails closed: an error is never a \"yes\".\n *\n * When no rule gives an answer, the authorizer asks the decider, if there is\n * one. A decider may answer at once, or fail with {@link Pending} when a person\n * or another service must answer later.\n *\n * @stability stable\n * @since 0.3.0\n */\nimport type * as Context from \"effect/Context\"\nimport type * as Duration from \"effect/Duration\"\nimport type * as Effect from \"effect/Effect\"\nimport type * as Layer from \"effect/Layer\"\nimport type * as Condition from \"./Condition.ts\"\nimport type * as Decision from \"./Decision.ts\"\nimport type * as Domain from \"./Domain.ts\"\nimport * as Internal from \"./internal/authorizer.ts\"\nimport type * as Policy from \"./Policy.ts\"\n\n/**\n * The error when a policy says no.\n *\n * @stability stable\n * @category errors\n * @since 0.3.0\n */\nexport const Forbidden: typeof Internal.Forbidden = Internal.Forbidden\n\n/**\n * @stability stable\n * @category errors\n * @since 0.3.0\n */\nexport type Forbidden = Internal.Forbidden\n\n/**\n * The error when the policy of the principal can not be loaded. The cause is\n * kept, but it is not shown to the client.\n *\n * @stability stable\n * @category errors\n * @since 0.3.0\n */\nexport const PolicyUnavailable: typeof Internal.PolicyUnavailable =\n\tInternal.PolicyUnavailable\n\n/**\n * @stability stable\n * @category errors\n * @since 0.3.0\n */\nexport type PolicyUnavailable = Internal.PolicyUnavailable\n\n/**\n * The error when a decider must wait for an answer. `ticket` names the\n * request that waits, so the client can come back for the answer.\n *\n * @stability stable\n * @category errors\n * @since 0.3.0\n */\nexport const Pending: typeof Internal.Pending = Internal.Pending\n\n/**\n * @stability stable\n * @category errors\n * @since 0.3.0\n */\nexport type Pending = Internal.Pending\n\n/**\n * What a check is about: an act on a resource value, or an act on a kind of\n * resource. A check on a kind passes only when the policy allows the act on\n * every value of the kind. With a scope (`within`), it passes when the policy\n * allows the act on every value in the scope, and the scope is not empty.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Target<D> = Policy.Target<D> | Policy.KindTarget<D>\n\n/**\n * A request to the decider.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type DeciderRequest<D> = Policy.Request<D> | Policy.KindRequest<D>\n\n/**\n * The options of a guard.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type GuardOptions<D, E2, K extends string = Domain.Kind<D>> = {\n\t/** The error when the principal may not see the resource. */\n\treadonly hide: () => E2\n} & (\"read\" extends Domain.CommonAction<D, K>\n\t? {\n\t\t\t/**\n\t\t\t * The action that lets the principal see the resource. It must be an\n\t\t\t * action of every kind in `K`. The default is `\"read\"`.\n\t\t\t */\n\t\t\treadonly read?: Domain.CommonAction<D, K>\n\t\t}\n\t: {\n\t\t\t/**\n\t\t\t * The action that lets the principal see the resource. It must be an\n\t\t\t * action of every kind in `K`. Some kind in `K` has no `\"read\"`\n\t\t\t * action, so you must give it.\n\t\t\t */\n\t\t\treadonly read: Domain.CommonAction<D, K>\n\t\t})\n\n/**\n * The service.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Authorizer<D extends Domain.Any, E, R> {\n\treadonly domain: D\n\t/** The principal of the current request. */\n\treadonly principal: Effect.Effect<Domain.Principal<D>, E, R>\n\t/**\n\t * The policy of the principal of the current request. Its predicates have\n\t * the services of the layer. It may have predicates, so it is opaque.\n\t */\n\treadonly policy: Effect.Effect<\n\t\tPolicy.Policy<D, Condition.Opaque<E>>,\n\t\tPolicyUnavailable | E,\n\t\tR\n\t>\n\t/** Gives the decision of the policy. It does not ask the decider. */\n\treadonly decide: (\n\t\ttarget: Policy.Target<D>,\n\t) => Effect.Effect<Decision.Decision, PolicyUnavailable | E, R>\n\t/** Succeeds when the principal may do the act, and fails when it may not. */\n\treadonly check: (\n\t\ttarget: Target<D>,\n\t) => Effect.Effect<void, Forbidden | Pending | PolicyUnavailable | E, R>\n\t/**\n\t * Checks the read action first, and fails with the error of `hide` when the\n\t * principal may not see the resource. Then it checks the act. Use it to\n\t * answer \"not found\" to a principal that may not know that a resource\n\t * exists.\n\t */\n\treadonly guard: <const T extends Policy.Target<D>, E2>(\n\t\ttarget: T,\n\t\toptions: GuardOptions<D, E2, T[\"resource\"][\"_tag\"]>,\n\t) => Effect.Effect<void, E2 | Forbidden | Pending | PolicyUnavailable | E, R>\n\t/**\n\t * Gives the condition on resource values that the principal may act on,\n\t * inside the scope of the target when it has one. Change it into a query\n\t * with `Condition.fold`. It is `False` when the principal may act on no\n\t * value, so the list is empty: it is not an error.\n\t */\n\treadonly filter: <const T extends Policy.KindTarget<D>>(\n\t\ttarget: T,\n\t) => Effect.Effect<\n\t\tCondition.Condition<\n\t\t\tPolicy.ResidualReads<D, T[\"kind\"]>,\n\t\t\tCondition.Opaque<E>\n\t\t>,\n\t\tPolicyUnavailable | E,\n\t\tR\n\t>\n\t/**\n\t * Tells if the principal may act on all, none or some of the values in\n\t * the scope of the target. See `Policy.coverage`. Use it to show a button\n\t * only when the answer is not `None`.\n\t */\n\treadonly coverage: <const T extends Policy.KindTarget<D>>(\n\t\ttarget: T,\n\t) => Effect.Effect<\n\t\tPolicy.Coverage<Policy.ResidualReads<D, T[\"kind\"]>, Condition.Opaque<E>>,\n\t\tPolicyUnavailable | E,\n\t\tR\n\t>\n\t/** Gives the fields of a value that the principal may use. */\n\treadonly permittedFields: (\n\t\ttarget: Policy.FieldlessTarget<D>,\n\t) => Effect.Effect<ReadonlyArray<string>, PolicyUnavailable | E, R>\n\t/**\n\t * Removes the cached policy of a principal, or of every principal. Call it\n\t * after a change to the rules or roles of a principal.\n\t */\n\treadonly invalidate: (principal?: Domain.Principal<D>) => Effect.Effect<void>\n}\n\n/**\n * The class made by {@link Service}. The static functions use the service\n * from the context.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface ServiceClass<\n\tSelf,\n\tId extends string,\n\tD extends Domain.Any,\n\tE,\n\tR,\n> extends Context.ServiceClass<Self, Id, Authorizer<D, E, R>> {\n\treadonly domain: D\n\t/** The Effect that gives the principal of the current request. */\n\treadonly principal: Effect.Effect<Domain.Principal<D>, E, R>\n\treadonly decide: (\n\t\ttarget: Policy.Target<D>,\n\t) => Effect.Effect<Decision.Decision, PolicyUnavailable | E, R | Self>\n\treadonly check: (\n\t\ttarget: Target<D>,\n\t) => Effect.Effect<\n\t\tvoid,\n\t\tForbidden | Pending | PolicyUnavailable | E,\n\t\tR | Self\n\t>\n\treadonly guard: <const T extends Policy.Target<D>, E2>(\n\t\ttarget: T,\n\t\toptions: GuardOptions<D, E2, T[\"resource\"][\"_tag\"]>,\n\t) => Effect.Effect<\n\t\tvoid,\n\t\tE2 | Forbidden | Pending | PolicyUnavailable | E,\n\t\tR | Self\n\t>\n\treadonly filter: <const T extends Policy.KindTarget<D>>(\n\t\ttarget: T,\n\t) => Effect.Effect<\n\t\tCondition.Condition<\n\t\t\tPolicy.ResidualReads<D, T[\"kind\"]>,\n\t\t\tCondition.Opaque<E>\n\t\t>,\n\t\tPolicyUnavailable | E,\n\t\tR | Self\n\t>\n\treadonly coverage: <const T extends Policy.KindTarget<D>>(\n\t\ttarget: T,\n\t) => Effect.Effect<\n\t\tPolicy.Coverage<Policy.ResidualReads<D, T[\"kind\"]>, Condition.Opaque<E>>,\n\t\tPolicyUnavailable | E,\n\t\tR | Self\n\t>\n\treadonly permittedFields: (\n\t\ttarget: Policy.FieldlessTarget<D>,\n\t) => Effect.Effect<ReadonlyArray<string>, PolicyUnavailable | E, R | Self>\n}\n\n/**\n * Any service class made by {@link Service}.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type AnyServiceClass = Context.Key<any, any> & {\n\treadonly domain: Domain.Any\n\treadonly principal: Effect.Effect<any, any, any>\n}\n\n/**\n * Makes an authorizer service class for a domain.\n *\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const Service: <Self>() => <\n\tconst Id extends string,\n\tD extends Domain.Any,\n\tE = never,\n\tR = never,\n>(\n\tid: Id,\n\toptions: {\n\t\treadonly domain: D\n\t\t/** Gives the principal of the current request. */\n\t\treadonly principal: Effect.Effect<Domain.Principal<NoInfer<D>>, E, R>\n\t},\n) => ServiceClass<Self, Id, D, E, R> = Internal.Service as never\n\n/**\n * The options of {@link layer}.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Options<D extends Domain.Any, E, R, EL, RL, RP> {\n\t/**\n\t * Loads the policy of a principal. A failure becomes\n\t * {@link PolicyUnavailable}. The services of the predicates of the policy\n\t * are taken when the layer is built.\n\t */\n\treadonly policy: (\n\t\tprincipal: Domain.Principal<D>,\n\t) => Effect.Effect<Policy.Policy<D, Condition.Opaque<E, RP>>, EL, RL>\n\t/**\n\t * Answers when no rule gives an answer. Without a decider, such a request\n\t * fails with {@link Forbidden}.\n\t */\n\treadonly decider?: (\n\t\trequest: DeciderRequest<D>,\n\t) => Effect.Effect<Decision.Decision, Pending | E, R>\n\t/**\n\t * How the policies are kept. The default keeps 1000 policies for 30 seconds.\n\t * Give `false` to load the policy for each check.\n\t *\n\t * The key of a principal is the text of its JSON form, from the Schema of\n\t * the principal of the domain. A principal is kept only when the value that\n\t * the Schema decodes from that form is `Equal` to it. The loader always\n\t * gets that decoded copy, also with no cache, so two principals with one\n\t * key get one policy, and the cache can not change an answer. So the loader\n\t * must decide by the data of the principal, not by the identity of its\n\t * objects. A principal with no JSON form is not kept, and the loader gets\n\t * it as it is. Give `key` to make the key in another way.\n\t */\n\treadonly cache?:\n\t\t| {\n\t\t\t\treadonly capacity?: number\n\t\t\t\treadonly timeToLive?: Duration.Input\n\t\t\t\treadonly key?: (principal: Domain.Principal<D>) => string | undefined\n\t\t }\n\t\t| false\n}\n\n/**\n * Makes the layer of an authorizer.\n *\n * @stability stable\n * @category layers\n * @since 0.3.0\n */\nexport const layer: <\n\tSelf,\n\tId extends string,\n\tD extends Domain.Any,\n\tE,\n\tR,\n\tEL = never,\n\tRL = never,\n\tRP = never,\n>(\n\tservice: ServiceClass<Self, Id, D, E, R>,\n\toptions: Options<D, NoInfer<E>, NoInfer<R>, EL, RL, RP>,\n) => Layer.Layer<Self, never, RL | RP> = Internal.makeLayer as never\n"],"mappings":";;;;;;;;;;;;;;;;;AAqDA,MAAa,YAAuCA;;;;;;;;;AAiBpD,MAAa,oBACZC;;;;;;;;;AAiBD,MAAa,UAAmCC;;;;;;;;AAmNhD,MAAa,UAY0BC;;;;;;;;AAsDvC,MAAa,QAY4BC"}
1
+ {"version":3,"file":"Authorizer.js","names":["Internal.Forbidden","Internal.PolicyUnavailable","Internal.Pending","Internal.Service","Internal.makeLayer"],"sources":["../src/Authorizer.ts"],"sourcesContent":["/**\n * An authorizer is an Effect service that makes decisions for the principal\n * of the current request.\n *\n * You make the service class, in the same way as `Context.Service`. Give the\n * domain, and the Effect that gives the principal of the current request. The\n * error type and the service type of the checks come from that Effect:\n *\n * ```ts\n * class Auth extends Authorizer.Service<Auth>()(\"app/Auth\", {\n * domain: App,\n * principal: Identity,\n * }) {}\n * ```\n *\n * Then give a layer with {@link layer}. It says how to load the policy of a\n * principal. The policy of each principal is loaded once and kept in a cache\n * for a short time.\n *\n * Then use the service in a handler:\n *\n * ```ts\n * yield* Auth.check({ action: \"update\", resource: document })\n * ```\n *\n * A \"no\" answer goes into the error channel as {@link Forbidden}. When the\n * policy can not be loaded, the check fails with {@link PolicyUnavailable}.\n * So the check fails closed: an error is never a \"yes\".\n *\n * When no rule gives an answer, the authorizer asks the decider, if there is\n * one. A decider may answer at once, or fail with {@link Pending} when a person\n * or another service must answer later.\n *\n * @stability stable\n * @since 0.3.0\n */\nimport type * as Context from \"effect/Context\"\nimport type * as Duration from \"effect/Duration\"\nimport type * as Effect from \"effect/Effect\"\nimport type * as Layer from \"effect/Layer\"\nimport type * as Condition from \"./Condition.ts\"\nimport type * as Decision from \"./Decision.ts\"\nimport type * as Domain from \"./Domain.ts\"\nimport * as Internal from \"./internal/authorizer.ts\"\nimport type * as Policy from \"./Policy.ts\"\n\n/**\n * The error when a policy says no.\n *\n * @stability stable\n * @category errors\n * @since 0.3.0\n */\nexport const Forbidden: typeof Internal.Forbidden = Internal.Forbidden\n\n/**\n * @stability stable\n * @category errors\n * @since 0.3.0\n */\nexport type Forbidden = Internal.Forbidden\n\n/**\n * The error when the policy of the principal can not be loaded. The cause is\n * kept, but it is not shown to the client.\n *\n * @stability stable\n * @category errors\n * @since 0.3.0\n */\nexport const PolicyUnavailable: typeof Internal.PolicyUnavailable =\n\tInternal.PolicyUnavailable\n\n/**\n * @stability stable\n * @category errors\n * @since 0.3.0\n */\nexport type PolicyUnavailable = Internal.PolicyUnavailable\n\n/**\n * The error when a decider must wait for an answer. `ticket` names the\n * request that waits, so the client can come back for the answer.\n *\n * @stability stable\n * @category errors\n * @since 0.3.0\n */\nexport const Pending: typeof Internal.Pending = Internal.Pending\n\n/**\n * @stability stable\n * @category errors\n * @since 0.3.0\n */\nexport type Pending = Internal.Pending\n\n/**\n * What a check is about: an act on a resource value, or an act on a kind of\n * resource. A check on a kind passes only when the policy allows the act on\n * every value of the kind. With a scope (`within`), it passes when the policy\n * allows the act on every value in the scope, and the scope is not empty.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Target<D> = Policy.Target<D> | Policy.KindTarget<D>\n\n/**\n * A {@link Target} with a field of any length, which a check checks with\n * `Policy.CheckField`.\n *\n * @stability stable\n * @category models\n * @since 2.1.0\n */\nexport type DeepTarget<D> = Policy.DeepTarget<D> | Policy.DeepKindTarget<D>\n\n/**\n * A request to the decider.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type DeciderRequest<D> = Policy.Request<D> | Policy.KindRequest<D>\n\n/**\n * The options of a guard.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type GuardOptions<D, E2, K extends string = Domain.Kind<D>> = {\n\t/** The error when the principal may not see the resource. */\n\treadonly hide: () => E2\n} & (\"read\" extends Domain.CommonAction<D, K>\n\t? {\n\t\t\t/**\n\t\t\t * The action that lets the principal see the resource. It must be an\n\t\t\t * action of every kind in `K`. The default is `\"read\"`.\n\t\t\t */\n\t\t\treadonly read?: Domain.CommonAction<D, K>\n\t\t}\n\t: {\n\t\t\t/**\n\t\t\t * The action that lets the principal see the resource. It must be an\n\t\t\t * action of every kind in `K`. Some kind in `K` has no `\"read\"`\n\t\t\t * action, so you must give it.\n\t\t\t */\n\t\t\treadonly read: Domain.CommonAction<D, K>\n\t\t})\n\n/**\n * The service.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Authorizer<D extends Domain.Any, E, R> {\n\treadonly domain: D\n\t/** The principal of the current request. */\n\treadonly principal: Effect.Effect<Domain.Principal<D>, E, R>\n\t/**\n\t * The policy of the principal of the current request. Its predicates have\n\t * the services of the layer. It may have predicates, so it is opaque.\n\t */\n\treadonly policy: Effect.Effect<\n\t\tPolicy.Policy<D, Condition.Opaque<E>>,\n\t\tPolicyUnavailable | E,\n\t\tR\n\t>\n\t/** Gives the decision of the policy. It does not ask the decider. */\n\treadonly decide: <const T extends Policy.DeepTarget<D>>(\n\t\ttarget: T & Policy.CheckField<D, T>,\n\t) => Effect.Effect<Decision.Decision, PolicyUnavailable | E, R>\n\t/** Succeeds when the principal may do the act, and fails when it may not. */\n\treadonly check: <const T extends DeepTarget<D>>(\n\t\ttarget: T & Policy.CheckField<D, T>,\n\t) => Effect.Effect<void, Forbidden | Pending | PolicyUnavailable | E, R>\n\t/**\n\t * Checks the read action first, and fails with the error of `hide` when the\n\t * principal may not see the resource. Then it checks the act. Use it to\n\t * answer \"not found\" to a principal that may not know that a resource\n\t * exists.\n\t */\n\treadonly guard: <const T extends Policy.DeepTarget<D>, E2>(\n\t\ttarget: T & Policy.CheckField<D, T>,\n\t\toptions: GuardOptions<D, E2, T[\"resource\"][\"_tag\"]>,\n\t) => Effect.Effect<void, E2 | Forbidden | Pending | PolicyUnavailable | E, R>\n\t/**\n\t * Gives the condition on resource values that the principal may act on,\n\t * inside the scope of the target when it has one. Change it into a query\n\t * with `Condition.fold`. It is `False` when the principal may act on no\n\t * value, so the list is empty: it is not an error.\n\t */\n\treadonly filter: <const T extends Policy.DeepKindTarget<D>>(\n\t\ttarget: T & Policy.CheckField<D, T>,\n\t) => Effect.Effect<\n\t\tCondition.Condition<\n\t\t\tPolicy.ResidualReads<D, T[\"kind\"]>,\n\t\t\tCondition.Opaque<E>\n\t\t>,\n\t\tPolicyUnavailable | E,\n\t\tR\n\t>\n\t/**\n\t * Tells if the principal may act on all, none or some of the values in\n\t * the scope of the target. See `Policy.coverage`. Use it to show a button\n\t * only when the answer is not `None`.\n\t */\n\treadonly coverage: <const T extends Policy.DeepKindTarget<D>>(\n\t\ttarget: T & Policy.CheckField<D, T>,\n\t) => Effect.Effect<\n\t\tPolicy.Coverage<Policy.ResidualReads<D, T[\"kind\"]>, Condition.Opaque<E>>,\n\t\tPolicyUnavailable | E,\n\t\tR\n\t>\n\t/** Gives the fields of a value that the principal may use. */\n\treadonly permittedFields: (\n\t\ttarget: Policy.FieldlessTarget<D>,\n\t) => Effect.Effect<ReadonlyArray<string>, PolicyUnavailable | E, R>\n\t/**\n\t * Removes the cached policy of a principal, or of every principal. Call it\n\t * after a change to the rules or roles of a principal.\n\t */\n\treadonly invalidate: (principal?: Domain.Principal<D>) => Effect.Effect<void>\n}\n\n/**\n * The class made by {@link Service}. The static functions use the service\n * from the context.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface ServiceClass<\n\tSelf,\n\tId extends string,\n\tD extends Domain.Any,\n\tE,\n\tR,\n> extends Context.ServiceClass<Self, Id, Authorizer<D, E, R>> {\n\treadonly domain: D\n\t/** The Effect that gives the principal of the current request. */\n\treadonly principal: Effect.Effect<Domain.Principal<D>, E, R>\n\treadonly decide: <const T extends Policy.DeepTarget<D>>(\n\t\ttarget: T & Policy.CheckField<D, T>,\n\t) => Effect.Effect<Decision.Decision, PolicyUnavailable | E, R | Self>\n\treadonly check: <const T extends DeepTarget<D>>(\n\t\ttarget: T & Policy.CheckField<D, T>,\n\t) => Effect.Effect<\n\t\tvoid,\n\t\tForbidden | Pending | PolicyUnavailable | E,\n\t\tR | Self\n\t>\n\treadonly guard: <const T extends Policy.DeepTarget<D>, E2>(\n\t\ttarget: T & Policy.CheckField<D, T>,\n\t\toptions: GuardOptions<D, E2, T[\"resource\"][\"_tag\"]>,\n\t) => Effect.Effect<\n\t\tvoid,\n\t\tE2 | Forbidden | Pending | PolicyUnavailable | E,\n\t\tR | Self\n\t>\n\treadonly filter: <const T extends Policy.DeepKindTarget<D>>(\n\t\ttarget: T & Policy.CheckField<D, T>,\n\t) => Effect.Effect<\n\t\tCondition.Condition<\n\t\t\tPolicy.ResidualReads<D, T[\"kind\"]>,\n\t\t\tCondition.Opaque<E>\n\t\t>,\n\t\tPolicyUnavailable | E,\n\t\tR | Self\n\t>\n\treadonly coverage: <const T extends Policy.DeepKindTarget<D>>(\n\t\ttarget: T & Policy.CheckField<D, T>,\n\t) => Effect.Effect<\n\t\tPolicy.Coverage<Policy.ResidualReads<D, T[\"kind\"]>, Condition.Opaque<E>>,\n\t\tPolicyUnavailable | E,\n\t\tR | Self\n\t>\n\treadonly permittedFields: (\n\t\ttarget: Policy.FieldlessTarget<D>,\n\t) => Effect.Effect<ReadonlyArray<string>, PolicyUnavailable | E, R | Self>\n}\n\n/**\n * Any service class made by {@link Service}.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type AnyServiceClass = Context.Key<any, any> & {\n\treadonly domain: Domain.Any\n\treadonly principal: Effect.Effect<any, any, any>\n}\n\n/**\n * Makes an authorizer service class for a domain.\n *\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const Service: <Self>() => <\n\tconst Id extends string,\n\tD extends Domain.Any,\n\tE = never,\n\tR = never,\n>(\n\tid: Id,\n\toptions: {\n\t\treadonly domain: D\n\t\t/** Gives the principal of the current request. */\n\t\treadonly principal: Effect.Effect<Domain.Principal<NoInfer<D>>, E, R>\n\t},\n) => ServiceClass<Self, Id, D, E, R> = Internal.Service as never\n\n/**\n * The options of {@link layer}.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Options<D extends Domain.Any, E, R, EL, RL, RP> {\n\t/**\n\t * Loads the policy of a principal. A failure becomes\n\t * {@link PolicyUnavailable}. The services of the predicates of the policy\n\t * are taken when the layer is built.\n\t */\n\treadonly policy: (\n\t\tprincipal: Domain.Principal<D>,\n\t) => Effect.Effect<Policy.Policy<D, Condition.Opaque<E, RP>>, EL, RL>\n\t/**\n\t * Answers when no rule gives an answer. Without a decider, such a request\n\t * fails with {@link Forbidden}.\n\t */\n\treadonly decider?: (\n\t\trequest: DeciderRequest<D>,\n\t) => Effect.Effect<Decision.Decision, Pending | E, R>\n\t/**\n\t * How the policies are kept. The default keeps 1000 policies for 30 seconds.\n\t * Give `false` to load the policy for each check.\n\t *\n\t * The key of a principal is the text of its JSON form, from the Schema of\n\t * the principal of the domain. A principal is kept only when the value that\n\t * the Schema decodes from that form is `Equal` to it. The loader always\n\t * gets that decoded copy, also with no cache, so two principals with one\n\t * key get one policy, and the cache can not change an answer. So the loader\n\t * must decide by the data of the principal, not by the identity of its\n\t * objects. A principal with no JSON form is not kept, and the loader gets\n\t * it as it is. Give `key` to make the key in another way.\n\t */\n\treadonly cache?:\n\t\t| {\n\t\t\t\treadonly capacity?: number\n\t\t\t\treadonly timeToLive?: Duration.Input\n\t\t\t\treadonly key?: (principal: Domain.Principal<D>) => string | undefined\n\t\t }\n\t\t| false\n}\n\n/**\n * Makes the layer of an authorizer.\n *\n * @stability stable\n * @category layers\n * @since 0.3.0\n */\nexport const layer: <\n\tSelf,\n\tId extends string,\n\tD extends Domain.Any,\n\tE,\n\tR,\n\tEL = never,\n\tRL = never,\n\tRP = never,\n>(\n\tservice: ServiceClass<Self, Id, D, E, R>,\n\toptions: Options<D, NoInfer<E>, NoInfer<R>, EL, RL, RP>,\n) => Layer.Layer<Self, never, RL | RP> = Internal.makeLayer as never\n"],"mappings":";;;;;;;;;;;;;;;;;AAqDA,MAAa,YAAuCA;;;;;;;;;AAiBpD,MAAa,oBACZC;;;;;;;;;AAiBD,MAAa,UAAmCC;;;;;;;;AA6NhD,MAAa,UAY0BC;;;;;;;;AAsDvC,MAAa,QAY4BC"}
@@ -9,14 +9,14 @@ import * as HashSet from "effect/HashSet";
9
9
  import * as Result from "effect/Result";
10
10
  import * as Schema from "effect/Schema";
11
11
  import * as Option from "effect/Option";
12
+ import * as Cause from "effect/Cause";
13
+ import * as Exit from "effect/Exit";
12
14
  import * as Duration from "effect/Duration";
13
15
  import * as BigDecimal from "effect/BigDecimal";
14
- import * as Cause from "effect/Cause";
15
16
  import * as DateTime from "effect/DateTime";
16
- import * as Exit from "effect/Exit";
17
17
  import * as Redacted from "effect/Redacted";
18
18
  declare namespace Condition_d_exports {
19
- export { And, Any, Ast, Builder, Compare, CompareOperator, Condition, Encoded, EncodedOperand, ErrorOf, Example, Exists, False, FieldName, FieldPath, FieldSelector, FieldValue, In, Input, Interpreter, Literal, Not, Opaque, OpaqueOf, Operand, OperandOf, Or, PathValue, PlainCondition, Predicate, PrincipalRef, Provided, Reads, ReadsOf, Ref, Satisfiability, SatisfiableOptions, Scalar, ServicesOf, Test, True, Under, Untranslatable, always, and, andAll, builder, evaluate, evaluateSync, fields, fold, never, not, or, orAll, partial, provideContext, satisfiable, schema, simplify };
19
+ export { And, Any, Ast, Builder, Compare, CompareOperator, Condition, Encoded, EncodedOperand, ErrorOf, Example, Exists, False, FieldName, FieldPath, FieldSelector, FieldValue, In, Input, Interpreter, Literal, NamePath, Not, Opaque, OpaqueOf, Operand, OperandOf, Or, PathValue, PlainCondition, Predicate, PrincipalRef, Provided, ReadPath, Reads, ReadsOf, Ref, Satisfiability, SatisfiableOptions, Scalar, SelectPath, ServicesOf, Test, True, Under, Untranslatable, always, and, andAll, builder, evaluate, evaluateSync, fields, fold, never, not, or, orAll, partial, provideContext, satisfiable, schema, simplify };
20
20
  }
21
21
  /**
22
22
  * A value that a condition can compare.
@@ -276,7 +276,7 @@ type FieldPathInternal<T, Depth extends number, Arrays extends boolean, Parents
276
276
  */
277
277
  type PathsOf<K extends string, V, Depth extends number, Arrays extends boolean, Parents extends boolean> = ([V] extends [never] ? K : {} extends V ? K : never) | ([Extract<V, Leaf | Whole>] extends [never] ? never : K) | ([Extract<V, ReadonlyArray<unknown>>] extends [never] ? never : Arrays extends true ? K : never) | (Arrays extends true ? ObjectPaths<K, Exclude<V, Leaf | Whole | Function | ReadonlyArray<unknown>>, Depth, Arrays, Parents> : [Extract<V, Whole | Function | ReadonlyArray<unknown>>] extends [never] ? ObjectPaths<K, Exclude<V, Leaf>, Depth, Arrays, Parents> : never);
278
278
  /** The paths of a field `K` that holds the objects `O`, and of the fields below. */
279
- type ObjectPaths<K extends string, O, Depth extends number, Arrays extends boolean, Parents extends boolean> = [O] extends [never] ? never : (Parents extends true ? K : Arrays extends true ? string extends keyof O ? K : number extends keyof O ? K : [Depth] extends [0] ? K : never : never) | `${K}.${FieldPathInternal<O, PreviousDepth[Depth], Arrays, Parents>}`;
279
+ type ObjectPaths<K extends string, O, Depth extends number, Arrays extends boolean, Parents extends boolean> = [O] extends [never] ? never : (Parents extends true ? K : Arrays extends true ? string extends keyof O ? K : number extends keyof O ? K : never : never) | `${K}.${FieldPathInternal<O, PreviousDepth[Depth], Arrays, Parents>}`;
280
280
  /**
281
281
  * The paths of the fields of `T` that hold one value, with dots for nested
282
282
  * fields. Arrays are left out. A map, a set, a date, a URL, a byte array, an
@@ -334,14 +334,116 @@ type Normalize<A> = Exclude<A, undefined> | (undefined extends A ? null : never)
334
334
  * @category utility types
335
335
  * @since 0.3.0
336
336
  */
337
- export type PathValue<T, Path extends string> = T extends unknown ? PathValueIn<T, Path> : never;
338
- /** The type of the field at `Path` of `T`, which is not a union. */
339
- type PathValueIn<T, Path extends string> = T extends object ? Path extends `${infer Head}.${infer Rest}` ? PathValue<ChildOf<T, Head>, Rest> : Normalize<ChildOf<T, Path>> : null;
337
+ export type PathValue<T, Path extends string> = ValueWalk<T, Path>;
338
+ /**
339
+ * The values of the part `Name` of each type of `U`. A part below a value
340
+ * that is not an object, as below a string or `null`, is `null`.
341
+ */
342
+ type StepValue<U, Name extends string> = U extends unknown ? U extends object ? ChildOf<U, Name> : null : never;
343
+ /**
344
+ * Walks a path two parts at a time, with the values of each step. The type
345
+ * checker takes at most about 1000 steps of a type that calls itself, so a
346
+ * walk of one part at a time would stop before a path of 1000 parts.
347
+ */
348
+ type ValueWalk<U, Path extends string> = Path extends `${infer A}.${infer B}.${infer Rest}` ? ValueWalk<StepValue<StepValue<U, A>, B>, Rest> : Path extends `${infer A}.${infer B}` ? Normalize<StepValue<StepValue<U, A>, B>> : Normalize<StepValue<U, Path>>;
340
349
  /**
341
350
  * The type of the part `Name` of `T`. A part of a path is text, so the part
342
351
  * `"1"` names the number key `1` too, as of a record with number keys.
343
352
  */
344
353
  type ChildOf<T, Name extends string> = Name extends keyof T ? T[Name] : Name extends `${infer N extends number}` ? N extends keyof T ? T[N] : number extends keyof T ? T[number] : never : never;
354
+ /**
355
+ * What a path may do, for one use of it: go below a list or a whole value,
356
+ * as a rule or a request may, and end at a struct, as the fields of a rule
357
+ * may. See {@link FieldPath}, {@link FieldSelector} and {@link FieldName},
358
+ * which list the short paths with the same rules.
359
+ */
360
+ interface PathRules {
361
+ readonly arrays: boolean;
362
+ readonly parents: boolean;
363
+ }
364
+ /** The rules of a path that a condition reads. */
365
+ interface ReadRules {
366
+ readonly arrays: false;
367
+ readonly parents: false;
368
+ }
369
+ /** The rules of the field of a request. */
370
+ interface SelectRules {
371
+ readonly arrays: true;
372
+ readonly parents: false;
373
+ }
374
+ /** The rules of a field of a rule, which may name a struct. */
375
+ interface NameRules {
376
+ readonly arrays: true;
377
+ readonly parents: true;
378
+ }
379
+ /** The objects below a field with the values `V`: see `PathsOf`. */
380
+ type ObjectsBelow<V, Arrays extends boolean> = Arrays extends true ? Exclude<V, Leaf | Whole | Function | ReadonlyArray<unknown>> : [Extract<V, Whole | Function | ReadonlyArray<unknown>>] extends [never] ? Exclude<V, Leaf> : never;
381
+ /** Tests if `Name` names a field of every object of `O`, as `keyof` does. */
382
+ type HasPart<O, Name extends string> = Name extends keyof O ? true : Name extends `${infer N extends number}` ? N extends keyof O ? true : number extends keyof O ? true : false : false;
383
+ /**
384
+ * The objects below the part `Name` of the objects `O`, for a path that goes
385
+ * on, or `never` when it can not go on.
386
+ */
387
+ type PathStep<O, Name extends string, R extends PathRules> = HasPart<O, Name> extends true ? ObjectsBelow<NonNullable<ChildOf<O, Name>>, R["arrays"]> : never;
388
+ /** Tests if a path may end at a field with the values `V`: see `PathsOf`. */
389
+ type EndsAt<V, R extends PathRules, Last extends boolean> = [V] extends [never] ? true : {} extends V ? true : [Extract<V, Leaf | Whole>] extends [never] ? R["arrays"] extends true ? [Extract<V, ReadonlyArray<unknown>>] extends [never] ? EndsAtObjects<ObjectsBelow<V, true>, R, Last> : true : false : true;
390
+ /**
391
+ * Tests if a path may end at a field that holds the objects `O`: a field of a
392
+ * rule may name a struct, and a request may name a record, or a struct at
393
+ * the last part that a path may have.
394
+ */
395
+ type EndsAtObjects<O, R extends PathRules, Last extends boolean> = [O] extends [never] ? false : R["parents"] extends true ? true : string extends keyof O ? true : number extends keyof O ? true : Last;
396
+ /** The paths one part below `Done`, as the names that may come next. */
397
+ type NextNames<O, Done extends string> = `${Done}${keyof O & (string | number)}`;
398
+ /**
399
+ * Walks a path two parts at a time, from the objects `O`. It gives `true`
400
+ * for a path that the rules `R` take, or the names that may come next after
401
+ * the last good part. `Count` counts the parts before `F`, so the walk knows
402
+ * the last part that a path may have: part 1000, the default of
403
+ * `Limits.fieldPathParts`.
404
+ */
405
+ type PathWalk<O, F extends string, Done extends string, R extends PathRules, Count extends ReadonlyArray<0>> = F extends `${infer A}.${infer B}.${infer Rest}` ? PathStep<O, A, R> extends (infer O1) ? [O1] extends [never] ? NextNames<O, Done> : PathStep<O1, B, R> extends (infer O2) ? [O2] extends [never] ? NextNames<O1, `${Done}${A}.`> : PathWalk<O2, Rest, `${Done}${A}.${B}.`, R, [...Count, 0, 0]> : never : never : F extends `${infer A}.${infer B}` ? PathStep<O, A, R> extends (infer O1) ? [O1] extends [never] ? NextNames<O, Done> : PathEnd<O1, B, `${Done}${A}.`, R, [...Count, 0]> : never : PathEnd<O, F, Done, R, Count>;
406
+ type PathEnd<O, Name extends string, Done extends string, R extends PathRules, Count extends ReadonlyArray<0>> = HasPart<O, Name> extends true ? EndsAt<NonNullable<ChildOf<O, Name>>, R, Count["length"] extends 999 ? true : false> extends true ? true : NextNames<ObjectsBelow<NonNullable<ChildOf<O, Name>>, R["arrays"]>, `${Done}${Name}.`> : NextNames<O, Done>;
407
+ /**
408
+ * Checks one field path `F` of `T`, of any length up to about 1000 parts.
409
+ * It gives `F` for a path that the rules `R` take. For another path, it gives
410
+ * the paths that may come next after its last good part, so a type error
411
+ * names them. For a union of types, a part must be in each of them.
412
+ */
413
+ type PathCheck<T, F extends string, R extends PathRules> = [T] extends [object] ? PathWalk<T, F, "", R, []> extends true ? F : NoInfer<PathWalk<T, F, "", R, []>> : never;
414
+ /**
415
+ * A path of `T` that a condition may read, as one of {@link FieldPath}, of
416
+ * any length up to about 1000 parts. It is `F` when `F` is such a path, and
417
+ * the names that may come next when it is not.
418
+ *
419
+ * @stability stable
420
+ * @category utility types
421
+ * @since 2.1.0
422
+ */
423
+ export type ReadPath<T, F extends string> = PathCheck<T, F, ReadRules>;
424
+ /**
425
+ * A path of `T` that a request may name, as one of {@link FieldSelector}, of
426
+ * any length up to about 1000 parts. See {@link ReadPath}.
427
+ *
428
+ * @stability stable
429
+ * @category utility types
430
+ * @since 2.1.0
431
+ */
432
+ export type SelectPath<T, F extends string> = PathCheck<T, F, SelectRules>;
433
+ /**
434
+ * A path of `T` that a field of a rule may name, as one of
435
+ * {@link FieldName}, of any length up to about 1000 parts. See
436
+ * {@link ReadPath}.
437
+ *
438
+ * @stability stable
439
+ * @category utility types
440
+ * @since 2.1.0
441
+ */
442
+ export type NamePath<T, F extends string> = PathCheck<T, F, NameRules>;
443
+ /** A path that a condition may read, with an ordered value. */
444
+ type OrderedReadPath<T, F extends string> = ReadPath<T, F> extends F ? Exclude<PathValue<T, F>, null> extends number | string ? F : never : ReadPath<T, F>;
445
+ /** A path that a condition may read, with a scalar value. */
446
+ type ScalarReadPath<T, F extends string> = ReadPath<T, F> extends F ? PathValue<T, F> extends Scalar ? F : never : ReadPath<T, F>;
345
447
  /**
346
448
  * A value for a field of type `A`: a fixed value, or a field of the principal
347
449
  * with the same type.
@@ -351,8 +453,6 @@ type ChildOf<T, Name extends string> = Name extends keyof T ? T[Name] : Name ext
351
453
  * @since 0.3.0
352
454
  */
353
455
  export type OperandOf<A, P = never> = Extract<A, Scalar> | Ref<A, P>;
354
- type ScalarPath<T> = { [F in FieldPath<T>]: PathValue<T, F> extends Scalar ? F : never; }[FieldPath<T>];
355
- type OrderedPath<T> = { [F in FieldPath<T>]: Exclude<PathValue<T, F>, null> extends number | string ? F : never; }[FieldPath<T>];
356
456
  /**
357
457
  * A test made by a {@link Builder}. It runs no code, but it keeps the value
358
458
  * type of its resource, so a test on the fields of one resource can not go
@@ -382,24 +482,24 @@ type PrincipalOf<V, _P> = [Extract<V, PrincipalRef>] extends [never] ? unknown :
382
482
  */
383
483
  export interface Builder<Data, Value, P> {
384
484
  /** The field is equal to the value. */
385
- readonly eq: <const F extends FieldPath<Data>, const V extends OperandOf<FieldValue<Data, F>, any>>(field: F, value: V) => Test<Value, PrincipalOf<V, P>>;
485
+ readonly eq: <const F extends string, const V extends OperandOf<FieldValue<Data, F>, any>>(field: ReadPath<Data, F>, value: V) => Test<Value, PrincipalOf<V, P>>;
386
486
  /** The field is not equal to the value. */
387
- readonly ne: <const F extends FieldPath<Data>, const V extends OperandOf<FieldValue<Data, F>, any>>(field: F, value: V) => Test<Value, PrincipalOf<V, P>>;
388
- readonly lt: <const F extends OrderedPath<Data>, const V extends OperandOf<Exclude<FieldValue<Data, F>, null>, any>>(field: F, value: V) => Test<Value, PrincipalOf<V, P>>;
389
- readonly lte: <const F extends OrderedPath<Data>, const V extends OperandOf<Exclude<FieldValue<Data, F>, null>, any>>(field: F, value: V) => Test<Value, PrincipalOf<V, P>>;
390
- readonly gt: <const F extends OrderedPath<Data>, const V extends OperandOf<Exclude<FieldValue<Data, F>, null>, any>>(field: F, value: V) => Test<Value, PrincipalOf<V, P>>;
391
- readonly gte: <const F extends OrderedPath<Data>, const V extends OperandOf<Exclude<FieldValue<Data, F>, null>, any>>(field: F, value: V) => Test<Value, PrincipalOf<V, P>>;
487
+ readonly ne: <const F extends string, const V extends OperandOf<FieldValue<Data, F>, any>>(field: ReadPath<Data, F>, value: V) => Test<Value, PrincipalOf<V, P>>;
488
+ readonly lt: <const F extends string, const V extends OperandOf<Exclude<FieldValue<Data, F>, null>, any>>(field: OrderedReadPath<Data, F>, value: V) => Test<Value, PrincipalOf<V, P>>;
489
+ readonly lte: <const F extends string, const V extends OperandOf<Exclude<FieldValue<Data, F>, null>, any>>(field: OrderedReadPath<Data, F>, value: V) => Test<Value, PrincipalOf<V, P>>;
490
+ readonly gt: <const F extends string, const V extends OperandOf<Exclude<FieldValue<Data, F>, null>, any>>(field: OrderedReadPath<Data, F>, value: V) => Test<Value, PrincipalOf<V, P>>;
491
+ readonly gte: <const F extends string, const V extends OperandOf<Exclude<FieldValue<Data, F>, null>, any>>(field: OrderedReadPath<Data, F>, value: V) => Test<Value, PrincipalOf<V, P>>;
392
492
  /** The field is equal to one of the values. */
393
- readonly in: <const F extends FieldPath<Data>, const Vs extends ReadonlyArray<OperandOf<FieldValue<Data, F>, any>>>(field: F, values: Vs) => Test<Value, PrincipalOf<Vs[number], P>>;
493
+ readonly in: <const F extends string, const Vs extends ReadonlyArray<OperandOf<FieldValue<Data, F>, any>>>(field: ReadPath<Data, F>, values: Vs) => Test<Value, PrincipalOf<Vs[number], P>>;
394
494
  /** The field has a value that is not `null`. */
395
- readonly exists: <const F extends FieldPath<Data>>(field: F) => Test<Value>;
495
+ readonly exists: <const F extends string>(field: ReadPath<Data, F>) => Test<Value>;
396
496
  /** The path of the resource starts with these parts. */
397
497
  readonly under: <const Ps extends ReadonlyArray<string | null | Ref<string | null, any>>>(...prefix: Ps) => Test<Value, PrincipalOf<Ps[number], P>>;
398
498
  /**
399
499
  * A field of the principal, to use as a value. The field must have a
400
500
  * {@link Scalar} type.
401
501
  */
402
- readonly principal: <const F extends ScalarPath<P>>(field: F) => Ref<PathValue<P, F>, P>;
502
+ readonly principal: <const F extends string>(field: ScalarReadPath<P, F>) => Ref<PathValue<P, F>, P>;
403
503
  readonly and: <const Cs extends ReadonlyArray<Any>>(...conditions: Cs) => Condition<ReadsOf<Cs[number]>, OpaqueOf<Cs[number]>>;
404
504
  readonly or: <const Cs extends ReadonlyArray<Any>>(...conditions: Cs) => Condition<ReadsOf<Cs[number]>, OpaqueOf<Cs[number]>>;
405
505
  readonly not: <C extends Any>(condition: C) => Condition<ReadsOf<C>, OpaqueOf<C>>;
@@ -1 +1 @@
1
- {"version":3,"file":"Condition.d.ts","names":["Nodes.Scalar","Nodes.Literal","Nodes.PrincipalRef","Nodes.CompareOperator","Nodes.True","Nodes.False","Nodes.Compare","Nodes.In","Nodes.Exists","Nodes.Under","Nodes.And","Nodes.Or","Nodes.Not","Nodes.Predicate","Nodes.Node","Resource.PathSegment","Search.Example","Search.Satisfiability"],"sources":["../src/Condition.ts"],"mappings":"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"}
1
+ {"version":3,"file":"Condition.d.ts","names":["Nodes.Scalar","Nodes.Literal","Nodes.PrincipalRef","Nodes.CompareOperator","Nodes.True","Nodes.False","Nodes.Compare","Nodes.In","Nodes.Exists","Nodes.Under","Nodes.And","Nodes.Or","Nodes.Not","Nodes.Predicate","Nodes.Node","Resource.PathSegment","Search.Example","Search.Satisfiability"],"sources":["../src/Condition.ts"],"mappings":"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"}
package/dist/Condition.js CHANGED
@@ -1,13 +1,14 @@
1
1
  import { __exportAll } from "./_virtual/_rolldown/runtime.js";
2
+ import { run } from "./internal/trampoline.js";
2
3
  import { And, Compare, Exists, In, Not, Or, Predicate, Under, always as always$1, isNode, literal, never as never$1, principalRef, toNode } from "./internal/nodes.js";
3
4
  import { evaluate as evaluate$1, evaluateSync as evaluateSync$1, fields as fields$1, partial as partial$1, provide, simplify as simplify$1 } from "./internal/algebra.js";
4
5
  import { catalogOf } from "./internal/catalog.js";
5
6
  import { decode, toJson } from "./internal/json.js";
6
7
  import { kindsIn, satisfiable as satisfiable$1 } from "./internal/search.js";
8
+ import * as Arr from "effect/Array";
7
9
  import * as Effect from "effect/Effect";
8
10
  import * as Result from "effect/Result";
9
11
  import * as Schema from "effect/Schema";
10
- import * as Arr from "effect/Array";
11
12
  import { dual } from "effect/Function";
12
13
  import { hasProperty } from "effect/Predicate";
13
14
  import * as SchemaIssue from "effect/SchemaIssue";
@@ -219,23 +220,31 @@ const literalValue = (operand, field) => {
219
220
  if (operand._tag !== "Literal") throw Untranslatable.make({ reason: `The field "${field}" uses a principal field. Call Condition.partial first.` });
220
221
  return operand.value;
221
222
  };
222
- /** Folds a condition. A shared child is folded again for each place. */
223
- const foldNode = (node, interpreter) => {
224
- switch (node._tag) {
225
- case "True": return interpreter.true();
226
- case "False": return interpreter.false();
227
- case "Compare": return interpreter.compare(node.op, node.field, literalValue(node.value, node.field));
228
- case "In": return interpreter.in(node.field, Arr.map(node.values, (operand) => literalValue(operand, node.field)));
229
- case "Exists": return interpreter.exists(node.field);
230
- case "Under": throw Untranslatable.make({ reason: "An Under node needs the resource path. Call Condition.partial first." });
231
- case "And": return interpreter.and(Arr.map(node.conditions, (child) => foldNode(child, interpreter)));
232
- case "Or": return interpreter.or(Arr.map(node.conditions, (child) => foldNode(child, interpreter)));
233
- case "Not": return interpreter.not(foldNode(node.condition, interpreter));
234
- case "Predicate":
235
- if (interpreter.predicate === void 0) throw Untranslatable.make({ reason: `The predicate "${node.name}" can not become a query` });
236
- return interpreter.predicate(node.name);
237
- }
238
- };
223
+ /**
224
+ * Folds a condition. A shared child is folded again for each place. The walk
225
+ * takes the steps of a trampoline, so a deep condition does not fill the
226
+ * stack.
227
+ */
228
+ const foldNode = (root, interpreter) => run(root.depth, (R) => {
229
+ const go = (node) => {
230
+ const children = (nodes) => R.forEach(nodes, (child) => R.suspend(() => go(child)));
231
+ switch (node._tag) {
232
+ case "True": return R.succeed(interpreter.true());
233
+ case "False": return R.succeed(interpreter.false());
234
+ case "Compare": return R.succeed(interpreter.compare(node.op, node.field, literalValue(node.value, node.field)));
235
+ case "In": return R.succeed(interpreter.in(node.field, Arr.map(node.values, (operand) => literalValue(operand, node.field))));
236
+ case "Exists": return R.succeed(interpreter.exists(node.field));
237
+ case "Under": throw Untranslatable.make({ reason: "An Under node needs the resource path. Call Condition.partial first." });
238
+ case "And": return R.map(children(node.conditions), interpreter.and);
239
+ case "Or": return R.map(children(node.conditions), interpreter.or);
240
+ case "Not": return R.map(R.suspend(() => go(node.condition)), interpreter.not);
241
+ case "Predicate":
242
+ if (interpreter.predicate === void 0) throw Untranslatable.make({ reason: `The predicate "${node.name}" can not become a query` });
243
+ return R.succeed(interpreter.predicate(node.name));
244
+ }
245
+ };
246
+ return go(root);
247
+ });
239
248
  /**
240
249
  * Changes a condition into another form with an interpreter. Call
241
250
  * {@link partial} first: `fold` fails on principal fields and on `Under`