@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.
Files changed (83) hide show
  1. package/README.md +322 -469
  2. package/dist/Authorizer.d.ts +216 -0
  3. package/dist/Authorizer.d.ts.map +1 -0
  4. package/dist/Authorizer.js +55 -0
  5. package/dist/Authorizer.js.map +1 -0
  6. package/dist/Condition.d.ts +536 -0
  7. package/dist/Condition.d.ts.map +1 -0
  8. package/dist/Condition.js +141 -0
  9. package/dist/Condition.js.map +1 -0
  10. package/dist/Decision.d.ts +131 -0
  11. package/dist/Decision.d.ts.map +1 -0
  12. package/dist/Decision.js +83 -0
  13. package/dist/Decision.js.map +1 -0
  14. package/dist/Domain.d.ts +148 -0
  15. package/dist/Domain.d.ts.map +1 -0
  16. package/dist/Domain.js +34 -0
  17. package/dist/Domain.js.map +1 -0
  18. package/dist/HttpApi.d.ts +129 -0
  19. package/dist/HttpApi.d.ts.map +1 -0
  20. package/dist/HttpApi.js +95 -0
  21. package/dist/HttpApi.js.map +1 -0
  22. package/dist/Policy.d.ts +429 -0
  23. package/dist/Policy.d.ts.map +1 -0
  24. package/dist/Policy.js +162 -0
  25. package/dist/Policy.js.map +1 -0
  26. package/dist/Principal.d.ts +35 -0
  27. package/dist/Principal.d.ts.map +1 -0
  28. package/dist/Principal.js +37 -0
  29. package/dist/Principal.js.map +1 -0
  30. package/dist/Resource.d.ts +213 -0
  31. package/dist/Resource.d.ts.map +1 -0
  32. package/dist/Resource.js +71 -0
  33. package/dist/Resource.js.map +1 -0
  34. package/dist/Rule.d.ts +189 -0
  35. package/dist/Rule.d.ts.map +1 -0
  36. package/dist/Rule.js +50 -0
  37. package/dist/Rule.js.map +1 -0
  38. package/dist/_virtual/_rolldown/runtime.js +1 -2
  39. package/dist/index.d.ts +9 -3
  40. package/dist/index.js +9 -3
  41. package/dist/internal/authorizer.d.ts +28 -0
  42. package/dist/internal/authorizer.d.ts.map +1 -0
  43. package/dist/internal/authorizer.js +153 -0
  44. package/dist/internal/authorizer.js.map +1 -0
  45. package/dist/internal/condition.d.ts +11 -0
  46. package/dist/internal/condition.d.ts.map +1 -0
  47. package/dist/internal/condition.js +393 -0
  48. package/dist/internal/condition.js.map +1 -0
  49. package/dist/internal/domain.js +34 -0
  50. package/dist/internal/domain.js.map +1 -0
  51. package/dist/internal/httpApi.js +41 -0
  52. package/dist/internal/httpApi.js.map +1 -0
  53. package/dist/internal/policy.js +524 -0
  54. package/dist/internal/policy.js.map +1 -0
  55. package/dist/internal/resource.js +66 -0
  56. package/dist/internal/resource.js.map +1 -0
  57. package/dist/internal/rule.js +131 -0
  58. package/dist/internal/rule.js.map +1 -0
  59. package/package.json +61 -72
  60. package/src/Authorizer.ts +330 -0
  61. package/src/Condition.ts +706 -0
  62. package/src/Decision.ts +117 -0
  63. package/src/Domain.ts +189 -0
  64. package/src/HttpApi.ts +148 -0
  65. package/src/Policy.ts +575 -0
  66. package/src/Principal.ts +41 -0
  67. package/src/Resource.ts +290 -0
  68. package/src/Rule.ts +265 -0
  69. package/src/index.ts +57 -0
  70. package/src/internal/authorizer.ts +271 -0
  71. package/src/internal/condition.ts +607 -0
  72. package/src/internal/domain.ts +56 -0
  73. package/src/internal/httpApi.ts +84 -0
  74. package/src/internal/policy.ts +815 -0
  75. package/src/internal/resource.ts +98 -0
  76. package/src/internal/rule.ts +203 -0
  77. package/dist/Ability.d.ts +0 -491
  78. package/dist/Ability.js +0 -207
  79. package/dist/AbilityExtra.d.ts +0 -79
  80. package/dist/AbilityExtra.js +0 -187
  81. package/dist/internal/ability.d.ts +0 -90
  82. package/dist/internal/ability.js +0 -550
  83. 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"}
@@ -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"}