@nmnmcc/ability 2.1.2 → 2.1.3

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.
@@ -1,6 +1,6 @@
1
1
  import { Condition, Opaque } from "./Condition.js";
2
2
  import { Any, CommonAction, Kind, Principal } from "./Domain.js";
3
- import { CheckField, Coverage, DeepKindTarget, DeepTarget as DeepTarget$1, FieldlessTarget, KindRequest, KindTarget, Policy, Request, ResidualReads, Target as Target$1 } from "./Policy.js";
3
+ import { Checked, 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";
@@ -123,29 +123,29 @@ export interface Authorizer<D extends Any, E, R> {
123
123
  */
124
124
  readonly policy: Effect.Effect<Policy<D, Opaque<E>>, PolicyUnavailable | E, R>;
125
125
  /** Gives the decision of the policy. It does not ask the decider. */
126
- readonly decide: <const T extends DeepTarget$1<D>>(target: T & CheckField<D, T>) => Effect.Effect<Decision, PolicyUnavailable | E, R>;
126
+ readonly decide: <const T extends DeepTarget$1<D>>(target: Checked<D, T>) => Effect.Effect<Decision, PolicyUnavailable | E, R>;
127
127
  /** Succeeds when the principal may do the act, and fails when it may not. */
128
- readonly check: <const T extends DeepTarget<D>>(target: T & CheckField<D, T>) => Effect.Effect<void, Forbidden | Pending | PolicyUnavailable | E, R>;
128
+ readonly check: <const T extends DeepTarget<D>>(target: Checked<D, T>) => Effect.Effect<void, Forbidden | Pending | PolicyUnavailable | E, R>;
129
129
  /**
130
130
  * Checks the read action first, and fails with the error of `hide` when the
131
131
  * principal may not see the resource. Then it checks the act. Use it to
132
132
  * answer "not found" to a principal that may not know that a resource
133
133
  * exists.
134
134
  */
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>;
135
+ readonly guard: <const T extends DeepTarget$1<D>, E2>(target: Checked<D, T>, options: GuardOptions<D, E2, T["resource"]["_tag"]>) => Effect.Effect<void, E2 | Forbidden | Pending | PolicyUnavailable | E, R>;
136
136
  /**
137
137
  * Gives the condition on resource values that the principal may act on,
138
138
  * inside the scope of the target when it has one. Change it into a query
139
139
  * with `Condition.fold`. It is `False` when the principal may act on no
140
140
  * value, so the list is empty: it is not an error.
141
141
  */
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>;
142
+ readonly filter: <const T extends DeepKindTarget<D>>(target: Checked<D, T>) => Effect.Effect<Condition<ResidualReads<D, T["kind"]>, Opaque<E>>, PolicyUnavailable | E, R>;
143
143
  /**
144
144
  * Tells if the principal may act on all, none or some of the values in
145
145
  * the scope of the target. See `Policy.coverage`. Use it to show a button
146
146
  * only when the answer is not `None`.
147
147
  */
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>;
148
+ readonly coverage: <const T extends DeepKindTarget<D>>(target: Checked<D, T>) => Effect.Effect<Coverage<ResidualReads<D, T["kind"]>, Opaque<E>>, PolicyUnavailable | E, R>;
149
149
  /** Gives the fields of a value that the principal may use. */
150
150
  readonly permittedFields: (target: FieldlessTarget<D>) => Effect.Effect<ReadonlyArray<string>, PolicyUnavailable | E, R>;
151
151
  /**
@@ -166,11 +166,11 @@ export interface ServiceClass<Self, Id extends string, D extends Any, E, R> exte
166
166
  readonly domain: D;
167
167
  /** The Effect that gives the principal of the current request. */
168
168
  readonly principal: Effect.Effect<Principal<D>, E, R>;
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>;
169
+ readonly decide: <const T extends DeepTarget$1<D>>(target: Checked<D, T>) => Effect.Effect<Decision, PolicyUnavailable | E, R | Self>;
170
+ readonly check: <const T extends DeepTarget<D>>(target: Checked<D, T>) => Effect.Effect<void, Forbidden | Pending | PolicyUnavailable | E, R | Self>;
171
+ readonly guard: <const T extends DeepTarget$1<D>, E2>(target: Checked<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: Checked<D, T>) => Effect.Effect<Condition<ResidualReads<D, T["kind"]>, Opaque<E>>, PolicyUnavailable | E, R | Self>;
173
+ readonly coverage: <const T extends DeepKindTarget<D>>(target: Checked<D, T>) => Effect.Effect<Coverage<ResidualReads<D, T["kind"]>, Opaque<E>>, PolicyUnavailable | E, R | Self>;
174
174
  readonly permittedFields: (target: FieldlessTarget<D>) => Effect.Effect<ReadonlyArray<string>, PolicyUnavailable | E, R | Self>;
175
175
  }
176
176
  /**
@@ -1 +1 @@
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
+ {"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.Checked","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 {@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"}
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: Policy.Checked<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: Policy.Checked<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: Policy.Checked<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: Policy.Checked<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: Policy.Checked<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: Policy.Checked<D, T>,\n\t) => Effect.Effect<Decision.Decision, PolicyUnavailable | E, R | Self>\n\treadonly check: <const T extends DeepTarget<D>>(\n\t\ttarget: Policy.Checked<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: Policy.Checked<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: Policy.Checked<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: Policy.Checked<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"}
package/dist/Policy.d.ts CHANGED
@@ -10,7 +10,7 @@ import * as Effect from "effect/Effect";
10
10
  import * as Schema from "effect/Schema";
11
11
  import * as Data from "effect/Data";
12
12
  declare namespace Policy_d_exports {
13
- export { ActionFor, ActionForTargets, Algorithm, AllNode, Any, AnyNode, AnyRequest, AnyRule, Builder, CeilingNode, CheckField, ConditionFor, Coverage, DataFor, DeepKindRequest, DeepKindTarget, DeepRequest, DeepTarget, DomainOf, EncodedNode, EncodedRule, Explanation, FieldFor, FieldlessRequest, FieldlessTarget, FieldsFor, FirstOfNode, KindOf, KindRequest, KindTarget, Node, OpaqueOf, Options, Policy, PolicyError, Request, ResidualReads, Rule, RuleOptions, RuleShape, RuleTarget, RulesNode, Scope, Step, Target, TargetOf, ValueFor, all, any, builder, ceiling, coverage, decide, decideSync, define, explain, firstOf, permittedFields, provideContext, residual, rule, schema };
13
+ export { ActionFor, ActionForTargets, Algorithm, AllNode, Any, AnyNode, AnyRequest, AnyRule, Builder, CeilingNode, CheckField, Checked, ConditionFor, Coverage, DataFor, DeepKindRequest, DeepKindTarget, DeepRequest, DeepTarget, DomainOf, EncodedNode, EncodedRule, Explanation, FieldFor, FieldlessRequest, FieldlessTarget, FieldsFor, FirstOfNode, KindOf, KindRequest, KindTarget, Node, OpaqueOf, Options, Policy, PolicyError, Request, ResidualReads, Rule, RuleOptions, RuleShape, RuleTarget, RulesNode, Scope, Step, Target, TargetOf, ValueFor, all, any, builder, ceiling, coverage, decide, decideSync, define, explain, firstOf, permittedFields, provideContext, residual, rule, schema };
14
14
  }
15
15
  /**
16
16
  * @stability stable
@@ -202,6 +202,16 @@ export type CheckField<D, T> = T extends {
202
202
  } ? [Exclude<F, undefined>] extends [never] ? unknown : {
203
203
  readonly field?: SelectPath<DataOf<D, KindOfTarget<T>>, Exclude<F, undefined> & string>;
204
204
  } : unknown;
205
+ /**
206
+ * A target or a request with its field checked, as {@link CheckField} does.
207
+ * Each member of a union is checked by itself, so a member with no field
208
+ * does not take the place of the check of another member.
209
+ *
210
+ * @stability stable
211
+ * @category utility types
212
+ * @since 2.1.3
213
+ */
214
+ export type Checked<D, T> = T extends unknown ? T & CheckField<D, T> : never;
205
215
  /**
206
216
  * A request: a principal, an action, and a resource value.
207
217
  *
@@ -590,7 +600,7 @@ export declare const provideContext: {
590
600
  * @category evaluation
591
601
  * @since 0.3.0
592
602
  */
593
- export declare const decide: <D extends Any$2, X, const Req extends DeepRequest<NoInfer<D>>>(policy: Policy<D, X>, request: Req & CheckField<NoInfer<D>, Req>) => Effect.Effect<Decision, ErrorOf<X>, ServicesOf<X>>;
603
+ export declare const decide: <D extends Any$2, X, const Req extends DeepRequest<NoInfer<D>>>(policy: Policy<D, X>, request: Checked<NoInfer<D>, Req>) => Effect.Effect<Decision, ErrorOf<X>, ServicesOf<X>>;
594
604
  /**
595
605
  * Gives the decision of a policy with no predicates, at once.
596
606
  *
@@ -598,7 +608,7 @@ export declare const decide: <D extends Any$2, X, const Req extends DeepRequest<
598
608
  * @category evaluation
599
609
  * @since 0.3.0
600
610
  */
601
- export declare const decideSync: <D extends Any$2, const Req extends DeepRequest<NoInfer<D>>>(policy: Policy<D>, request: Req & CheckField<NoInfer<D>, Req>) => Decision;
611
+ export declare const decideSync: <D extends Any$2, const Req extends DeepRequest<NoInfer<D>>>(policy: Policy<D>, request: Checked<NoInfer<D>, Req>) => Decision;
602
612
  /**
603
613
  * Gives the decision of a policy and the rules that were tested to make it.
604
614
  *
@@ -609,7 +619,7 @@ export declare const decideSync: <D extends Any$2, const Req extends DeepRequest
609
619
  * @category evaluation
610
620
  * @since 0.3.0
611
621
  */
612
- export declare const explain: <D extends Any$2, X, const Req extends DeepRequest<NoInfer<D>>>(policy: Policy<D, X>, request: Req & CheckField<NoInfer<D>, Req>) => Effect.Effect<Explanation, ErrorOf<X>, ServicesOf<X>>;
622
+ export declare const explain: <D extends Any$2, X, const Req extends DeepRequest<NoInfer<D>>>(policy: Policy<D, X>, request: Checked<NoInfer<D>, Req>) => Effect.Effect<Explanation, ErrorOf<X>, ServicesOf<X>>;
613
623
  /**
614
624
  * Gives the fields of a resource value that the policy lets a request use. It
615
625
  * tests each field that a list of fields shows: each scalar, record or array
@@ -663,7 +673,7 @@ export type ResidualReads<D, K> = Reads<(K extends unknown ? (value: ValueOf<D,
663
673
  * @category evaluation
664
674
  * @since 0.3.0
665
675
  */
666
- export declare const residual: <D extends Any$2, X, const Req extends DeepKindRequest<NoInfer<D>>>(policy: Policy<D, X>, request: Req & CheckField<NoInfer<D>, Req>) => Condition<ResidualReads<D, Req["kind"]>, X>;
676
+ export declare const residual: <D extends Any$2, X, const Req extends DeepKindRequest<NoInfer<D>>>(policy: Policy<D, X>, request: Checked<NoInfer<D>, Req>) => Condition<ResidualReads<D, Req["kind"]>, X>;
667
677
  /**
668
678
  * How much of a scope a policy allows. In each case, `condition` is the exact
669
679
  * condition on the values in the scope that the policy allows: give it to
@@ -719,7 +729,7 @@ export type Coverage<I = unknown, X = never> = Data.TaggedEnum<{
719
729
  * @category evaluation
720
730
  * @since 1.0.0
721
731
  */
722
- export declare const coverage: <D extends Any$2, X, const Req extends DeepKindRequest<NoInfer<D>>>(policy: Policy<D, X>, request: Req & CheckField<NoInfer<D>, Req>) => Coverage<ResidualReads<D, Req["kind"]>, X>;
732
+ export declare const coverage: <D extends Any$2, X, const Req extends DeepKindRequest<NoInfer<D>>>(policy: Policy<D, X>, request: Checked<NoInfer<D>, Req>) => Coverage<ResidualReads<D, Req["kind"]>, X>;
723
733
  /**
724
734
  * The JSON form of a rule.
725
735
  *
@@ -1 +1 @@
1
- {"version":3,"file":"Policy.d.ts","names":["PolicyNodes.Algorithm","PolicyNodes.Rules","PolicyNodes.All","PolicyNodes.Any","PolicyNodes.FirstOf","PolicyNodes.Ceiling","PolicyNodes.Node","Domain.Any","Internal.PolicyData","Domain.Kind","Domain.ActionOf","Domain.ValueOf","Domain.DataOf","Condition.FieldSelector","Domain.Principal","Condition.Builder","Condition.Reads","Condition.Condition","Condition.SelectPath","Decision.Decision","RuleData.Rule","Domain.Resources","Resource.Kind","Domain.AnyAction","Domain.CommonAction","Domain.AnyValue","Condition.FieldName","Condition.NamePath","Condition.Any","Domain.Meta","Condition.ReadsOf","Condition.OpaqueOf","Internal.PolicyError","Condition.ServicesOf","Condition.Provided","Condition.ErrorOf","Condition.Example","Condition.Encoded"],"sources":["../src/Policy.ts"],"mappings":"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"}
1
+ {"version":3,"file":"Policy.d.ts","names":["PolicyNodes.Algorithm","PolicyNodes.Rules","PolicyNodes.All","PolicyNodes.Any","PolicyNodes.FirstOf","PolicyNodes.Ceiling","PolicyNodes.Node","Domain.Any","Internal.PolicyData","Domain.Kind","Domain.ActionOf","Domain.ValueOf","Domain.DataOf","Condition.FieldSelector","Domain.Principal","Condition.Builder","Condition.Reads","Condition.Condition","Condition.SelectPath","Decision.Decision","RuleData.Rule","Domain.Resources","Resource.Kind","Domain.AnyAction","Domain.CommonAction","Domain.AnyValue","Condition.FieldName","Condition.NamePath","Condition.Any","Domain.Meta","Condition.ReadsOf","Condition.OpaqueOf","Internal.PolicyError","Condition.ServicesOf","Condition.Provided","Condition.ErrorOf","Condition.Example","Condition.Encoded"],"sources":["../src/Policy.ts"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Policy.js","names":["RuleData.builder","RuleData.makePlain","Internal.PolicyError","Internal.define","Internal.combine","Internal.ceiling","Internal.provideContext","Decide.decideAny","Decide.decideSync","Decide.explain","Decide.permittedFields","Analysis.residual","Analysis.coverageAny","Internal.schema"],"sources":["../src/Policy.ts"],"sourcesContent":["/**\n * A policy is a tree that gives a {@link Decision.Decision} for a request.\n *\n * The leaves of the tree are lists of rules. A combining algorithm decides\n * which rule gives the answer when more than one rule applies:\n * - `denyOverrides` (the default): a deny rule wins over every allow rule.\n * - `permitOverrides`: an allow rule wins over every deny rule.\n * - `firstApplicable`: the first rule that applies wins.\n * - `lastApplicable`: the last rule that applies wins.\n *\n * The branches put policies together:\n * - {@link all}: every policy must allow, and one deny is enough to deny. Use\n * it when a user token may never do more than its user.\n * - {@link any}: one allow is enough.\n * - {@link firstOf}: the first policy that gives an answer wins. Use it for\n * grants first, then rules.\n * - {@link ceiling}: the deny rules of a second policy are a limit for\n * everyone. Its allow rules do nothing.\n *\n * A policy gives three kinds of answers:\n * - {@link decide}: the decision for one resource value.\n * - {@link residual}: a condition on resource values. A value passes when the\n * policy allows the request for that value. Use it to make a database\n * query, or to ask \"may this principal do this act on some resource of\n * this kind?\"\n * - {@link permittedFields}: the fields that the policy lets a request use.\n *\n * Each of them takes the policy first and the request second, as in\n * `Policy.decide(policy, request)`. The policy gives the domain, so\n * TypeScript checks the request against it.\n *\n * A policy without predicates can become JSON with {@link schema}.\n *\n * @stability stable\n * @since 0.3.0\n */\nimport type * as Context from \"effect/Context\"\nimport type * as Data from \"effect/Data\"\nimport type * as Effect from \"effect/Effect\"\nimport type * as Schema from \"effect/Schema\"\nimport type * as Condition from \"./Condition.ts\"\nimport * as Analysis from \"./internal/analysis.ts\"\nimport * as Decide from \"./internal/decide.ts\"\nimport * as Internal from \"./internal/policy.ts\"\nimport type * as PolicyNodes from \"./internal/policy-nodes.ts\"\nimport * as RuleData from \"./internal/rule.ts\"\nimport type * as Decision from \"./Decision.ts\"\nimport type * as Domain from \"./Domain.ts\"\nimport type * as Resource from \"./Resource.ts\"\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Algorithm = PolicyNodes.Algorithm\n\n/**\n * A list of rules with a combining algorithm.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type RulesNode = PolicyNodes.Rules\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type AllNode = PolicyNodes.All\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type AnyNode = PolicyNodes.Any\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type FirstOfNode = PolicyNodes.FirstOf\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type CeilingNode = PolicyNodes.Ceiling\n\n/**\n * The nodes of a policy tree, without types. Each node is a class, and only\n * the functions of this module and the Schema make one.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Node = PolicyNodes.Node\n\n/**\n * A policy for the domain `D`. `X` is `Condition.Opaque` when a rule of the\n * policy has a predicate, and `never` when the policy is plain data. A plain\n * policy can become JSON, and `decideSync` takes it.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Policy<D extends Domain.Any, X = never> = Internal.PolicyData<D, X>\n\n/**\n * Any policy.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Any = Policy<any, any>\n\n/**\n * The domain of a policy.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type DomainOf<P> = P extends Policy<infer D, any> ? D : never\n\n/**\n * The mark of a policy or a rule: `Condition.Opaque` when it has a predicate.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type OpaqueOf<P> = P extends { readonly \"~Opaque\": () => infer X }\n\t? X\n\t: never\n\n/**\n * One act on one resource value, for each kind of the domain. The action must\n * be an action of the kind, and the field must be a field of the kind.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Target<D> = {\n\t[K in Domain.Kind<D>]: {\n\t\treadonly action: Domain.ActionOf<D, K>\n\t\treadonly resource: Domain.ValueOf<D, K>\n\t\treadonly field?: Condition.FieldSelector<Domain.DataOf<D, K>>\n\t\t/** A target has a resource value or a kind, never both. */\n\t\treadonly kind?: never\n\t}\n}[Domain.Kind<D>]\n\n/**\n * A {@link Target} with no field. Each kind keeps its own actions.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type FieldlessTarget<D> = {\n\t[K in Domain.Kind<D>]: {\n\t\treadonly action: Domain.ActionOf<D, K>\n\t\treadonly resource: Domain.ValueOf<D, K>\n\t\treadonly kind?: never\n\t}\n}[Domain.Kind<D>]\n\n/**\n * A scope: a part of a kind, as a condition on its values. It gets a builder\n * with the types of the kind and of the principal, like the condition of a\n * rule. A scope is plain data, so it can not have a predicate.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport type Scope<D, K extends string> = (\n\tbuilder: Condition.Builder<\n\t\tDomain.DataOf<D, K>,\n\t\tDomain.ValueOf<D, K>,\n\t\tDomain.Principal<D>\n\t>,\n) => Condition.Condition<\n\tCondition.Reads<Domain.ValueOf<D, K>, Domain.Principal<D>>\n>\n\n/**\n * One act on one kind of resource, with no value. With `within`, the target is\n * only the values of the kind in the scope. Without it, the target is every\n * value of the kind.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type KindTarget<D> = {\n\t[K in Domain.Kind<D>]: {\n\t\treadonly action: Domain.ActionOf<D, K>\n\t\treadonly kind: K\n\t\treadonly field?: Condition.FieldSelector<Domain.DataOf<D, K>>\n\t\t/** The part of the kind. See {@link Scope}. */\n\t\treadonly within?: Scope<D, K>\n\t\t/** A target has a resource value or a kind, never both. */\n\t\treadonly resource?: never\n\t}\n}[Domain.Kind<D>]\n\n/**\n * A {@link Target} with a field of any length. A function that takes a\n * target checks its field with {@link CheckField}, so a field of up to about\n * 1000 parts is fine, and a field that is not a field of the kind is a type\n * error.\n *\n * @stability stable\n * @category models\n * @since 2.1.0\n */\nexport type DeepTarget<D> = {\n\t[K in Domain.Kind<D>]: {\n\t\treadonly action: Domain.ActionOf<D, K>\n\t\treadonly resource: Domain.ValueOf<D, K>\n\t\treadonly field?: string\n\t\treadonly kind?: never\n\t}\n}[Domain.Kind<D>]\n\n/**\n * A {@link KindTarget} with a field of any length. See {@link DeepTarget}.\n *\n * @stability stable\n * @category models\n * @since 2.1.0\n */\nexport type DeepKindTarget<D> = {\n\t[K in Domain.Kind<D>]: {\n\t\treadonly action: Domain.ActionOf<D, K>\n\t\treadonly kind: K\n\t\treadonly field?: string\n\t\treadonly within?: Scope<D, K>\n\t\treadonly resource?: never\n\t}\n}[Domain.Kind<D>]\n\n/** The kind of a target: its `kind`, or the `_tag` of its resource value. */\ntype KindOfTarget<T> = T extends { readonly kind: infer K extends string }\n\t? K\n\t: T extends { readonly resource: { readonly _tag: infer K extends string } }\n\t\t? K\n\t\t: never\n\n/**\n * Checks the field of a target or a request: a field of its kind that a\n * request may name, of any length up to about 1000 parts. See\n * `Condition.SelectPath`. A target with no field needs no check.\n *\n * @stability stable\n * @category utility types\n * @since 2.1.0\n */\nexport type CheckField<D, T> = T extends { readonly field?: infer F }\n\t? [Exclude<F, undefined>] extends [never]\n\t\t? unknown\n\t\t: {\n\t\t\t\t// A field that the target may leave out is checked too, when it is\n\t\t\t\t// there.\n\t\t\t\treadonly field?: Condition.SelectPath<\n\t\t\t\t\tDomain.DataOf<D, KindOfTarget<T>>,\n\t\t\t\t\tExclude<F, undefined> & string\n\t\t\t\t>\n\t\t\t}\n\t: unknown\n\n/**\n * A request: a principal, an action, and a resource value.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Request<D> = Target<D> & { readonly principal: Domain.Principal<D> }\n\n/**\n * A {@link Request} with a field of any length. See {@link DeepTarget}.\n *\n * @stability stable\n * @category models\n * @since 2.1.0\n */\nexport type DeepRequest<D> = DeepTarget<D> & {\n\treadonly principal: Domain.Principal<D>\n}\n\n/**\n * A {@link Request} with no field.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type FieldlessRequest<D> = FieldlessTarget<D> & {\n\treadonly principal: Domain.Principal<D>\n}\n\n/**\n * A request about a kind of resource, with no value.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type KindRequest<D> = KindTarget<D> & {\n\treadonly principal: Domain.Principal<D>\n}\n\n/**\n * A {@link KindRequest} with a field of any length. See {@link DeepTarget}.\n *\n * @stability stable\n * @category models\n * @since 2.1.0\n */\nexport type DeepKindRequest<D> = DeepKindTarget<D> & {\n\treadonly principal: Domain.Principal<D>\n}\n\n/**\n * A request with no types.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface AnyRequest {\n\treadonly principal: object\n\treadonly action: string\n\treadonly resource: object\n\treadonly field?: string | undefined\n}\n\n/**\n * One rule that a decision tested. `path` gives the place of the rule in the\n * policy tree: the index of each child, then the index of the rule.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Step {\n\treadonly path: ReadonlyArray<number>\n\treadonly rule: AnyRule\n\treadonly applies: boolean\n}\n\n/**\n * A decision, and the rules that were tested to make it, in order. Keep it in\n * an audit log.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Explanation {\n\treadonly decision: Decision.Decision\n\treadonly steps: ReadonlyArray<Step>\n}\n\n// Rules\n\n/**\n * A rule for the domain `D`. `I` is what the tests of its condition read, and\n * `X` is its mark: see `Condition.Condition`. A predicate reads the values and\n * the principal of its domain, so a rule may go only into a policy of its own\n * domain. A rule from {@link rule} has the domain `any`.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Rule<D = any, I = unknown, X = never> = RuleData.Rule<D, I, X>\n\n/**\n * The data of a rule.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport interface RuleShape<I = unknown, X = never> {\n\treadonly _tag: \"Allow\" | \"Deny\"\n\treadonly actions: ReadonlyArray<string>\n\treadonly resources: ReadonlyArray<string>\n\treadonly when?: Condition.Condition<I, X>\n\treadonly fields?: ReadonlyArray<string>\n\treadonly reason?: string\n\treadonly id?: string\n\treadonly meta?: unknown\n\t/**\n\t * The domain of the builder that made the rule. Two domains may have the\n\t * same types but other paths, so the types can not tell them apart. It is\n\t * not in the JSON form of a rule.\n\t */\n\treadonly domain?: Domain.Any\n}\n\n/**\n * Any rule.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\n// Every rule fits `never` as what it reads, and a condition taken from such a\n// rule fits no rule that reads a value or a principal.\nexport type AnyRule = Rule<any, never, any>\n\n/**\n * A resource in a rule: a kind name, a resource of the domain, or `\"*\"`.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type RuleTarget<D> = Domain.Kind<D> | Domain.Resources<D> | \"*\"\n\n/**\n * The kind name of a target.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type KindOf<T> = T extends string ? T : Resource.Kind<T>\n\n/**\n * The actions that a rule may use for the kinds `K`.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type ActionFor<D, K> =\n\t| \"*\"\n\t| (\"*\" extends K\n\t\t\t? Domain.AnyAction<D>\n\t\t\t: Domain.ActionOf<D, Extract<K, string>>)\n\n/**\n * The targets in the resource argument of a rule: the one target, or the\n * targets of a list.\n *\n * @stability stable\n * @category utility types\n * @since 1.0.0\n */\nexport type TargetOf<Res> = Res extends ReadonlyArray<infer X> ? X : Res\n\n/**\n * The actions that a rule may use for its resource argument. A list of\n * resources may use an action of any of them. One target with a union type\n * may use only an action of every kind in the union, because its value may be\n * any one of them. When the argument may be a list or one target, the rule\n * may use only an action that each of these shapes allows.\n *\n * @stability stable\n * @category utility types\n * @since 1.0.0\n */\nexport type ActionForTargets<D, Res> = (\n\tRes extends ReadonlyArray<infer X>\n\t\t? (action: ActionFor<D, KindOf<X>>) => void\n\t\t: (action: ActionForTarget<D, Res>) => void\n) extends (action: infer A) => void\n\t? A\n\t: never\n\n/** The actions for one target that is not a list. */\ntype ActionForTarget<D, Res> =\n\t| \"*\"\n\t| (\"*\" extends KindOf<Res>\n\t\t\t? Domain.AnyAction<D>\n\t\t\t: Domain.CommonAction<D, Extract<KindOf<Res>, string>>)\n\n/**\n * The data type of the kinds `K`. For `\"*\"` it has no fields.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type DataFor<D, K> = \"*\" extends K\n\t? {}\n\t: Domain.DataOf<D, Extract<K, string>>\n\n/**\n * The value type of the kinds `K`.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type ValueFor<D, K> = \"*\" extends K\n\t? Domain.AnyValue<D>\n\t: Domain.ValueOf<D, Extract<K, string>>\n\n/**\n * A field name or a field pattern of the kinds `K`.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type FieldFor<D, K> =\n\tCondition.FieldName<DataFor<D, K>> | `${string}*${string}`\n\n/**\n * A condition that a rule for the kinds `K` may have. Its predicates may read\n * only the values of these kinds and the principal of the domain.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport type ConditionFor<D, K> = Condition.Condition<\n\tCondition.Reads<ValueFor<D, K>, Domain.Principal<D>>,\n\tany\n>\n\n/**\n * Checks each field of a rule: a field pattern with a star, or a name of the\n * kinds `K`, of any length up to about 1000 parts. A name that is not a field\n * gives the names that may come next, so the type error names them. See\n * `Condition.NamePath`.\n *\n * @stability stable\n * @category utility types\n * @since 2.1.0\n */\nexport type FieldsFor<D, K, Fields extends ReadonlyArray<string>> = {\n\treadonly [I in keyof Fields]: Fields[I] extends `${string}*${string}`\n\t\t? Fields[I]\n\t\t: Condition.NamePath<DataFor<D, K>, Fields[I] & string>\n}\n\n/**\n * The options of a rule. `Fields` is the list of the fields of the rule.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface RuleOptions<\n\tD,\n\tK,\n\tC extends Condition.Any,\n\tFields extends ReadonlyArray<string> = ReadonlyArray<FieldFor<D, K>>,\n> {\n\t/** The condition. It gets a builder with the types of the resource. */\n\treadonly when?: (\n\t\tbuilder: Condition.Builder<\n\t\t\tDataFor<D, K>,\n\t\t\tValueFor<D, K>,\n\t\t\tDomain.Principal<D>\n\t\t>,\n\t) => C\n\treadonly fields?: Fields & FieldsFor<D, K, Fields>\n\treadonly reason?: string\n\treadonly id?: string\n\treadonly meta?: Domain.Meta<D>\n}\n\ntype SingleOrArray<A> = A | ReadonlyArray<A>\n\n/**\n * Makes rules with the types of a domain.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Builder<D> {\n\treadonly allow: <\n\t\tconst Res extends SingleOrArray<RuleTarget<D>>,\n\t\tconst A extends ActionForTargets<D, Res>,\n\t\tconst C extends ConditionFor<D, KindOf<TargetOf<Res>>> =\n\t\t\tCondition.Condition,\n\t\tconst Fields extends ReadonlyArray<string> = readonly [],\n\t>(\n\t\taction: SingleOrArray<A>,\n\t\tresource: Res,\n\t\toptions?: RuleOptions<D, KindOf<TargetOf<Res>>, C, Fields>,\n\t) => Rule<D, Condition.ReadsOf<C>, Condition.OpaqueOf<C>>\n\treadonly deny: <\n\t\tconst Res extends SingleOrArray<RuleTarget<D>>,\n\t\tconst A extends ActionForTargets<D, Res>,\n\t\tconst C extends ConditionFor<D, KindOf<TargetOf<Res>>> =\n\t\t\tCondition.Condition,\n\t\tconst Fields extends ReadonlyArray<string> = readonly [],\n\t>(\n\t\taction: SingleOrArray<A>,\n\t\tresource: Res,\n\t\toptions?: RuleOptions<D, KindOf<TargetOf<Res>>, C, Fields>,\n\t) => Rule<D, Condition.ReadsOf<C>, Condition.OpaqueOf<C>>\n}\n\n/**\n * Makes rules with the types of a domain. `Policy.define` gives one to its\n * generator. Use this one to make rules outside of a generator.\n *\n * @example\n * ```ts\n * const _ = Policy.builder(App)\n * const rule = _.allow(\"read\", Document, {\n * when: ($) => $.eq(\"ownerId\", $.principal(\"id\")),\n * })\n * ```\n *\n * @stability stable\n * @category constructors\n * @since 2.0.0\n */\nexport const builder = <D extends Domain.Any>(domain: D): Builder<D> =>\n\tRuleData.builder(domain) as never\n\n/**\n * Makes a rule from its data, with no types. It does not check the data\n * against a domain: a policy does that when the rule goes into it. Use\n * {@link builder} for rules with types, or {@link schema} for rules from JSON.\n *\n * The condition may not have a predicate. A policy checks the fields of a\n * condition against the resources of its rule, but it can not check what\n * the code of a predicate reads. A rule from the builder keeps that in its\n * types; this one could give a predicate of one kind to another kind.\n *\n * @stability stable\n * @category constructors\n * @since 2.0.0\n */\nexport const rule: <I = unknown>(\n\tdata: RuleShape<I, never>,\n\t// The types come from the data only, not from where the rule goes.\n) => Rule<any, NoInfer<I>> = RuleData.makePlain as never\n\n/**\n * The options of a list of rules.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Options {\n\t/** The default is `denyOverrides`. */\n\treadonly algorithm?: Algorithm\n}\n\n/**\n * The error when a rule does not fit its domain: it names a kind, an action,\n * a field or a field of the principal that the domain does not have, or it\n * tests a field with a value that the field can not hold. It has one issue\n * for each problem, with its path, and a suggestion when a name has a mistake.\n *\n * @stability stable\n * @category errors\n * @since 2.0.0\n */\nexport const PolicyError: typeof Internal.PolicyError = Internal.PolicyError\n\n/**\n * @stability stable\n * @category errors\n * @since 2.0.0\n */\nexport type PolicyError = Internal.PolicyError\n\n/** The mark of a union of rules: `Condition.Opaque` when one has a predicate. */\ntype RulesOpaque<Rules> = Rules extends { readonly \"~Opaque\": () => infer X }\n\t? X\n\t: never\n\n/**\n * Makes a policy from a generator function that gives rules. It is pure and it\n * gives its result at once.\n *\n * @example\n * ```ts\n * const policy = Policy.define(App)(function* (_) {\n * yield* _.allow(\"read\", Document)\n * yield* _.allow([\"update\", \"delete\"], Document, {\n * when: ($) => $.eq(\"ownerId\", $.principal(\"id\")),\n * })\n * })\n * ```\n *\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const define: <D extends Domain.Any>(\n\tdomain: D,\n\toptions?: Options,\n) => <Rules extends Rule<D, never, any>, A>(\n\tbody: (builder: Builder<D>) => Generator<Rules, A, unknown>,\n) => Policy<D, RulesOpaque<Rules>> = Internal.define as never\n\ntype Combined<D extends Domain.Any, Ps extends ReadonlyArray<Any>> = Policy<\n\tD,\n\tOpaqueOf<Ps[number]>\n>\n\n/**\n * Every policy must allow, and one deny is enough to deny. With some policies\n * not applicable and none that deny, the result is not applicable.\n *\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const all: <const Ps extends readonly [Any, ...Array<Any>]>(\n\tpolicies: Ps,\n) => Combined<DomainOf<Ps[0]>, Ps> = Internal.combine(\"All\")\n\n/**\n * One allow is enough. Without an allow, one deny gives a deny.\n *\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const any: <const Ps extends readonly [Any, ...Array<Any>]>(\n\tpolicies: Ps,\n) => Combined<DomainOf<Ps[0]>, Ps> = Internal.combine(\"Any\")\n\n/**\n * The first policy that allows or denies gives the answer.\n *\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const firstOf: <const Ps extends readonly [Any, ...Array<Any>]>(\n\tpolicies: Ps,\n) => Combined<DomainOf<Ps[0]>, Ps> = Internal.combine(\"FirstOf\")\n\n/**\n * Puts a limit on a policy. A deny from `cap` always wins. An allow from `cap`\n * does nothing.\n *\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const ceiling: {\n\t<D extends Domain.Any, X2>(\n\t\tcap: Policy<D, X2>,\n\t): <X>(policy: Policy<D, X>) => Policy<D, X | X2>\n\t<D extends Domain.Any, X, X2>(\n\t\tpolicy: Policy<D, X>,\n\t\tcap: Policy<D, X2>,\n\t): Policy<D, X | X2>\n} = Internal.ceiling as never\n\n/**\n * Gives the services in `context` to every predicate of a policy, so the\n * policy needs no services when it runs.\n *\n * @stability stable\n * @category services\n * @since 1.0.0\n */\nexport const provideContext: {\n\t<R>(\n\t\tcontext: Context.Context<R>,\n\t): <D extends Domain.Any, X>(\n\t\tpolicy: Policy<D, X> &\n\t\t\t([Condition.ServicesOf<X>] extends [R] ? unknown : never),\n\t) => Policy<D, Condition.Provided<X>>\n\t<D extends Domain.Any, X>(\n\t\tpolicy: Policy<D, X>,\n\t\tcontext: Context.Context<Condition.ServicesOf<X>>,\n\t): Policy<D, Condition.Provided<X>>\n} = Internal.provideContext as never\n\n// Decisions\n\n/**\n * Gives the decision of a policy for a request.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const decide: <\n\tD extends Domain.Any,\n\tX,\n\tconst Req extends DeepRequest<NoInfer<D>>,\n>(\n\tpolicy: Policy<D, X>,\n\trequest: Req & CheckField<NoInfer<D>, Req>,\n) => Effect.Effect<\n\tDecision.Decision,\n\tCondition.ErrorOf<X>,\n\tCondition.ServicesOf<X>\n> = Decide.decideAny as never\n\n/**\n * Gives the decision of a policy with no predicates, at once.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const decideSync: <\n\tD extends Domain.Any,\n\tconst Req extends DeepRequest<NoInfer<D>>,\n>(\n\tpolicy: Policy<D>,\n\trequest: Req & CheckField<NoInfer<D>, Req>,\n) => Decision.Decision = Decide.decideSync\n\n/**\n * Gives the decision of a policy and the rules that were tested to make it.\n *\n * One node may be a child of many nodes. Its rules are tested, and are in the\n * steps, each time that the decision comes to it.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const explain: <\n\tD extends Domain.Any,\n\tX,\n\tconst Req extends DeepRequest<NoInfer<D>>,\n>(\n\tpolicy: Policy<D, X>,\n\trequest: Req & CheckField<NoInfer<D>, Req>,\n) => Effect.Effect<Explanation, Condition.ErrorOf<X>, Condition.ServicesOf<X>> =\n\tDecide.explain as never\n\n/**\n * Gives the fields of a resource value that the policy lets a request use. It\n * tests each field that a list of fields shows: each scalar, record or array\n * of the resource Schema, with dots for nested fields.\n *\n * A field that holds more than one value, such as a record, is left out when a\n * deny rule names a part of it. The list can not name that part, and the whole\n * field would show it.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const permittedFields: <D extends Domain.Any, X>(\n\tpolicy: Policy<D, X>,\n\trequest: FieldlessRequest<NoInfer<D>>,\n) => Effect.Effect<\n\tReadonlyArray<string>,\n\tCondition.ErrorOf<X>,\n\tCondition.ServicesOf<X>\n> = Decide.permittedFields as never\n\n// Residual conditions\n\n/**\n * What a residual condition reads: a value of the kind `K`. The principal is\n * already in it. A residual is for one kind, so when `K` is a union of kinds,\n * the value must be a value of each of them. No value is, so such a residual\n * can not be evaluated on a value of the wrong kind.\n *\n * @stability stable\n * @category utility types\n * @since 1.0.0\n */\nexport type ResidualReads<D, K> = Condition.Reads<\n\t(\n\t\tK extends unknown ? (value: Domain.ValueOf<D, K & string>) => void : never\n\t) extends (value: infer V) => void\n\t\t? V\n\t\t: never,\n\tunknown\n>\n\n/**\n * Gives the condition on resource values for which the policy allows a\n * request. It has no principal fields and no `Under` nodes, so you can give it\n * to `Condition.fold`. It is made smaller, so it is often `True` or `False`\n * when the answer does not depend on the value, but it does no search: a\n * condition that is true for every value may stay a test. To know if the\n * policy allows every value, or some value, use {@link coverage}.\n *\n * With a scope (`within`), the condition is the scope and the residual\n * together, so it is false for every value outside the scope. Give the policy\n * first to use a scope. The condition comes from its parts, with no search. To\n * know if it allows all of the scope or none of it, use {@link coverage}.\n *\n * When a rule that the request may use has a predicate, the condition is one\n * predicate with the name `\"policy\"`. It runs the whole policy for each value,\n * so its answers and its failures are the same as those of {@link decide}. It\n * takes the principal with it. Give it resource values with their `_tag`. It\n * is false for a value of another kind.\n *\n * A policy tree may use the condition of a child two times, so a small policy\n * may give a very large condition. When the condition would have more than\n * the `residualNodes` of the domain, 100000 by default, this function throws\n * an error. In an `Authorizer`, the error is a defect, so the check fails.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const residual: <\n\tD extends Domain.Any,\n\tX,\n\tconst Req extends DeepKindRequest<NoInfer<D>>,\n>(\n\tpolicy: Policy<D, X>,\n\trequest: Req & CheckField<NoInfer<D>, Req>,\n) => Condition.Condition<ResidualReads<D, Req[\"kind\"]>, X> =\n\tAnalysis.residual as never\n\n/**\n * How much of a scope a policy allows. In each case, `condition` is the exact\n * condition on the values in the scope that the policy allows: give it to\n * `Condition.fold` for a list query.\n * - `All`: the policy allows every value in the scope. `condition` is the\n * scope (`True` with no scope).\n * - `None`: the policy allows no value in the scope. `condition` is `False`.\n * An empty scope is `None` too, so a check on a scope that has a mistake,\n * such as a principal field with no value, never passes.\n * - `Some`: the policy allows some values in the scope and not others.\n * `allowed` is an example of a value that it allows, and `refused` of a\n * value in the scope that it does not allow.\n * - `Unknown`: the answer needs a predicate, or the search went past its\n * budget.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport type Coverage<I = unknown, X = never> = Data.TaggedEnum<{\n\tAll: { readonly condition: Condition.Condition<I, X> }\n\tNone: { readonly condition: Condition.Condition<I, X> }\n\tSome: {\n\t\treadonly condition: Condition.Condition<I, X>\n\t\treadonly allowed: Condition.Example\n\t\treadonly refused: Condition.Example\n\t}\n\tUnknown: {\n\t\treadonly condition: Condition.Condition<I, X>\n\t\treadonly reason: \"predicate\" | \"budget\"\n\t}\n}>\n\n/**\n * Tells how much of a scope the policy allows: all of it, none of it, or some\n * of it. See {@link Coverage}. With no scope (`within`), the scope is every\n * value of the kind.\n *\n * The answer comes from {@link Condition.satisfiable} with the shape of the\n * Schema of the resource. `All` and `None` hold for every value of the\n * Schema. `Some` means that, by the shape of the Schema, a value may get\n * either answer: a check such as a minimum length may still stop one of the\n * examples. `Unknown` comes only from a predicate or from the budget of the\n * search.\n *\n * `Some` does not mean that such a value is in your database. To know that,\n * run `condition` as a query.\n *\n * @stability stable\n * @category evaluation\n * @since 1.0.0\n */\nexport const coverage: <\n\tD extends Domain.Any,\n\tX,\n\tconst Req extends DeepKindRequest<NoInfer<D>>,\n>(\n\tpolicy: Policy<D, X>,\n\trequest: Req & CheckField<NoInfer<D>, Req>,\n) => Coverage<ResidualReads<D, Req[\"kind\"]>, X> = Analysis.coverageAny as never\n\n// Schema\n\n/**\n * The JSON form of a rule.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface EncodedRule {\n\treadonly _tag: \"Allow\" | \"Deny\"\n\treadonly actions: ReadonlyArray<string>\n\treadonly resources: ReadonlyArray<string>\n\treadonly when?: Condition.Encoded\n\treadonly fields?: ReadonlyArray<string>\n\treadonly reason?: string\n\treadonly id?: string\n\treadonly meta?: unknown\n}\n\n/**\n * The JSON form of a policy.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type EncodedNode =\n\t| {\n\t\t\treadonly _tag: \"Rules\"\n\t\t\treadonly algorithm: Algorithm\n\t\t\treadonly rules: ReadonlyArray<EncodedRule>\n\t }\n\t| {\n\t\t\treadonly _tag: \"All\" | \"Any\" | \"FirstOf\"\n\t\t\treadonly policies: ReadonlyArray<EncodedNode>\n\t }\n\t| {\n\t\t\treadonly _tag: \"Ceiling\"\n\t\t\treadonly cap: EncodedNode\n\t\t\treadonly policy: EncodedNode\n\t }\n\n/**\n * The Schema of the policies of a domain with no predicates. Decoding checks\n * every kind, action, field and principal field against the domain, and the\n * `meta` of each rule against the `meta` Schema of the domain.\n *\n * The decoder takes the limits of the domain: at most `policyNodes` nodes\n * of the tree, `conditionNodes` nodes of each condition, and `jsonNodes`\n * objects and array items, with a shared object counted for each place. It\n * stops at the first one past a limit. It takes any number of levels, and it\n * reads only the own data fields of the input.\n *\n * @stability stable\n * @category schemas\n * @since 0.3.0\n */\nexport const schema: <D extends Domain.Any>(\n\tdomain: D,\n) => Schema.Codec<Policy<D>, EncodedNode> = Internal.schema as never\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsnBA,MAAa,WAAiC,WAC7CA,UAAiB,MAAM;;;;;;;;;;;;;;;AAgBxB,MAAa,OAGgBC;;;;;;;;;;;AAwB7B,MAAa,cAA2CC;;;;;;;;;;;;;;;;;;;AAgCxD,MAAa,SAKwBC;;;;;;;;;AAerC,MAAa,MAEwBC,QAAiB,KAAK;;;;;;;;AAS3D,MAAa,MAEwBA,QAAiB,KAAK;;;;;;;;AAS3D,MAAa,UAEwBA,QAAiB,SAAS;;;;;;;;;AAU/D,MAAa,UAQTC;;;;;;;;;AAUJ,MAAa,iBAWTC;;;;;;;;AAWJ,MAAa,SAWTC;;;;;;;;AASJ,MAAa,aAMYC;;;;;;;;;;;AAYzB,MAAa,UAQZC;;;;;;;;;;;;;;AAeD,MAAa,kBAOTC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDJ,MAAa,WAQZC;;;;;;;;;;;;;;;;;;;;AAsDD,MAAa,WAOqCC;;;;;;;;;;;;;;;;AA4DlD,MAAa,SAE+BC"}
1
+ {"version":3,"file":"Policy.js","names":["RuleData.builder","RuleData.makePlain","Internal.PolicyError","Internal.define","Internal.combine","Internal.ceiling","Internal.provideContext","Decide.decideAny","Decide.decideSync","Decide.explain","Decide.permittedFields","Analysis.residual","Analysis.coverageAny","Internal.schema"],"sources":["../src/Policy.ts"],"sourcesContent":["/**\n * A policy is a tree that gives a {@link Decision.Decision} for a request.\n *\n * The leaves of the tree are lists of rules. A combining algorithm decides\n * which rule gives the answer when more than one rule applies:\n * - `denyOverrides` (the default): a deny rule wins over every allow rule.\n * - `permitOverrides`: an allow rule wins over every deny rule.\n * - `firstApplicable`: the first rule that applies wins.\n * - `lastApplicable`: the last rule that applies wins.\n *\n * The branches put policies together:\n * - {@link all}: every policy must allow, and one deny is enough to deny. Use\n * it when a user token may never do more than its user.\n * - {@link any}: one allow is enough.\n * - {@link firstOf}: the first policy that gives an answer wins. Use it for\n * grants first, then rules.\n * - {@link ceiling}: the deny rules of a second policy are a limit for\n * everyone. Its allow rules do nothing.\n *\n * A policy gives three kinds of answers:\n * - {@link decide}: the decision for one resource value.\n * - {@link residual}: a condition on resource values. A value passes when the\n * policy allows the request for that value. Use it to make a database\n * query, or to ask \"may this principal do this act on some resource of\n * this kind?\"\n * - {@link permittedFields}: the fields that the policy lets a request use.\n *\n * Each of them takes the policy first and the request second, as in\n * `Policy.decide(policy, request)`. The policy gives the domain, so\n * TypeScript checks the request against it.\n *\n * A policy without predicates can become JSON with {@link schema}.\n *\n * @stability stable\n * @since 0.3.0\n */\nimport type * as Context from \"effect/Context\"\nimport type * as Data from \"effect/Data\"\nimport type * as Effect from \"effect/Effect\"\nimport type * as Schema from \"effect/Schema\"\nimport type * as Condition from \"./Condition.ts\"\nimport * as Analysis from \"./internal/analysis.ts\"\nimport * as Decide from \"./internal/decide.ts\"\nimport * as Internal from \"./internal/policy.ts\"\nimport type * as PolicyNodes from \"./internal/policy-nodes.ts\"\nimport * as RuleData from \"./internal/rule.ts\"\nimport type * as Decision from \"./Decision.ts\"\nimport type * as Domain from \"./Domain.ts\"\nimport type * as Resource from \"./Resource.ts\"\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Algorithm = PolicyNodes.Algorithm\n\n/**\n * A list of rules with a combining algorithm.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type RulesNode = PolicyNodes.Rules\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type AllNode = PolicyNodes.All\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type AnyNode = PolicyNodes.Any\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type FirstOfNode = PolicyNodes.FirstOf\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type CeilingNode = PolicyNodes.Ceiling\n\n/**\n * The nodes of a policy tree, without types. Each node is a class, and only\n * the functions of this module and the Schema make one.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Node = PolicyNodes.Node\n\n/**\n * A policy for the domain `D`. `X` is `Condition.Opaque` when a rule of the\n * policy has a predicate, and `never` when the policy is plain data. A plain\n * policy can become JSON, and `decideSync` takes it.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Policy<D extends Domain.Any, X = never> = Internal.PolicyData<D, X>\n\n/**\n * Any policy.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Any = Policy<any, any>\n\n/**\n * The domain of a policy.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type DomainOf<P> = P extends Policy<infer D, any> ? D : never\n\n/**\n * The mark of a policy or a rule: `Condition.Opaque` when it has a predicate.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type OpaqueOf<P> = P extends { readonly \"~Opaque\": () => infer X }\n\t? X\n\t: never\n\n/**\n * One act on one resource value, for each kind of the domain. The action must\n * be an action of the kind, and the field must be a field of the kind.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Target<D> = {\n\t[K in Domain.Kind<D>]: {\n\t\treadonly action: Domain.ActionOf<D, K>\n\t\treadonly resource: Domain.ValueOf<D, K>\n\t\treadonly field?: Condition.FieldSelector<Domain.DataOf<D, K>>\n\t\t/** A target has a resource value or a kind, never both. */\n\t\treadonly kind?: never\n\t}\n}[Domain.Kind<D>]\n\n/**\n * A {@link Target} with no field. Each kind keeps its own actions.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type FieldlessTarget<D> = {\n\t[K in Domain.Kind<D>]: {\n\t\treadonly action: Domain.ActionOf<D, K>\n\t\treadonly resource: Domain.ValueOf<D, K>\n\t\treadonly kind?: never\n\t}\n}[Domain.Kind<D>]\n\n/**\n * A scope: a part of a kind, as a condition on its values. It gets a builder\n * with the types of the kind and of the principal, like the condition of a\n * rule. A scope is plain data, so it can not have a predicate.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport type Scope<D, K extends string> = (\n\tbuilder: Condition.Builder<\n\t\tDomain.DataOf<D, K>,\n\t\tDomain.ValueOf<D, K>,\n\t\tDomain.Principal<D>\n\t>,\n) => Condition.Condition<\n\tCondition.Reads<Domain.ValueOf<D, K>, Domain.Principal<D>>\n>\n\n/**\n * One act on one kind of resource, with no value. With `within`, the target is\n * only the values of the kind in the scope. Without it, the target is every\n * value of the kind.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type KindTarget<D> = {\n\t[K in Domain.Kind<D>]: {\n\t\treadonly action: Domain.ActionOf<D, K>\n\t\treadonly kind: K\n\t\treadonly field?: Condition.FieldSelector<Domain.DataOf<D, K>>\n\t\t/** The part of the kind. See {@link Scope}. */\n\t\treadonly within?: Scope<D, K>\n\t\t/** A target has a resource value or a kind, never both. */\n\t\treadonly resource?: never\n\t}\n}[Domain.Kind<D>]\n\n/**\n * A {@link Target} with a field of any length. A function that takes a\n * target checks its field with {@link CheckField}, so a field of up to about\n * 1000 parts is fine, and a field that is not a field of the kind is a type\n * error.\n *\n * @stability stable\n * @category models\n * @since 2.1.0\n */\nexport type DeepTarget<D> = {\n\t[K in Domain.Kind<D>]: {\n\t\treadonly action: Domain.ActionOf<D, K>\n\t\treadonly resource: Domain.ValueOf<D, K>\n\t\treadonly field?: string\n\t\treadonly kind?: never\n\t}\n}[Domain.Kind<D>]\n\n/**\n * A {@link KindTarget} with a field of any length. See {@link DeepTarget}.\n *\n * @stability stable\n * @category models\n * @since 2.1.0\n */\nexport type DeepKindTarget<D> = {\n\t[K in Domain.Kind<D>]: {\n\t\treadonly action: Domain.ActionOf<D, K>\n\t\treadonly kind: K\n\t\treadonly field?: string\n\t\treadonly within?: Scope<D, K>\n\t\treadonly resource?: never\n\t}\n}[Domain.Kind<D>]\n\n/** The kind of a target: its `kind`, or the `_tag` of its resource value. */\ntype KindOfTarget<T> = T extends { readonly kind: infer K extends string }\n\t? K\n\t: T extends { readonly resource: { readonly _tag: infer K extends string } }\n\t\t? K\n\t\t: never\n\n/**\n * Checks the field of a target or a request: a field of its kind that a\n * request may name, of any length up to about 1000 parts. See\n * `Condition.SelectPath`. A target with no field needs no check.\n *\n * @stability stable\n * @category utility types\n * @since 2.1.0\n */\nexport type CheckField<D, T> = T extends { readonly field?: infer F }\n\t? [Exclude<F, undefined>] extends [never]\n\t\t? unknown\n\t\t: {\n\t\t\t\t// A field that the target may leave out is checked too, when it is\n\t\t\t\t// there.\n\t\t\t\treadonly field?: Condition.SelectPath<\n\t\t\t\t\tDomain.DataOf<D, KindOfTarget<T>>,\n\t\t\t\t\tExclude<F, undefined> & string\n\t\t\t\t>\n\t\t\t}\n\t: unknown\n\n/**\n * A target or a request with its field checked, as {@link CheckField} does.\n * Each member of a union is checked by itself, so a member with no field\n * does not take the place of the check of another member.\n *\n * @stability stable\n * @category utility types\n * @since 2.1.3\n */\nexport type Checked<D, T> = T extends unknown ? T & CheckField<D, T> : never\n\n/**\n * A request: a principal, an action, and a resource value.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Request<D> = Target<D> & { readonly principal: Domain.Principal<D> }\n\n/**\n * A {@link Request} with a field of any length. See {@link DeepTarget}.\n *\n * @stability stable\n * @category models\n * @since 2.1.0\n */\nexport type DeepRequest<D> = DeepTarget<D> & {\n\treadonly principal: Domain.Principal<D>\n}\n\n/**\n * A {@link Request} with no field.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type FieldlessRequest<D> = FieldlessTarget<D> & {\n\treadonly principal: Domain.Principal<D>\n}\n\n/**\n * A request about a kind of resource, with no value.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type KindRequest<D> = KindTarget<D> & {\n\treadonly principal: Domain.Principal<D>\n}\n\n/**\n * A {@link KindRequest} with a field of any length. See {@link DeepTarget}.\n *\n * @stability stable\n * @category models\n * @since 2.1.0\n */\nexport type DeepKindRequest<D> = DeepKindTarget<D> & {\n\treadonly principal: Domain.Principal<D>\n}\n\n/**\n * A request with no types.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface AnyRequest {\n\treadonly principal: object\n\treadonly action: string\n\treadonly resource: object\n\treadonly field?: string | undefined\n}\n\n/**\n * One rule that a decision tested. `path` gives the place of the rule in the\n * policy tree: the index of each child, then the index of the rule.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Step {\n\treadonly path: ReadonlyArray<number>\n\treadonly rule: AnyRule\n\treadonly applies: boolean\n}\n\n/**\n * A decision, and the rules that were tested to make it, in order. Keep it in\n * an audit log.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Explanation {\n\treadonly decision: Decision.Decision\n\treadonly steps: ReadonlyArray<Step>\n}\n\n// Rules\n\n/**\n * A rule for the domain `D`. `I` is what the tests of its condition read, and\n * `X` is its mark: see `Condition.Condition`. A predicate reads the values and\n * the principal of its domain, so a rule may go only into a policy of its own\n * domain. A rule from {@link rule} has the domain `any`.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Rule<D = any, I = unknown, X = never> = RuleData.Rule<D, I, X>\n\n/**\n * The data of a rule.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport interface RuleShape<I = unknown, X = never> {\n\treadonly _tag: \"Allow\" | \"Deny\"\n\treadonly actions: ReadonlyArray<string>\n\treadonly resources: ReadonlyArray<string>\n\treadonly when?: Condition.Condition<I, X>\n\treadonly fields?: ReadonlyArray<string>\n\treadonly reason?: string\n\treadonly id?: string\n\treadonly meta?: unknown\n\t/**\n\t * The domain of the builder that made the rule. Two domains may have the\n\t * same types but other paths, so the types can not tell them apart. It is\n\t * not in the JSON form of a rule.\n\t */\n\treadonly domain?: Domain.Any\n}\n\n/**\n * Any rule.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\n// Every rule fits `never` as what it reads, and a condition taken from such a\n// rule fits no rule that reads a value or a principal.\nexport type AnyRule = Rule<any, never, any>\n\n/**\n * A resource in a rule: a kind name, a resource of the domain, or `\"*\"`.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type RuleTarget<D> = Domain.Kind<D> | Domain.Resources<D> | \"*\"\n\n/**\n * The kind name of a target.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type KindOf<T> = T extends string ? T : Resource.Kind<T>\n\n/**\n * The actions that a rule may use for the kinds `K`.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type ActionFor<D, K> =\n\t| \"*\"\n\t| (\"*\" extends K\n\t\t\t? Domain.AnyAction<D>\n\t\t\t: Domain.ActionOf<D, Extract<K, string>>)\n\n/**\n * The targets in the resource argument of a rule: the one target, or the\n * targets of a list.\n *\n * @stability stable\n * @category utility types\n * @since 1.0.0\n */\nexport type TargetOf<Res> = Res extends ReadonlyArray<infer X> ? X : Res\n\n/**\n * The actions that a rule may use for its resource argument. A list of\n * resources may use an action of any of them. One target with a union type\n * may use only an action of every kind in the union, because its value may be\n * any one of them. When the argument may be a list or one target, the rule\n * may use only an action that each of these shapes allows.\n *\n * @stability stable\n * @category utility types\n * @since 1.0.0\n */\nexport type ActionForTargets<D, Res> = (\n\tRes extends ReadonlyArray<infer X>\n\t\t? (action: ActionFor<D, KindOf<X>>) => void\n\t\t: (action: ActionForTarget<D, Res>) => void\n) extends (action: infer A) => void\n\t? A\n\t: never\n\n/** The actions for one target that is not a list. */\ntype ActionForTarget<D, Res> =\n\t| \"*\"\n\t| (\"*\" extends KindOf<Res>\n\t\t\t? Domain.AnyAction<D>\n\t\t\t: Domain.CommonAction<D, Extract<KindOf<Res>, string>>)\n\n/**\n * The data type of the kinds `K`. For `\"*\"` it has no fields.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type DataFor<D, K> = \"*\" extends K\n\t? {}\n\t: Domain.DataOf<D, Extract<K, string>>\n\n/**\n * The value type of the kinds `K`.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type ValueFor<D, K> = \"*\" extends K\n\t? Domain.AnyValue<D>\n\t: Domain.ValueOf<D, Extract<K, string>>\n\n/**\n * A field name or a field pattern of the kinds `K`.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type FieldFor<D, K> =\n\tCondition.FieldName<DataFor<D, K>> | `${string}*${string}`\n\n/**\n * A condition that a rule for the kinds `K` may have. Its predicates may read\n * only the values of these kinds and the principal of the domain.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport type ConditionFor<D, K> = Condition.Condition<\n\tCondition.Reads<ValueFor<D, K>, Domain.Principal<D>>,\n\tany\n>\n\n/**\n * Checks each field of a rule: a field pattern with a star, or a name of the\n * kinds `K`, of any length up to about 1000 parts. A name that is not a field\n * gives the names that may come next, so the type error names them. See\n * `Condition.NamePath`.\n *\n * @stability stable\n * @category utility types\n * @since 2.1.0\n */\nexport type FieldsFor<D, K, Fields extends ReadonlyArray<string>> = {\n\treadonly [I in keyof Fields]: Fields[I] extends `${string}*${string}`\n\t\t? Fields[I]\n\t\t: Condition.NamePath<DataFor<D, K>, Fields[I] & string>\n}\n\n/**\n * The options of a rule. `Fields` is the list of the fields of the rule.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface RuleOptions<\n\tD,\n\tK,\n\tC extends Condition.Any,\n\tFields extends ReadonlyArray<string> = ReadonlyArray<FieldFor<D, K>>,\n> {\n\t/** The condition. It gets a builder with the types of the resource. */\n\treadonly when?: (\n\t\tbuilder: Condition.Builder<\n\t\t\tDataFor<D, K>,\n\t\t\tValueFor<D, K>,\n\t\t\tDomain.Principal<D>\n\t\t>,\n\t) => C\n\treadonly fields?: Fields & FieldsFor<D, K, Fields>\n\treadonly reason?: string\n\treadonly id?: string\n\treadonly meta?: Domain.Meta<D>\n}\n\ntype SingleOrArray<A> = A | ReadonlyArray<A>\n\n/**\n * Makes rules with the types of a domain.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Builder<D> {\n\treadonly allow: <\n\t\tconst Res extends SingleOrArray<RuleTarget<D>>,\n\t\tconst A extends ActionForTargets<D, Res>,\n\t\tconst C extends ConditionFor<D, KindOf<TargetOf<Res>>> =\n\t\t\tCondition.Condition,\n\t\tconst Fields extends ReadonlyArray<string> = readonly [],\n\t>(\n\t\taction: SingleOrArray<A>,\n\t\tresource: Res,\n\t\toptions?: RuleOptions<D, KindOf<TargetOf<Res>>, C, Fields>,\n\t) => Rule<D, Condition.ReadsOf<C>, Condition.OpaqueOf<C>>\n\treadonly deny: <\n\t\tconst Res extends SingleOrArray<RuleTarget<D>>,\n\t\tconst A extends ActionForTargets<D, Res>,\n\t\tconst C extends ConditionFor<D, KindOf<TargetOf<Res>>> =\n\t\t\tCondition.Condition,\n\t\tconst Fields extends ReadonlyArray<string> = readonly [],\n\t>(\n\t\taction: SingleOrArray<A>,\n\t\tresource: Res,\n\t\toptions?: RuleOptions<D, KindOf<TargetOf<Res>>, C, Fields>,\n\t) => Rule<D, Condition.ReadsOf<C>, Condition.OpaqueOf<C>>\n}\n\n/**\n * Makes rules with the types of a domain. `Policy.define` gives one to its\n * generator. Use this one to make rules outside of a generator.\n *\n * @example\n * ```ts\n * const _ = Policy.builder(App)\n * const rule = _.allow(\"read\", Document, {\n * when: ($) => $.eq(\"ownerId\", $.principal(\"id\")),\n * })\n * ```\n *\n * @stability stable\n * @category constructors\n * @since 2.0.0\n */\nexport const builder = <D extends Domain.Any>(domain: D): Builder<D> =>\n\tRuleData.builder(domain) as never\n\n/**\n * Makes a rule from its data, with no types. It does not check the data\n * against a domain: a policy does that when the rule goes into it. Use\n * {@link builder} for rules with types, or {@link schema} for rules from JSON.\n *\n * The condition may not have a predicate. A policy checks the fields of a\n * condition against the resources of its rule, but it can not check what\n * the code of a predicate reads. A rule from the builder keeps that in its\n * types; this one could give a predicate of one kind to another kind.\n *\n * @stability stable\n * @category constructors\n * @since 2.0.0\n */\nexport const rule: <I = unknown>(\n\tdata: RuleShape<I, never>,\n\t// The types come from the data only, not from where the rule goes.\n) => Rule<any, NoInfer<I>> = RuleData.makePlain as never\n\n/**\n * The options of a list of rules.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Options {\n\t/** The default is `denyOverrides`. */\n\treadonly algorithm?: Algorithm\n}\n\n/**\n * The error when a rule does not fit its domain: it names a kind, an action,\n * a field or a field of the principal that the domain does not have, or it\n * tests a field with a value that the field can not hold. It has one issue\n * for each problem, with its path, and a suggestion when a name has a mistake.\n *\n * @stability stable\n * @category errors\n * @since 2.0.0\n */\nexport const PolicyError: typeof Internal.PolicyError = Internal.PolicyError\n\n/**\n * @stability stable\n * @category errors\n * @since 2.0.0\n */\nexport type PolicyError = Internal.PolicyError\n\n/** The mark of a union of rules: `Condition.Opaque` when one has a predicate. */\ntype RulesOpaque<Rules> = Rules extends { readonly \"~Opaque\": () => infer X }\n\t? X\n\t: never\n\n/**\n * Makes a policy from a generator function that gives rules. It is pure and it\n * gives its result at once.\n *\n * @example\n * ```ts\n * const policy = Policy.define(App)(function* (_) {\n * yield* _.allow(\"read\", Document)\n * yield* _.allow([\"update\", \"delete\"], Document, {\n * when: ($) => $.eq(\"ownerId\", $.principal(\"id\")),\n * })\n * })\n * ```\n *\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const define: <D extends Domain.Any>(\n\tdomain: D,\n\toptions?: Options,\n) => <Rules extends Rule<D, never, any>, A>(\n\tbody: (builder: Builder<D>) => Generator<Rules, A, unknown>,\n) => Policy<D, RulesOpaque<Rules>> = Internal.define as never\n\ntype Combined<D extends Domain.Any, Ps extends ReadonlyArray<Any>> = Policy<\n\tD,\n\tOpaqueOf<Ps[number]>\n>\n\n/**\n * Every policy must allow, and one deny is enough to deny. With some policies\n * not applicable and none that deny, the result is not applicable.\n *\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const all: <const Ps extends readonly [Any, ...Array<Any>]>(\n\tpolicies: Ps,\n) => Combined<DomainOf<Ps[0]>, Ps> = Internal.combine(\"All\")\n\n/**\n * One allow is enough. Without an allow, one deny gives a deny.\n *\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const any: <const Ps extends readonly [Any, ...Array<Any>]>(\n\tpolicies: Ps,\n) => Combined<DomainOf<Ps[0]>, Ps> = Internal.combine(\"Any\")\n\n/**\n * The first policy that allows or denies gives the answer.\n *\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const firstOf: <const Ps extends readonly [Any, ...Array<Any>]>(\n\tpolicies: Ps,\n) => Combined<DomainOf<Ps[0]>, Ps> = Internal.combine(\"FirstOf\")\n\n/**\n * Puts a limit on a policy. A deny from `cap` always wins. An allow from `cap`\n * does nothing.\n *\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const ceiling: {\n\t<D extends Domain.Any, X2>(\n\t\tcap: Policy<D, X2>,\n\t): <X>(policy: Policy<D, X>) => Policy<D, X | X2>\n\t<D extends Domain.Any, X, X2>(\n\t\tpolicy: Policy<D, X>,\n\t\tcap: Policy<D, X2>,\n\t): Policy<D, X | X2>\n} = Internal.ceiling as never\n\n/**\n * Gives the services in `context` to every predicate of a policy, so the\n * policy needs no services when it runs.\n *\n * @stability stable\n * @category services\n * @since 1.0.0\n */\nexport const provideContext: {\n\t<R>(\n\t\tcontext: Context.Context<R>,\n\t): <D extends Domain.Any, X>(\n\t\tpolicy: Policy<D, X> &\n\t\t\t([Condition.ServicesOf<X>] extends [R] ? unknown : never),\n\t) => Policy<D, Condition.Provided<X>>\n\t<D extends Domain.Any, X>(\n\t\tpolicy: Policy<D, X>,\n\t\tcontext: Context.Context<Condition.ServicesOf<X>>,\n\t): Policy<D, Condition.Provided<X>>\n} = Internal.provideContext as never\n\n// Decisions\n\n/**\n * Gives the decision of a policy for a request.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const decide: <\n\tD extends Domain.Any,\n\tX,\n\tconst Req extends DeepRequest<NoInfer<D>>,\n>(\n\tpolicy: Policy<D, X>,\n\trequest: Checked<NoInfer<D>, Req>,\n) => Effect.Effect<\n\tDecision.Decision,\n\tCondition.ErrorOf<X>,\n\tCondition.ServicesOf<X>\n> = Decide.decideAny as never\n\n/**\n * Gives the decision of a policy with no predicates, at once.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const decideSync: <\n\tD extends Domain.Any,\n\tconst Req extends DeepRequest<NoInfer<D>>,\n>(\n\tpolicy: Policy<D>,\n\trequest: Checked<NoInfer<D>, Req>,\n) => Decision.Decision = Decide.decideSync\n\n/**\n * Gives the decision of a policy and the rules that were tested to make it.\n *\n * One node may be a child of many nodes. Its rules are tested, and are in the\n * steps, each time that the decision comes to it.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const explain: <\n\tD extends Domain.Any,\n\tX,\n\tconst Req extends DeepRequest<NoInfer<D>>,\n>(\n\tpolicy: Policy<D, X>,\n\trequest: Checked<NoInfer<D>, Req>,\n) => Effect.Effect<Explanation, Condition.ErrorOf<X>, Condition.ServicesOf<X>> =\n\tDecide.explain as never\n\n/**\n * Gives the fields of a resource value that the policy lets a request use. It\n * tests each field that a list of fields shows: each scalar, record or array\n * of the resource Schema, with dots for nested fields.\n *\n * A field that holds more than one value, such as a record, is left out when a\n * deny rule names a part of it. The list can not name that part, and the whole\n * field would show it.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const permittedFields: <D extends Domain.Any, X>(\n\tpolicy: Policy<D, X>,\n\trequest: FieldlessRequest<NoInfer<D>>,\n) => Effect.Effect<\n\tReadonlyArray<string>,\n\tCondition.ErrorOf<X>,\n\tCondition.ServicesOf<X>\n> = Decide.permittedFields as never\n\n// Residual conditions\n\n/**\n * What a residual condition reads: a value of the kind `K`. The principal is\n * already in it. A residual is for one kind, so when `K` is a union of kinds,\n * the value must be a value of each of them. No value is, so such a residual\n * can not be evaluated on a value of the wrong kind.\n *\n * @stability stable\n * @category utility types\n * @since 1.0.0\n */\nexport type ResidualReads<D, K> = Condition.Reads<\n\t(\n\t\tK extends unknown ? (value: Domain.ValueOf<D, K & string>) => void : never\n\t) extends (value: infer V) => void\n\t\t? V\n\t\t: never,\n\tunknown\n>\n\n/**\n * Gives the condition on resource values for which the policy allows a\n * request. It has no principal fields and no `Under` nodes, so you can give it\n * to `Condition.fold`. It is made smaller, so it is often `True` or `False`\n * when the answer does not depend on the value, but it does no search: a\n * condition that is true for every value may stay a test. To know if the\n * policy allows every value, or some value, use {@link coverage}.\n *\n * With a scope (`within`), the condition is the scope and the residual\n * together, so it is false for every value outside the scope. Give the policy\n * first to use a scope. The condition comes from its parts, with no search. To\n * know if it allows all of the scope or none of it, use {@link coverage}.\n *\n * When a rule that the request may use has a predicate, the condition is one\n * predicate with the name `\"policy\"`. It runs the whole policy for each value,\n * so its answers and its failures are the same as those of {@link decide}. It\n * takes the principal with it. Give it resource values with their `_tag`. It\n * is false for a value of another kind.\n *\n * A policy tree may use the condition of a child two times, so a small policy\n * may give a very large condition. When the condition would have more than\n * the `residualNodes` of the domain, 100000 by default, this function throws\n * an error. In an `Authorizer`, the error is a defect, so the check fails.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const residual: <\n\tD extends Domain.Any,\n\tX,\n\tconst Req extends DeepKindRequest<NoInfer<D>>,\n>(\n\tpolicy: Policy<D, X>,\n\trequest: Checked<NoInfer<D>, Req>,\n) => Condition.Condition<ResidualReads<D, Req[\"kind\"]>, X> =\n\tAnalysis.residual as never\n\n/**\n * How much of a scope a policy allows. In each case, `condition` is the exact\n * condition on the values in the scope that the policy allows: give it to\n * `Condition.fold` for a list query.\n * - `All`: the policy allows every value in the scope. `condition` is the\n * scope (`True` with no scope).\n * - `None`: the policy allows no value in the scope. `condition` is `False`.\n * An empty scope is `None` too, so a check on a scope that has a mistake,\n * such as a principal field with no value, never passes.\n * - `Some`: the policy allows some values in the scope and not others.\n * `allowed` is an example of a value that it allows, and `refused` of a\n * value in the scope that it does not allow.\n * - `Unknown`: the answer needs a predicate, or the search went past its\n * budget.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport type Coverage<I = unknown, X = never> = Data.TaggedEnum<{\n\tAll: { readonly condition: Condition.Condition<I, X> }\n\tNone: { readonly condition: Condition.Condition<I, X> }\n\tSome: {\n\t\treadonly condition: Condition.Condition<I, X>\n\t\treadonly allowed: Condition.Example\n\t\treadonly refused: Condition.Example\n\t}\n\tUnknown: {\n\t\treadonly condition: Condition.Condition<I, X>\n\t\treadonly reason: \"predicate\" | \"budget\"\n\t}\n}>\n\n/**\n * Tells how much of a scope the policy allows: all of it, none of it, or some\n * of it. See {@link Coverage}. With no scope (`within`), the scope is every\n * value of the kind.\n *\n * The answer comes from {@link Condition.satisfiable} with the shape of the\n * Schema of the resource. `All` and `None` hold for every value of the\n * Schema. `Some` means that, by the shape of the Schema, a value may get\n * either answer: a check such as a minimum length may still stop one of the\n * examples. `Unknown` comes only from a predicate or from the budget of the\n * search.\n *\n * `Some` does not mean that such a value is in your database. To know that,\n * run `condition` as a query.\n *\n * @stability stable\n * @category evaluation\n * @since 1.0.0\n */\nexport const coverage: <\n\tD extends Domain.Any,\n\tX,\n\tconst Req extends DeepKindRequest<NoInfer<D>>,\n>(\n\tpolicy: Policy<D, X>,\n\trequest: Checked<NoInfer<D>, Req>,\n) => Coverage<ResidualReads<D, Req[\"kind\"]>, X> = Analysis.coverageAny as never\n\n// Schema\n\n/**\n * The JSON form of a rule.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface EncodedRule {\n\treadonly _tag: \"Allow\" | \"Deny\"\n\treadonly actions: ReadonlyArray<string>\n\treadonly resources: ReadonlyArray<string>\n\treadonly when?: Condition.Encoded\n\treadonly fields?: ReadonlyArray<string>\n\treadonly reason?: string\n\treadonly id?: string\n\treadonly meta?: unknown\n}\n\n/**\n * The JSON form of a policy.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type EncodedNode =\n\t| {\n\t\t\treadonly _tag: \"Rules\"\n\t\t\treadonly algorithm: Algorithm\n\t\t\treadonly rules: ReadonlyArray<EncodedRule>\n\t }\n\t| {\n\t\t\treadonly _tag: \"All\" | \"Any\" | \"FirstOf\"\n\t\t\treadonly policies: ReadonlyArray<EncodedNode>\n\t }\n\t| {\n\t\t\treadonly _tag: \"Ceiling\"\n\t\t\treadonly cap: EncodedNode\n\t\t\treadonly policy: EncodedNode\n\t }\n\n/**\n * The Schema of the policies of a domain with no predicates. Decoding checks\n * every kind, action, field and principal field against the domain, and the\n * `meta` of each rule against the `meta` Schema of the domain.\n *\n * The decoder takes the limits of the domain: at most `policyNodes` nodes\n * of the tree, `conditionNodes` nodes of each condition, and `jsonNodes`\n * objects and array items, with a shared object counted for each place. It\n * stops at the first one past a limit. It takes any number of levels, and it\n * reads only the own data fields of the input.\n *\n * @stability stable\n * @category schemas\n * @since 0.3.0\n */\nexport const schema: <D extends Domain.Any>(\n\tdomain: D,\n) => Schema.Codec<Policy<D>, EncodedNode> = Internal.schema as never\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAioBA,MAAa,WAAiC,WAC7CA,UAAiB,MAAM;;;;;;;;;;;;;;;AAgBxB,MAAa,OAGgBC;;;;;;;;;;;AAwB7B,MAAa,cAA2CC;;;;;;;;;;;;;;;;;;;AAgCxD,MAAa,SAKwBC;;;;;;;;;AAerC,MAAa,MAEwBC,QAAiB,KAAK;;;;;;;;AAS3D,MAAa,MAEwBA,QAAiB,KAAK;;;;;;;;AAS3D,MAAa,UAEwBA,QAAiB,SAAS;;;;;;;;;AAU/D,MAAa,UAQTC;;;;;;;;;AAUJ,MAAa,iBAWTC;;;;;;;;AAWJ,MAAa,SAWTC;;;;;;;;AASJ,MAAa,aAMYC;;;;;;;;;;;AAYzB,MAAa,UAQZC;;;;;;;;;;;;;;AAeD,MAAa,kBAOTC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDJ,MAAa,WAQZC;;;;;;;;;;;;;;;;;;;;AAsDD,MAAa,WAOqCC;;;;;;;;;;;;;;;;AA4DlD,MAAa,SAE+BC"}
@@ -358,21 +358,24 @@ const provide = (node, context) => run(node.depth, (R) => {
358
358
  });
359
359
  /** The fields that a condition tests, in the order that they first come. */
360
360
  const fields = (node) => {
361
- const all = run(node.depth, (R) => {
361
+ const seen = /* @__PURE__ */ new Set();
362
+ run(node.depth, (R) => {
362
363
  const go = (current) => {
363
364
  switch (current._tag) {
364
365
  case "Compare":
365
366
  case "In":
366
- case "Exists": return R.succeed([current.field]);
367
+ case "Exists":
368
+ seen.add(current.field);
369
+ return R.succeed(void 0);
367
370
  case "And":
368
- case "Or": return R.map(eachChild(R, current.conditions, go), Arr.flatten);
371
+ case "Or": return R.map(eachChild(R, current.conditions, go), () => void 0);
369
372
  case "Not": return R.suspend(() => go(current.condition));
370
- default: return R.succeed([]);
373
+ default: return R.succeed(void 0);
371
374
  }
372
375
  };
373
376
  return go(node);
374
377
  });
375
- return Array.from(new Set(all));
378
+ return Array.from(seen);
376
379
  };
377
380
  export { and, evaluate, evaluateSync, fields, keyOf, not, or, partial, provide, simplify, testCompare };
378
381