@nmnmcc/ability 1.0.1 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +112 -69
- package/dist/Authorizer.d.ts +43 -47
- package/dist/Authorizer.d.ts.map +1 -1
- package/dist/Authorizer.js +5 -290
- package/dist/Authorizer.js.map +1 -1
- package/dist/Condition.d.ts +164 -332
- package/dist/Condition.d.ts.map +1 -1
- package/dist/Condition.js +75 -890
- package/dist/Condition.js.map +1 -1
- package/dist/Decision.d.ts +13 -13
- package/dist/Decision.d.ts.map +1 -1
- package/dist/Decision.js.map +1 -1
- package/dist/Domain.d.ts +10 -21
- package/dist/Domain.d.ts.map +1 -1
- package/dist/Domain.js +4 -62
- package/dist/Domain.js.map +1 -1
- package/dist/HttpApi.d.ts +31 -7
- package/dist/HttpApi.d.ts.map +1 -1
- package/dist/HttpApi.js +25 -8
- package/dist/HttpApi.js.map +1 -1
- package/dist/Limits.d.ts +114 -0
- package/dist/Limits.d.ts.map +1 -0
- package/dist/Limits.js +132 -0
- package/dist/Limits.js.map +1 -0
- package/dist/Policy.d.ts +276 -269
- package/dist/Policy.d.ts.map +1 -1
- package/dist/Policy.js +73 -1177
- package/dist/Policy.js.map +1 -1
- package/dist/Resource.d.ts +4 -177
- package/dist/Resource.d.ts.map +1 -1
- package/dist/Resource.js +4 -803
- package/dist/Resource.js.map +1 -1
- package/dist/index.d.ts +3 -4
- package/dist/index.js +4 -5
- package/dist/internal/algebra.js +267 -0
- package/dist/internal/algebra.js.map +1 -0
- package/dist/internal/analysis.js +245 -0
- package/dist/internal/analysis.js.map +1 -0
- package/dist/internal/authorizer.d.ts +30 -0
- package/dist/internal/authorizer.d.ts.map +1 -0
- package/dist/internal/authorizer.js +221 -0
- package/dist/internal/authorizer.js.map +1 -0
- package/dist/internal/bind.js +311 -0
- package/dist/internal/bind.js.map +1 -0
- package/dist/internal/catalog.d.ts +56 -0
- package/dist/internal/catalog.d.ts.map +1 -0
- package/dist/internal/catalog.js +292 -0
- package/dist/internal/catalog.js.map +1 -0
- package/dist/internal/decide.js +166 -0
- package/dist/internal/decide.js.map +1 -0
- package/dist/internal/domain.js +32 -0
- package/dist/internal/domain.js.map +1 -0
- package/dist/internal/json.js +134 -0
- package/dist/internal/json.js.map +1 -0
- package/dist/internal/limits.d.ts +14 -0
- package/dist/internal/limits.d.ts.map +1 -0
- package/dist/internal/limits.js +43 -0
- package/dist/internal/limits.js.map +1 -0
- package/dist/internal/nodes.d.ts +121 -0
- package/dist/internal/nodes.d.ts.map +1 -0
- package/dist/internal/nodes.js +277 -0
- package/dist/internal/nodes.js.map +1 -0
- package/dist/internal/patterns.js +110 -0
- package/dist/internal/patterns.js.map +1 -0
- package/dist/internal/policy-json.js +265 -0
- package/dist/internal/policy-json.js.map +1 -0
- package/dist/internal/policy-nodes.d.ts +61 -0
- package/dist/internal/policy-nodes.d.ts.map +1 -0
- package/dist/internal/policy-nodes.js +146 -0
- package/dist/internal/policy-nodes.js.map +1 -0
- package/dist/internal/policy.d.ts +42 -0
- package/dist/internal/policy.d.ts.map +1 -0
- package/dist/internal/policy.js +124 -0
- package/dist/internal/policy.js.map +1 -0
- package/dist/internal/read.js +39 -0
- package/dist/internal/read.js.map +1 -0
- package/dist/internal/resource.js +115 -0
- package/dist/internal/resource.js.map +1 -0
- package/dist/internal/rule.d.ts +26 -0
- package/dist/internal/rule.d.ts.map +1 -0
- package/dist/internal/rule.js +103 -0
- package/dist/internal/rule.js.map +1 -0
- package/dist/internal/search.d.ts +22 -0
- package/dist/internal/search.d.ts.map +1 -0
- package/dist/internal/search.js +274 -0
- package/dist/internal/search.js.map +1 -0
- package/dist/internal/suggest.js +46 -0
- package/dist/internal/suggest.js.map +1 -0
- package/package.json +3 -4
- package/src/Authorizer.ts +67 -583
- package/src/Condition.ts +339 -2095
- package/src/Decision.ts +6 -5
- package/src/Domain.ts +12 -69
- package/src/HttpApi.ts +72 -10
- package/src/Limits.ts +132 -0
- package/src/Policy.ts +391 -2772
- package/src/Resource.ts +7 -1548
- package/src/index.ts +3 -9
- package/src/internal/algebra.ts +482 -0
- package/src/internal/analysis.ts +478 -0
- package/src/internal/authorizer.ts +418 -0
- package/src/internal/bind.ts +648 -0
- package/src/internal/catalog.ts +534 -0
- package/src/internal/decide.ts +402 -0
- package/src/internal/domain.ts +66 -0
- package/src/internal/json.ts +260 -0
- package/src/internal/limits.ts +78 -0
- package/src/internal/nodes.ts +404 -0
- package/src/internal/patterns.ts +211 -0
- package/src/internal/policy-json.ts +487 -0
- package/src/internal/policy-nodes.ts +207 -0
- package/src/internal/policy.ts +264 -0
- package/src/internal/read.ts +55 -0
- package/src/internal/resource.ts +180 -0
- package/src/internal/rule.ts +196 -0
- package/src/internal/search.ts +541 -0
- package/src/internal/suggest.ts +104 -0
- package/dist/Principal.d.ts +0 -35
- package/dist/Principal.d.ts.map +0 -1
- package/dist/Principal.js +0 -37
- package/dist/Principal.js.map +0 -1
- package/dist/Rule.d.ts +0 -275
- package/dist/Rule.d.ts.map +0 -1
- package/dist/Rule.js +0 -257
- package/dist/Rule.js.map +0 -1
- package/src/Principal.ts +0 -41
- package/src/Rule.ts +0 -683
package/dist/Principal.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { __exportAll } from "./_virtual/_rolldown/runtime.js";
|
|
2
|
-
import * as Schema from "effect/Schema";
|
|
3
|
-
// src/Principal.ts
|
|
4
|
-
/**
|
|
5
|
-
* A principal is the one who asks to do an act. It may be a person, an API
|
|
6
|
-
* token, or another service.
|
|
7
|
-
*
|
|
8
|
-
* A principal is a Schema. Make it with {@link Class}, in the same way as
|
|
9
|
-
* `Schema.Class`, or use any `Schema.Struct`. Conditions can use the fields of
|
|
10
|
-
* the principal. See `Condition.Builder.principal`.
|
|
11
|
-
*
|
|
12
|
-
* @stability stable
|
|
13
|
-
* @since 0.3.0
|
|
14
|
-
*/
|
|
15
|
-
var Principal_exports = /* @__PURE__ */ __exportAll({ Class: () => Class });
|
|
16
|
-
/**
|
|
17
|
-
* Makes a principal as a Schema class. It is the same as `Schema.Class`.
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* ```ts
|
|
21
|
-
* import { Schema } from "effect"
|
|
22
|
-
* import { Principal } from "@nmnmcc/ability"
|
|
23
|
-
*
|
|
24
|
-
* class Caller extends Principal.Class<Caller>("Caller")({
|
|
25
|
-
* userId: Schema.String,
|
|
26
|
-
* organizationId: Schema.String,
|
|
27
|
-
* }) {}
|
|
28
|
-
* ```
|
|
29
|
-
*
|
|
30
|
-
* @stability stable
|
|
31
|
-
* @category constructors
|
|
32
|
-
* @since 0.3.0
|
|
33
|
-
*/
|
|
34
|
-
const Class = Schema.Class;
|
|
35
|
-
export { Class, Principal_exports };
|
|
36
|
-
|
|
37
|
-
//# sourceMappingURL=Principal.js.map
|
package/dist/Principal.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Principal.js","names":[],"sources":["../src/Principal.ts"],"sourcesContent":["/**\n * A principal is the one who asks to do an act. It may be a person, an API\n * token, or another service.\n *\n * A principal is a Schema. Make it with {@link Class}, in the same way as\n * `Schema.Class`, or use any `Schema.Struct`. Conditions can use the fields of\n * the principal. See `Condition.Builder.principal`.\n *\n * @stability stable\n * @since 0.3.0\n */\nimport * as Schema from \"effect/Schema\"\n\n/**\n * Any Schema that can be a principal. Its type must be an object.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Any = Schema.Top & { readonly Type: object }\n\n/**\n * Makes a principal as a Schema class. It is the same as `Schema.Class`.\n *\n * @example\n * ```ts\n * import { Schema } from \"effect\"\n * import { Principal } from \"@nmnmcc/ability\"\n *\n * class Caller extends Principal.Class<Caller>(\"Caller\")({\n * userId: Schema.String,\n * organizationId: Schema.String,\n * }) {}\n * ```\n *\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const Class: typeof Schema.Class = Schema.Class\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,MAAa,QAA6B,OAAO"}
|
package/dist/Rule.d.ts
DELETED
|
@@ -1,275 +0,0 @@
|
|
|
1
|
-
import { Descriptor, Kind } from "./Resource.js";
|
|
2
|
-
import { Any as Any$1, Builder as Builder$1, Checked, Condition, Error as Error$1, FieldSelector, OpaqueOf as OpaqueOf$1, Reads, ReadsOf, Services as Services$1, Variance } from "./Condition.js";
|
|
3
|
-
import { ActionOf, Any as Any$2, AnyAction, AnyValue, CommonAction, DataOf, Kind as Kind$1, Meta, Principal, Resources, ValueOf } from "./Domain.js";
|
|
4
|
-
import * as Pipeable from "effect/Pipeable";
|
|
5
|
-
declare namespace Rule_d_exports {
|
|
6
|
-
export { ActionFor, ActionForTargets, Any, Builder, ConditionFor, DataFor, Error, FieldFor, KindOf, OpaqueOf, Options, Rule, Services, Shape, Target, TargetOf, ValueFor, builder, domainOf, isRule, make, matchesField, matchesInside, matchesTarget };
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* A rule. `E`, `R` and `O` come from its condition. See
|
|
10
|
-
* `Condition.Condition`. `D` is the domain of the rule. A predicate reads the
|
|
11
|
-
* values and the principal of its domain, so a rule may go only into a policy
|
|
12
|
-
* of its own domain. A rule from {@link make} has the domain `any`. `I` is
|
|
13
|
-
* what the predicates of its condition read. See `Condition.Reads`.
|
|
14
|
-
*
|
|
15
|
-
* @stability stable
|
|
16
|
-
* @category models
|
|
17
|
-
* @since 0.3.0
|
|
18
|
-
*/
|
|
19
|
-
export interface Rule<E = never, R = never, O = never, D = any, I = unknown> extends Shape<E, R, O, I>, Pipeable.Pipeable {
|
|
20
|
-
readonly "~Rule": Variance<E, R, O>;
|
|
21
|
-
readonly "~Domain": (domain: D) => D;
|
|
22
|
-
[Symbol.iterator](): Generator<Rule<E, R, O, D, I>, Rule<E, R, O, D, I>, unknown>;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* The data of a rule.
|
|
26
|
-
*
|
|
27
|
-
* @stability stable
|
|
28
|
-
* @category models
|
|
29
|
-
* @since 1.0.0
|
|
30
|
-
*/
|
|
31
|
-
export interface Shape<E = never, R = never, O = never, I = unknown> {
|
|
32
|
-
readonly _tag: "Allow" | "Deny";
|
|
33
|
-
readonly actions: ReadonlyArray<string>;
|
|
34
|
-
readonly resources: ReadonlyArray<string>;
|
|
35
|
-
readonly when?: Condition<E, R, O, I>;
|
|
36
|
-
readonly fields?: ReadonlyArray<string>;
|
|
37
|
-
readonly reason?: string;
|
|
38
|
-
readonly id?: string;
|
|
39
|
-
readonly meta?: unknown;
|
|
40
|
-
/**
|
|
41
|
-
* The domain of the builder that made the rule. Two domains may have the
|
|
42
|
-
* same types but other paths, so the types can not tell them apart. It is
|
|
43
|
-
* not in the JSON form of a rule.
|
|
44
|
-
*/
|
|
45
|
-
readonly domain?: Any$2;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Any rule.
|
|
49
|
-
*
|
|
50
|
-
* @stability stable
|
|
51
|
-
* @category models
|
|
52
|
-
* @since 0.3.0
|
|
53
|
-
*/
|
|
54
|
-
export type Any = Rule<any, any, any, any, never>;
|
|
55
|
-
/**
|
|
56
|
-
* The error type of a rule.
|
|
57
|
-
*
|
|
58
|
-
* @stability stable
|
|
59
|
-
* @category utility types
|
|
60
|
-
* @since 0.3.0
|
|
61
|
-
*/
|
|
62
|
-
export type Error<A> = A extends {
|
|
63
|
-
readonly "~Rule"?: Variance<infer E, infer _R, infer _O>;
|
|
64
|
-
} ? E : never;
|
|
65
|
-
/**
|
|
66
|
-
* The service type of a rule.
|
|
67
|
-
*
|
|
68
|
-
* @stability stable
|
|
69
|
-
* @category utility types
|
|
70
|
-
* @since 0.3.0
|
|
71
|
-
*/
|
|
72
|
-
export type Services<A> = A extends {
|
|
73
|
-
readonly "~Rule"?: Variance<infer _E, infer R, infer _O>;
|
|
74
|
-
} ? R : never;
|
|
75
|
-
/**
|
|
76
|
-
* `Condition.Opaque` when a rule has a predicate.
|
|
77
|
-
*
|
|
78
|
-
* @stability stable
|
|
79
|
-
* @category utility types
|
|
80
|
-
* @since 0.3.0
|
|
81
|
-
*/
|
|
82
|
-
export type OpaqueOf<A> = A extends {
|
|
83
|
-
readonly "~Rule"?: Variance<infer _E, infer _R, infer O>;
|
|
84
|
-
} ? O : never;
|
|
85
|
-
/**
|
|
86
|
-
* A resource in a rule: a kind name, a resource of the domain, or `"*"`.
|
|
87
|
-
*
|
|
88
|
-
* @stability stable
|
|
89
|
-
* @category models
|
|
90
|
-
* @since 0.3.0
|
|
91
|
-
*/
|
|
92
|
-
export type Target<D> = Kind$1<D> | Resources<D> | "*";
|
|
93
|
-
/**
|
|
94
|
-
* The kind name of a target.
|
|
95
|
-
*
|
|
96
|
-
* @stability stable
|
|
97
|
-
* @category utility types
|
|
98
|
-
* @since 0.3.0
|
|
99
|
-
*/
|
|
100
|
-
export type KindOf<T> = T extends string ? T : Kind<T>;
|
|
101
|
-
/**
|
|
102
|
-
* The actions that a rule may use for the kinds `K`.
|
|
103
|
-
*
|
|
104
|
-
* @stability stable
|
|
105
|
-
* @category utility types
|
|
106
|
-
* @since 0.3.0
|
|
107
|
-
*/
|
|
108
|
-
export type ActionFor<D, K> = "*" | ("*" extends K ? AnyAction<D> : ActionOf<D, Extract<K, string>>);
|
|
109
|
-
/**
|
|
110
|
-
* The targets in the resource argument of a rule: the one target, or the
|
|
111
|
-
* targets of a list.
|
|
112
|
-
*
|
|
113
|
-
* @stability stable
|
|
114
|
-
* @category utility types
|
|
115
|
-
* @since 1.0.0
|
|
116
|
-
*/
|
|
117
|
-
export type TargetOf<Res> = Res extends ReadonlyArray<infer X> ? X : Res;
|
|
118
|
-
/**
|
|
119
|
-
* The actions that a rule may use for its resource argument. A list of
|
|
120
|
-
* resources may use an action of any of them. One target with a union type
|
|
121
|
-
* may use only an action of every kind in the union, because its value may be
|
|
122
|
-
* any one of them. When the argument may be a list or one target, the rule
|
|
123
|
-
* may use only an action that each of these shapes allows.
|
|
124
|
-
*
|
|
125
|
-
* @stability stable
|
|
126
|
-
* @category utility types
|
|
127
|
-
* @since 1.0.0
|
|
128
|
-
*/
|
|
129
|
-
export type ActionForTargets<D, Res> = (Res extends ReadonlyArray<infer X> ? (action: ActionFor<D, KindOf<X>>) => void : (action: ActionForTarget<D, Res>) => void) extends ((action: infer A) => void) ? A : never;
|
|
130
|
-
/** The actions for one target that is not a list. */
|
|
131
|
-
type ActionForTarget<D, Res> = "*" | ("*" extends KindOf<Res> ? AnyAction<D> : CommonAction<D, Extract<KindOf<Res>, string>>);
|
|
132
|
-
/**
|
|
133
|
-
* The data type of the kinds `K`. For `"*"` it has no fields.
|
|
134
|
-
*
|
|
135
|
-
* @stability stable
|
|
136
|
-
* @category utility types
|
|
137
|
-
* @since 0.3.0
|
|
138
|
-
*/
|
|
139
|
-
export type DataFor<D, K> = "*" extends K ? {} : DataOf<D, Extract<K, string>>;
|
|
140
|
-
/**
|
|
141
|
-
* The value type of the kinds `K`.
|
|
142
|
-
*
|
|
143
|
-
* @stability stable
|
|
144
|
-
* @category utility types
|
|
145
|
-
* @since 0.3.0
|
|
146
|
-
*/
|
|
147
|
-
export type ValueFor<D, K> = "*" extends K ? AnyValue<D> : ValueOf<D, Extract<K, string>>;
|
|
148
|
-
/**
|
|
149
|
-
* A field name or a field pattern of the kinds `K`.
|
|
150
|
-
*
|
|
151
|
-
* @stability stable
|
|
152
|
-
* @category models
|
|
153
|
-
* @since 0.3.0
|
|
154
|
-
*/
|
|
155
|
-
export type FieldFor<D, K> = FieldSelector<DataFor<D, K>> | `${string}*${string}`;
|
|
156
|
-
/**
|
|
157
|
-
* A condition that a rule for the kinds `K` may have. Its predicates may read
|
|
158
|
-
* only the values of these kinds and the principal of the domain.
|
|
159
|
-
*
|
|
160
|
-
* @stability stable
|
|
161
|
-
* @category models
|
|
162
|
-
* @since 1.0.0
|
|
163
|
-
*/
|
|
164
|
-
export type ConditionFor<D, K> = Condition<any, any, any, Reads<ValueFor<D, K>, Principal<D>>>;
|
|
165
|
-
/**
|
|
166
|
-
* The options of a rule.
|
|
167
|
-
*
|
|
168
|
-
* @stability stable
|
|
169
|
-
* @category models
|
|
170
|
-
* @since 0.3.0
|
|
171
|
-
*/
|
|
172
|
-
export interface Options<D, K, C extends Any$1> {
|
|
173
|
-
/** The condition. It gets a builder with the types of the resource. */
|
|
174
|
-
readonly when?: (builder: Builder$1<DataFor<D, K>, ValueFor<D, K>, Principal<D>>) => C & Checked<C>;
|
|
175
|
-
readonly fields?: ReadonlyArray<FieldFor<D, K>>;
|
|
176
|
-
readonly reason?: string;
|
|
177
|
-
readonly id?: string;
|
|
178
|
-
readonly meta?: Meta<D>;
|
|
179
|
-
}
|
|
180
|
-
type SingleOrArray<A> = A | ReadonlyArray<A>;
|
|
181
|
-
/**
|
|
182
|
-
* Makes rules with the types of a domain.
|
|
183
|
-
*
|
|
184
|
-
* @stability stable
|
|
185
|
-
* @category models
|
|
186
|
-
* @since 0.3.0
|
|
187
|
-
*/
|
|
188
|
-
export interface Builder<D> {
|
|
189
|
-
readonly allow: <const Res extends SingleOrArray<Target<D>>, const A extends ActionForTargets<D, Res>, const C extends ConditionFor<D, KindOf<TargetOf<Res>>> = Condition>(action: SingleOrArray<A>, resource: Res, options?: Options<D, KindOf<TargetOf<Res>>, C>) => Rule<Error$1<C>, Services$1<C>, OpaqueOf$1<C>, D, ReadsOf<C>>;
|
|
190
|
-
readonly deny: <const Res extends SingleOrArray<Target<D>>, const A extends ActionForTargets<D, Res>, const C extends ConditionFor<D, KindOf<TargetOf<Res>>> = Condition>(action: SingleOrArray<A>, resource: Res, options?: Options<D, KindOf<TargetOf<Res>>, C>) => Rule<Error$1<C>, Services$1<C>, OpaqueOf$1<C>, D, ReadsOf<C>>;
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* Makes a rule from its data. It does not check the data against a domain.
|
|
194
|
-
* Use {@link builder} for rules with types, or `Policy.schema` for rules from
|
|
195
|
-
* JSON.
|
|
196
|
-
*
|
|
197
|
-
* @stability stable
|
|
198
|
-
* @category constructors
|
|
199
|
-
* @since 1.0.0
|
|
200
|
-
*/
|
|
201
|
-
export declare const make: <E = never, R = never, O = never, I = unknown>(data: Shape<E, R, O, I>) => Rule<E, R, O, any, I>;
|
|
202
|
-
/**
|
|
203
|
-
* Gives the domain of the builder that made a rule. A rule from {@link make}
|
|
204
|
-
* has none, unless its data gives one.
|
|
205
|
-
*
|
|
206
|
-
* @stability stable
|
|
207
|
-
* @category getters
|
|
208
|
-
* @since 1.0.0
|
|
209
|
-
*/
|
|
210
|
-
export declare const domainOf: (rule: Any) => Any$2 | undefined;
|
|
211
|
-
/**
|
|
212
|
-
* Makes a rule builder for a domain.
|
|
213
|
-
*
|
|
214
|
-
* @example
|
|
215
|
-
* ```ts
|
|
216
|
-
* const _ = Rule.builder(App)
|
|
217
|
-
* const rule = _.allow("read", Document, {
|
|
218
|
-
* when: ($) => $.eq("ownerId", $.principal("id")),
|
|
219
|
-
* })
|
|
220
|
-
* ```
|
|
221
|
-
*
|
|
222
|
-
* @stability stable
|
|
223
|
-
* @category constructors
|
|
224
|
-
* @since 0.3.0
|
|
225
|
-
*/
|
|
226
|
-
export declare const builder: <D extends Any$2>(domain: D) => Builder<D>;
|
|
227
|
-
/**
|
|
228
|
-
* Tests if a value is a rule.
|
|
229
|
-
*
|
|
230
|
-
* @stability stable
|
|
231
|
-
* @category guards
|
|
232
|
-
* @since 0.3.0
|
|
233
|
-
*/
|
|
234
|
-
export declare const isRule: (u: unknown) => u is Any;
|
|
235
|
-
/**
|
|
236
|
-
* Tests if a field name matches a field name or a field pattern of a rule.
|
|
237
|
-
*
|
|
238
|
-
* @stability stable
|
|
239
|
-
* @category predicates
|
|
240
|
-
* @since 0.3.0
|
|
241
|
-
*/
|
|
242
|
-
export declare const matchesField: (pattern: string, field: string) => boolean;
|
|
243
|
-
/**
|
|
244
|
-
* Tests if a field pattern may match a field inside `field`, such as
|
|
245
|
-
* `settings.secret` inside `settings`, or `settings.` for the empty key of a
|
|
246
|
-
* record.
|
|
247
|
-
*
|
|
248
|
-
* @stability stable
|
|
249
|
-
* @category predicates
|
|
250
|
-
* @since 1.0.0
|
|
251
|
-
*/
|
|
252
|
-
export declare const matchesInside: (pattern: string, field: string) => boolean;
|
|
253
|
-
/**
|
|
254
|
-
* Tests the parts of a rule that do not need the resource value: the action,
|
|
255
|
-
* the kind and the field.
|
|
256
|
-
*
|
|
257
|
-
* A rule with an empty list of fields covers no request. A rule with fields
|
|
258
|
-
* covers a request with no field only when it is an allow rule. So "may update some fields" is a yes. A deny rule for some fields does
|
|
259
|
-
* not stop a request for the whole value. With the `descriptor` of the kind,
|
|
260
|
-
* such an allow rule covers the request only when one of its patterns may
|
|
261
|
-
* match a field of the kind. A grant of fields that the kind does not have is
|
|
262
|
-
* not a grant of some fields.
|
|
263
|
-
*
|
|
264
|
-
* @stability stable
|
|
265
|
-
* @category predicates
|
|
266
|
-
* @since 1.0.0
|
|
267
|
-
*/
|
|
268
|
-
export declare const matchesTarget: (rule: Any, target: {
|
|
269
|
-
readonly action: string;
|
|
270
|
-
readonly kind: string;
|
|
271
|
-
readonly field?: string | undefined;
|
|
272
|
-
readonly descriptor?: Descriptor | undefined;
|
|
273
|
-
}) => boolean;
|
|
274
|
-
export { Rule_d_exports };
|
|
275
|
-
//# sourceMappingURL=Rule.d.ts.map
|
package/dist/Rule.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Rule.d.ts","names":["Condition.Variance","Condition.Condition","Domain.Any","Domain.Kind","Domain.Resources","Resource.Kind","Domain.AnyAction","Domain.ActionOf","Domain.CommonAction","Domain.DataOf","Domain.AnyValue","Domain.ValueOf","Condition.FieldSelector","Domain.Principal","Condition.Reads","Condition.Any","Condition.Builder","Condition.Checked","Domain.Meta","Condition.Error","Condition.Services","Condition.OpaqueOf","Condition.ReadsOf","Resource.Descriptor"],"sources":["../src/Rule.ts"],"mappings":"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"}
|
package/dist/Rule.js
DELETED
|
@@ -1,257 +0,0 @@
|
|
|
1
|
-
import { __exportAll } from "./_virtual/_rolldown/runtime.js";
|
|
2
|
-
import { descriptor, hasMatchingGetter, hasMatchingPath, isResource } from "./Resource.js";
|
|
3
|
-
import { builder as builder$1 } from "./Condition.js";
|
|
4
|
-
import * as Arr from "effect/Array";
|
|
5
|
-
import * as Data from "effect/Data";
|
|
6
|
-
import * as HashSet from "effect/HashSet";
|
|
7
|
-
// src/Rule.ts
|
|
8
|
-
/**
|
|
9
|
-
* A rule says that a principal may (`Allow`) or may not (`Deny`) do some
|
|
10
|
-
* actions on some resources. A rule may have:
|
|
11
|
-
* - a condition, which must be true for the rule to apply;
|
|
12
|
-
* - a list of fields, for rules about parts of a resource;
|
|
13
|
-
* - a reason, an id, and extra data (`meta`).
|
|
14
|
-
*
|
|
15
|
-
* Rules do not change, and two rules with the same data are equal. A rule
|
|
16
|
-
* works in a generator, so you can write `yield* _.allow(...)` inside
|
|
17
|
-
* `Policy.define`.
|
|
18
|
-
*
|
|
19
|
-
* The action `"*"` means every action. The resource `"*"` means every
|
|
20
|
-
* resource.
|
|
21
|
-
*
|
|
22
|
-
* Field names in a rule may have patterns. `*` stands for any part of one
|
|
23
|
-
* field name, and `**` stands for any number of parts. So `address.*` covers
|
|
24
|
-
* `address.city`, and `**` covers every field.
|
|
25
|
-
*
|
|
26
|
-
* @stability stable
|
|
27
|
-
* @since 0.3.0
|
|
28
|
-
*/
|
|
29
|
-
var Rule_exports = /* @__PURE__ */ __exportAll({
|
|
30
|
-
builder: () => builder,
|
|
31
|
-
domainOf: () => domainOf,
|
|
32
|
-
isRule: () => isRule,
|
|
33
|
-
make: () => make,
|
|
34
|
-
matchesField: () => matchesField,
|
|
35
|
-
matchesInside: () => matchesInside,
|
|
36
|
-
matchesTarget: () => matchesTarget
|
|
37
|
-
});
|
|
38
|
-
/**
|
|
39
|
-
* The class of every rule value. A rule works in a generator: it gives
|
|
40
|
-
* itself, so `yield* _.allow(...)` gives the rule to `Policy.define`.
|
|
41
|
-
*/
|
|
42
|
-
var RuleData = class extends Data.Class {
|
|
43
|
-
*[Symbol.iterator]() {
|
|
44
|
-
yield this;
|
|
45
|
-
return this;
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
/**
|
|
49
|
-
* Makes a rule from its data. It does not check the data against a domain.
|
|
50
|
-
* Use {@link builder} for rules with types, or `Policy.schema` for rules from
|
|
51
|
-
* JSON.
|
|
52
|
-
*
|
|
53
|
-
* @stability stable
|
|
54
|
-
* @category constructors
|
|
55
|
-
* @since 1.0.0
|
|
56
|
-
*/
|
|
57
|
-
const make = (data) => {
|
|
58
|
-
return new RuleData({
|
|
59
|
-
_tag: data._tag,
|
|
60
|
-
actions: [...data.actions],
|
|
61
|
-
resources: [...data.resources],
|
|
62
|
-
...data.when === void 0 ? {} : { when: data.when },
|
|
63
|
-
...data.fields === void 0 ? {} : { fields: [...data.fields] },
|
|
64
|
-
...data.reason === void 0 ? {} : { reason: data.reason },
|
|
65
|
-
...data.id === void 0 ? {} : { id: data.id },
|
|
66
|
-
...data.meta === void 0 ? {} : { meta: data.meta },
|
|
67
|
-
...data.domain === void 0 ? {} : { domain: data.domain }
|
|
68
|
-
});
|
|
69
|
-
};
|
|
70
|
-
const toArray = (value) => Array.isArray(value) ? value : [value];
|
|
71
|
-
const kindName = (target) => isResource(target) ? descriptor(target).kind : target;
|
|
72
|
-
/**
|
|
73
|
-
* Gives the domain of the builder that made a rule. A rule from {@link make}
|
|
74
|
-
* has none, unless its data gives one.
|
|
75
|
-
*
|
|
76
|
-
* @stability stable
|
|
77
|
-
* @category getters
|
|
78
|
-
* @since 1.0.0
|
|
79
|
-
*/
|
|
80
|
-
const domainOf = (rule) => rule.domain;
|
|
81
|
-
const makeFromOptions = (tag, domain) => (action, resource, options) => make({
|
|
82
|
-
_tag: tag,
|
|
83
|
-
actions: toArray(action),
|
|
84
|
-
resources: Arr.map(toArray(resource), kindName),
|
|
85
|
-
...options?.when === void 0 ? {} : { when: options.when(builder$1()) },
|
|
86
|
-
...options?.fields === void 0 ? {} : { fields: options.fields },
|
|
87
|
-
...options?.reason === void 0 ? {} : { reason: options.reason },
|
|
88
|
-
...options?.id === void 0 ? {} : { id: options.id },
|
|
89
|
-
...options?.meta === void 0 ? {} : { meta: options.meta },
|
|
90
|
-
domain
|
|
91
|
-
});
|
|
92
|
-
/**
|
|
93
|
-
* Makes a rule builder for a domain.
|
|
94
|
-
*
|
|
95
|
-
* @example
|
|
96
|
-
* ```ts
|
|
97
|
-
* const _ = Rule.builder(App)
|
|
98
|
-
* const rule = _.allow("read", Document, {
|
|
99
|
-
* when: ($) => $.eq("ownerId", $.principal("id")),
|
|
100
|
-
* })
|
|
101
|
-
* ```
|
|
102
|
-
*
|
|
103
|
-
* @stability stable
|
|
104
|
-
* @category constructors
|
|
105
|
-
* @since 0.3.0
|
|
106
|
-
*/
|
|
107
|
-
const builder = (domain) => ({
|
|
108
|
-
allow: makeFromOptions("Allow", domain),
|
|
109
|
-
deny: makeFromOptions("Deny", domain)
|
|
110
|
-
});
|
|
111
|
-
/**
|
|
112
|
-
* Tests if a value is a rule.
|
|
113
|
-
*
|
|
114
|
-
* @stability stable
|
|
115
|
-
* @category guards
|
|
116
|
-
* @since 0.3.0
|
|
117
|
-
*/
|
|
118
|
-
const isRule = (u) => u instanceof RuleData;
|
|
119
|
-
/**
|
|
120
|
-
* Gives the parts of a pattern. It reads the pattern by Unicode code points,
|
|
121
|
-
* as `run` reads the field. One star is `*`. Two or more stars next to each
|
|
122
|
-
* other match what `**` matches, so they are one part, `**`. So two star parts
|
|
123
|
-
* are never next to each other.
|
|
124
|
-
*/
|
|
125
|
-
const tokensOf = (pattern) => Arr.map(normalize(pattern).match(/\*+|[^*]/gu) ?? [], (part) => part.startsWith("*") ? part.length === 1 ? "*" : "**" : part);
|
|
126
|
-
/**
|
|
127
|
-
* Puts each run of whole `**` parts together into one part. `a.**.**` matches
|
|
128
|
-
* what `a.**` matches, and with one part the rule of {@link skips} for no
|
|
129
|
-
* parts covers the whole run.
|
|
130
|
-
*/
|
|
131
|
-
const normalize = (pattern) => Arr.dedupeAdjacentWith(pattern.split("."), (left, right) => isGlobstar(left) && isGlobstar(right)).join(".");
|
|
132
|
-
/** Tests if a part of a pattern is only stars, two or more of them. */
|
|
133
|
-
const isGlobstar = (part) => /^\*{2,}$/u.test(part);
|
|
134
|
-
const isStar = (token) => token === "*" || token === "**";
|
|
135
|
-
/**
|
|
136
|
-
* Gives the places that a match may reach from `state` with no input. A star
|
|
137
|
-
* may match nothing. A `**` that is a whole part may also match no parts, so
|
|
138
|
-
* the dot next to it may be left out too: `**.secret` and `settings.**.secret`
|
|
139
|
-
* match `secret` and `settings.secret`, and `settings.**` matches `settings`.
|
|
140
|
-
*/
|
|
141
|
-
const skips = (tokens, state) => {
|
|
142
|
-
const token = tokens[state];
|
|
143
|
-
const startsPart = state === 0 || tokens[state - 1] === ".";
|
|
144
|
-
return [
|
|
145
|
-
...isStar(token) ? [state + 1] : [],
|
|
146
|
-
...token === "**" && startsPart && tokens[state + 1] === "." ? [state + 2] : [],
|
|
147
|
-
...token === "." && tokens[state + 1] === "**" && state + 2 === tokens.length && state > 0 ? [state + 2] : []
|
|
148
|
-
];
|
|
149
|
-
};
|
|
150
|
-
/**
|
|
151
|
-
* Adds the places that a match may reach with no input. See {@link skips}.
|
|
152
|
-
* Each step reads only the places that the step before found, so each place
|
|
153
|
-
* is read one time.
|
|
154
|
-
*/
|
|
155
|
-
const close = (tokens, states, found = states) => {
|
|
156
|
-
const after = HashSet.filter(HashSet.fromIterable(Arr.flatMap(Array.from(found), (state) => skips(tokens, state))), (state) => !HashSet.has(states, state));
|
|
157
|
-
return HashSet.size(after) === 0 ? states : close(tokens, HashSet.union(states, after), after);
|
|
158
|
-
};
|
|
159
|
-
/**
|
|
160
|
-
* Gives the places in the pattern after one more character of the input. A
|
|
161
|
-
* star that takes the character stays at its place. It has taken part of a
|
|
162
|
-
* name, so it may not match no parts any more: only the place after it is
|
|
163
|
-
* added, with no other skips from {@link skips}.
|
|
164
|
-
*/
|
|
165
|
-
const step = (tokens, states, char) => {
|
|
166
|
-
const list = Array.from(states);
|
|
167
|
-
const stars = Arr.filter(list, (state) => {
|
|
168
|
-
const token = tokens[state];
|
|
169
|
-
return token === "**" || token === "*" && char !== ".";
|
|
170
|
-
});
|
|
171
|
-
const moved = Arr.flatMap(list, (state) => !isStar(tokens[state]) && tokens[state] === char ? [state + 1] : []);
|
|
172
|
-
return HashSet.union(HashSet.fromIterable(stars), close(tokens, HashSet.fromIterable([...moved, ...Arr.map(stars, (state) => state + 1)])));
|
|
173
|
-
};
|
|
174
|
-
/**
|
|
175
|
-
* Gives every place in the pattern that a match may have reached after
|
|
176
|
-
* `input`. It keeps a set of places, and it does not go back, so the time is
|
|
177
|
-
* at most the length of the input times the length of the pattern. A regular
|
|
178
|
-
* expression may take a very long time on a pattern with many stars.
|
|
179
|
-
*/
|
|
180
|
-
const run = (tokens, input) => Arr.reduce(Array.from(input), close(tokens, HashSet.make(0)), (states, char) => HashSet.size(states) === 0 ? states : step(tokens, states, char));
|
|
181
|
-
/**
|
|
182
|
-
* Tests if a field name matches a field name or a field pattern of a rule.
|
|
183
|
-
*
|
|
184
|
-
* @stability stable
|
|
185
|
-
* @category predicates
|
|
186
|
-
* @since 0.3.0
|
|
187
|
-
*/
|
|
188
|
-
const matchesField = (pattern, field) => {
|
|
189
|
-
if (!pattern.includes("*")) return pattern === field;
|
|
190
|
-
const tokens = tokensOf(pattern);
|
|
191
|
-
return HashSet.has(run(tokens, field), tokens.length);
|
|
192
|
-
};
|
|
193
|
-
/**
|
|
194
|
-
* Tests if a field pattern may match a field inside `field`, such as
|
|
195
|
-
* `settings.secret` inside `settings`, or `settings.` for the empty key of a
|
|
196
|
-
* record.
|
|
197
|
-
*
|
|
198
|
-
* @stability stable
|
|
199
|
-
* @category predicates
|
|
200
|
-
* @since 1.0.0
|
|
201
|
-
*/
|
|
202
|
-
const matchesInside = (pattern, field) => HashSet.size(run(tokensOf(pattern), `${field}.`)) > 0;
|
|
203
|
-
/**
|
|
204
|
-
* Tests if a field pattern may match a field of a kind: a field in its list,
|
|
205
|
-
* a path that the Schema has, such as a key of a record, or a getter. See
|
|
206
|
-
* `Resource.hasMatchingPath` and `Resource.hasMatchingGetter`.
|
|
207
|
-
*/
|
|
208
|
-
const fitsSomeField = (pattern, descriptor) => Arr.some(descriptor.fieldPaths, (field) => matchesField(pattern, field)) || pattern.split(".", maxPatternParts + 1).length <= maxPatternParts && Arr.some(partLists(pattern), (parts) => hasMatchingPath(descriptor.schema, parts, matchesField) || hasMatchingGetter(descriptor.schema, parts, matchesField));
|
|
209
|
-
/** The most parts of a pattern that the walk of the Schema takes. */
|
|
210
|
-
const maxPatternParts = 256;
|
|
211
|
-
/**
|
|
212
|
-
* The lists of parts that a pattern may stand for. A part that is only stars
|
|
213
|
-
* is `**`. One `**` inside a part, as in `**value`, may take the dots of more
|
|
214
|
-
* parts, so such a part gives two lists: one with the part as it is, with
|
|
215
|
-
* `*` for `**`, and one with the part cut at the stars, as in `*`, `**`,
|
|
216
|
-
* `*value`. A part with two such runs stays as it is, with `*` for `**`, so
|
|
217
|
-
* it may miss a field but never fits one too many. The number of lists is
|
|
218
|
-
* kept small.
|
|
219
|
-
*/
|
|
220
|
-
const partLists = (pattern) => Arr.take(Arr.reduce(normalize(pattern).split("."), [[]], (lists, part) => {
|
|
221
|
-
const choices = isGlobstar(part) ? [["**"]] : (part.match(/\*{2,}/gu) ?? []).length === 1 ? [[part.replace(/\*{2,}/gu, "*")], [
|
|
222
|
-
`${part.slice(0, part.indexOf("**"))}*`,
|
|
223
|
-
"**",
|
|
224
|
-
`*${part.slice(part.lastIndexOf("**") + 2)}`
|
|
225
|
-
]] : [[part]];
|
|
226
|
-
return Arr.take(Arr.flatMap(lists, (list) => Arr.map(choices, (choice) => [...list, ...choice])), 16);
|
|
227
|
-
}), 16);
|
|
228
|
-
/**
|
|
229
|
-
* Tests the parts of a rule that do not need the resource value: the action,
|
|
230
|
-
* the kind and the field.
|
|
231
|
-
*
|
|
232
|
-
* A rule with an empty list of fields covers no request. A rule with fields
|
|
233
|
-
* covers a request with no field only when it is an allow rule. So "may update some fields" is a yes. A deny rule for some fields does
|
|
234
|
-
* not stop a request for the whole value. With the `descriptor` of the kind,
|
|
235
|
-
* such an allow rule covers the request only when one of its patterns may
|
|
236
|
-
* match a field of the kind. A grant of fields that the kind does not have is
|
|
237
|
-
* not a grant of some fields.
|
|
238
|
-
*
|
|
239
|
-
* @stability stable
|
|
240
|
-
* @category predicates
|
|
241
|
-
* @since 1.0.0
|
|
242
|
-
*/
|
|
243
|
-
const matchesTarget = (rule, target) => {
|
|
244
|
-
if (!rule.actions.includes("*") && !rule.actions.includes(target.action)) return false;
|
|
245
|
-
if (!rule.resources.includes("*") && !rule.resources.includes(target.kind)) return false;
|
|
246
|
-
if (rule.fields === void 0) return true;
|
|
247
|
-
if (rule.fields.length === 0) return false;
|
|
248
|
-
if (target.field === void 0) {
|
|
249
|
-
const descriptor = target.descriptor;
|
|
250
|
-
return rule._tag === "Allow" && (descriptor === void 0 || Arr.some(rule.fields, (pattern) => fitsSomeField(pattern, descriptor)));
|
|
251
|
-
}
|
|
252
|
-
const field = target.field;
|
|
253
|
-
return rule.fields.some((pattern) => matchesField(pattern, field));
|
|
254
|
-
};
|
|
255
|
-
export { Rule_exports, builder, domainOf, isRule, make, matchesField, matchesInside, matchesTarget };
|
|
256
|
-
|
|
257
|
-
//# sourceMappingURL=Rule.js.map
|
package/dist/Rule.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Rule.js","names":["Resource.isResource","Resource.descriptor","Condition.builder","Resource.hasMatchingPath","Resource.hasMatchingGetter"],"sources":["../src/Rule.ts"],"sourcesContent":["/**\n * A rule says that a principal may (`Allow`) or may not (`Deny`) do some\n * actions on some resources. A rule may have:\n * - a condition, which must be true for the rule to apply;\n * - a list of fields, for rules about parts of a resource;\n * - a reason, an id, and extra data (`meta`).\n *\n * Rules do not change, and two rules with the same data are equal. A rule\n * works in a generator, so you can write `yield* _.allow(...)` inside\n * `Policy.define`.\n *\n * The action `\"*\"` means every action. The resource `\"*\"` means every\n * resource.\n *\n * Field names in a rule may have patterns. `*` stands for any part of one\n * field name, and `**` stands for any number of parts. So `address.*` covers\n * `address.city`, and `**` covers every field.\n *\n * @stability stable\n * @since 0.3.0\n */\nimport * as Arr from \"effect/Array\"\nimport * as Data from \"effect/Data\"\nimport * as HashSet from \"effect/HashSet\"\nimport type * as Pipeable from \"effect/Pipeable\"\nimport * as Condition from \"./Condition.ts\"\nimport type * as Domain from \"./Domain.ts\"\nimport * as Resource from \"./Resource.ts\"\n\n/**\n * A rule. `E`, `R` and `O` come from its condition. See\n * `Condition.Condition`. `D` is the domain of the rule. A predicate reads the\n * values and the principal of its domain, so a rule may go only into a policy\n * of its own domain. A rule from {@link make} has the domain `any`. `I` is\n * what the predicates of its condition read. See `Condition.Reads`.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Rule<E = never, R = never, O = never, D = any, I = unknown>\n\textends Shape<E, R, O, I>, Pipeable.Pipeable {\n\treadonly \"~Rule\": Condition.Variance<E, R, O>\n\treadonly \"~Domain\": (domain: D) => D\n\t[Symbol.iterator](): Generator<\n\t\tRule<E, R, O, D, I>,\n\t\tRule<E, R, O, D, I>,\n\t\tunknown\n\t>\n}\n\n/**\n * The data of a rule.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport interface Shape<E = never, R = never, O = never, I = unknown> {\n\treadonly _tag: \"Allow\" | \"Deny\"\n\treadonly actions: ReadonlyArray<string>\n\treadonly resources: ReadonlyArray<string>\n\treadonly when?: Condition.Condition<E, R, O, I>\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 Any = Rule<any, any, any, any, never>\n\n/**\n * The error type of a rule.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type Error<A> = A extends {\n\treadonly \"~Rule\"?: Condition.Variance<infer E, infer _R, infer _O>\n}\n\t? E\n\t: never\n\n/**\n * The service type of a rule.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type Services<A> = A extends {\n\treadonly \"~Rule\"?: Condition.Variance<infer _E, infer R, infer _O>\n}\n\t? R\n\t: never\n\n/**\n * `Condition.Opaque` when a rule has a predicate.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type OpaqueOf<A> = A extends {\n\treadonly \"~Rule\"?: Condition.Variance<infer _E, infer _R, infer O>\n}\n\t? O\n\t: never\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 Target<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.FieldSelector<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\tany,\n\tany,\n\tany,\n\tCondition.Reads<ValueFor<D, K>, Domain.Principal<D>>\n>\n\n/**\n * The options of a rule.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Options<D, K, C extends Condition.Any> {\n\t/** The condition. It gets a builder with the types of the resource. */\n\treadonly when?: (\n\t\tbuilder: Condition.Builder<\n\t\t\tDataFor<D, K>,\n\t\t\tValueFor<D, K>,\n\t\t\tDomain.Principal<D>\n\t\t>,\n\t) => C & Condition.Checked<C>\n\treadonly fields?: ReadonlyArray<FieldFor<D, K>>\n\treadonly reason?: string\n\treadonly id?: string\n\treadonly meta?: Domain.Meta<D>\n}\n\ntype SingleOrArray<A> = A | ReadonlyArray<A>\n\n/**\n * Makes rules with the types of a domain.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Builder<D> {\n\treadonly allow: <\n\t\tconst Res extends SingleOrArray<Target<D>>,\n\t\tconst A extends ActionForTargets<D, Res>,\n\t\tconst C extends ConditionFor<D, KindOf<TargetOf<Res>>> =\n\t\t\tCondition.Condition,\n\t>(\n\t\taction: SingleOrArray<A>,\n\t\tresource: Res,\n\t\toptions?: Options<D, KindOf<TargetOf<Res>>, C>,\n\t) => Rule<\n\t\tCondition.Error<C>,\n\t\tCondition.Services<C>,\n\t\tCondition.OpaqueOf<C>,\n\t\tD,\n\t\tCondition.ReadsOf<C>\n\t>\n\treadonly deny: <\n\t\tconst Res extends SingleOrArray<Target<D>>,\n\t\tconst A extends ActionForTargets<D, Res>,\n\t\tconst C extends ConditionFor<D, KindOf<TargetOf<Res>>> =\n\t\t\tCondition.Condition,\n\t>(\n\t\taction: SingleOrArray<A>,\n\t\tresource: Res,\n\t\toptions?: Options<D, KindOf<TargetOf<Res>>, C>,\n\t) => Rule<\n\t\tCondition.Error<C>,\n\t\tCondition.Services<C>,\n\t\tCondition.OpaqueOf<C>,\n\t\tD,\n\t\tCondition.ReadsOf<C>\n\t>\n}\n\n/**\n * The class of every rule value. A rule works in a generator: it gives\n * itself, so `yield* _.allow(...)` gives the rule to `Policy.define`.\n */\nclass RuleData extends Data.Class<Shape<unknown, unknown, unknown, any>> {\n\t*[Symbol.iterator](): Generator<this, this, unknown> {\n\t\tyield this\n\t\treturn this\n\t}\n}\n\n/**\n * Makes a rule from its data. It does not check the data against a domain.\n * Use {@link builder} for rules with types, or `Policy.schema` for rules from\n * JSON.\n *\n * @stability stable\n * @category constructors\n * @since 1.0.0\n */\nexport const make = <E = never, R = never, O = never, I = unknown>(\n\tdata: Shape<E, R, O, I>,\n): Rule<E, R, O, any, I> => {\n\t// A missing option is left out, so two rules with the same data are equal.\n\tconst shape: Shape<E, R, O, I> = {\n\t\t_tag: data._tag,\n\t\tactions: [...data.actions],\n\t\tresources: [...data.resources],\n\t\t...(data.when === undefined ? {} : { when: data.when }),\n\t\t...(data.fields === undefined ? {} : { fields: [...data.fields] }),\n\t\t...(data.reason === undefined ? {} : { reason: data.reason }),\n\t\t...(data.id === undefined ? {} : { id: data.id }),\n\t\t...(data.meta === undefined ? {} : { meta: data.meta }),\n\t\t...(data.domain === undefined ? {} : { domain: data.domain }),\n\t}\n\treturn new RuleData(shape) as never\n}\n\nconst toArray = <A>(value: A | ReadonlyArray<A>): ReadonlyArray<A> =>\n\tArray.isArray(value) ? value : [value as A]\n\nconst kindName = (target: unknown): string =>\n\tResource.isResource(target)\n\t\t? Resource.descriptor(target).kind\n\t\t: (target as string)\n\n/**\n * Gives the domain of the builder that made a rule. A rule from {@link make}\n * has none, unless its data gives one.\n *\n * @stability stable\n * @category getters\n * @since 1.0.0\n */\nexport const domainOf = (rule: Any): Domain.Any | undefined => rule.domain\n\nconst makeFromOptions =\n\t(tag: \"Allow\" | \"Deny\", domain: Domain.Any) =>\n\t(\n\t\taction: string | ReadonlyArray<string>,\n\t\tresource: unknown,\n\t\toptions?: {\n\t\t\treadonly when?: (builder: never) => Condition.Any\n\t\t\treadonly fields?: ReadonlyArray<string>\n\t\t\treadonly reason?: string\n\t\t\treadonly id?: string\n\t\t\treadonly meta?: unknown\n\t\t},\n\t): Any =>\n\t\tmake({\n\t\t\t_tag: tag,\n\t\t\tactions: toArray(action),\n\t\t\tresources: Arr.map(toArray(resource), kindName),\n\t\t\t...(options?.when === undefined\n\t\t\t\t? {}\n\t\t\t\t: { when: options.when(Condition.builder() as never) }),\n\t\t\t...(options?.fields === undefined ? {} : { fields: options.fields }),\n\t\t\t...(options?.reason === undefined ? {} : { reason: options.reason }),\n\t\t\t...(options?.id === undefined ? {} : { id: options.id }),\n\t\t\t...(options?.meta === undefined ? {} : { meta: options.meta }),\n\t\t\tdomain,\n\t\t})\n\n/**\n * Makes a rule builder for a domain.\n *\n * @example\n * ```ts\n * const _ = Rule.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 0.3.0\n */\nexport const builder = <D extends Domain.Any>(domain: D): Builder<D> =>\n\t({\n\t\tallow: makeFromOptions(\"Allow\", domain),\n\t\tdeny: makeFromOptions(\"Deny\", domain),\n\t}) as never\n\n/**\n * Tests if a value is a rule.\n *\n * @stability stable\n * @category guards\n * @since 0.3.0\n */\nexport const isRule = (u: unknown): u is Any => u instanceof RuleData\n\n/**\n * A part of a field pattern: `\"**\"`, `\"*\"`, or one plain Unicode code point.\n */\ntype Token = string\n\n/**\n * Gives the parts of a pattern. It reads the pattern by Unicode code points,\n * as `run` reads the field. One star is `*`. Two or more stars next to each\n * other match what `**` matches, so they are one part, `**`. So two star parts\n * are never next to each other.\n */\nconst tokensOf = (pattern: string): ReadonlyArray<Token> =>\n\tArr.map(normalize(pattern).match(/\\*+|[^*]/gu) ?? [], (part) =>\n\t\tpart.startsWith(\"*\") ? (part.length === 1 ? \"*\" : \"**\") : part,\n\t)\n\n/**\n * Puts each run of whole `**` parts together into one part. `a.**.**` matches\n * what `a.**` matches, and with one part the rule of {@link skips} for no\n * parts covers the whole run.\n */\nconst normalize = (pattern: string): string =>\n\tArr.dedupeAdjacentWith(\n\t\tpattern.split(\".\"),\n\t\t(left, right) => isGlobstar(left) && isGlobstar(right),\n\t).join(\".\")\n\n/** Tests if a part of a pattern is only stars, two or more of them. */\nconst isGlobstar = (part: string): boolean => /^\\*{2,}$/u.test(part)\n\nconst isStar = (token: Token | undefined): boolean =>\n\ttoken === \"*\" || token === \"**\"\n\ntype States = HashSet.HashSet<number>\n\n/**\n * Gives the places that a match may reach from `state` with no input. A star\n * may match nothing. A `**` that is a whole part may also match no parts, so\n * the dot next to it may be left out too: `**.secret` and `settings.**.secret`\n * match `secret` and `settings.secret`, and `settings.**` matches `settings`.\n */\nconst skips = (\n\ttokens: ReadonlyArray<Token>,\n\tstate: number,\n): ReadonlyArray<number> => {\n\tconst token = tokens[state]\n\tconst startsPart = state === 0 || tokens[state - 1] === \".\"\n\treturn [\n\t\t...(isStar(token) ? [state + 1] : []),\n\t\t...(token === \"**\" && startsPart && tokens[state + 1] === \".\"\n\t\t\t? [state + 2]\n\t\t\t: []),\n\t\t...(token === \".\" &&\n\t\ttokens[state + 1] === \"**\" &&\n\t\tstate + 2 === tokens.length &&\n\t\tstate > 0\n\t\t\t? [state + 2]\n\t\t\t: []),\n\t]\n}\n\n/**\n * Adds the places that a match may reach with no input. See {@link skips}.\n * Each step reads only the places that the step before found, so each place\n * is read one time.\n */\nconst close = (\n\ttokens: ReadonlyArray<Token>,\n\tstates: States,\n\tfound: States = states,\n): States => {\n\tconst after = HashSet.filter(\n\t\tHashSet.fromIterable(\n\t\t\tArr.flatMap(Array.from(found), (state) => skips(tokens, state)),\n\t\t),\n\t\t(state) => !HashSet.has(states, state),\n\t)\n\treturn HashSet.size(after) === 0\n\t\t? states\n\t\t: close(tokens, HashSet.union(states, after), after)\n}\n\n/**\n * Gives the places in the pattern after one more character of the input. A\n * star that takes the character stays at its place. It has taken part of a\n * name, so it may not match no parts any more: only the place after it is\n * added, with no other skips from {@link skips}.\n */\nconst step = (\n\ttokens: ReadonlyArray<Token>,\n\tstates: States,\n\tchar: string,\n): States => {\n\tconst list = Array.from(states)\n\tconst stars = Arr.filter(list, (state) => {\n\t\tconst token = tokens[state]\n\t\treturn token === \"**\" || (token === \"*\" && char !== \".\")\n\t})\n\tconst moved = Arr.flatMap(list, (state) =>\n\t\t!isStar(tokens[state]) && tokens[state] === char ? [state + 1] : [],\n\t)\n\treturn HashSet.union(\n\t\tHashSet.fromIterable(stars),\n\t\tclose(\n\t\t\ttokens,\n\t\t\tHashSet.fromIterable([...moved, ...Arr.map(stars, (state) => state + 1)]),\n\t\t),\n\t)\n}\n\n/**\n * Gives every place in the pattern that a match may have reached after\n * `input`. It keeps a set of places, and it does not go back, so the time is\n * at most the length of the input times the length of the pattern. A regular\n * expression may take a very long time on a pattern with many stars.\n */\nconst run = (tokens: ReadonlyArray<Token>, input: string): States =>\n\tArr.reduce(\n\t\tArray.from(input),\n\t\tclose(tokens, HashSet.make(0)),\n\t\t(states, char) =>\n\t\t\tHashSet.size(states) === 0 ? states : step(tokens, states, char),\n\t)\n\n/**\n * Tests if a field name matches a field name or a field pattern of a rule.\n *\n * @stability stable\n * @category predicates\n * @since 0.3.0\n */\nexport const matchesField = (pattern: string, field: string): boolean => {\n\tif (!pattern.includes(\"*\")) {\n\t\treturn pattern === field\n\t}\n\tconst tokens = tokensOf(pattern)\n\treturn HashSet.has(run(tokens, field), tokens.length)\n}\n\n/**\n * Tests if a field pattern may match a field inside `field`, such as\n * `settings.secret` inside `settings`, or `settings.` for the empty key of a\n * record.\n *\n * @stability stable\n * @category predicates\n * @since 1.0.0\n */\nexport const matchesInside = (pattern: string, field: string): boolean =>\n\t// The name of a part may be empty, as a key of a record may be. So a match\n\t// that ends just after the dot names a part too.\n\tHashSet.size(run(tokensOf(pattern), `${field}.`)) > 0\n\n/**\n * Tests if a field pattern may match a field of a kind: a field in its list,\n * a path that the Schema has, such as a key of a record, or a getter. See\n * `Resource.hasMatchingPath` and `Resource.hasMatchingGetter`.\n */\nconst fitsSomeField = (\n\tpattern: string,\n\tdescriptor: Resource.Descriptor,\n): boolean =>\n\tArr.some(descriptor.fieldPaths, (field) => matchesField(pattern, field)) ||\n\t// A pattern with more parts than a field path may have fits no other\n\t// field, and it is not cut into lists of parts.\n\t(pattern.split(\".\", maxPatternParts + 1).length <= maxPatternParts &&\n\t\tArr.some(\n\t\t\tpartLists(pattern),\n\t\t\t(parts) =>\n\t\t\t\tResource.hasMatchingPath(descriptor.schema, parts, matchesField) ||\n\t\t\t\tResource.hasMatchingGetter(descriptor.schema, parts, matchesField),\n\t\t))\n\n/** The most parts of a pattern that the walk of the Schema takes. */\nconst maxPatternParts = 256\n\n/**\n * The lists of parts that a pattern may stand for. A part that is only stars\n * is `**`. One `**` inside a part, as in `**value`, may take the dots of more\n * parts, so such a part gives two lists: one with the part as it is, with\n * `*` for `**`, and one with the part cut at the stars, as in `*`, `**`,\n * `*value`. A part with two such runs stays as it is, with `*` for `**`, so\n * it may miss a field but never fits one too many. The number of lists is\n * kept small.\n */\nconst partLists = (pattern: string): ReadonlyArray<ReadonlyArray<string>> =>\n\tArr.take(\n\t\tArr.reduce(\n\t\t\tnormalize(pattern).split(\".\"),\n\t\t\t[[]] as ReadonlyArray<ReadonlyArray<string>>,\n\t\t\t(lists, part) => {\n\t\t\t\tconst choices: ReadonlyArray<ReadonlyArray<string>> = isGlobstar(part)\n\t\t\t\t\t? [[\"**\"]]\n\t\t\t\t\t: // Only one run of stars: with two, the cut would leave out the\n\t\t\t\t\t\t// text between them, and the lists would fit more fields.\n\t\t\t\t\t\t(part.match(/\\*{2,}/gu) ?? []).length === 1\n\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\t[part.replace(/\\*{2,}/gu, \"*\")],\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t`${part.slice(0, part.indexOf(\"**\"))}*`,\n\t\t\t\t\t\t\t\t\t\"**\",\n\t\t\t\t\t\t\t\t\t`*${part.slice(part.lastIndexOf(\"**\") + 2)}`,\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t: [[part]]\n\t\t\t\treturn Arr.take(\n\t\t\t\t\tArr.flatMap(lists, (list) =>\n\t\t\t\t\t\tArr.map(choices, (choice) => [...list, ...choice]),\n\t\t\t\t\t),\n\t\t\t\t\t16,\n\t\t\t\t)\n\t\t\t},\n\t\t),\n\t\t16,\n\t)\n\n/**\n * Tests the parts of a rule that do not need the resource value: the action,\n * the kind and the field.\n *\n * A rule with an empty list of fields covers no request. A rule with fields\n * covers a request with no field only when it is an allow rule. So \"may update some fields\" is a yes. A deny rule for some fields does\n * not stop a request for the whole value. With the `descriptor` of the kind,\n * such an allow rule covers the request only when one of its patterns may\n * match a field of the kind. A grant of fields that the kind does not have is\n * not a grant of some fields.\n *\n * @stability stable\n * @category predicates\n * @since 1.0.0\n */\nexport const matchesTarget = (\n\trule: Any,\n\ttarget: {\n\t\treadonly action: string\n\t\treadonly kind: string\n\t\treadonly field?: string | undefined\n\t\treadonly descriptor?: Resource.Descriptor | undefined\n\t},\n): boolean => {\n\tif (!rule.actions.includes(\"*\") && !rule.actions.includes(target.action)) {\n\t\treturn false\n\t}\n\tif (!rule.resources.includes(\"*\") && !rule.resources.includes(target.kind)) {\n\t\treturn false\n\t}\n\tif (rule.fields === undefined) {\n\t\treturn true\n\t}\n\t// A rule for no fields is a rule for nothing. A grant with its last field\n\t// taken away must not cover the whole value.\n\tif (rule.fields.length === 0) {\n\t\treturn false\n\t}\n\tif (target.field === undefined) {\n\t\tconst descriptor = target.descriptor\n\t\treturn (\n\t\t\trule._tag === \"Allow\" &&\n\t\t\t(descriptor === undefined ||\n\t\t\t\tArr.some(rule.fields, (pattern) => fitsSomeField(pattern, descriptor)))\n\t\t)\n\t}\n\tconst field = target.field\n\treturn rule.fields.some((pattern) => matchesField(pattern, field))\n}\n"],"mappings":"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"}
|