@nmnmcc/ability 0.2.0 → 0.3.0
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 +322 -469
- package/dist/Authorizer.d.ts +216 -0
- package/dist/Authorizer.d.ts.map +1 -0
- package/dist/Authorizer.js +55 -0
- package/dist/Authorizer.js.map +1 -0
- package/dist/Condition.d.ts +536 -0
- package/dist/Condition.d.ts.map +1 -0
- package/dist/Condition.js +141 -0
- package/dist/Condition.js.map +1 -0
- package/dist/Decision.d.ts +131 -0
- package/dist/Decision.d.ts.map +1 -0
- package/dist/Decision.js +83 -0
- package/dist/Decision.js.map +1 -0
- package/dist/Domain.d.ts +148 -0
- package/dist/Domain.d.ts.map +1 -0
- package/dist/Domain.js +34 -0
- package/dist/Domain.js.map +1 -0
- package/dist/HttpApi.d.ts +129 -0
- package/dist/HttpApi.d.ts.map +1 -0
- package/dist/HttpApi.js +95 -0
- package/dist/HttpApi.js.map +1 -0
- package/dist/Policy.d.ts +429 -0
- package/dist/Policy.d.ts.map +1 -0
- package/dist/Policy.js +162 -0
- package/dist/Policy.js.map +1 -0
- package/dist/Principal.d.ts +35 -0
- package/dist/Principal.d.ts.map +1 -0
- package/dist/Principal.js +37 -0
- package/dist/Principal.js.map +1 -0
- package/dist/Resource.d.ts +213 -0
- package/dist/Resource.d.ts.map +1 -0
- package/dist/Resource.js +71 -0
- package/dist/Resource.js.map +1 -0
- package/dist/Rule.d.ts +189 -0
- package/dist/Rule.d.ts.map +1 -0
- package/dist/Rule.js +50 -0
- package/dist/Rule.js.map +1 -0
- package/dist/_virtual/_rolldown/runtime.js +1 -2
- package/dist/index.d.ts +9 -3
- package/dist/index.js +9 -3
- package/dist/internal/authorizer.d.ts +28 -0
- package/dist/internal/authorizer.d.ts.map +1 -0
- package/dist/internal/authorizer.js +153 -0
- package/dist/internal/authorizer.js.map +1 -0
- package/dist/internal/condition.d.ts +11 -0
- package/dist/internal/condition.d.ts.map +1 -0
- package/dist/internal/condition.js +393 -0
- package/dist/internal/condition.js.map +1 -0
- package/dist/internal/domain.js +34 -0
- package/dist/internal/domain.js.map +1 -0
- package/dist/internal/httpApi.js +41 -0
- package/dist/internal/httpApi.js.map +1 -0
- package/dist/internal/policy.js +524 -0
- package/dist/internal/policy.js.map +1 -0
- package/dist/internal/resource.js +66 -0
- package/dist/internal/resource.js.map +1 -0
- package/dist/internal/rule.js +131 -0
- package/dist/internal/rule.js.map +1 -0
- package/package.json +61 -72
- package/src/Authorizer.ts +330 -0
- package/src/Condition.ts +706 -0
- package/src/Decision.ts +117 -0
- package/src/Domain.ts +189 -0
- package/src/HttpApi.ts +148 -0
- package/src/Policy.ts +575 -0
- package/src/Principal.ts +41 -0
- package/src/Resource.ts +290 -0
- package/src/Rule.ts +265 -0
- package/src/index.ts +57 -0
- package/src/internal/authorizer.ts +271 -0
- package/src/internal/condition.ts +607 -0
- package/src/internal/domain.ts +56 -0
- package/src/internal/httpApi.ts +84 -0
- package/src/internal/policy.ts +815 -0
- package/src/internal/resource.ts +98 -0
- package/src/internal/rule.ts +203 -0
- package/dist/Ability.d.ts +0 -491
- package/dist/Ability.js +0 -207
- package/dist/AbilityExtra.d.ts +0 -79
- package/dist/AbilityExtra.js +0 -187
- package/dist/internal/ability.d.ts +0 -90
- package/dist/internal/ability.js +0 -550
- package/dist/internal/serializable.js +0 -22
package/dist/HttpApi.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { Forbidden, Pending, PolicyUnavailable } from "./Authorizer.js";
|
|
2
|
+
import { layer as layer$1, requires as requires$1 } from "./internal/httpApi.js";
|
|
3
|
+
import * as Context from "effect/Context";
|
|
4
|
+
import { HttpApiSchema } from "effect/http-api";
|
|
5
|
+
// src/HttpApi.ts
|
|
6
|
+
/**
|
|
7
|
+
* Tools to check authorization in an `effect/http-api` server.
|
|
8
|
+
*
|
|
9
|
+
* Each endpoint says what it needs with the {@link Required} annotation. A
|
|
10
|
+
* group can give a default with {@link GroupRequired}: one list for GET
|
|
11
|
+
* requests and one list for all other methods. A middleware checks the
|
|
12
|
+
* requirements before the handler runs. An endpoint with no annotation is a
|
|
13
|
+
* defect, so a new endpoint is closed until you say what it needs. An empty
|
|
14
|
+
* list means the endpoint is open.
|
|
15
|
+
*
|
|
16
|
+
* ```ts
|
|
17
|
+
* class Authorization extends HttpApiMiddleware.Service<
|
|
18
|
+
* Authorization,
|
|
19
|
+
* { requires: Identity }
|
|
20
|
+
* >()("app/Authorization", { error: HttpApi.errors }) {}
|
|
21
|
+
*
|
|
22
|
+
* const endpoint = HttpApiEndpoint.patch("update", "/bots/:id", { ... })
|
|
23
|
+
* .annotate(HttpApi.Required, [
|
|
24
|
+
* HttpApi.requires(Auth, "update", "Bot", (params) => Bots.find(params.id)),
|
|
25
|
+
* ])
|
|
26
|
+
*
|
|
27
|
+
* const AuthorizationLive = HttpApi.layer(Authorization, Auth)
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* This module is a separate entry point, `@nmnmcc/ability/HttpApi`, because
|
|
31
|
+
* `effect/http-api` is not stable yet.
|
|
32
|
+
*
|
|
33
|
+
* @stability unstable
|
|
34
|
+
* @since 0.3.0
|
|
35
|
+
*/
|
|
36
|
+
/**
|
|
37
|
+
* The checks that an endpoint needs.
|
|
38
|
+
*
|
|
39
|
+
* @stability unstable
|
|
40
|
+
* @category annotations
|
|
41
|
+
* @since 0.3.0
|
|
42
|
+
*/
|
|
43
|
+
var Required = class extends Context.Service()("@nmnmcc/ability/HttpApi/Required") {};
|
|
44
|
+
/**
|
|
45
|
+
* The checks for every endpoint of a group with no {@link Required}
|
|
46
|
+
* annotation. `read` is for GET requests. `write` is for all other methods.
|
|
47
|
+
*
|
|
48
|
+
* @stability unstable
|
|
49
|
+
* @category annotations
|
|
50
|
+
* @since 0.3.0
|
|
51
|
+
*/
|
|
52
|
+
var GroupRequired = class extends Context.Service()("@nmnmcc/ability/HttpApi/GroupRequired") {};
|
|
53
|
+
/**
|
|
54
|
+
* Makes a {@link Requirement} with the types of an authorizer. The action must
|
|
55
|
+
* be an action of the kind, and `load` must give a value of the kind.
|
|
56
|
+
*
|
|
57
|
+
* `load` may fail. Its errors must be errors of the middleware, and the
|
|
58
|
+
* services that it needs must be given to {@link layer}.
|
|
59
|
+
*
|
|
60
|
+
* @stability unstable
|
|
61
|
+
* @category constructors
|
|
62
|
+
* @since 0.3.0
|
|
63
|
+
*/
|
|
64
|
+
const requires = requires$1;
|
|
65
|
+
/**
|
|
66
|
+
* The errors of the middleware, with HTTP status codes: 403 for
|
|
67
|
+
* `Forbidden`, 503 for `PolicyUnavailable`, and 409 for `Pending`.
|
|
68
|
+
*
|
|
69
|
+
* @stability unstable
|
|
70
|
+
* @category errors
|
|
71
|
+
* @since 0.3.0
|
|
72
|
+
*/
|
|
73
|
+
const errors = [
|
|
74
|
+
Forbidden.pipe(HttpApiSchema.status(403)),
|
|
75
|
+
PolicyUnavailable.pipe(HttpApiSchema.status(503)),
|
|
76
|
+
Pending.pipe(HttpApiSchema.status(409))
|
|
77
|
+
];
|
|
78
|
+
/**
|
|
79
|
+
* Makes the layer of an authorization middleware. The middleware reads the
|
|
80
|
+
* {@link Required} and {@link GroupRequired} annotations and checks each
|
|
81
|
+
* requirement with the authorizer.
|
|
82
|
+
*
|
|
83
|
+
* The layer takes the authorizer when it is built. The middleware must
|
|
84
|
+
* require the services of the authorizer, such as the identity of the
|
|
85
|
+
* caller. `R` is the type of the services that the `load` functions need. The
|
|
86
|
+
* layer takes them when it is built too.
|
|
87
|
+
*
|
|
88
|
+
* @stability unstable
|
|
89
|
+
* @category layers
|
|
90
|
+
* @since 0.3.0
|
|
91
|
+
*/
|
|
92
|
+
const layer = layer$1;
|
|
93
|
+
export { GroupRequired, Required, errors, layer, requires };
|
|
94
|
+
|
|
95
|
+
//# sourceMappingURL=HttpApi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HttpApi.js","names":["internal.requires","internal.layer"],"sources":["../src/HttpApi.ts"],"sourcesContent":["/**\n * Tools to check authorization in an `effect/http-api` server.\n *\n * Each endpoint says what it needs with the {@link Required} annotation. A\n * group can give a default with {@link GroupRequired}: one list for GET\n * requests and one list for all other methods. A middleware checks the\n * requirements before the handler runs. An endpoint with no annotation is a\n * defect, so a new endpoint is closed until you say what it needs. An empty\n * list means the endpoint is open.\n *\n * ```ts\n * class Authorization extends HttpApiMiddleware.Service<\n * Authorization,\n * { requires: Identity }\n * >()(\"app/Authorization\", { error: HttpApi.errors }) {}\n *\n * const endpoint = HttpApiEndpoint.patch(\"update\", \"/bots/:id\", { ... })\n * .annotate(HttpApi.Required, [\n * HttpApi.requires(Auth, \"update\", \"Bot\", (params) => Bots.find(params.id)),\n * ])\n *\n * const AuthorizationLive = HttpApi.layer(Authorization, Auth)\n * ```\n *\n * This module is a separate entry point, `@nmnmcc/ability/HttpApi`, because\n * `effect/http-api` is not stable yet.\n *\n * @stability unstable\n * @since 0.3.0\n */\nimport * as Context from \"effect/Context\"\nimport type * as Effect from \"effect/Effect\"\nimport type * as Layer from \"effect/Layer\"\nimport { HttpApiSchema } from \"effect/http-api\"\nimport * as Authorizer from \"./Authorizer.ts\"\nimport type * as Domain from \"./Domain.ts\"\nimport * as internal from \"./internal/httpApi.ts\"\n\n/**\n * One check that an endpoint needs: an action on a kind of resource. With\n * `load`, the middleware loads the resource value from the path parameters\n * and checks the action on that value. Without `load`, it checks the action\n * on the kind.\n *\n * @stability unstable\n * @category models\n * @since 0.3.0\n */\nexport interface Requirement {\n\treadonly action: string\n\treadonly kind: string\n\treadonly load?: (\n\t\tparams: Readonly<Record<string, string | undefined>>,\n\t) => Effect.Effect<object, unknown, unknown>\n}\n\n/**\n * The checks that an endpoint needs.\n *\n * @stability unstable\n * @category annotations\n * @since 0.3.0\n */\nexport class Required extends Context.Service<\n\tRequired,\n\tReadonlyArray<Requirement>\n>()(\"@nmnmcc/ability/HttpApi/Required\") {}\n\n/**\n * The checks for every endpoint of a group with no {@link Required}\n * annotation. `read` is for GET requests. `write` is for all other methods.\n *\n * @stability unstable\n * @category annotations\n * @since 0.3.0\n */\nexport class GroupRequired extends Context.Service<\n\tGroupRequired,\n\t{\n\t\treadonly read: ReadonlyArray<Requirement>\n\t\treadonly write: ReadonlyArray<Requirement>\n\t}\n>()(\"@nmnmcc/ability/HttpApi/GroupRequired\") {}\n\n/**\n * Makes a {@link Requirement} with the types of an authorizer. The action must\n * be an action of the kind, and `load` must give a value of the kind.\n *\n * `load` may fail. Its errors must be errors of the middleware, and the\n * services that it needs must be given to {@link layer}.\n *\n * @stability unstable\n * @category constructors\n * @since 0.3.0\n */\nexport const requires: <\n\tA extends { readonly domain: Domain.Any },\n\tconst K extends Domain.Kind<A[\"domain\"]>,\n>(\n\tauthorizer: A,\n\taction: Domain.ActionOf<A[\"domain\"], K>,\n\tkind: K,\n\tload?: (\n\t\tparams: Readonly<Record<string, string | undefined>>,\n\t) => Effect.Effect<Domain.ValueOf<A[\"domain\"], K>, unknown, unknown>,\n) => Requirement = internal.requires\n\n/**\n * The errors of the middleware, with HTTP status codes: 403 for\n * `Forbidden`, 503 for `PolicyUnavailable`, and 409 for `Pending`.\n *\n * @stability unstable\n * @category errors\n * @since 0.3.0\n */\nexport const errors = [\n\tAuthorizer.Forbidden.pipe(HttpApiSchema.status(403)),\n\tAuthorizer.PolicyUnavailable.pipe(HttpApiSchema.status(503)),\n\tAuthorizer.Pending.pipe(HttpApiSchema.status(409)),\n] as const\n\n/**\n * Makes the layer of an authorization middleware. The middleware reads the\n * {@link Required} and {@link GroupRequired} annotations and checks each\n * requirement with the authorizer.\n *\n * The layer takes the authorizer when it is built. The middleware must\n * require the services of the authorizer, such as the identity of the\n * caller. `R` is the type of the services that the `load` functions need. The\n * layer takes them when it is built too.\n *\n * @stability unstable\n * @category layers\n * @since 0.3.0\n */\nexport const layer: <\n\tSelf,\n\tId extends string,\n\tA extends Authorizer.AnyServiceClass,\n\tR = never,\n>(\n\tmiddleware: Context.ServiceClass<Self, Id, any>,\n\tauthorizer: A,\n) => Layer.Layer<\n\tSelf,\n\tnever,\n\t(A extends Context.Key<infer I, any> ? I : never) | R\n> = internal.layer as never\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+DA,IAAa,WAAb,cAA8B,QAAQ,QAGpC,CAAC,CAAC,kCAAkC,CAAC,CAAC,CAAC;;;;;;;;;AAUzC,IAAa,gBAAb,cAAmC,QAAQ,QAMzC,CAAC,CAAC,uCAAuC,CAAC,CAAC,CAAC;;;;;;;;;;;;AAa9C,MAAa,WAUMA;;;;;;;;;AAUnB,MAAa,SAAS;CACA,UAAA,KAAK,cAAc,OAAO,GAAG,CAAC;CACtB,kBAAA,KAAK,cAAc,OAAO,GAAG,CAAC;CACxC,QAAA,KAAK,cAAc,OAAO,GAAG,CAAC;AAClD;;;;;;;;;;;;;;;AAgBA,MAAa,QAYTC"}
|
package/dist/Policy.d.ts
ADDED
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
import { Condition, Encoded, FieldPath, Variance } from "./Condition.js";
|
|
2
|
+
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 { Decision } from "./Decision.js";
|
|
5
|
+
import * as Effect from "effect/Effect";
|
|
6
|
+
import * as Equal from "effect/Equal";
|
|
7
|
+
import * as Schema from "effect/Schema";
|
|
8
|
+
import * as Inspectable from "effect/Inspectable";
|
|
9
|
+
import * as Pipeable from "effect/Pipeable";
|
|
10
|
+
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, TypeId, all, any, ceiling, decide, decideSync, define, empty, explain, firstOf, isPolicy, permittedFields, residual, rules, schema };
|
|
12
|
+
}
|
|
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
|
+
/**
|
|
26
|
+
* @stability stable
|
|
27
|
+
* @category models
|
|
28
|
+
* @since 0.3.0
|
|
29
|
+
*/
|
|
30
|
+
export type Algorithm = "denyOverrides" | "permitOverrides" | "firstApplicable" | "lastApplicable";
|
|
31
|
+
/**
|
|
32
|
+
* @stability stable
|
|
33
|
+
* @category models
|
|
34
|
+
* @since 0.3.0
|
|
35
|
+
*/
|
|
36
|
+
export interface RulesNode {
|
|
37
|
+
readonly _tag: "Rules";
|
|
38
|
+
readonly algorithm: Algorithm;
|
|
39
|
+
readonly rules: ReadonlyArray<Any$2>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* @stability stable
|
|
43
|
+
* @category models
|
|
44
|
+
* @since 0.3.0
|
|
45
|
+
*/
|
|
46
|
+
export interface AllNode {
|
|
47
|
+
readonly _tag: "All";
|
|
48
|
+
readonly policies: ReadonlyArray<Node>;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* @stability stable
|
|
52
|
+
* @category models
|
|
53
|
+
* @since 0.3.0
|
|
54
|
+
*/
|
|
55
|
+
export interface AnyNode {
|
|
56
|
+
readonly _tag: "Any";
|
|
57
|
+
readonly policies: ReadonlyArray<Node>;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* @stability stable
|
|
61
|
+
* @category models
|
|
62
|
+
* @since 0.3.0
|
|
63
|
+
*/
|
|
64
|
+
export interface FirstOfNode {
|
|
65
|
+
readonly _tag: "FirstOf";
|
|
66
|
+
readonly policies: ReadonlyArray<Node>;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* @stability stable
|
|
70
|
+
* @category models
|
|
71
|
+
* @since 0.3.0
|
|
72
|
+
*/
|
|
73
|
+
export interface CeilingNode {
|
|
74
|
+
readonly _tag: "Ceiling";
|
|
75
|
+
readonly cap: Node;
|
|
76
|
+
readonly policy: Node;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The nodes of a policy tree.
|
|
80
|
+
*
|
|
81
|
+
* @stability stable
|
|
82
|
+
* @category models
|
|
83
|
+
* @since 0.3.0
|
|
84
|
+
*/
|
|
85
|
+
export type Node = RulesNode | AllNode | AnyNode | FirstOfNode | CeilingNode;
|
|
86
|
+
/**
|
|
87
|
+
* A policy for the domain `D`. `E`, `R` and `O` come from the conditions of
|
|
88
|
+
* its rules. See `Condition.Condition`.
|
|
89
|
+
*
|
|
90
|
+
* @stability stable
|
|
91
|
+
* @category models
|
|
92
|
+
* @since 0.3.0
|
|
93
|
+
*/
|
|
94
|
+
export interface Policy<D extends Any$1, E = never, R = never, O = never> extends Equal.Equal, Inspectable.Inspectable, Pipeable.Pipeable {
|
|
95
|
+
readonly [TypeId]: TypeId;
|
|
96
|
+
readonly domain: D;
|
|
97
|
+
readonly node: Node;
|
|
98
|
+
readonly "~Policy"?: Variance<E, R, O>;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Any policy.
|
|
102
|
+
*
|
|
103
|
+
* @stability stable
|
|
104
|
+
* @category models
|
|
105
|
+
* @since 0.3.0
|
|
106
|
+
*/
|
|
107
|
+
export type Any = Policy<any, any, any, any>;
|
|
108
|
+
/**
|
|
109
|
+
* The domain of a policy.
|
|
110
|
+
*
|
|
111
|
+
* @stability stable
|
|
112
|
+
* @category utility types
|
|
113
|
+
* @since 0.3.0
|
|
114
|
+
*/
|
|
115
|
+
export type DomainOf<P> = P extends Policy<infer D, any, any, any> ? D : never;
|
|
116
|
+
/**
|
|
117
|
+
* The error type of a policy.
|
|
118
|
+
*
|
|
119
|
+
* @stability stable
|
|
120
|
+
* @category utility types
|
|
121
|
+
* @since 0.3.0
|
|
122
|
+
*/
|
|
123
|
+
export type Error<P> = P extends {
|
|
124
|
+
readonly "~Policy"?: Variance<infer E, infer _R, infer _O>;
|
|
125
|
+
} ? E : never;
|
|
126
|
+
/**
|
|
127
|
+
* The service type of a policy.
|
|
128
|
+
*
|
|
129
|
+
* @stability stable
|
|
130
|
+
* @category utility types
|
|
131
|
+
* @since 0.3.0
|
|
132
|
+
*/
|
|
133
|
+
export type Services<P> = P extends {
|
|
134
|
+
readonly "~Policy"?: Variance<infer _E, infer R, infer _O>;
|
|
135
|
+
} ? R : never;
|
|
136
|
+
/**
|
|
137
|
+
* `Condition.Opaque` when a policy has a predicate.
|
|
138
|
+
*
|
|
139
|
+
* @stability stable
|
|
140
|
+
* @category utility types
|
|
141
|
+
* @since 0.3.0
|
|
142
|
+
*/
|
|
143
|
+
export type OpaqueOf<P> = P extends {
|
|
144
|
+
readonly "~Policy"?: Variance<infer _E, infer _R, infer O>;
|
|
145
|
+
} ? O : never;
|
|
146
|
+
/**
|
|
147
|
+
* One act on one resource value, for each kind of the domain. The action must
|
|
148
|
+
* be an action of the kind, and the field must be a field of the kind.
|
|
149
|
+
*
|
|
150
|
+
* @stability stable
|
|
151
|
+
* @category models
|
|
152
|
+
* @since 0.3.0
|
|
153
|
+
*/
|
|
154
|
+
export type Target<D> = { [K in Kind<D>]: {
|
|
155
|
+
readonly action: ActionOf<D, K>;
|
|
156
|
+
readonly resource: ValueOf<D, K>;
|
|
157
|
+
readonly field?: FieldPath<DataOf<D, K>>;
|
|
158
|
+
}; }[Kind<D>];
|
|
159
|
+
/**
|
|
160
|
+
* One act on one kind of resource, with no value.
|
|
161
|
+
*
|
|
162
|
+
* @stability stable
|
|
163
|
+
* @category models
|
|
164
|
+
* @since 0.3.0
|
|
165
|
+
*/
|
|
166
|
+
export type KindTarget<D> = { [K in Kind<D>]: {
|
|
167
|
+
readonly action: ActionOf<D, K>;
|
|
168
|
+
readonly kind: K;
|
|
169
|
+
readonly field?: FieldPath<DataOf<D, K>>;
|
|
170
|
+
}; }[Kind<D>];
|
|
171
|
+
/**
|
|
172
|
+
* A request: a principal, an action, and a resource value.
|
|
173
|
+
*
|
|
174
|
+
* @stability stable
|
|
175
|
+
* @category models
|
|
176
|
+
* @since 0.3.0
|
|
177
|
+
*/
|
|
178
|
+
export type Request<D> = Target<D> & {
|
|
179
|
+
readonly principal: Principal<D>;
|
|
180
|
+
};
|
|
181
|
+
/**
|
|
182
|
+
* A request about a kind of resource, with no value.
|
|
183
|
+
*
|
|
184
|
+
* @stability stable
|
|
185
|
+
* @category models
|
|
186
|
+
* @since 0.3.0
|
|
187
|
+
*/
|
|
188
|
+
export type KindRequest<D> = KindTarget<D> & {
|
|
189
|
+
readonly principal: Principal<D>;
|
|
190
|
+
};
|
|
191
|
+
/**
|
|
192
|
+
* A request with no types.
|
|
193
|
+
*
|
|
194
|
+
* @stability stable
|
|
195
|
+
* @category models
|
|
196
|
+
* @since 0.3.0
|
|
197
|
+
*/
|
|
198
|
+
export interface AnyRequest {
|
|
199
|
+
readonly principal: object;
|
|
200
|
+
readonly action: string;
|
|
201
|
+
readonly resource: object;
|
|
202
|
+
readonly field?: string | undefined;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* One rule that a decision tested. `path` gives the place of the rule in the
|
|
206
|
+
* policy tree: the index of each child, then the index of the rule.
|
|
207
|
+
*
|
|
208
|
+
* @stability stable
|
|
209
|
+
* @category models
|
|
210
|
+
* @since 0.3.0
|
|
211
|
+
*/
|
|
212
|
+
export interface Step {
|
|
213
|
+
readonly path: ReadonlyArray<number>;
|
|
214
|
+
readonly rule: Any$2;
|
|
215
|
+
readonly applies: boolean;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* A decision, and the rules that were tested to make it, in order. Keep it in
|
|
219
|
+
* an audit log.
|
|
220
|
+
*
|
|
221
|
+
* @stability stable
|
|
222
|
+
* @category models
|
|
223
|
+
* @since 0.3.0
|
|
224
|
+
*/
|
|
225
|
+
export interface Explanation {
|
|
226
|
+
readonly decision: Decision;
|
|
227
|
+
readonly steps: ReadonlyArray<Step>;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* The options of a list of rules.
|
|
231
|
+
*
|
|
232
|
+
* @stability stable
|
|
233
|
+
* @category models
|
|
234
|
+
* @since 0.3.0
|
|
235
|
+
*/
|
|
236
|
+
export interface Options {
|
|
237
|
+
/** The default is `denyOverrides`. */
|
|
238
|
+
readonly algorithm?: Algorithm;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Makes a policy from a generator function that gives rules. It is pure and it
|
|
242
|
+
* gives its result at once.
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
* ```ts
|
|
246
|
+
* const policy = Policy.define(App)(function* (_) {
|
|
247
|
+
* yield* _.allow("read", Bot)
|
|
248
|
+
* yield* _.allow(["update", "delete"], Bot, {
|
|
249
|
+
* when: ($) => $.eq("ownerUserId", $.principal("userId")),
|
|
250
|
+
* })
|
|
251
|
+
* })
|
|
252
|
+
* ```
|
|
253
|
+
*
|
|
254
|
+
* @stability stable
|
|
255
|
+
* @category constructors
|
|
256
|
+
* @since 0.3.0
|
|
257
|
+
*/
|
|
258
|
+
export declare const define: <D extends Any$1>(domain: D, options?: Options) => <Rules extends Any$2, A>(body: (builder: Builder<D>) => Generator<Rules, A, unknown>) => Policy<D, Error$1<Rules>, Services$1<Rules>, OpaqueOf$1<Rules>>;
|
|
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>>;
|
|
267
|
+
/**
|
|
268
|
+
* A policy with no rules. It is not applicable to any request.
|
|
269
|
+
*
|
|
270
|
+
* @stability stable
|
|
271
|
+
* @category constructors
|
|
272
|
+
* @since 0.3.0
|
|
273
|
+
*/
|
|
274
|
+
export declare const empty: <D extends Any$1>(domain: D) => Policy<D>;
|
|
275
|
+
type Combined<D extends Any$1, Ps extends ReadonlyArray<Any>> = Policy<D, Error<Ps[number]>, Services<Ps[number]>, OpaqueOf<Ps[number]>>;
|
|
276
|
+
/**
|
|
277
|
+
* Every policy must allow, and one deny is enough to deny. With some policies
|
|
278
|
+
* not applicable and none that deny, the result is not applicable.
|
|
279
|
+
*
|
|
280
|
+
* @stability stable
|
|
281
|
+
* @category combinators
|
|
282
|
+
* @since 0.3.0
|
|
283
|
+
*/
|
|
284
|
+
export declare const all: <const Ps extends readonly [Policy<any, any, any, any>, ...Array<Any>]>(policies: Ps) => Combined<DomainOf<Ps[0]>, Ps>;
|
|
285
|
+
/**
|
|
286
|
+
* One allow is enough. Without an allow, one deny gives a deny.
|
|
287
|
+
*
|
|
288
|
+
* @stability stable
|
|
289
|
+
* @category combinators
|
|
290
|
+
* @since 0.3.0
|
|
291
|
+
*/
|
|
292
|
+
export declare const any: <const Ps extends readonly [Policy<any, any, any, any>, ...Array<Any>]>(policies: Ps) => Combined<DomainOf<Ps[0]>, Ps>;
|
|
293
|
+
/**
|
|
294
|
+
* The first policy that allows or denies gives the answer.
|
|
295
|
+
*
|
|
296
|
+
* @stability stable
|
|
297
|
+
* @category combinators
|
|
298
|
+
* @since 0.3.0
|
|
299
|
+
*/
|
|
300
|
+
export declare const firstOf: <const Ps extends readonly [Policy<any, any, any, any>, ...Array<Any>]>(policies: Ps) => Combined<DomainOf<Ps[0]>, Ps>;
|
|
301
|
+
/**
|
|
302
|
+
* Puts a limit on a policy. A deny from `cap` always wins. An allow from `cap`
|
|
303
|
+
* does nothing.
|
|
304
|
+
*
|
|
305
|
+
* @stability stable
|
|
306
|
+
* @category combinators
|
|
307
|
+
* @since 0.3.0
|
|
308
|
+
*/
|
|
309
|
+
export declare const ceiling: {
|
|
310
|
+
<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
|
+
<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
|
+
};
|
|
313
|
+
/**
|
|
314
|
+
* Gives the decision of a policy for a request.
|
|
315
|
+
*
|
|
316
|
+
* @stability stable
|
|
317
|
+
* @category evaluation
|
|
318
|
+
* @since 0.3.0
|
|
319
|
+
*/
|
|
320
|
+
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>;
|
|
322
|
+
<D extends Any$1, E, R, O>(policy: Policy<D, E, R, O>, request: Request<NoInfer<D>>): Effect.Effect<Decision, E, R>;
|
|
323
|
+
};
|
|
324
|
+
/**
|
|
325
|
+
* Gives the decision of a policy with no predicates, at once.
|
|
326
|
+
*
|
|
327
|
+
* @stability stable
|
|
328
|
+
* @category evaluation
|
|
329
|
+
* @since 0.3.0
|
|
330
|
+
*/
|
|
331
|
+
export declare const decideSync: {
|
|
332
|
+
<D extends Any$1>(request: Request<D>): (policy: Policy<D>) => Decision;
|
|
333
|
+
<D extends Any$1>(policy: Policy<D>, request: Request<NoInfer<D>>): Decision;
|
|
334
|
+
};
|
|
335
|
+
/**
|
|
336
|
+
* Gives the decision of a policy and the rules that were tested to make it.
|
|
337
|
+
*
|
|
338
|
+
* @stability stable
|
|
339
|
+
* @category evaluation
|
|
340
|
+
* @since 0.3.0
|
|
341
|
+
*/
|
|
342
|
+
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>;
|
|
344
|
+
<D extends Any$1, E, R, O>(policy: Policy<D, E, R, O>, request: Request<NoInfer<D>>): Effect.Effect<Explanation, E, R>;
|
|
345
|
+
};
|
|
346
|
+
/**
|
|
347
|
+
* Gives the condition on resource values for which the policy allows a
|
|
348
|
+
* request. It has no principal fields and no `Under` nodes, so you can give it
|
|
349
|
+
* to `Condition.fold`. It is `True` when the policy allows every value of the
|
|
350
|
+
* kind, and `False` when it allows none.
|
|
351
|
+
*
|
|
352
|
+
* Predicates stay in the condition. They take the principal with them.
|
|
353
|
+
*
|
|
354
|
+
* @stability stable
|
|
355
|
+
* @category evaluation
|
|
356
|
+
* @since 0.3.0
|
|
357
|
+
*/
|
|
358
|
+
export declare const residual: {
|
|
359
|
+
<D extends Any$1>(request: KindRequest<D>): <E, R, O>(policy: Policy<D, E, R, O>) => Condition<E, R, O>;
|
|
360
|
+
<D extends Any$1, E, R, O>(policy: Policy<D, E, R, O>, request: KindRequest<NoInfer<D>>): Condition<E, R, O>;
|
|
361
|
+
};
|
|
362
|
+
/**
|
|
363
|
+
* Gives the fields of a resource value that the policy lets a request use. It
|
|
364
|
+
* tests each field of the resource Schema, with dots for nested fields.
|
|
365
|
+
*
|
|
366
|
+
* @stability stable
|
|
367
|
+
* @category evaluation
|
|
368
|
+
* @since 0.3.0
|
|
369
|
+
*/
|
|
370
|
+
export declare const permittedFields: {
|
|
371
|
+
<D extends Any$1>(request: Omit<Request<D>, "field">): <E, R, O>(policy: Policy<D, E, R, O>) => Effect.Effect<ReadonlyArray<string>, E, R>;
|
|
372
|
+
<D extends Any$1, E, R, O>(policy: Policy<D, E, R, O>, request: Omit<Request<NoInfer<D>>, "field">): Effect.Effect<ReadonlyArray<string>, E, R>;
|
|
373
|
+
};
|
|
374
|
+
/**
|
|
375
|
+
* The JSON form of a rule.
|
|
376
|
+
*
|
|
377
|
+
* @stability stable
|
|
378
|
+
* @category models
|
|
379
|
+
* @since 0.3.0
|
|
380
|
+
*/
|
|
381
|
+
export interface EncodedRule {
|
|
382
|
+
readonly _tag: "Allow" | "Deny";
|
|
383
|
+
readonly actions: ReadonlyArray<string>;
|
|
384
|
+
readonly resources: ReadonlyArray<string>;
|
|
385
|
+
readonly when?: Encoded;
|
|
386
|
+
readonly fields?: ReadonlyArray<string>;
|
|
387
|
+
readonly reason?: string;
|
|
388
|
+
readonly id?: string;
|
|
389
|
+
readonly meta?: unknown;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* The JSON form of a policy.
|
|
393
|
+
*
|
|
394
|
+
* @stability stable
|
|
395
|
+
* @category models
|
|
396
|
+
* @since 0.3.0
|
|
397
|
+
*/
|
|
398
|
+
export type EncodedNode = {
|
|
399
|
+
readonly _tag: "Rules";
|
|
400
|
+
readonly algorithm: Algorithm;
|
|
401
|
+
readonly rules: ReadonlyArray<EncodedRule>;
|
|
402
|
+
} | {
|
|
403
|
+
readonly _tag: "All" | "Any" | "FirstOf";
|
|
404
|
+
readonly policies: ReadonlyArray<EncodedNode>;
|
|
405
|
+
} | {
|
|
406
|
+
readonly _tag: "Ceiling";
|
|
407
|
+
readonly cap: EncodedNode;
|
|
408
|
+
readonly policy: EncodedNode;
|
|
409
|
+
};
|
|
410
|
+
/**
|
|
411
|
+
* The Schema of the policies of a domain with no predicates. Decoding checks
|
|
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.
|
|
414
|
+
*
|
|
415
|
+
* @stability stable
|
|
416
|
+
* @category schemas
|
|
417
|
+
* @since 0.3.0
|
|
418
|
+
*/
|
|
419
|
+
export declare const schema: <D extends Any$1>(domain: D) => Schema.Codec<Policy<D>, EncodedNode>;
|
|
420
|
+
/**
|
|
421
|
+
* Tests if a value is a policy.
|
|
422
|
+
*
|
|
423
|
+
* @stability stable
|
|
424
|
+
* @category guards
|
|
425
|
+
* @since 0.3.0
|
|
426
|
+
*/
|
|
427
|
+
export declare const isPolicy: (u: unknown) => u is Any;
|
|
428
|
+
export { Policy_d_exports };
|
|
429
|
+
//# sourceMappingURL=Policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Policy.d.ts","names":["Rule.Any","Domain.Any","Condition.Variance","Domain.Kind","Domain.ActionOf","Domain.ValueOf","Domain.DataOf","Condition.FieldPath","Domain.Principal","Decision.Decision","Rule.Builder","Rule.Error","Rule.Services","Rule.OpaqueOf","Condition.Condition","Condition.Encoded"],"sources":["../src/Policy.ts"],"mappings":"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"}
|