@nmnmcc/ability 0.3.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +199 -31
- package/dist/Authorizer.d.ts +64 -39
- package/dist/Authorizer.d.ts.map +1 -1
- package/dist/Authorizer.js +291 -6
- package/dist/Authorizer.js.map +1 -1
- package/dist/Condition.d.ts +444 -65
- package/dist/Condition.d.ts.map +1 -1
- package/dist/Condition.js +1007 -25
- package/dist/Condition.js.map +1 -1
- package/dist/Domain.d.ts +27 -17
- package/dist/Domain.d.ts.map +1 -1
- package/dist/Domain.js +52 -10
- package/dist/Domain.js.map +1 -1
- package/dist/HttpApi.d.ts +84 -40
- package/dist/HttpApi.d.ts.map +1 -1
- package/dist/HttpApi.js +103 -13
- package/dist/HttpApi.js.map +1 -1
- package/dist/Policy.d.ts +314 -56
- package/dist/Policy.d.ts.map +1 -1
- package/dist/Policy.js +1215 -38
- package/dist/Policy.js.map +1 -1
- package/dist/Principal.js +2 -2
- package/dist/Principal.js.map +1 -1
- package/dist/Resource.d.ts +171 -20
- package/dist/Resource.d.ts.map +1 -1
- package/dist/Resource.js +788 -15
- package/dist/Resource.js.map +1 -1
- package/dist/Rule.d.ts +115 -29
- package/dist/Rule.d.ts.map +1 -1
- package/dist/Rule.js +219 -12
- package/dist/Rule.js.map +1 -1
- package/dist/index.js +4 -4
- package/package.json +2 -2
- package/src/Authorizer.ts +625 -61
- package/src/Condition.ts +2403 -112
- package/src/Domain.ts +80 -23
- package/src/HttpApi.ts +225 -25
- package/src/Policy.ts +2836 -96
- package/src/Principal.ts +2 -2
- package/src/Resource.ts +1544 -29
- package/src/Rule.ts +463 -45
- package/dist/internal/authorizer.d.ts +0 -28
- package/dist/internal/authorizer.d.ts.map +0 -1
- package/dist/internal/authorizer.js +0 -153
- package/dist/internal/authorizer.js.map +0 -1
- package/dist/internal/condition.d.ts +0 -11
- package/dist/internal/condition.d.ts.map +0 -1
- package/dist/internal/condition.js +0 -393
- package/dist/internal/condition.js.map +0 -1
- package/dist/internal/domain.js +0 -34
- package/dist/internal/domain.js.map +0 -1
- package/dist/internal/httpApi.js +0 -41
- package/dist/internal/httpApi.js.map +0 -1
- package/dist/internal/policy.js +0 -524
- package/dist/internal/policy.js.map +0 -1
- package/dist/internal/resource.js +0 -66
- package/dist/internal/resource.js.map +0 -1
- package/dist/internal/rule.js +0 -131
- package/dist/internal/rule.js.map +0 -1
- package/src/internal/authorizer.ts +0 -271
- package/src/internal/condition.ts +0 -607
- package/src/internal/domain.ts +0 -56
- package/src/internal/httpApi.ts +0 -84
- package/src/internal/policy.ts +0 -815
- package/src/internal/resource.ts +0 -98
- package/src/internal/rule.ts +0 -203
package/dist/Policy.d.ts
CHANGED
|
@@ -1,27 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Descriptor } from "./Resource.js";
|
|
2
|
+
import { Builder, Condition, Encoded, Example, FieldSelector, Reads, Variance } from "./Condition.js";
|
|
2
3
|
import { ActionOf, Any as Any$1, DataOf, Kind, Principal, ValueOf } from "./Domain.js";
|
|
3
|
-
import { Any as Any$2, Builder, Error as Error$1, OpaqueOf as OpaqueOf$1, Services as Services$1 } from "./Rule.js";
|
|
4
|
+
import { Any as Any$2, Builder as Builder$1, Error as Error$1, OpaqueOf as OpaqueOf$1, Rule, Services as Services$1 } from "./Rule.js";
|
|
4
5
|
import { Decision } from "./Decision.js";
|
|
6
|
+
import * as Context from "effect/Context";
|
|
5
7
|
import * as Effect from "effect/Effect";
|
|
6
|
-
import * as Equal from "effect/Equal";
|
|
7
8
|
import * as Schema from "effect/Schema";
|
|
8
|
-
import * as
|
|
9
|
+
import * as Data from "effect/Data";
|
|
9
10
|
import * as Pipeable from "effect/Pipeable";
|
|
10
11
|
declare namespace Policy_d_exports {
|
|
11
|
-
export { Algorithm, AllNode, Any, AnyNode, AnyRequest, CeilingNode, DomainOf, EncodedNode, EncodedRule, Error, Explanation, FirstOfNode, KindRequest, KindTarget, Node, OpaqueOf, Options, Policy, Request, RulesNode, Services, Step, Target,
|
|
12
|
+
export { Algorithm, AllNode, Any, AnyKindRequest, AnyNode, AnyRequest, CeilingNode, Coverage, DomainOf, EncodedNode, EncodedRule, Error, Explanation, FieldlessRequest, FieldlessTarget, FirstOfNode, KindRequest, KindTarget, Node, OpaqueOf, Options, Policy, Request, ResidualReads, Residuals, RulesNode, Scope, Services, Step, Target, TypedNode, all, any, ceiling, coverage, decide, decideSync, define, empty, explain, firstOf, fitsKind, isPolicy, permittedFields, provideContext, residual, residuals, rules, schema, scopeHasValue, scopeIsEmpty };
|
|
12
13
|
}
|
|
13
|
-
/**
|
|
14
|
-
* @stability stable
|
|
15
|
-
* @category type IDs
|
|
16
|
-
* @since 0.3.0
|
|
17
|
-
*/
|
|
18
|
-
export declare const TypeId: "~@nmnmcc/ability/Policy";
|
|
19
|
-
/**
|
|
20
|
-
* @stability stable
|
|
21
|
-
* @category type IDs
|
|
22
|
-
* @since 0.3.0
|
|
23
|
-
*/
|
|
24
|
-
export type TypeId = typeof TypeId;
|
|
25
14
|
/**
|
|
26
15
|
* @stability stable
|
|
27
16
|
* @category models
|
|
@@ -83,6 +72,30 @@ export interface CeilingNode {
|
|
|
83
72
|
* @since 0.3.0
|
|
84
73
|
*/
|
|
85
74
|
export type Node = RulesNode | AllNode | AnyNode | FirstOfNode | CeilingNode;
|
|
75
|
+
/**
|
|
76
|
+
* The tree of a policy with the types of its predicates and its domain `D`.
|
|
77
|
+
* Each rule and each child has the types too, and `"~Node"` is only in the types. A node made by
|
|
78
|
+
* hand does not have it. So the node of one policy, or a part of it, can not
|
|
79
|
+
* go into a policy with other types.
|
|
80
|
+
*
|
|
81
|
+
* @stability stable
|
|
82
|
+
* @category models
|
|
83
|
+
* @since 1.0.0
|
|
84
|
+
*/
|
|
85
|
+
export type TypedNode<E = never, R = never, O = never, D = any> = ({
|
|
86
|
+
readonly _tag: "Rules";
|
|
87
|
+
readonly algorithm: Algorithm;
|
|
88
|
+
readonly rules: ReadonlyArray<Rule<E, R, O, D, never>>;
|
|
89
|
+
} | {
|
|
90
|
+
readonly _tag: "All" | "Any" | "FirstOf";
|
|
91
|
+
readonly policies: ReadonlyArray<TypedNode<E, R, O, D>>;
|
|
92
|
+
} | {
|
|
93
|
+
readonly _tag: "Ceiling";
|
|
94
|
+
readonly cap: TypedNode<E, R, O, D>;
|
|
95
|
+
readonly policy: TypedNode<E, R, O, D>;
|
|
96
|
+
}) & {
|
|
97
|
+
readonly "~Node": Variance<E, R, O>;
|
|
98
|
+
};
|
|
86
99
|
/**
|
|
87
100
|
* A policy for the domain `D`. `E`, `R` and `O` come from the conditions of
|
|
88
101
|
* its rules. See `Condition.Condition`.
|
|
@@ -91,11 +104,15 @@ export type Node = RulesNode | AllNode | AnyNode | FirstOfNode | CeilingNode;
|
|
|
91
104
|
* @category models
|
|
92
105
|
* @since 0.3.0
|
|
93
106
|
*/
|
|
94
|
-
export interface Policy<D extends Any$1, E = never, R = never, O = never> extends
|
|
95
|
-
readonly [TypeId]: TypeId;
|
|
107
|
+
export interface Policy<D extends Any$1, E = never, R = never, O = never> extends Pipeable.Pipeable {
|
|
96
108
|
readonly domain: D;
|
|
97
|
-
readonly node:
|
|
98
|
-
readonly "~Policy"
|
|
109
|
+
readonly node: TypedNode<E, R, O, D>;
|
|
110
|
+
readonly "~Policy": Variance<E, R, O>;
|
|
111
|
+
/**
|
|
112
|
+
* Only in the types. A policy reads the values and the principal of its
|
|
113
|
+
* domain, so a policy of one domain is not a policy of a wider domain.
|
|
114
|
+
*/
|
|
115
|
+
readonly "~Domain": (domain: D) => D;
|
|
99
116
|
}
|
|
100
117
|
/**
|
|
101
118
|
* Any policy.
|
|
@@ -154,10 +171,36 @@ export type OpaqueOf<P> = P extends {
|
|
|
154
171
|
export type Target<D> = { [K in Kind<D>]: {
|
|
155
172
|
readonly action: ActionOf<D, K>;
|
|
156
173
|
readonly resource: ValueOf<D, K>;
|
|
157
|
-
readonly field?:
|
|
174
|
+
readonly field?: FieldSelector<DataOf<D, K>>;
|
|
175
|
+
/** A target has a resource value or a kind, never both. */
|
|
176
|
+
readonly kind?: never;
|
|
177
|
+
}; }[Kind<D>];
|
|
178
|
+
/**
|
|
179
|
+
* A {@link Target} with no field. Each kind keeps its own actions.
|
|
180
|
+
*
|
|
181
|
+
* @stability stable
|
|
182
|
+
* @category models
|
|
183
|
+
* @since 0.3.0
|
|
184
|
+
*/
|
|
185
|
+
export type FieldlessTarget<D> = { [K in Kind<D>]: {
|
|
186
|
+
readonly action: ActionOf<D, K>;
|
|
187
|
+
readonly resource: ValueOf<D, K>;
|
|
188
|
+
readonly kind?: never;
|
|
158
189
|
}; }[Kind<D>];
|
|
159
190
|
/**
|
|
160
|
-
*
|
|
191
|
+
* A scope: a part of a kind, as a condition on its values. It gets a builder
|
|
192
|
+
* with the types of the kind and of the principal, like the condition of a
|
|
193
|
+
* rule. A scope is plain data, so it can not have a predicate.
|
|
194
|
+
*
|
|
195
|
+
* @stability stable
|
|
196
|
+
* @category models
|
|
197
|
+
* @since 1.0.0
|
|
198
|
+
*/
|
|
199
|
+
export type Scope<D, K extends string> = (builder: Builder<DataOf<D, K>, ValueOf<D, K>, Principal<D>>) => Condition<never, never, never, Reads<ValueOf<D, K>, Principal<D>>>;
|
|
200
|
+
/**
|
|
201
|
+
* One act on one kind of resource, with no value. With `within`, the target is
|
|
202
|
+
* only the values of the kind in the scope. Without it, the target is every
|
|
203
|
+
* value of the kind.
|
|
161
204
|
*
|
|
162
205
|
* @stability stable
|
|
163
206
|
* @category models
|
|
@@ -166,7 +209,11 @@ export type Target<D> = { [K in Kind<D>]: {
|
|
|
166
209
|
export type KindTarget<D> = { [K in Kind<D>]: {
|
|
167
210
|
readonly action: ActionOf<D, K>;
|
|
168
211
|
readonly kind: K;
|
|
169
|
-
readonly field?:
|
|
212
|
+
readonly field?: FieldSelector<DataOf<D, K>>;
|
|
213
|
+
/** The part of the kind. See {@link Scope}. */
|
|
214
|
+
readonly within?: Scope<D, K>;
|
|
215
|
+
/** A target has a resource value or a kind, never both. */
|
|
216
|
+
readonly resource?: never;
|
|
170
217
|
}; }[Kind<D>];
|
|
171
218
|
/**
|
|
172
219
|
* A request: a principal, an action, and a resource value.
|
|
@@ -178,6 +225,16 @@ export type KindTarget<D> = { [K in Kind<D>]: {
|
|
|
178
225
|
export type Request<D> = Target<D> & {
|
|
179
226
|
readonly principal: Principal<D>;
|
|
180
227
|
};
|
|
228
|
+
/**
|
|
229
|
+
* A {@link Request} with no field.
|
|
230
|
+
*
|
|
231
|
+
* @stability stable
|
|
232
|
+
* @category models
|
|
233
|
+
* @since 0.3.0
|
|
234
|
+
*/
|
|
235
|
+
export type FieldlessRequest<D> = FieldlessTarget<D> & {
|
|
236
|
+
readonly principal: Principal<D>;
|
|
237
|
+
};
|
|
181
238
|
/**
|
|
182
239
|
* A request about a kind of resource, with no value.
|
|
183
240
|
*
|
|
@@ -237,6 +294,14 @@ export interface Options {
|
|
|
237
294
|
/** The default is `denyOverrides`. */
|
|
238
295
|
readonly algorithm?: Algorithm;
|
|
239
296
|
}
|
|
297
|
+
/**
|
|
298
|
+
* Makes a policy from a list of rules.
|
|
299
|
+
*
|
|
300
|
+
* @stability stable
|
|
301
|
+
* @category constructors
|
|
302
|
+
* @since 0.3.0
|
|
303
|
+
*/
|
|
304
|
+
export declare const rules: <D extends Any$1, Rules extends Rule<any, any, any, D, never>>(domain: D, rules: Iterable<Rules>, options?: Options) => Policy<D, Error$1<Rules>, Services$1<Rules>, OpaqueOf$1<Rules>>;
|
|
240
305
|
/**
|
|
241
306
|
* Makes a policy from a generator function that gives rules. It is pure and it
|
|
242
307
|
* gives its result at once.
|
|
@@ -244,9 +309,9 @@ export interface Options {
|
|
|
244
309
|
* @example
|
|
245
310
|
* ```ts
|
|
246
311
|
* const policy = Policy.define(App)(function* (_) {
|
|
247
|
-
* yield* _.allow("read",
|
|
248
|
-
* yield* _.allow(["update", "delete"],
|
|
249
|
-
* when: ($) => $.eq("
|
|
312
|
+
* yield* _.allow("read", Document)
|
|
313
|
+
* yield* _.allow(["update", "delete"], Document, {
|
|
314
|
+
* when: ($) => $.eq("ownerId", $.principal("id")),
|
|
250
315
|
* })
|
|
251
316
|
* })
|
|
252
317
|
* ```
|
|
@@ -255,15 +320,7 @@ export interface Options {
|
|
|
255
320
|
* @category constructors
|
|
256
321
|
* @since 0.3.0
|
|
257
322
|
*/
|
|
258
|
-
export declare const define: <D extends Any$1>(domain: D, options?: Options) => <Rules extends
|
|
259
|
-
/**
|
|
260
|
-
* Makes a policy from a list of rules.
|
|
261
|
-
*
|
|
262
|
-
* @stability stable
|
|
263
|
-
* @category constructors
|
|
264
|
-
* @since 0.3.0
|
|
265
|
-
*/
|
|
266
|
-
export declare const rules: <D extends Any$1, Rules extends Any$2>(domain: D, rules: Iterable<Rules>, options?: Options) => Policy<D, Error$1<Rules>, Services$1<Rules>, OpaqueOf$1<Rules>>;
|
|
323
|
+
export declare const define: <D extends Any$1>(domain: D, options?: Options) => <Rules extends Rule<any, any, any, D, never>, A>(body: (builder: Builder$1<D>) => Generator<Rules, A, unknown>) => Policy<D, Error$1<Rules>, Services$1<Rules>, OpaqueOf$1<Rules>>;
|
|
267
324
|
/**
|
|
268
325
|
* A policy with no rules. It is not applicable to any request.
|
|
269
326
|
*
|
|
@@ -310,6 +367,33 @@ export declare const ceiling: {
|
|
|
310
367
|
<D extends Any$1, E2, R2, O2>(cap: Policy<D, E2, R2, O2>): <E, R, O>(policy: Policy<D, E, R, O>) => Policy<D, E | E2, R | R2, O | O2>;
|
|
311
368
|
<D extends Any$1, E, R, O, E2, R2, O2>(policy: Policy<D, E, R, O>, cap: Policy<D, E2, R2, O2>): Policy<D, E | E2, R | R2, O | O2>;
|
|
312
369
|
};
|
|
370
|
+
/**
|
|
371
|
+
* Gives the services in `context` to every predicate of a policy, so the
|
|
372
|
+
* policy needs no services when it runs.
|
|
373
|
+
*
|
|
374
|
+
* @stability stable
|
|
375
|
+
* @category services
|
|
376
|
+
* @since 1.0.0
|
|
377
|
+
*/
|
|
378
|
+
export declare const provideContext: {
|
|
379
|
+
<R>(context: Context.Context<R>): <D extends Any$1, E, O>(policy: Policy<D, E, R, O>) => Policy<D, E, never, O>;
|
|
380
|
+
<D extends Any$1, E, R, O>(policy: Policy<D, E, R, O>, context: Context.Context<R>): Policy<D, E, never, O>;
|
|
381
|
+
};
|
|
382
|
+
/**
|
|
383
|
+
* Tests if a request fits its kind: the action is an action of the kind, and
|
|
384
|
+
* the field, if there is one, is a field of the kind. The types check this,
|
|
385
|
+
* but a value with a union type, or a value from outside, may get past them.
|
|
386
|
+
* A rule for every action (`"*"`) must not cover an action that the kind does
|
|
387
|
+
* not have, so such a request is not applicable.
|
|
388
|
+
*
|
|
389
|
+
* @stability stable
|
|
390
|
+
* @category predicates
|
|
391
|
+
* @since 1.0.0
|
|
392
|
+
*/
|
|
393
|
+
export declare const fitsKind: (descriptor: Descriptor, request: {
|
|
394
|
+
readonly action: string;
|
|
395
|
+
readonly field?: string | undefined;
|
|
396
|
+
}) => boolean;
|
|
313
397
|
/**
|
|
314
398
|
* Gives the decision of a policy for a request.
|
|
315
399
|
*
|
|
@@ -318,7 +402,7 @@ export declare const ceiling: {
|
|
|
318
402
|
* @since 0.3.0
|
|
319
403
|
*/
|
|
320
404
|
export declare const decide: {
|
|
321
|
-
<D extends Any$1>(request: Request<D>): <E, R, O>(policy: Policy<D, E, R, O>) => Effect.Effect<Decision, E, R>;
|
|
405
|
+
<D extends Any$1 = never>(request: Request<D>): <E, R, O>(policy: Policy<D, E, R, O>) => Effect.Effect<Decision, E, R>;
|
|
322
406
|
<D extends Any$1, E, R, O>(policy: Policy<D, E, R, O>, request: Request<NoInfer<D>>): Effect.Effect<Decision, E, R>;
|
|
323
407
|
};
|
|
324
408
|
/**
|
|
@@ -329,47 +413,221 @@ export declare const decide: {
|
|
|
329
413
|
* @since 0.3.0
|
|
330
414
|
*/
|
|
331
415
|
export declare const decideSync: {
|
|
332
|
-
<D extends Any$1>(request: Request<D>): (policy: Policy<D>) => Decision;
|
|
416
|
+
<D extends Any$1 = never>(request: Request<D>): (policy: Policy<D>) => Decision;
|
|
333
417
|
<D extends Any$1>(policy: Policy<D>, request: Request<NoInfer<D>>): Decision;
|
|
334
418
|
};
|
|
335
419
|
/**
|
|
336
420
|
* Gives the decision of a policy and the rules that were tested to make it.
|
|
337
421
|
*
|
|
422
|
+
* One node may be a child of many nodes. A node with no predicate that the
|
|
423
|
+
* request may use gives the same decision each time, so its rules are tested,
|
|
424
|
+
* and are in the steps, only the first time. So a small tree with many shared
|
|
425
|
+
* nodes gives a short list of steps.
|
|
426
|
+
*
|
|
338
427
|
* @stability stable
|
|
339
428
|
* @category evaluation
|
|
340
429
|
* @since 0.3.0
|
|
341
430
|
*/
|
|
342
431
|
export declare const explain: {
|
|
343
|
-
<D extends Any$1>(request: Request<D>): <E, R, O>(policy: Policy<D, E, R, O>) => Effect.Effect<Explanation, E, R>;
|
|
432
|
+
<D extends Any$1 = never>(request: Request<D>): <E, R, O>(policy: Policy<D, E, R, O>) => Effect.Effect<Explanation, E, R>;
|
|
344
433
|
<D extends Any$1, E, R, O>(policy: Policy<D, E, R, O>, request: Request<NoInfer<D>>): Effect.Effect<Explanation, E, R>;
|
|
345
434
|
};
|
|
435
|
+
/**
|
|
436
|
+
* Gives the fields of a resource value that the policy lets a request use. It
|
|
437
|
+
* tests each field of the resource Schema, with dots for nested fields.
|
|
438
|
+
*
|
|
439
|
+
* A field that holds more than one value, such as a record, is left out when a
|
|
440
|
+
* deny rule names a part of it. The list can not name that part, and the whole
|
|
441
|
+
* field would show it.
|
|
442
|
+
*
|
|
443
|
+
* @stability stable
|
|
444
|
+
* @category evaluation
|
|
445
|
+
* @since 0.3.0
|
|
446
|
+
*/
|
|
447
|
+
export declare const permittedFields: {
|
|
448
|
+
<D extends Any$1 = never>(request: FieldlessRequest<D>): <E, R, O>(policy: Policy<D, E, R, O>) => Effect.Effect<ReadonlyArray<string>, E, R>;
|
|
449
|
+
<D extends Any$1, E, R, O>(policy: Policy<D, E, R, O>, request: FieldlessRequest<NoInfer<D>>): Effect.Effect<ReadonlyArray<string>, E, R>;
|
|
450
|
+
};
|
|
451
|
+
/**
|
|
452
|
+
* The two residual conditions of a request. See {@link residuals}.
|
|
453
|
+
*
|
|
454
|
+
* @stability stable
|
|
455
|
+
* @category models
|
|
456
|
+
* @since 1.0.0
|
|
457
|
+
*/
|
|
458
|
+
export interface Residuals<E = never, R = never, O = never, I = unknown> {
|
|
459
|
+
/** The condition on resource values for which the policy allows. */
|
|
460
|
+
readonly allow: Condition<E, R, O, I>;
|
|
461
|
+
/** The condition on resource values for which the policy denies. */
|
|
462
|
+
readonly deny: Condition<E, R, O, I>;
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* A request about a kind of resource, with no types.
|
|
466
|
+
*
|
|
467
|
+
* @stability stable
|
|
468
|
+
* @category models
|
|
469
|
+
* @since 1.0.0
|
|
470
|
+
*/
|
|
471
|
+
export interface AnyKindRequest {
|
|
472
|
+
readonly principal: object;
|
|
473
|
+
readonly action: string;
|
|
474
|
+
readonly kind: string;
|
|
475
|
+
readonly field?: string | undefined;
|
|
476
|
+
/**
|
|
477
|
+
* A scope needs the types of the domain for its builder. With the request
|
|
478
|
+
* first, the domain is not known yet, so give the policy first.
|
|
479
|
+
*/
|
|
480
|
+
readonly within?: never;
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* `unknown` when the request `Req` is a request of the type `T`, and `never`
|
|
484
|
+
* when it is not. With the request first and the policy later, the request is
|
|
485
|
+
* checked when the policy, and so the domain, is known. For a union, each
|
|
486
|
+
* member must be such a request.
|
|
487
|
+
*/
|
|
488
|
+
type Fits<Req, T> = [Req] extends [T] ? unknown : never;
|
|
489
|
+
/**
|
|
490
|
+
* What a residual condition reads: a value of the kind `K`. The principal is
|
|
491
|
+
* already in it. A residual is for one kind, so when `K` is a union of kinds,
|
|
492
|
+
* the value must be a value of each of them. No value is, so such a residual
|
|
493
|
+
* can not be evaluated on a value of the wrong kind.
|
|
494
|
+
*
|
|
495
|
+
* @stability stable
|
|
496
|
+
* @category utility types
|
|
497
|
+
* @since 1.0.0
|
|
498
|
+
*/
|
|
499
|
+
export type ResidualReads<D, K> = Reads<(K extends unknown ? (value: ValueOf<D, K & string>) => void : never) extends ((value: infer V) => void) ? V : never, unknown>;
|
|
500
|
+
/** A request about a kind with no types, with the scope of a target. */
|
|
501
|
+
interface ScopedRequest {
|
|
502
|
+
readonly principal: object;
|
|
503
|
+
readonly action: string;
|
|
504
|
+
readonly kind: string;
|
|
505
|
+
readonly field?: string | undefined;
|
|
506
|
+
readonly within?: unknown;
|
|
507
|
+
}
|
|
346
508
|
/**
|
|
347
509
|
* Gives the condition on resource values for which the policy allows a
|
|
348
510
|
* request. It has no principal fields and no `Under` nodes, so you can give it
|
|
349
511
|
* to `Condition.fold`. It is `True` when the policy allows every value of the
|
|
350
512
|
* kind, and `False` when it allows none.
|
|
351
513
|
*
|
|
352
|
-
*
|
|
514
|
+
* With a scope (`within`), the condition is the scope and the residual
|
|
515
|
+
* together, so it is false for every value outside the scope. Give the policy
|
|
516
|
+
* first to use a scope. The condition comes from its parts, with no search. To
|
|
517
|
+
* know if it allows all of the scope or none of it, use {@link coverage}.
|
|
518
|
+
*
|
|
519
|
+
* When a rule that the request may use has a predicate, the condition is one
|
|
520
|
+
* predicate with the name `"policy"`. It runs the whole policy for each value,
|
|
521
|
+
* so its answers and its failures are the same as those of {@link decide}. It
|
|
522
|
+
* takes the principal with it. Give it resource values with their `_tag`. It
|
|
523
|
+
* is false for a value of another kind.
|
|
524
|
+
*
|
|
525
|
+
* A policy tree may use the condition of a child two times, so a small policy
|
|
526
|
+
* may give a very large condition. When the condition would have more than
|
|
527
|
+
* 10000 nodes or 500 levels, this function throws an error. In an
|
|
528
|
+
* `Authorizer`, the error is
|
|
529
|
+
* a defect, so the check fails.
|
|
353
530
|
*
|
|
354
531
|
* @stability stable
|
|
355
532
|
* @category evaluation
|
|
356
533
|
* @since 0.3.0
|
|
357
534
|
*/
|
|
358
535
|
export declare const residual: {
|
|
359
|
-
<
|
|
360
|
-
<D extends Any$1, E, R, O
|
|
536
|
+
<const Req extends AnyKindRequest>(request: Req): <D extends Any$1, E, R, O>(policy: Policy<D, E, R, O> & Fits<Req, KindRequest<D>>) => Condition<E, R, O, ResidualReads<D, Req["kind"]>>;
|
|
537
|
+
<D extends Any$1, E, R, O, const Req extends KindRequest<NoInfer<D>>>(policy: Policy<D, E, R, O>, request: Req): Condition<E, R, O, ResidualReads<D, Req["kind"]>>;
|
|
361
538
|
};
|
|
362
539
|
/**
|
|
363
|
-
* Gives
|
|
364
|
-
*
|
|
540
|
+
* Gives both residual conditions of a request: the values that the policy
|
|
541
|
+
* allows, and the values that it denies. A value in neither is not
|
|
542
|
+
* applicable. See {@link residual}.
|
|
365
543
|
*
|
|
366
544
|
* @stability stable
|
|
367
545
|
* @category evaluation
|
|
368
|
-
* @since 0.
|
|
546
|
+
* @since 1.0.0
|
|
369
547
|
*/
|
|
370
|
-
export declare const
|
|
371
|
-
<
|
|
372
|
-
<D extends Any$1, E, R, O
|
|
548
|
+
export declare const residuals: {
|
|
549
|
+
<const Req extends AnyKindRequest>(request: Req): <D extends Any$1, E, R, O>(policy: Policy<D, E, R, O> & Fits<Req, KindRequest<D>>) => Residuals<E, R, O, ResidualReads<D, Req["kind"]>>;
|
|
550
|
+
<D extends Any$1, E, R, O, const Req extends KindRequest<NoInfer<D>>>(policy: Policy<D, E, R, O>, request: Req): Residuals<E, R, O, ResidualReads<D, Req["kind"]>>;
|
|
551
|
+
};
|
|
552
|
+
/**
|
|
553
|
+
* How much of a scope a policy allows. In each case, `condition` is the exact
|
|
554
|
+
* condition on the values in the scope that the policy allows: give it to
|
|
555
|
+
* `Condition.fold` for a list query.
|
|
556
|
+
* - `All`: the policy allows every value in the scope. `condition` is the
|
|
557
|
+
* scope (`True` with no scope).
|
|
558
|
+
* - `None`: the policy allows no value in the scope. `condition` is `False`.
|
|
559
|
+
* An empty scope is `None` too, so a check on a scope that has a mistake,
|
|
560
|
+
* such as a principal field with no value, never passes.
|
|
561
|
+
* - `Some`: the policy allows some values in the scope and not others.
|
|
562
|
+
* `allowed` is an example of a value that it allows, and `refused` of a
|
|
563
|
+
* value in the scope that it does not allow.
|
|
564
|
+
* - `Unknown`: the answer needs a predicate, or the search went past its
|
|
565
|
+
* budget.
|
|
566
|
+
*
|
|
567
|
+
* @stability stable
|
|
568
|
+
* @category models
|
|
569
|
+
* @since 1.0.0
|
|
570
|
+
*/
|
|
571
|
+
export type Coverage<E = never, R = never, O = never, I = unknown> = Data.TaggedEnum<{
|
|
572
|
+
All: {
|
|
573
|
+
readonly condition: Condition<E, R, O, I>;
|
|
574
|
+
};
|
|
575
|
+
None: {
|
|
576
|
+
readonly condition: Condition<E, R, O, I>;
|
|
577
|
+
};
|
|
578
|
+
Some: {
|
|
579
|
+
readonly condition: Condition<E, R, O, I>;
|
|
580
|
+
readonly allowed: Example;
|
|
581
|
+
readonly refused: Example;
|
|
582
|
+
};
|
|
583
|
+
Unknown: {
|
|
584
|
+
readonly condition: Condition<E, R, O, I>;
|
|
585
|
+
readonly reason: "predicate" | "budget" | "schema";
|
|
586
|
+
};
|
|
587
|
+
}>;
|
|
588
|
+
/**
|
|
589
|
+
* Tests if the scope of a request has a value of the Schema of its kind. The
|
|
590
|
+
* answer is `true` only when the search finds such a value. When the search
|
|
591
|
+
* can not say, the answer is `false`. So a "yes" from it is safe to act on,
|
|
592
|
+
* as for the question "may the decider answer for this scope?".
|
|
593
|
+
*
|
|
594
|
+
* @stability stable
|
|
595
|
+
* @category evaluation
|
|
596
|
+
* @since 1.0.0
|
|
597
|
+
*/
|
|
598
|
+
export declare const scopeHasValue: (policy: Any, request: ScopedRequest) => boolean;
|
|
599
|
+
/**
|
|
600
|
+
* Tests if the scope of a request has no value of the Schema of its kind. A
|
|
601
|
+
* scope with a mistake, such as two values for one field, is empty. With no
|
|
602
|
+
* scope, the answer is `false` when the kind has a value. When the search can
|
|
603
|
+
* not say, the answer is `false`.
|
|
604
|
+
*
|
|
605
|
+
* @stability stable
|
|
606
|
+
* @category evaluation
|
|
607
|
+
* @since 1.0.0
|
|
608
|
+
*/
|
|
609
|
+
export declare const scopeIsEmpty: (policy: Any, request: ScopedRequest) => boolean;
|
|
610
|
+
/**
|
|
611
|
+
* Tells how much of a scope the policy allows: all of it, none of it, or some
|
|
612
|
+
* of it. See {@link Coverage}. With no scope (`within`), the scope is every
|
|
613
|
+
* value of the kind.
|
|
614
|
+
*
|
|
615
|
+
* The answer comes from {@link Condition.satisfiable} with the Schema of the
|
|
616
|
+
* resource, so it is exact for the values of the Schema. When a condition
|
|
617
|
+
* tests a field that is not a plain scalar (see `Resource.isPlainField`),
|
|
618
|
+
* such as a field with a check other than a finite or integer check, the
|
|
619
|
+
* answer is `Unknown`, and a check on the kind says no.
|
|
620
|
+
*
|
|
621
|
+
* `Some` means that some value of the Schema is allowed. It does not mean that
|
|
622
|
+
* such a value is in your database. To know that, run `condition` as a query.
|
|
623
|
+
*
|
|
624
|
+
* @stability stable
|
|
625
|
+
* @category evaluation
|
|
626
|
+
* @since 1.0.0
|
|
627
|
+
*/
|
|
628
|
+
export declare const coverage: {
|
|
629
|
+
<const Req extends AnyKindRequest>(request: Req): <D extends Any$1, E, R, O>(policy: Policy<D, E, R, O> & Fits<Req, KindRequest<D>>) => Coverage<E, R, O, ResidualReads<D, Req["kind"]>>;
|
|
630
|
+
<D extends Any$1, E, R, O, const Req extends KindRequest<NoInfer<D>>>(policy: Policy<D, E, R, O>, request: Req): Coverage<E, R, O, ResidualReads<D, Req["kind"]>>;
|
|
373
631
|
};
|
|
374
632
|
/**
|
|
375
633
|
* The JSON form of a rule.
|
|
@@ -408,22 +666,22 @@ export type EncodedNode = {
|
|
|
408
666
|
readonly policy: EncodedNode;
|
|
409
667
|
};
|
|
410
668
|
/**
|
|
411
|
-
*
|
|
412
|
-
* every kind, action, field and principal field against the domain, and the
|
|
413
|
-
* `meta` of each rule against the `meta` Schema of the domain.
|
|
669
|
+
* Tests if a value is a policy.
|
|
414
670
|
*
|
|
415
671
|
* @stability stable
|
|
416
|
-
* @category
|
|
672
|
+
* @category guards
|
|
417
673
|
* @since 0.3.0
|
|
418
674
|
*/
|
|
419
|
-
export declare const
|
|
675
|
+
export declare const isPolicy: (u: unknown) => u is Any;
|
|
420
676
|
/**
|
|
421
|
-
*
|
|
677
|
+
* The Schema of the policies of a domain with no predicates. Decoding checks
|
|
678
|
+
* every kind, action, field and principal field against the domain, and the
|
|
679
|
+
* `meta` of each rule against the `meta` Schema of the domain.
|
|
422
680
|
*
|
|
423
681
|
* @stability stable
|
|
424
|
-
* @category
|
|
682
|
+
* @category schemas
|
|
425
683
|
* @since 0.3.0
|
|
426
684
|
*/
|
|
427
|
-
export declare const
|
|
685
|
+
export declare const schema: <D extends Any$1>(domain: D) => Schema.Codec<Policy<D>, EncodedNode>;
|
|
428
686
|
export { Policy_d_exports };
|
|
429
687
|
//# sourceMappingURL=Policy.d.ts.map
|
package/dist/Policy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Policy.d.ts","names":["Rule.Any","
|
|
1
|
+
{"version":3,"file":"Policy.d.ts","names":["Rule.Any","Rule.Rule","Condition.Variance","Domain.Any","Domain.Kind","Domain.ActionOf","Domain.ValueOf","Domain.DataOf","Condition.FieldSelector","Domain.Principal","Condition.Builder","Condition.Reads","Condition.Condition","Decision.Decision","Rule.Error","Rule.Services","Rule.OpaqueOf","Rule.Builder","Resource.Descriptor","Condition.Example","Condition.Encoded"],"sources":["../src/Policy.ts"],"mappings":"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"}
|