@nmnmcc/ability 0.1.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 +353 -170
- 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 -4
- package/dist/index.js +9 -4
- 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 -74
- 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 -516
- package/dist/Ability.js +0 -211
- package/dist/AbilityExtra.d.ts +0 -79
- package/dist/AbilityExtra.js +0 -195
- package/dist/AbilityRef.d.ts +0 -110
- package/dist/AbilityRef.js +0 -160
- package/dist/internal/ability.d.ts +0 -114
- package/dist/internal/ability.js +0 -624
- package/dist/internal/serializable.js +0 -22
package/dist/Policy.js
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { __exportAll } from "./_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { TypeId as TypeId$1, all as all$1, any as any$1, ceiling as ceiling$1, decide as decide$1, decideSync as decideSync$1, define as define$1, empty as empty$1, explain as explain$1, firstOf as firstOf$1, isPolicy as isPolicy$1, permittedFields as permittedFields$1, residual as residual$1, rules as rules$1, schema as schema$1 } from "./internal/policy.js";
|
|
3
|
+
// src/Policy.ts
|
|
4
|
+
var Policy_exports = /* @__PURE__ */ __exportAll({
|
|
5
|
+
TypeId: () => TypeId,
|
|
6
|
+
all: () => all,
|
|
7
|
+
any: () => any,
|
|
8
|
+
ceiling: () => ceiling,
|
|
9
|
+
decide: () => decide,
|
|
10
|
+
decideSync: () => decideSync,
|
|
11
|
+
define: () => define,
|
|
12
|
+
empty: () => empty,
|
|
13
|
+
explain: () => explain,
|
|
14
|
+
firstOf: () => firstOf,
|
|
15
|
+
isPolicy: () => isPolicy,
|
|
16
|
+
permittedFields: () => permittedFields,
|
|
17
|
+
residual: () => residual,
|
|
18
|
+
rules: () => rules,
|
|
19
|
+
schema: () => schema
|
|
20
|
+
});
|
|
21
|
+
/**
|
|
22
|
+
* @stability stable
|
|
23
|
+
* @category type IDs
|
|
24
|
+
* @since 0.3.0
|
|
25
|
+
*/
|
|
26
|
+
const TypeId = TypeId$1;
|
|
27
|
+
/**
|
|
28
|
+
* Makes a policy from a generator function that gives rules. It is pure and it
|
|
29
|
+
* gives its result at once.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* const policy = Policy.define(App)(function* (_) {
|
|
34
|
+
* yield* _.allow("read", Bot)
|
|
35
|
+
* yield* _.allow(["update", "delete"], Bot, {
|
|
36
|
+
* when: ($) => $.eq("ownerUserId", $.principal("userId")),
|
|
37
|
+
* })
|
|
38
|
+
* })
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @stability stable
|
|
42
|
+
* @category constructors
|
|
43
|
+
* @since 0.3.0
|
|
44
|
+
*/
|
|
45
|
+
const define = define$1;
|
|
46
|
+
/**
|
|
47
|
+
* Makes a policy from a list of rules.
|
|
48
|
+
*
|
|
49
|
+
* @stability stable
|
|
50
|
+
* @category constructors
|
|
51
|
+
* @since 0.3.0
|
|
52
|
+
*/
|
|
53
|
+
const rules = rules$1;
|
|
54
|
+
/**
|
|
55
|
+
* A policy with no rules. It is not applicable to any request.
|
|
56
|
+
*
|
|
57
|
+
* @stability stable
|
|
58
|
+
* @category constructors
|
|
59
|
+
* @since 0.3.0
|
|
60
|
+
*/
|
|
61
|
+
const empty = empty$1;
|
|
62
|
+
/**
|
|
63
|
+
* Every policy must allow, and one deny is enough to deny. With some policies
|
|
64
|
+
* not applicable and none that deny, the result is not applicable.
|
|
65
|
+
*
|
|
66
|
+
* @stability stable
|
|
67
|
+
* @category combinators
|
|
68
|
+
* @since 0.3.0
|
|
69
|
+
*/
|
|
70
|
+
const all = all$1;
|
|
71
|
+
/**
|
|
72
|
+
* One allow is enough. Without an allow, one deny gives a deny.
|
|
73
|
+
*
|
|
74
|
+
* @stability stable
|
|
75
|
+
* @category combinators
|
|
76
|
+
* @since 0.3.0
|
|
77
|
+
*/
|
|
78
|
+
const any = any$1;
|
|
79
|
+
/**
|
|
80
|
+
* The first policy that allows or denies gives the answer.
|
|
81
|
+
*
|
|
82
|
+
* @stability stable
|
|
83
|
+
* @category combinators
|
|
84
|
+
* @since 0.3.0
|
|
85
|
+
*/
|
|
86
|
+
const firstOf = firstOf$1;
|
|
87
|
+
/**
|
|
88
|
+
* Puts a limit on a policy. A deny from `cap` always wins. An allow from `cap`
|
|
89
|
+
* does nothing.
|
|
90
|
+
*
|
|
91
|
+
* @stability stable
|
|
92
|
+
* @category combinators
|
|
93
|
+
* @since 0.3.0
|
|
94
|
+
*/
|
|
95
|
+
const ceiling = ceiling$1;
|
|
96
|
+
/**
|
|
97
|
+
* Gives the decision of a policy for a request.
|
|
98
|
+
*
|
|
99
|
+
* @stability stable
|
|
100
|
+
* @category evaluation
|
|
101
|
+
* @since 0.3.0
|
|
102
|
+
*/
|
|
103
|
+
const decide = decide$1;
|
|
104
|
+
/**
|
|
105
|
+
* Gives the decision of a policy with no predicates, at once.
|
|
106
|
+
*
|
|
107
|
+
* @stability stable
|
|
108
|
+
* @category evaluation
|
|
109
|
+
* @since 0.3.0
|
|
110
|
+
*/
|
|
111
|
+
const decideSync = decideSync$1;
|
|
112
|
+
/**
|
|
113
|
+
* Gives the decision of a policy and the rules that were tested to make it.
|
|
114
|
+
*
|
|
115
|
+
* @stability stable
|
|
116
|
+
* @category evaluation
|
|
117
|
+
* @since 0.3.0
|
|
118
|
+
*/
|
|
119
|
+
const explain = explain$1;
|
|
120
|
+
/**
|
|
121
|
+
* Gives the condition on resource values for which the policy allows a
|
|
122
|
+
* request. It has no principal fields and no `Under` nodes, so you can give it
|
|
123
|
+
* to `Condition.fold`. It is `True` when the policy allows every value of the
|
|
124
|
+
* kind, and `False` when it allows none.
|
|
125
|
+
*
|
|
126
|
+
* Predicates stay in the condition. They take the principal with them.
|
|
127
|
+
*
|
|
128
|
+
* @stability stable
|
|
129
|
+
* @category evaluation
|
|
130
|
+
* @since 0.3.0
|
|
131
|
+
*/
|
|
132
|
+
const residual = residual$1;
|
|
133
|
+
/**
|
|
134
|
+
* Gives the fields of a resource value that the policy lets a request use. It
|
|
135
|
+
* tests each field of the resource Schema, with dots for nested fields.
|
|
136
|
+
*
|
|
137
|
+
* @stability stable
|
|
138
|
+
* @category evaluation
|
|
139
|
+
* @since 0.3.0
|
|
140
|
+
*/
|
|
141
|
+
const permittedFields = permittedFields$1;
|
|
142
|
+
/**
|
|
143
|
+
* The Schema of the policies of a domain with no predicates. Decoding checks
|
|
144
|
+
* every kind, action, field and principal field against the domain, and the
|
|
145
|
+
* `meta` of each rule against the `meta` Schema of the domain.
|
|
146
|
+
*
|
|
147
|
+
* @stability stable
|
|
148
|
+
* @category schemas
|
|
149
|
+
* @since 0.3.0
|
|
150
|
+
*/
|
|
151
|
+
const schema = schema$1;
|
|
152
|
+
/**
|
|
153
|
+
* Tests if a value is a policy.
|
|
154
|
+
*
|
|
155
|
+
* @stability stable
|
|
156
|
+
* @category guards
|
|
157
|
+
* @since 0.3.0
|
|
158
|
+
*/
|
|
159
|
+
const isPolicy = isPolicy$1;
|
|
160
|
+
export { Policy_exports, TypeId, all, any, ceiling, decide, decideSync, define, empty, explain, firstOf, isPolicy, permittedFields, residual, rules, schema };
|
|
161
|
+
|
|
162
|
+
//# sourceMappingURL=Policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Policy.js","names":["internal.TypeId","internal.define","internal.rules","internal.empty","internal.all","internal.any","internal.firstOf","internal.ceiling","internal.decide","internal.decideSync","internal.explain","internal.residual","internal.permittedFields","internal.schema","internal.isPolicy"],"sources":["../src/Policy.ts"],"sourcesContent":["/**\n * A policy is a tree that gives a {@link Decision.Decision} for a request.\n *\n * The leaves of the tree are lists of rules. A combining algorithm decides\n * which rule gives the answer when more than one rule applies:\n * - `denyOverrides` (the default): a deny rule wins over every allow rule.\n * - `permitOverrides`: an allow rule wins over every deny rule.\n * - `firstApplicable`: the first rule that applies wins.\n * - `lastApplicable`: the last rule that applies wins.\n *\n * The branches put policies together:\n * - {@link all}: every policy must allow, and one deny is enough to deny. Use\n * it when a user token may never do more than its user.\n * - {@link any}: one allow is enough.\n * - {@link firstOf}: the first policy that gives an answer wins. Use it for\n * grants first, then rules.\n * - {@link ceiling}: the deny rules of a second policy are a limit for\n * everyone. Its allow rules do nothing.\n *\n * A policy gives three kinds of answers:\n * - {@link decide}: the decision for one resource value.\n * - {@link residual}: a condition on resource values. A value passes when the\n * policy allows the request for that value. Use it to make a database\n * query, or to ask \"may this principal do this act on some resource of\n * this kind?\"\n * - {@link permittedFields}: the fields that the policy lets a request use.\n *\n * A policy without predicates can become JSON with {@link schema}.\n *\n * @stability stable\n * @since 0.3.0\n */\nimport type * as Effect from \"effect/Effect\"\nimport type * as Equal from \"effect/Equal\"\nimport type * as Inspectable from \"effect/Inspectable\"\nimport type * as Pipeable from \"effect/Pipeable\"\nimport type * as Schema from \"effect/Schema\"\nimport type * as Condition from \"./Condition.ts\"\nimport type * as Decision from \"./Decision.ts\"\nimport type * as Domain from \"./Domain.ts\"\nimport * as internal from \"./internal/policy.ts\"\nimport type * as Rule from \"./Rule.ts\"\n\n/**\n * @stability stable\n * @category type IDs\n * @since 0.3.0\n */\nexport const TypeId: \"~@nmnmcc/ability/Policy\" = internal.TypeId\n\n/**\n * @stability stable\n * @category type IDs\n * @since 0.3.0\n */\nexport type TypeId = typeof TypeId\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Algorithm =\n\t\"denyOverrides\" | \"permitOverrides\" | \"firstApplicable\" | \"lastApplicable\"\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface RulesNode {\n\treadonly _tag: \"Rules\"\n\treadonly algorithm: Algorithm\n\treadonly rules: ReadonlyArray<Rule.Any>\n}\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface AllNode {\n\treadonly _tag: \"All\"\n\treadonly policies: ReadonlyArray<Node>\n}\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface AnyNode {\n\treadonly _tag: \"Any\"\n\treadonly policies: ReadonlyArray<Node>\n}\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface FirstOfNode {\n\treadonly _tag: \"FirstOf\"\n\treadonly policies: ReadonlyArray<Node>\n}\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface CeilingNode {\n\treadonly _tag: \"Ceiling\"\n\treadonly cap: Node\n\treadonly policy: Node\n}\n\n/**\n * The nodes of a policy tree.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Node = RulesNode | AllNode | AnyNode | FirstOfNode | CeilingNode\n\n/**\n * A policy for the domain `D`. `E`, `R` and `O` come from the conditions of\n * its rules. See `Condition.Condition`.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Policy<D extends Domain.Any, E = never, R = never, O = never>\n\textends Equal.Equal, Inspectable.Inspectable, Pipeable.Pipeable {\n\treadonly [TypeId]: TypeId\n\treadonly domain: D\n\treadonly node: Node\n\treadonly \"~Policy\"?: Condition.Variance<E, R, O>\n}\n\n/**\n * Any policy.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Any = Policy<any, any, any, any>\n\n/**\n * The domain of a policy.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type DomainOf<P> = P extends Policy<infer D, any, any, any> ? D : never\n\n/**\n * The error type of a policy.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type Error<P> = P extends {\n\treadonly \"~Policy\"?: Condition.Variance<infer E, infer _R, infer _O>\n}\n\t? E\n\t: never\n\n/**\n * The service type of a policy.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type Services<P> = P extends {\n\treadonly \"~Policy\"?: Condition.Variance<infer _E, infer R, infer _O>\n}\n\t? R\n\t: never\n\n/**\n * `Condition.Opaque` when a policy has a predicate.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type OpaqueOf<P> = P extends {\n\treadonly \"~Policy\"?: Condition.Variance<infer _E, infer _R, infer O>\n}\n\t? O\n\t: never\n\n/**\n * One act on one resource value, for each kind of the domain. The action must\n * be an action of the kind, and the field must be a field of the kind.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Target<D> = {\n\t[K in Domain.Kind<D>]: {\n\t\treadonly action: Domain.ActionOf<D, K>\n\t\treadonly resource: Domain.ValueOf<D, K>\n\t\treadonly field?: Condition.FieldPath<Domain.DataOf<D, K>>\n\t}\n}[Domain.Kind<D>]\n\n/**\n * One act on one kind of resource, with no value.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type KindTarget<D> = {\n\t[K in Domain.Kind<D>]: {\n\t\treadonly action: Domain.ActionOf<D, K>\n\t\treadonly kind: K\n\t\treadonly field?: Condition.FieldPath<Domain.DataOf<D, K>>\n\t}\n}[Domain.Kind<D>]\n\n/**\n * A request: a principal, an action, and a resource value.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Request<D> = Target<D> & { readonly principal: Domain.Principal<D> }\n\n/**\n * A request about a kind of resource, with no value.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type KindRequest<D> = KindTarget<D> & {\n\treadonly principal: Domain.Principal<D>\n}\n\n/**\n * A request with no types.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface AnyRequest {\n\treadonly principal: object\n\treadonly action: string\n\treadonly resource: object\n\treadonly field?: string | undefined\n}\n\n/**\n * One rule that a decision tested. `path` gives the place of the rule in the\n * policy tree: the index of each child, then the index of the rule.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Step {\n\treadonly path: ReadonlyArray<number>\n\treadonly rule: Rule.Any\n\treadonly applies: boolean\n}\n\n/**\n * A decision, and the rules that were tested to make it, in order. Keep it in\n * an audit log.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Explanation {\n\treadonly decision: Decision.Decision\n\treadonly steps: ReadonlyArray<Step>\n}\n\n/**\n * The options of a list of rules.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Options {\n\t/** The default is `denyOverrides`. */\n\treadonly algorithm?: Algorithm\n}\n\n/**\n * Makes a policy from a generator function that gives rules. It is pure and it\n * gives its result at once.\n *\n * @example\n * ```ts\n * const policy = Policy.define(App)(function* (_) {\n * yield* _.allow(\"read\", Bot)\n * yield* _.allow([\"update\", \"delete\"], Bot, {\n * when: ($) => $.eq(\"ownerUserId\", $.principal(\"userId\")),\n * })\n * })\n * ```\n *\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const define: <D extends Domain.Any>(\n\tdomain: D,\n\toptions?: Options,\n) => <Rules extends Rule.Any, A>(\n\tbody: (builder: Rule.Builder<D>) => Generator<Rules, A, unknown>,\n) => Policy<D, Rule.Error<Rules>, Rule.Services<Rules>, Rule.OpaqueOf<Rules>> =\n\tinternal.define as never\n\n/**\n * Makes a policy from a list of rules.\n *\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const rules: <D extends Domain.Any, Rules extends Rule.Any>(\n\tdomain: D,\n\trules: Iterable<Rules>,\n\toptions?: Options,\n) => Policy<D, Rule.Error<Rules>, Rule.Services<Rules>, Rule.OpaqueOf<Rules>> =\n\tinternal.rules\n\n/**\n * A policy with no rules. It is not applicable to any request.\n *\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const empty: <D extends Domain.Any>(domain: D) => Policy<D> =\n\tinternal.empty\n\ntype Combined<D extends Domain.Any, Ps extends ReadonlyArray<Any>> = Policy<\n\tD,\n\tError<Ps[number]>,\n\tServices<Ps[number]>,\n\tOpaqueOf<Ps[number]>\n>\n\n/**\n * Every policy must allow, and one deny is enough to deny. With some policies\n * not applicable and none that deny, the result is not applicable.\n *\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const all: <\n\tconst Ps extends readonly [Policy<any, any, any, any>, ...Array<Any>],\n>(\n\tpolicies: Ps,\n) => Combined<DomainOf<Ps[0]>, Ps> = internal.all\n\n/**\n * One allow is enough. Without an allow, one deny gives a deny.\n *\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const any: <\n\tconst Ps extends readonly [Policy<any, any, any, any>, ...Array<Any>],\n>(\n\tpolicies: Ps,\n) => Combined<DomainOf<Ps[0]>, Ps> = internal.any\n\n/**\n * The first policy that allows or denies gives the answer.\n *\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const firstOf: <\n\tconst Ps extends readonly [Policy<any, any, any, any>, ...Array<Any>],\n>(\n\tpolicies: Ps,\n) => Combined<DomainOf<Ps[0]>, Ps> = internal.firstOf\n\n/**\n * Puts a limit on a policy. A deny from `cap` always wins. An allow from `cap`\n * does nothing.\n *\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const ceiling: {\n\t<D extends Domain.Any, E2, R2, O2>(\n\t\tcap: Policy<D, E2, R2, O2>,\n\t): <E, R, O>(policy: Policy<D, E, R, O>) => Policy<D, E | E2, R | R2, O | O2>\n\t<D extends Domain.Any, E, R, O, E2, R2, O2>(\n\t\tpolicy: Policy<D, E, R, O>,\n\t\tcap: Policy<D, E2, R2, O2>,\n\t): Policy<D, E | E2, R | R2, O | O2>\n} = internal.ceiling\n\n/**\n * Gives the decision of a policy for a request.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const decide: {\n\t<D extends Domain.Any>(\n\t\trequest: Request<D>,\n\t): <E, R, O>(\n\t\tpolicy: Policy<D, E, R, O>,\n\t) => Effect.Effect<Decision.Decision, E, R>\n\t<D extends Domain.Any, E, R, O>(\n\t\tpolicy: Policy<D, E, R, O>,\n\t\trequest: Request<NoInfer<D>>,\n\t): Effect.Effect<Decision.Decision, E, R>\n} = internal.decide as never\n\n/**\n * Gives the decision of a policy with no predicates, at once.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const decideSync: {\n\t<D extends Domain.Any>(\n\t\trequest: Request<D>,\n\t): (policy: Policy<D>) => Decision.Decision\n\t<D extends Domain.Any>(\n\t\tpolicy: Policy<D>,\n\t\trequest: Request<NoInfer<D>>,\n\t): Decision.Decision\n} = internal.decideSync\n\n/**\n * Gives the decision of a policy and the rules that were tested to make it.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const explain: {\n\t<D extends Domain.Any>(\n\t\trequest: Request<D>,\n\t): <E, R, O>(policy: Policy<D, E, R, O>) => Effect.Effect<Explanation, E, R>\n\t<D extends Domain.Any, E, R, O>(\n\t\tpolicy: Policy<D, E, R, O>,\n\t\trequest: Request<NoInfer<D>>,\n\t): Effect.Effect<Explanation, E, R>\n} = internal.explain as never\n\n/**\n * Gives the condition on resource values for which the policy allows a\n * request. It has no principal fields and no `Under` nodes, so you can give it\n * to `Condition.fold`. It is `True` when the policy allows every value of the\n * kind, and `False` when it allows none.\n *\n * Predicates stay in the condition. They take the principal with them.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const residual: {\n\t<D extends Domain.Any>(\n\t\trequest: KindRequest<D>,\n\t): <E, R, O>(policy: Policy<D, E, R, O>) => Condition.Condition<E, R, O>\n\t<D extends Domain.Any, E, R, O>(\n\t\tpolicy: Policy<D, E, R, O>,\n\t\trequest: KindRequest<NoInfer<D>>,\n\t): Condition.Condition<E, R, O>\n} = internal.residual as never\n\n/**\n * Gives the fields of a resource value that the policy lets a request use. It\n * tests each field of the resource Schema, with dots for nested fields.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const permittedFields: {\n\t<D extends Domain.Any>(\n\t\trequest: Omit<Request<D>, \"field\">,\n\t): <E, R, O>(\n\t\tpolicy: Policy<D, E, R, O>,\n\t) => Effect.Effect<ReadonlyArray<string>, E, R>\n\t<D extends Domain.Any, E, R, O>(\n\t\tpolicy: Policy<D, E, R, O>,\n\t\trequest: Omit<Request<NoInfer<D>>, \"field\">,\n\t): Effect.Effect<ReadonlyArray<string>, E, R>\n} = internal.permittedFields as never\n\n/**\n * The JSON form of a rule.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface EncodedRule {\n\treadonly _tag: \"Allow\" | \"Deny\"\n\treadonly actions: ReadonlyArray<string>\n\treadonly resources: ReadonlyArray<string>\n\treadonly when?: Condition.Encoded\n\treadonly fields?: ReadonlyArray<string>\n\treadonly reason?: string\n\treadonly id?: string\n\treadonly meta?: unknown\n}\n\n/**\n * The JSON form of a policy.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type EncodedNode =\n\t| {\n\t\t\treadonly _tag: \"Rules\"\n\t\t\treadonly algorithm: Algorithm\n\t\t\treadonly rules: ReadonlyArray<EncodedRule>\n\t }\n\t| {\n\t\t\treadonly _tag: \"All\" | \"Any\" | \"FirstOf\"\n\t\t\treadonly policies: ReadonlyArray<EncodedNode>\n\t }\n\t| {\n\t\t\treadonly _tag: \"Ceiling\"\n\t\t\treadonly cap: EncodedNode\n\t\t\treadonly policy: EncodedNode\n\t }\n\n/**\n * The Schema of the policies of a domain with no predicates. Decoding checks\n * every kind, action, field and principal field against the domain, and the\n * `meta` of each rule against the `meta` Schema of the domain.\n *\n * @stability stable\n * @category schemas\n * @since 0.3.0\n */\nexport const schema: <D extends Domain.Any>(\n\tdomain: D,\n) => Schema.Codec<Policy<D>, EncodedNode> = internal.schema\n\n/**\n * Tests if a value is a policy.\n *\n * @stability stable\n * @category guards\n * @since 0.3.0\n */\nexport const isPolicy: (u: unknown) => u is Any = internal.isPolicy\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAgDA,MAAa,SAAoCA;;;;;;;;;;;;;;;;;;;AAiRjD,MAAa,SAMZC;;;;;;;;AASD,MAAa,QAKZC;;;;;;;;AASD,MAAa,QACZC;;;;;;;;;AAiBD,MAAa,MAIwBC;;;;;;;;AASrC,MAAa,MAIwBC;;;;;;;;AASrC,MAAa,UAIwBC;;;;;;;;;AAUrC,MAAa,UAQTC;;;;;;;;AASJ,MAAa,SAUTC;;;;;;;;AASJ,MAAa,aAQTC;;;;;;;;AASJ,MAAa,UAQTC;;;;;;;;;;;;;AAcJ,MAAa,WAQTC;;;;;;;;;AAUJ,MAAa,kBAUTC;;;;;;;;;;AAoDJ,MAAa,SAE+BC;;;;;;;;AAS5C,MAAa,WAAqCC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema";
|
|
2
|
+
declare namespace Principal_d_exports {
|
|
3
|
+
export { Any, Class };
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Any Schema that can be a principal. Its type must be an object.
|
|
7
|
+
*
|
|
8
|
+
* @stability stable
|
|
9
|
+
* @category models
|
|
10
|
+
* @since 0.3.0
|
|
11
|
+
*/
|
|
12
|
+
export type Any = Schema.Top & {
|
|
13
|
+
readonly Type: object;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Makes a principal as a Schema class. It is the same as `Schema.Class`.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { Schema } from "effect"
|
|
21
|
+
* import { Principal } from "@nmnmcc/ability"
|
|
22
|
+
*
|
|
23
|
+
* class Caller extends Principal.Class<Caller>("Caller")({
|
|
24
|
+
* userId: Schema.String,
|
|
25
|
+
* organizationId: Schema.String,
|
|
26
|
+
* }) {}
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @stability stable
|
|
30
|
+
* @category constructors
|
|
31
|
+
* @since 0.3.0
|
|
32
|
+
*/
|
|
33
|
+
export declare const Class: typeof Schema.Class;
|
|
34
|
+
export { Principal_d_exports };
|
|
35
|
+
//# sourceMappingURL=Principal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Principal.d.ts","names":[],"sources":["../src/Principal.ts"],"mappings":";;;;;;;;;;;YAoBY,MAAM,OAAO;WAAiB;;;;;;;;;;;;;;;;;;;;qBAoB7B,cAAc,OAAO"}
|
|
@@ -0,0 +1,37 @@
|
|
|
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, a user
|
|
6
|
+
* token, or a Bot.
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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, a user\n * token, or a Bot.\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"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema";
|
|
2
|
+
declare namespace Resource_d_exports {
|
|
3
|
+
export { Action, Any, Class, Data, Descriptor, FieldRef, Kind, Options, PathSegment, Resource, Struct, TypeId, Value, descriptor, isResource, make };
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* @stability stable
|
|
7
|
+
* @category type IDs
|
|
8
|
+
* @since 0.3.0
|
|
9
|
+
*/
|
|
10
|
+
export declare const TypeId: "~@nmnmcc/ability/Resource";
|
|
11
|
+
/**
|
|
12
|
+
* @stability stable
|
|
13
|
+
* @category type IDs
|
|
14
|
+
* @since 0.3.0
|
|
15
|
+
*/
|
|
16
|
+
export type TypeId = typeof TypeId;
|
|
17
|
+
/**
|
|
18
|
+
* One part of a resource path. A string is a fixed part. A field reference
|
|
19
|
+
* takes the part from a field of the value.
|
|
20
|
+
*
|
|
21
|
+
* @stability stable
|
|
22
|
+
* @category models
|
|
23
|
+
* @since 0.3.0
|
|
24
|
+
*/
|
|
25
|
+
export type PathSegment = string | FieldRef<string>;
|
|
26
|
+
/**
|
|
27
|
+
* A reference to a top-level field of a resource, used in a path.
|
|
28
|
+
*
|
|
29
|
+
* @stability stable
|
|
30
|
+
* @category models
|
|
31
|
+
* @since 0.3.0
|
|
32
|
+
*/
|
|
33
|
+
export interface FieldRef<Name extends string> {
|
|
34
|
+
readonly _tag: "Field";
|
|
35
|
+
readonly field: Name;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The runtime data of a resource.
|
|
39
|
+
*
|
|
40
|
+
* @stability stable
|
|
41
|
+
* @category models
|
|
42
|
+
* @since 0.3.0
|
|
43
|
+
*/
|
|
44
|
+
export interface Descriptor {
|
|
45
|
+
readonly kind: string;
|
|
46
|
+
readonly actions: ReadonlyArray<string>;
|
|
47
|
+
readonly path: ReadonlyArray<PathSegment> | undefined;
|
|
48
|
+
/** The paths of the data fields, with dots for nested fields. */
|
|
49
|
+
readonly fieldPaths: ReadonlyArray<string>;
|
|
50
|
+
/** The Schema of the values, with the `_tag` field. */
|
|
51
|
+
readonly schema: Schema.Top;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* A resource. `Kind` is its name, `Action` is the union of its actions, `Data`
|
|
55
|
+
* is the type of its Schema fields, and `Value` is the type of its values.
|
|
56
|
+
*
|
|
57
|
+
* @stability stable
|
|
58
|
+
* @category models
|
|
59
|
+
* @since 0.3.0
|
|
60
|
+
*/
|
|
61
|
+
export interface Resource<Kind extends string, Action extends string, Data extends object, Value extends {
|
|
62
|
+
readonly _tag: Kind;
|
|
63
|
+
}> {
|
|
64
|
+
readonly [TypeId]: Descriptor;
|
|
65
|
+
readonly "~Resource"?: {
|
|
66
|
+
readonly Kind: Kind;
|
|
67
|
+
readonly Action: Action;
|
|
68
|
+
readonly Data: Data;
|
|
69
|
+
readonly Value: Value;
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Any resource.
|
|
74
|
+
*
|
|
75
|
+
* @stability stable
|
|
76
|
+
* @category models
|
|
77
|
+
* @since 0.3.0
|
|
78
|
+
*/
|
|
79
|
+
export type Any = Resource<string, string, object, {
|
|
80
|
+
readonly _tag: string;
|
|
81
|
+
}>;
|
|
82
|
+
/**
|
|
83
|
+
* The kind name of a resource.
|
|
84
|
+
*
|
|
85
|
+
* @stability stable
|
|
86
|
+
* @category utility types
|
|
87
|
+
* @since 0.3.0
|
|
88
|
+
*/
|
|
89
|
+
export type Kind<R> = R extends Resource<infer K, any, any, any> ? K : never;
|
|
90
|
+
/**
|
|
91
|
+
* The actions of a resource.
|
|
92
|
+
*
|
|
93
|
+
* @stability stable
|
|
94
|
+
* @category utility types
|
|
95
|
+
* @since 0.3.0
|
|
96
|
+
*/
|
|
97
|
+
export type Action<R> = R extends Resource<any, infer A, any, any> ? A : never;
|
|
98
|
+
/**
|
|
99
|
+
* The type of the Schema fields of a resource, without `_tag`.
|
|
100
|
+
*
|
|
101
|
+
* @stability stable
|
|
102
|
+
* @category utility types
|
|
103
|
+
* @since 0.3.0
|
|
104
|
+
*/
|
|
105
|
+
export type Data<R> = R extends Resource<any, any, infer D, any> ? D : never;
|
|
106
|
+
/**
|
|
107
|
+
* The type of the values of a resource.
|
|
108
|
+
*
|
|
109
|
+
* @stability stable
|
|
110
|
+
* @category utility types
|
|
111
|
+
* @since 0.3.0
|
|
112
|
+
*/
|
|
113
|
+
export type Value<R> = R extends Resource<any, any, any, infer V> ? V : never;
|
|
114
|
+
/**
|
|
115
|
+
* The options of a resource.
|
|
116
|
+
*
|
|
117
|
+
* @stability stable
|
|
118
|
+
* @category models
|
|
119
|
+
* @since 0.3.0
|
|
120
|
+
*/
|
|
121
|
+
export interface Options<Actions extends ReadonlyArray<string>, Fields extends Schema.Struct.Fields> {
|
|
122
|
+
readonly actions: Actions;
|
|
123
|
+
readonly fields: Fields;
|
|
124
|
+
/**
|
|
125
|
+
* Gives the path of the resource. The function gets one reference for each
|
|
126
|
+
* top-level field.
|
|
127
|
+
*/
|
|
128
|
+
readonly path?: (fields: { readonly [K in keyof Fields & string]: FieldRef<K>; }) => ReadonlyArray<PathSegment>;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* The type of a class made by {@link Class}.
|
|
132
|
+
*
|
|
133
|
+
* @stability stable
|
|
134
|
+
* @category models
|
|
135
|
+
* @since 0.3.0
|
|
136
|
+
*/
|
|
137
|
+
export type Class<Self, Kind extends string, Actions extends ReadonlyArray<string>, Fields extends Schema.Struct.Fields> = Schema.Class<Self, Schema.TaggedStruct<Kind, Fields>, {}> & Resource<Kind, Actions[number], Schema.Struct.Type<Fields>, Self & {
|
|
138
|
+
readonly _tag: Kind;
|
|
139
|
+
}> & {
|
|
140
|
+
readonly kind: Kind;
|
|
141
|
+
readonly actions: Actions;
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Makes a resource as a Schema class. Use it in the same way as
|
|
145
|
+
* `Schema.TaggedClass`.
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```ts
|
|
149
|
+
* import { Schema } from "effect"
|
|
150
|
+
* import { Resource } from "@nmnmcc/ability"
|
|
151
|
+
*
|
|
152
|
+
* class Bot extends Resource.Class<Bot>()("Bot", {
|
|
153
|
+
* actions: ["read", "update"],
|
|
154
|
+
* fields: {
|
|
155
|
+
* id: Schema.String,
|
|
156
|
+
* ownerUserId: Schema.NullOr(Schema.String),
|
|
157
|
+
* },
|
|
158
|
+
* path: (f) => ["user", f.ownerUserId, "bot", f.id],
|
|
159
|
+
* }) {}
|
|
160
|
+
*
|
|
161
|
+
* const bot = new Bot({ id: "b1", ownerUserId: "u1" })
|
|
162
|
+
* ```
|
|
163
|
+
*
|
|
164
|
+
* @stability stable
|
|
165
|
+
* @category constructors
|
|
166
|
+
* @since 0.3.0
|
|
167
|
+
*/
|
|
168
|
+
export declare const Class: <Self = never>(identifier?: string) => <const Kind extends string, const Actions extends ReadonlyArray<string>, const Fields extends Schema.Struct.Fields>(kind: Kind, options: Options<Actions, Fields>) => [Self] extends [never] ? "Missing `Self` type: use Resource.Class<Self>()(...)" : Class<Self, Kind, Actions, Fields>;
|
|
169
|
+
/**
|
|
170
|
+
* A resource made by {@link make}. Its values are plain objects.
|
|
171
|
+
*
|
|
172
|
+
* @stability stable
|
|
173
|
+
* @category models
|
|
174
|
+
* @since 0.3.0
|
|
175
|
+
*/
|
|
176
|
+
export interface Struct<Kind extends string, Actions extends ReadonlyArray<string>, Fields extends Schema.Struct.Fields> extends Resource<Kind, Actions[number], Schema.Struct.Type<Fields>, Schema.Struct.Type<Fields> & {
|
|
177
|
+
readonly _tag: Kind;
|
|
178
|
+
}> {
|
|
179
|
+
readonly kind: Kind;
|
|
180
|
+
readonly actions: Actions;
|
|
181
|
+
readonly schema: Schema.TaggedStruct<Kind, Fields>;
|
|
182
|
+
/** Makes a value. It puts the `_tag` field on the value for you. */
|
|
183
|
+
readonly make: (input: Schema.Struct.Type<Fields>) => Schema.Struct.Type<Fields> & {
|
|
184
|
+
readonly _tag: Kind;
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Makes a resource from plain fields. Its values are plain objects with a
|
|
189
|
+
* `_tag` field.
|
|
190
|
+
*
|
|
191
|
+
* @stability stable
|
|
192
|
+
* @category constructors
|
|
193
|
+
* @since 0.3.0
|
|
194
|
+
*/
|
|
195
|
+
export declare const make: <const Kind extends string, const Actions extends ReadonlyArray<string>, const Fields extends Schema.Struct.Fields>(kind: Kind, options: Options<Actions, Fields>) => Struct<Kind, Actions, Fields>;
|
|
196
|
+
/**
|
|
197
|
+
* Tests if a value is a resource.
|
|
198
|
+
*
|
|
199
|
+
* @stability stable
|
|
200
|
+
* @category guards
|
|
201
|
+
* @since 0.3.0
|
|
202
|
+
*/
|
|
203
|
+
export declare const isResource: (u: unknown) => u is Any;
|
|
204
|
+
/**
|
|
205
|
+
* Gets the runtime data of a resource.
|
|
206
|
+
*
|
|
207
|
+
* @stability stable
|
|
208
|
+
* @category getters
|
|
209
|
+
* @since 0.3.0
|
|
210
|
+
*/
|
|
211
|
+
export declare const descriptor: (resource: Any) => Descriptor;
|
|
212
|
+
export { Resource_d_exports };
|
|
213
|
+
//# sourceMappingURL=Resource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Resource.d.ts","names":[],"sources":["../src/Resource.ts"],"mappings":";;;;;;;;;qBA+Ba;;;;;;YAOD,gBAAgB;;;;;;;;;YAUhB,uBAAuB;;;;;;;;iBASlB,SAAS;WAChB;WACA,OAAO;;;;;;;;;iBAUA;WACP;WACA,SAAS;WACT,MAAM,cAAc;;WAEpB,YAAY;;WAEZ,QAAQ,OAAO;;;;;;;;;;iBAWR,SAChB,qBACA,uBACA,qBACA;WAAyB,MAAM;;YAErB,SAAS;WACV;aACC,MAAM;aACN,QAAQ;aACR,MAAM;aACN,OAAO;;;;;;;;;;YAWN,MAAM;WAA4C;;;;;;;;;YASlD,KAAK,KAAK,UAAU,eAAe,oBAAoB;;;;;;;;YASvD,OAAO,KAAK,UAAU,oBAAoB,eAAe;;;;;;;;YASzD,KAAK,KAAK,UAAU,yBAAyB,UAAU;;;;;;;;YASvD,MAAM,KAAK,UAAU,8BAA8B,KAAK;;;;;;;;iBASnD,QAChB,gBAAgB,uBAChB,eAAe,OAAO,OAAO;WAEpB,SAAS;WACT,QAAQ;;;;;WAKR,QAAQ,oBACN,WAAW,kBAAkB,SAAS,UAC3C,cAAc;;;;;;;;;YAUT,MACX,MACA,qBACA,gBAAgB,uBAChB,eAAe,OAAO,OAAO,UAC1B,OAAO,MAAM,MAAM,OAAO,aAAa,MAAM,eAChD,SACC,MACA,iBACA,OAAO,OAAO,KAAK,SACnB;WAAkB,MAAM;;WAEf,MAAM;WACN,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;qBA4BP,QAAQ,cACpB,+BAEM,2BACA,gBAAgB,6BAChB,eAAe,OAAO,OAAO,QAEnC,MAAM,MACN,SAAS,QAAQ,SAAS,aACrB,iFAEH,MAAM,MAAM,MAAM,SAAS;;;;;;;;iBASb,OAChB,qBACA,gBAAgB,uBAChB,eAAe,OAAO,OAAO,gBACpB,SACT,MACA,iBACA,OAAO,OAAO,KAAK,SACnB,OAAO,OAAO,KAAK;WAAqB,MAAM;;WAErC,MAAM;WACN,SAAS;WACT,QAAQ,OAAO,aAAa,MAAM;;WAElC,OACR,OAAO,OAAO,OAAO,KAAK,YACtB,OAAO,OAAO,KAAK;aAAqB,MAAM;;;;;;;;;;;qBAWvC,aACN,2BACA,gBAAgB,6BAChB,eAAe,OAAO,OAAO,QAEnC,MAAM,MACN,SAAS,QAAQ,SAAS,YACtB,OAAO,MAAM,SAAS;;;;;;;;qBASd,aAAa,eAAe,KAAK;;;;;;;;qBASjC,aAAa,UAAU,QAAQ"}
|
package/dist/Resource.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { __exportAll } from "./_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { Class as Class$1, TypeId as TypeId$1, descriptor as descriptor$1, isResource as isResource$1, make as make$1 } from "./internal/resource.js";
|
|
3
|
+
import "effect/Schema";
|
|
4
|
+
// src/Resource.ts
|
|
5
|
+
var Resource_exports = /* @__PURE__ */ __exportAll({
|
|
6
|
+
Class: () => Class,
|
|
7
|
+
TypeId: () => TypeId,
|
|
8
|
+
descriptor: () => descriptor,
|
|
9
|
+
isResource: () => isResource,
|
|
10
|
+
make: () => make
|
|
11
|
+
});
|
|
12
|
+
/**
|
|
13
|
+
* @stability stable
|
|
14
|
+
* @category type IDs
|
|
15
|
+
* @since 0.3.0
|
|
16
|
+
*/
|
|
17
|
+
const TypeId = TypeId$1;
|
|
18
|
+
/**
|
|
19
|
+
* Makes a resource as a Schema class. Use it in the same way as
|
|
20
|
+
* `Schema.TaggedClass`.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* import { Schema } from "effect"
|
|
25
|
+
* import { Resource } from "@nmnmcc/ability"
|
|
26
|
+
*
|
|
27
|
+
* class Bot extends Resource.Class<Bot>()("Bot", {
|
|
28
|
+
* actions: ["read", "update"],
|
|
29
|
+
* fields: {
|
|
30
|
+
* id: Schema.String,
|
|
31
|
+
* ownerUserId: Schema.NullOr(Schema.String),
|
|
32
|
+
* },
|
|
33
|
+
* path: (f) => ["user", f.ownerUserId, "bot", f.id],
|
|
34
|
+
* }) {}
|
|
35
|
+
*
|
|
36
|
+
* const bot = new Bot({ id: "b1", ownerUserId: "u1" })
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @stability stable
|
|
40
|
+
* @category constructors
|
|
41
|
+
* @since 0.3.0
|
|
42
|
+
*/
|
|
43
|
+
const Class = Class$1;
|
|
44
|
+
/**
|
|
45
|
+
* Makes a resource from plain fields. Its values are plain objects with a
|
|
46
|
+
* `_tag` field.
|
|
47
|
+
*
|
|
48
|
+
* @stability stable
|
|
49
|
+
* @category constructors
|
|
50
|
+
* @since 0.3.0
|
|
51
|
+
*/
|
|
52
|
+
const make = make$1;
|
|
53
|
+
/**
|
|
54
|
+
* Tests if a value is a resource.
|
|
55
|
+
*
|
|
56
|
+
* @stability stable
|
|
57
|
+
* @category guards
|
|
58
|
+
* @since 0.3.0
|
|
59
|
+
*/
|
|
60
|
+
const isResource = isResource$1;
|
|
61
|
+
/**
|
|
62
|
+
* Gets the runtime data of a resource.
|
|
63
|
+
*
|
|
64
|
+
* @stability stable
|
|
65
|
+
* @category getters
|
|
66
|
+
* @since 0.3.0
|
|
67
|
+
*/
|
|
68
|
+
const descriptor = descriptor$1;
|
|
69
|
+
export { Class, Resource_exports, TypeId, descriptor, isResource, make };
|
|
70
|
+
|
|
71
|
+
//# sourceMappingURL=Resource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Resource.js","names":["internal.TypeId","internal.Class","internal.make","internal.isResource","internal.descriptor"],"sources":["../src/Resource.ts"],"sourcesContent":["/**\n * A resource is a kind of thing that a person may act on, such as a Bot or a\n * document. Each resource has a kind name, a list of actions, a Schema for its\n * data, and an optional path.\n *\n * Make a resource in one of two ways:\n * - {@link Class} makes a Schema class, in the same way as\n * `Schema.TaggedClass`. The class is a Schema, a constructor, and a resource\n * at the same time.\n * - {@link make} makes a resource from plain fields. Its values are plain\n * objects with a `_tag` field.\n *\n * Every value of a resource has a `_tag` field with the kind name. The library\n * uses this field to find the resource of a value. It does not guess from the\n * constructor name.\n *\n * A path puts a resource inside a tree, such as\n * `[\"org\", organizationId, \"user\", ownerUserId, \"bot\", id]`. A condition can\n * then ask if a value is under a part of the tree. See `Condition.under`.\n *\n * @stability stable\n * @since 0.3.0\n */\nimport * as Schema from \"effect/Schema\"\nimport * as internal from \"./internal/resource.ts\"\n\n/**\n * @stability stable\n * @category type IDs\n * @since 0.3.0\n */\nexport const TypeId: \"~@nmnmcc/ability/Resource\" = internal.TypeId\n\n/**\n * @stability stable\n * @category type IDs\n * @since 0.3.0\n */\nexport type TypeId = typeof TypeId\n\n/**\n * One part of a resource path. A string is a fixed part. A field reference\n * takes the part from a field of the value.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type PathSegment = string | FieldRef<string>\n\n/**\n * A reference to a top-level field of a resource, used in a path.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface FieldRef<Name extends string> {\n\treadonly _tag: \"Field\"\n\treadonly field: Name\n}\n\n/**\n * The runtime data of a resource.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Descriptor {\n\treadonly kind: string\n\treadonly actions: ReadonlyArray<string>\n\treadonly path: ReadonlyArray<PathSegment> | undefined\n\t/** The paths of the data fields, with dots for nested fields. */\n\treadonly fieldPaths: ReadonlyArray<string>\n\t/** The Schema of the values, with the `_tag` field. */\n\treadonly schema: Schema.Top\n}\n\n/**\n * A resource. `Kind` is its name, `Action` is the union of its actions, `Data`\n * is the type of its Schema fields, and `Value` is the type of its values.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Resource<\n\tKind extends string,\n\tAction extends string,\n\tData extends object,\n\tValue extends { readonly _tag: Kind },\n> {\n\treadonly [TypeId]: Descriptor\n\treadonly \"~Resource\"?: {\n\t\treadonly Kind: Kind\n\t\treadonly Action: Action\n\t\treadonly Data: Data\n\t\treadonly Value: Value\n\t}\n}\n\n/**\n * Any resource.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Any = Resource<string, string, object, { readonly _tag: string }>\n\n/**\n * The kind name of a resource.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type Kind<R> = R extends Resource<infer K, any, any, any> ? K : never\n\n/**\n * The actions of a resource.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type Action<R> = R extends Resource<any, infer A, any, any> ? A : never\n\n/**\n * The type of the Schema fields of a resource, without `_tag`.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type Data<R> = R extends Resource<any, any, infer D, any> ? D : never\n\n/**\n * The type of the values of a resource.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type Value<R> = R extends Resource<any, any, any, infer V> ? V : never\n\n/**\n * The options of a resource.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Options<\n\tActions extends ReadonlyArray<string>,\n\tFields extends Schema.Struct.Fields,\n> {\n\treadonly actions: Actions\n\treadonly fields: Fields\n\t/**\n\t * Gives the path of the resource. The function gets one reference for each\n\t * top-level field.\n\t */\n\treadonly path?: (fields: {\n\t\treadonly [K in keyof Fields & string]: FieldRef<K>\n\t}) => ReadonlyArray<PathSegment>\n}\n\n/**\n * The type of a class made by {@link Class}.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Class<\n\tSelf,\n\tKind extends string,\n\tActions extends ReadonlyArray<string>,\n\tFields extends Schema.Struct.Fields,\n> = Schema.Class<Self, Schema.TaggedStruct<Kind, Fields>, {}> &\n\tResource<\n\t\tKind,\n\t\tActions[number],\n\t\tSchema.Struct.Type<Fields>,\n\t\tSelf & { readonly _tag: Kind }\n\t> & {\n\t\treadonly kind: Kind\n\t\treadonly actions: Actions\n\t}\n\n/**\n * Makes a resource as a Schema class. Use it in the same way as\n * `Schema.TaggedClass`.\n *\n * @example\n * ```ts\n * import { Schema } from \"effect\"\n * import { Resource } from \"@nmnmcc/ability\"\n *\n * class Bot extends Resource.Class<Bot>()(\"Bot\", {\n * actions: [\"read\", \"update\"],\n * fields: {\n * id: Schema.String,\n * ownerUserId: Schema.NullOr(Schema.String),\n * },\n * path: (f) => [\"user\", f.ownerUserId, \"bot\", f.id],\n * }) {}\n *\n * const bot = new Bot({ id: \"b1\", ownerUserId: \"u1\" })\n * ```\n *\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const Class: <Self = never>(\n\tidentifier?: string,\n) => <\n\tconst Kind extends string,\n\tconst Actions extends ReadonlyArray<string>,\n\tconst Fields extends Schema.Struct.Fields,\n>(\n\tkind: Kind,\n\toptions: Options<Actions, Fields>,\n) => [Self] extends [never]\n\t? \"Missing `Self` type: use Resource.Class<Self>()(...)\"\n\t: Class<Self, Kind, Actions, Fields> = internal.Class as never\n\n/**\n * A resource made by {@link make}. Its values are plain objects.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Struct<\n\tKind extends string,\n\tActions extends ReadonlyArray<string>,\n\tFields extends Schema.Struct.Fields,\n> extends Resource<\n\tKind,\n\tActions[number],\n\tSchema.Struct.Type<Fields>,\n\tSchema.Struct.Type<Fields> & { readonly _tag: Kind }\n> {\n\treadonly kind: Kind\n\treadonly actions: Actions\n\treadonly schema: Schema.TaggedStruct<Kind, Fields>\n\t/** Makes a value. It puts the `_tag` field on the value for you. */\n\treadonly make: (\n\t\tinput: Schema.Struct.Type<Fields>,\n\t) => Schema.Struct.Type<Fields> & { readonly _tag: Kind }\n}\n\n/**\n * Makes a resource from plain fields. Its values are plain objects with a\n * `_tag` field.\n *\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const make: <\n\tconst Kind extends string,\n\tconst Actions extends ReadonlyArray<string>,\n\tconst Fields extends Schema.Struct.Fields,\n>(\n\tkind: Kind,\n\toptions: Options<Actions, Fields>,\n) => Struct<Kind, Actions, Fields> = internal.make as never\n\n/**\n * Tests if a value is a resource.\n *\n * @stability stable\n * @category guards\n * @since 0.3.0\n */\nexport const isResource: (u: unknown) => u is Any = internal.isResource\n\n/**\n * Gets the runtime data of a resource.\n *\n * @stability stable\n * @category getters\n * @since 0.3.0\n */\nexport const descriptor: (resource: Any) => Descriptor = internal.descriptor\n"],"mappings":";;;;;;;;;;;;;;;;AA+BA,MAAa,SAAsCA;;;;;;;;;;;;;;;;;;;;;;;;;;AA0LnD,MAAa,QAW2BC;;;;;;;;;AAoCxC,MAAa,OAOwBC;;;;;;;;AASrC,MAAa,aAAuCC;;;;;;;;AASpD,MAAa,aAA4CC"}
|