@nmnmcc/ability 0.3.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +199 -31
  2. package/dist/Authorizer.d.ts +64 -39
  3. package/dist/Authorizer.d.ts.map +1 -1
  4. package/dist/Authorizer.js +291 -6
  5. package/dist/Authorizer.js.map +1 -1
  6. package/dist/Condition.d.ts +444 -65
  7. package/dist/Condition.d.ts.map +1 -1
  8. package/dist/Condition.js +1007 -25
  9. package/dist/Condition.js.map +1 -1
  10. package/dist/Domain.d.ts +27 -17
  11. package/dist/Domain.d.ts.map +1 -1
  12. package/dist/Domain.js +52 -10
  13. package/dist/Domain.js.map +1 -1
  14. package/dist/HttpApi.d.ts +84 -40
  15. package/dist/HttpApi.d.ts.map +1 -1
  16. package/dist/HttpApi.js +103 -13
  17. package/dist/HttpApi.js.map +1 -1
  18. package/dist/Policy.d.ts +314 -56
  19. package/dist/Policy.d.ts.map +1 -1
  20. package/dist/Policy.js +1215 -38
  21. package/dist/Policy.js.map +1 -1
  22. package/dist/Principal.js +2 -2
  23. package/dist/Principal.js.map +1 -1
  24. package/dist/Resource.d.ts +171 -20
  25. package/dist/Resource.d.ts.map +1 -1
  26. package/dist/Resource.js +788 -15
  27. package/dist/Resource.js.map +1 -1
  28. package/dist/Rule.d.ts +115 -29
  29. package/dist/Rule.d.ts.map +1 -1
  30. package/dist/Rule.js +219 -12
  31. package/dist/Rule.js.map +1 -1
  32. package/dist/index.js +4 -4
  33. package/package.json +2 -2
  34. package/src/Authorizer.ts +625 -61
  35. package/src/Condition.ts +2403 -112
  36. package/src/Domain.ts +80 -23
  37. package/src/HttpApi.ts +225 -25
  38. package/src/Policy.ts +2836 -96
  39. package/src/Principal.ts +2 -2
  40. package/src/Resource.ts +1544 -29
  41. package/src/Rule.ts +463 -45
  42. package/dist/internal/authorizer.d.ts +0 -28
  43. package/dist/internal/authorizer.d.ts.map +0 -1
  44. package/dist/internal/authorizer.js +0 -153
  45. package/dist/internal/authorizer.js.map +0 -1
  46. package/dist/internal/condition.d.ts +0 -11
  47. package/dist/internal/condition.d.ts.map +0 -1
  48. package/dist/internal/condition.js +0 -393
  49. package/dist/internal/condition.js.map +0 -1
  50. package/dist/internal/domain.js +0 -34
  51. package/dist/internal/domain.js.map +0 -1
  52. package/dist/internal/httpApi.js +0 -41
  53. package/dist/internal/httpApi.js.map +0 -1
  54. package/dist/internal/policy.js +0 -524
  55. package/dist/internal/policy.js.map +0 -1
  56. package/dist/internal/resource.js +0 -66
  57. package/dist/internal/resource.js.map +0 -1
  58. package/dist/internal/rule.js +0 -131
  59. package/dist/internal/rule.js.map +0 -1
  60. package/src/internal/authorizer.ts +0 -271
  61. package/src/internal/condition.ts +0 -607
  62. package/src/internal/domain.ts +0 -56
  63. package/src/internal/httpApi.ts +0 -84
  64. package/src/internal/policy.ts +0 -815
  65. package/src/internal/resource.ts +0 -98
  66. package/src/internal/rule.ts +0 -203
@@ -1,153 +0,0 @@
1
- import { Allow, Deny, NotApplicable, reason } from "../Decision.js";
2
- import { kindOf } from "./domain.js";
3
- import { decideOf, permittedFieldsOf, residualOf, residualPair } from "./policy.js";
4
- import * as Cache from "effect/Cache";
5
- import * as Context from "effect/Context";
6
- import * as Effect from "effect/Effect";
7
- import * as Equal from "effect/Equal";
8
- import * as Hash from "effect/Hash";
9
- import * as Layer from "effect/Layer";
10
- import * as Schema from "effect/Schema";
11
- // src/internal/authorizer.ts
12
- /** @internal */
13
- var Forbidden = class extends Schema.TaggedError("@nmnmcc/ability/Authorizer/Forbidden")("Forbidden", {
14
- action: Schema.String,
15
- kind: Schema.String,
16
- field: Schema.optionalKey(Schema.String),
17
- reason: Schema.optionalKey(Schema.String)
18
- }) {};
19
- /** @internal */
20
- var PolicyUnavailable = class extends Schema.TaggedError("@nmnmcc/ability/Authorizer/PolicyUnavailable")("PolicyUnavailable", { cause: Schema.Defect() }) {};
21
- /** @internal */
22
- var Pending = class extends Schema.TaggedError("@nmnmcc/ability/Authorizer/Pending")("Pending", {
23
- ticket: Schema.String,
24
- reason: Schema.optionalKey(Schema.String)
25
- }) {};
26
- /** @internal */
27
- const Service = () => (id, domain) => {
28
- const Base = Context.Service()(id);
29
- return class extends Base {
30
- static domain = domain;
31
- static decide = (target) => this.use((service) => service.decide(target));
32
- static check = (target) => this.use((service) => service.check(target));
33
- static guard = (target, options) => this.use((service) => service.guard(target, options));
34
- static filter = (target) => this.use((service) => service.filter(target));
35
- static permittedFields = (target) => this.use((service) => service.permittedFields(target));
36
- };
37
- };
38
- /**
39
- * A cache key for a principal. Two principals with the same encoded value are
40
- * the same key.
41
- */
42
- var PrincipalKey = class PrincipalKey {
43
- principal;
44
- json;
45
- constructor(principal, json) {
46
- this.principal = principal;
47
- this.json = json;
48
- }
49
- [Equal.symbol](that) {
50
- return that instanceof PrincipalKey && that.json === this.json;
51
- }
52
- [Hash.symbol]() {
53
- return Hash.string(this.json);
54
- }
55
- };
56
- const forbidden = (target, kind, reason) => Forbidden.make({
57
- action: target.action,
58
- kind,
59
- ...target.field === void 0 ? {} : { field: target.field },
60
- ...reason === void 0 ? {} : { reason }
61
- });
62
- /** @internal */
63
- const layer = (service, options) => {
64
- const domain = service.domain;
65
- const encode = Schema.encodeUnknownSync(domain.principal);
66
- const keyOf = (principal) => new PrincipalKey(principal, JSON.stringify(encode(principal)));
67
- return Layer.effect(service, Effect.gen(function* () {
68
- const services = yield* Effect.context();
69
- const load = (principal) => options.policy(principal).pipe(Effect.provideContext(services), Effect.mapError((cause) => PolicyUnavailable.make({ cause })));
70
- const cache = options.cache === false ? void 0 : yield* Cache.make({
71
- capacity: options.cache?.capacity ?? 1e3,
72
- timeToLive: options.cache?.timeToLive ?? "30 seconds",
73
- lookup: (key) => load(key.principal)
74
- });
75
- const policyFor = (principal) => {
76
- if (cache === void 0) return load(principal);
77
- const key = keyOf(principal);
78
- return Cache.get(cache, key).pipe(Effect.tapError(() => Cache.invalidate(cache, key)));
79
- };
80
- const withServices = (effect) => Effect.provideContext(effect, services);
81
- const current = Effect.gen(function* () {
82
- const principal = yield* options.principal;
83
- return {
84
- principal,
85
- policy: yield* policyFor(principal)
86
- };
87
- });
88
- const decide = Effect.fnUntraced(function* (target) {
89
- const { principal, policy: value } = yield* current;
90
- return yield* withServices(decideOf(value, {
91
- ...target,
92
- principal
93
- }));
94
- });
95
- const kindDecision = (value, principal, target) => {
96
- const pair = residualPair(value, {
97
- ...target,
98
- principal
99
- });
100
- if (pair.allow._tag === "True") return Allow({});
101
- if (pair.deny._tag === "True") return Deny({});
102
- return NotApplicable;
103
- };
104
- const check = Effect.fnUntraced(function* (target) {
105
- const { principal, policy: value } = yield* current;
106
- const kind = target.resource === void 0 ? target.kind ?? "" : kindOf(target.resource) ?? "";
107
- let decision = target.resource === void 0 ? kindDecision(value, principal, target) : yield* withServices(decideOf(value, {
108
- ...target,
109
- principal
110
- }));
111
- if (decision._tag === "NotApplicable" && options.decider !== void 0) decision = yield* options.decider({
112
- ...target,
113
- principal
114
- });
115
- if (decision._tag !== "Allow") return yield* forbidden(target, kind, reason(decision));
116
- });
117
- const guard = Effect.fnUntraced(function* (target, guardOptions) {
118
- const read = guardOptions.read ?? "read";
119
- const { field: _field, ...rest } = target;
120
- if ((yield* decide({
121
- ...rest,
122
- action: read
123
- }))._tag !== "Allow") return yield* Effect.fail(guardOptions.hide());
124
- if (target.action !== read || target.field !== void 0) yield* check(target);
125
- });
126
- const filter = (target) => Effect.map(current, ({ principal, policy: value }) => residualOf(value, {
127
- ...target,
128
- principal
129
- }));
130
- const permittedFields = Effect.fnUntraced(function* (target) {
131
- const { principal, policy: value } = yield* current;
132
- return yield* withServices(permittedFieldsOf(value, {
133
- ...target,
134
- principal
135
- }));
136
- });
137
- const invalidate = (principal) => cache === void 0 ? Effect.void : principal === void 0 ? Cache.invalidateAll(cache) : Cache.invalidate(cache, keyOf(principal));
138
- return {
139
- domain,
140
- principal: options.principal,
141
- policy: Effect.map(current, ({ policy: value }) => value),
142
- decide,
143
- check,
144
- guard,
145
- filter,
146
- permittedFields,
147
- invalidate
148
- };
149
- }));
150
- };
151
- export { Forbidden, Pending, PolicyUnavailable, Service, layer };
152
-
153
- //# sourceMappingURL=authorizer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"authorizer.js","names":["policy.decideOf","policy.residualPair","Decision.Allow","Decision.Deny","Decision.NotApplicable","Decision.reason","policy.residualOf","policy.permittedFieldsOf"],"sources":["../../src/internal/authorizer.ts"],"sourcesContent":["// The service erases the error type and the service type of predicates,\n// principals and deciders to `unknown`. The public types in\n// `src/Authorizer.ts` keep them, so the language service check for `unknown`\n// in an Effect is off here.\n// @effect-diagnostics anyUnknownInErrorContext:off\nimport * as Cache from \"effect/Cache\"\nimport * as Context from \"effect/Context\"\nimport * as Effect from \"effect/Effect\"\nimport * as Equal from \"effect/Equal\"\nimport * as Hash from \"effect/Hash\"\nimport * as Layer from \"effect/Layer\"\nimport * as Schema from \"effect/Schema\"\nimport type * as Authorizer from \"../Authorizer.ts\"\nimport type * as Condition from \"../Condition.ts\"\nimport * as Decision from \"../Decision.ts\"\nimport type * as Domain from \"../Domain.ts\"\nimport type * as Policy from \"../Policy.ts\"\nimport { kindOf } from \"./domain.ts\"\nimport * as policy from \"./policy.ts\"\n\n/** @internal */\nexport class Forbidden extends Schema.TaggedError<Forbidden>(\n\t\"@nmnmcc/ability/Authorizer/Forbidden\",\n)(\"Forbidden\", {\n\taction: Schema.String,\n\tkind: Schema.String,\n\tfield: Schema.optionalKey(Schema.String),\n\treason: Schema.optionalKey(Schema.String),\n}) {}\n\n/** @internal */\nexport class PolicyUnavailable extends Schema.TaggedError<PolicyUnavailable>(\n\t\"@nmnmcc/ability/Authorizer/PolicyUnavailable\",\n)(\"PolicyUnavailable\", { cause: Schema.Defect() }) {}\n\n/** @internal */\nexport class Pending extends Schema.TaggedError<Pending>(\n\t\"@nmnmcc/ability/Authorizer/Pending\",\n)(\"Pending\", {\n\tticket: Schema.String,\n\treason: Schema.optionalKey(Schema.String),\n}) {}\n\ntype AnyTarget = {\n\treadonly action: string\n\treadonly resource?: object\n\treadonly kind?: string\n\treadonly field?: string\n}\n\n/** @internal */\nexport const Service =\n\t() =>\n\t(id: string, domain: Domain.Any): Authorizer.AnyServiceClass => {\n\t\tconst Base = Context.Service<any, any>()(id)\n\t\treturn class extends Base {\n\t\t\tstatic readonly domain = domain\n\t\t\tstatic readonly decide = (target: AnyTarget) =>\n\t\t\t\tthis.use((service: any) => service.decide(target))\n\t\t\tstatic readonly check = (target: AnyTarget) =>\n\t\t\t\tthis.use((service: any) => service.check(target))\n\t\t\tstatic readonly guard = (target: AnyTarget, options: unknown) =>\n\t\t\t\tthis.use((service: any) => service.guard(target, options))\n\t\t\tstatic readonly filter = (target: AnyTarget) =>\n\t\t\t\tthis.use((service: any) => service.filter(target))\n\t\t\tstatic readonly permittedFields = (target: AnyTarget) =>\n\t\t\t\tthis.use((service: any) => service.permittedFields(target))\n\t\t} as never\n\t}\n\n/**\n * A cache key for a principal. Two principals with the same encoded value are\n * the same key.\n */\nclass PrincipalKey implements Equal.Equal {\n\treadonly principal: object\n\treadonly json: string\n\tconstructor(principal: object, json: string) {\n\t\tthis.principal = principal\n\t\tthis.json = json\n\t}\n\t[Equal.symbol](that: unknown): boolean {\n\t\treturn that instanceof PrincipalKey && that.json === this.json\n\t}\n\t[Hash.symbol](): number {\n\t\treturn Hash.string(this.json)\n\t}\n}\n\nconst forbidden = (\n\ttarget: AnyTarget,\n\tkind: string,\n\treason: string | undefined,\n): Forbidden =>\n\tForbidden.make({\n\t\taction: target.action,\n\t\tkind,\n\t\t...(target.field === undefined ? {} : { field: target.field }),\n\t\t...(reason === undefined ? {} : { reason }),\n\t})\n\n/** @internal */\nexport const layer = (\n\tservice: Authorizer.AnyServiceClass,\n\toptions: {\n\t\treadonly principal: Effect.Effect<object, unknown, unknown>\n\t\treadonly policy: (\n\t\t\tprincipal: object,\n\t\t) => Effect.Effect<Policy.Any, unknown, unknown>\n\t\treadonly decider?: (\n\t\t\trequest: object,\n\t\t) => Effect.Effect<Decision.Decision, unknown, unknown>\n\t\treadonly cache?:\n\t\t\t{ readonly capacity?: number; readonly timeToLive?: any } | false\n\t},\n) => {\n\tconst domain: Domain.Any = service.domain\n\tconst encode = Schema.encodeUnknownSync(\n\t\tdomain.principal as unknown as Schema.Codec<unknown, unknown>,\n\t)\n\tconst keyOf = (principal: object) =>\n\t\tnew PrincipalKey(principal, JSON.stringify(encode(principal)))\n\treturn Layer.effect(\n\t\tservice,\n\t\tEffect.gen(function* () {\n\t\t\t// The services of the policy loader and of the predicates come from the\n\t\t\t// layer, so a check does not need them.\n\t\t\tconst services = yield* Effect.context<never>()\n\n\t\t\tconst load = (principal: object) =>\n\t\t\t\toptions.policy(principal).pipe(\n\t\t\t\t\tEffect.provideContext(services),\n\t\t\t\t\tEffect.mapError((cause) => PolicyUnavailable.make({ cause })),\n\t\t\t\t)\n\n\t\t\tconst cache =\n\t\t\t\toptions.cache === false\n\t\t\t\t\t? undefined\n\t\t\t\t\t: yield* Cache.make({\n\t\t\t\t\t\t\tcapacity: options.cache?.capacity ?? 1000,\n\t\t\t\t\t\t\ttimeToLive: options.cache?.timeToLive ?? \"30 seconds\",\n\t\t\t\t\t\t\tlookup: (key: PrincipalKey) => load(key.principal),\n\t\t\t\t\t\t})\n\n\t\t\tconst policyFor = (principal: object) => {\n\t\t\t\tif (cache === undefined) {\n\t\t\t\t\treturn load(principal)\n\t\t\t\t}\n\t\t\t\tconst key = keyOf(principal)\n\t\t\t\t// A failed lookup is kept in the cache. Remove it, so the next check\n\t\t\t\t// tries again.\n\t\t\t\treturn Cache.get(cache, key).pipe(\n\t\t\t\t\tEffect.tapError(() => Cache.invalidate(cache, key)),\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst withServices = <A, E>(\n\t\t\t\teffect: Effect.Effect<A, E, unknown>,\n\t\t\t): Effect.Effect<A, E, unknown> => Effect.provideContext(effect, services)\n\n\t\t\tconst current = Effect.gen(function* () {\n\t\t\t\tconst principal = yield* options.principal\n\t\t\t\tconst value = yield* policyFor(principal)\n\t\t\t\treturn { principal, policy: value }\n\t\t\t})\n\n\t\t\tconst decide = Effect.fnUntraced(function* (target: AnyTarget) {\n\t\t\t\tconst { principal, policy: value } = yield* current\n\t\t\t\tconst decision: Decision.Decision = yield* withServices(\n\t\t\t\t\tpolicy.decideOf(value, { ...target, principal } as never),\n\t\t\t\t)\n\t\t\t\treturn decision\n\t\t\t})\n\n\t\t\tconst kindDecision = (\n\t\t\t\tvalue: Policy.Any,\n\t\t\t\tprincipal: object,\n\t\t\t\ttarget: AnyTarget,\n\t\t\t): Decision.Decision => {\n\t\t\t\tconst pair = policy.residualPair(value, {\n\t\t\t\t\t...target,\n\t\t\t\t\tprincipal,\n\t\t\t\t} as never)\n\t\t\t\tif (pair.allow._tag === \"True\") {\n\t\t\t\t\treturn Decision.Allow({})\n\t\t\t\t}\n\t\t\t\tif (pair.deny._tag === \"True\") {\n\t\t\t\t\treturn Decision.Deny({})\n\t\t\t\t}\n\t\t\t\treturn Decision.NotApplicable\n\t\t\t}\n\n\t\t\tconst check = Effect.fnUntraced(function* (target: AnyTarget) {\n\t\t\t\tconst { principal, policy: value } = yield* current\n\t\t\t\tconst kind =\n\t\t\t\t\ttarget.resource === undefined\n\t\t\t\t\t\t? (target.kind ?? \"\")\n\t\t\t\t\t\t: (kindOf(target.resource) ?? \"\")\n\t\t\t\tlet decision: Decision.Decision =\n\t\t\t\t\ttarget.resource === undefined\n\t\t\t\t\t\t? kindDecision(value, principal, target)\n\t\t\t\t\t\t: yield* withServices(\n\t\t\t\t\t\t\t\tpolicy.decideOf(value, { ...target, principal } as never),\n\t\t\t\t\t\t\t)\n\t\t\t\tif (\n\t\t\t\t\tdecision._tag === \"NotApplicable\" &&\n\t\t\t\t\toptions.decider !== undefined\n\t\t\t\t) {\n\t\t\t\t\tdecision = yield* options.decider({ ...target, principal })\n\t\t\t\t}\n\t\t\t\tif (decision._tag !== \"Allow\") {\n\t\t\t\t\treturn yield* forbidden(target, kind, Decision.reason(decision))\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tconst guard = Effect.fnUntraced(function* (\n\t\t\t\ttarget: AnyTarget,\n\t\t\t\tguardOptions: {\n\t\t\t\t\treadonly read?: string\n\t\t\t\t\treadonly hide: () => unknown\n\t\t\t\t},\n\t\t\t) {\n\t\t\t\tconst read = guardOptions.read ?? \"read\"\n\t\t\t\tconst { field: _field, ...rest } = target\n\t\t\t\tconst visible: Decision.Decision = yield* decide({\n\t\t\t\t\t...rest,\n\t\t\t\t\taction: read,\n\t\t\t\t})\n\t\t\t\tif (visible._tag !== \"Allow\") {\n\t\t\t\t\treturn yield* Effect.fail(guardOptions.hide())\n\t\t\t\t}\n\t\t\t\tif (target.action !== read || target.field !== undefined) {\n\t\t\t\t\tyield* check(target)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tconst filter = (\n\t\t\t\ttarget: AnyTarget,\n\t\t\t): Effect.Effect<Condition.Ast, unknown, unknown> =>\n\t\t\t\tEffect.map(current, ({ principal, policy: value }) =>\n\t\t\t\t\tpolicy.residualOf(value, { ...target, principal } as never),\n\t\t\t\t)\n\n\t\t\tconst permittedFields = Effect.fnUntraced(function* (target: AnyTarget) {\n\t\t\t\tconst { principal, policy: value } = yield* current\n\t\t\t\treturn yield* withServices(\n\t\t\t\t\tpolicy.permittedFieldsOf(value, { ...target, principal } as never),\n\t\t\t\t)\n\t\t\t})\n\n\t\t\tconst invalidate = (principal?: object) =>\n\t\t\t\tcache === undefined\n\t\t\t\t\t? Effect.void\n\t\t\t\t\t: principal === undefined\n\t\t\t\t\t\t? Cache.invalidateAll(cache)\n\t\t\t\t\t\t: Cache.invalidate(cache, keyOf(principal))\n\n\t\t\treturn {\n\t\t\t\tdomain,\n\t\t\t\tprincipal: options.principal,\n\t\t\t\tpolicy: Effect.map(current, ({ policy: value }) => value),\n\t\t\t\tdecide,\n\t\t\t\tcheck,\n\t\t\t\tguard,\n\t\t\t\tfilter,\n\t\t\t\tpermittedFields,\n\t\t\t\tinvalidate,\n\t\t\t} as never\n\t\t}),\n\t)\n}\n"],"mappings":"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"}
@@ -1,11 +0,0 @@
1
- import "../Resource.js";
2
- import "../Condition.js";
3
- import "effect/Effect";
4
- import * as Schema from "effect/Schema";
5
- declare const Untranslatable_base: Schema.Class<Untranslatable, Schema.TaggedStruct<"Untranslatable", {
6
- readonly reason: Schema.String;
7
- }>, import("effect/Cause").YieldableError>;
8
- /** @internal */
9
- export declare class Untranslatable extends Untranslatable_base {}
10
- export {};
11
- //# sourceMappingURL=condition.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"condition.d.ts","names":[],"sources":["../../src/internal/condition.ts"],"mappings":";;;;;;;;qBAwda,uBAAuB"}
@@ -1,393 +0,0 @@
1
- import { __exportAll } from "../_virtual/_rolldown/runtime.js";
2
- import * as Effect from "effect/Effect";
3
- import * as Equal from "effect/Equal";
4
- import * as Schema from "effect/Schema";
5
- import * as Predicate from "effect/Predicate";
6
- import { dual } from "effect/Function";
7
- // src/internal/condition.ts
8
- var condition_exports = /* @__PURE__ */ __exportAll({
9
- Untranslatable: () => Untranslatable,
10
- always: () => always,
11
- and: () => and,
12
- builder: () => builder,
13
- evaluate: () => evaluate,
14
- evaluateOf: () => evaluateOf,
15
- evaluateSync: () => evaluateSync,
16
- evaluateSyncOf: () => evaluateSyncOf,
17
- fields: () => fields,
18
- fold: () => fold,
19
- getField: () => getField,
20
- hasPredicate: () => hasPredicate,
21
- never: () => never,
22
- not: () => not,
23
- or: () => or,
24
- partial: () => partial,
25
- partialOf: () => partialOf,
26
- schema: () => schema,
27
- simplify: () => simplify
28
- });
29
- /** @internal */
30
- const always = Object.freeze({ _tag: "True" });
31
- /** @internal */
32
- const never = Object.freeze({ _tag: "False" });
33
- const literal = (value) => Object.freeze({
34
- _tag: "Literal",
35
- value
36
- });
37
- const isOperand = (u) => Predicate.hasProperty(u, "_tag") && (u._tag === "Literal" || u._tag === "Principal");
38
- const toOperand = (value) => isOperand(value) ? value : literal(value);
39
- const compare = (op) => (field, value) => Object.freeze({
40
- _tag: "Compare",
41
- op,
42
- field,
43
- value: toOperand(value)
44
- });
45
- /** @internal */
46
- const and = (...conditions) => Object.freeze({
47
- _tag: "And",
48
- conditions: Object.freeze([...conditions])
49
- });
50
- /** @internal */
51
- const or = (...conditions) => Object.freeze({
52
- _tag: "Or",
53
- conditions: Object.freeze([...conditions])
54
- });
55
- /** @internal */
56
- const not = (condition) => Object.freeze({
57
- _tag: "Not",
58
- condition
59
- });
60
- /** @internal */
61
- const builder = () => Object.freeze({
62
- eq: compare("eq"),
63
- ne: compare("ne"),
64
- lt: compare("lt"),
65
- lte: compare("lte"),
66
- gt: compare("gt"),
67
- gte: compare("gte"),
68
- in: (field, values) => Object.freeze({
69
- _tag: "In",
70
- field,
71
- values: Object.freeze(values.map(toOperand))
72
- }),
73
- exists: (field) => Object.freeze({
74
- _tag: "Exists",
75
- field
76
- }),
77
- under: (...prefix) => Object.freeze({
78
- _tag: "Under",
79
- prefix: Object.freeze(prefix.map(toOperand))
80
- }),
81
- principal: (path) => Object.freeze({
82
- _tag: "Principal",
83
- path
84
- }),
85
- and,
86
- or,
87
- not,
88
- predicate: (name, test) => Object.freeze({
89
- _tag: "Predicate",
90
- name,
91
- run: (value, principal) => Effect.suspend(() => {
92
- const result = test(value, principal);
93
- return Effect.isEffect(result) ? result : Effect.succeed(result);
94
- })
95
- })
96
- });
97
- /**
98
- * Gets a field of an object by a path with dots. A missing field, or a field
99
- * under a value that is not an object, gives `null`.
100
- *
101
- * @internal
102
- */
103
- const getField = (value, path) => {
104
- let cursor = value;
105
- for (const key of path.split(".")) {
106
- if (!Predicate.isObject(cursor) || !Object.hasOwn(cursor, key)) return null;
107
- cursor = cursor[key];
108
- }
109
- return cursor === void 0 ? null : cursor;
110
- };
111
- /**
112
- * Gives the value of an operand. A principal field that is `null` or missing
113
- * gives `undefined`. No field of a resource is `undefined`, so a test with it
114
- * is never true. This keeps the check closed: a principal with no id never
115
- * matches a resource with no owner.
116
- */
117
- const resolve = (operand, principal) => operand._tag === "Literal" ? operand.value : getField(principal, operand.path) ?? void 0;
118
- const testCompare = (op, left, right) => {
119
- if (right === void 0) return false;
120
- switch (op) {
121
- case "eq": return left === right;
122
- case "ne": return left !== right;
123
- default: {
124
- if (!(typeof left === "number" && typeof right === "number" || typeof left === "string" && typeof right === "string")) return false;
125
- const a = left;
126
- const b = right;
127
- switch (op) {
128
- case "lt": return a < b;
129
- case "lte": return a <= b;
130
- case "gt": return a > b;
131
- case "gte": return a >= b;
132
- }
133
- }
134
- }
135
- };
136
- /**
137
- * Gives the values of a resource path. It gives `undefined` when the resource
138
- * has no path.
139
- */
140
- const pathValues = (value, path) => path?.map((segment) => typeof segment === "string" ? segment : getField(value, segment.field));
141
- const testUnder = (prefix, input) => {
142
- const values = pathValues(input.value, input.path);
143
- if (values === void 0 || prefix.length > values.length) return false;
144
- return prefix.every((operand, index) => resolve(operand, input.principal) === values[index]);
145
- };
146
- /** @internal */
147
- const hasPredicate = (ast) => {
148
- switch (ast._tag) {
149
- case "Predicate": return true;
150
- case "And":
151
- case "Or": return ast.conditions.some(hasPredicate);
152
- case "Not": return hasPredicate(ast.condition);
153
- default: return false;
154
- }
155
- };
156
- /** @internal */
157
- const evaluateSyncOf = (ast, input) => {
158
- switch (ast._tag) {
159
- case "True": return true;
160
- case "False": return false;
161
- case "Compare": return testCompare(ast.op, getField(input.value, ast.field), resolve(ast.value, input.principal));
162
- case "In": {
163
- const field = getField(input.value, ast.field);
164
- return ast.values.some((operand) => resolve(operand, input.principal) === field);
165
- }
166
- case "Exists": return getField(input.value, ast.field) !== null;
167
- case "Under": return testUnder(ast.prefix, input);
168
- case "And": return ast.conditions.every((child) => evaluateSyncOf(child, input));
169
- case "Or": return ast.conditions.some((child) => evaluateSyncOf(child, input));
170
- case "Not": return !evaluateSyncOf(ast.condition, input);
171
- case "Predicate": throw new Error(`The predicate "${ast.name}" needs an Effect. Use Condition.evaluate.`);
172
- }
173
- };
174
- /** @internal */
175
- const evaluateOf = (ast, input) => {
176
- if (!hasPredicate(ast)) return Effect.sync(() => evaluateSyncOf(ast, input));
177
- switch (ast._tag) {
178
- case "Predicate": return ast.run(input.value, input.principal);
179
- case "Not": return Effect.map(evaluateOf(ast.condition, input), (value) => !value);
180
- case "And": return Effect.gen(function* () {
181
- for (const child of ast.conditions) if (!(yield* evaluateOf(child, input))) return false;
182
- return true;
183
- });
184
- case "Or": return Effect.gen(function* () {
185
- for (const child of ast.conditions) if (yield* evaluateOf(child, input)) return true;
186
- return false;
187
- });
188
- default: return Effect.sync(() => evaluateSyncOf(ast, input));
189
- }
190
- };
191
- const dedupe = (conditions) => {
192
- const output = [];
193
- for (const condition of conditions) if (!output.some((other) => Equal.equals(other, condition))) output.push(condition);
194
- return output;
195
- };
196
- /**
197
- * Removes the children that the other children make useless. In an `Or`,
198
- * `a OR (a AND b)` is `a`. In an `And`, `a AND (a OR b)` is `a`.
199
- */
200
- const absorb = (inner, conditions) => conditions.filter((condition) => condition._tag !== inner || !conditions.some((other) => other !== condition && condition.conditions.some((part) => Equal.equals(part, other))));
201
- const flatten = (tag, conditions) => conditions.flatMap((child) => {
202
- const simple = simplify(child);
203
- return simple._tag === tag ? simple.conditions : [simple];
204
- });
205
- /** @internal */
206
- const simplify = (ast) => {
207
- switch (ast._tag) {
208
- case "And": {
209
- const children = flatten("And", ast.conditions).filter((child) => child._tag !== "True");
210
- if (children.some((child) => child._tag === "False")) return never;
211
- const unique = absorb("Or", dedupe(children));
212
- if (unique.length === 0) return always;
213
- return unique.length === 1 ? unique[0] : and(...unique);
214
- }
215
- case "Or": {
216
- const children = flatten("Or", ast.conditions).filter((child) => child._tag !== "False");
217
- if (children.some((child) => child._tag === "True")) return always;
218
- const unique = absorb("And", dedupe(children));
219
- if (unique.length === 0) return never;
220
- return unique.length === 1 ? unique[0] : or(...unique);
221
- }
222
- case "Not": {
223
- const child = simplify(ast.condition);
224
- switch (child._tag) {
225
- case "True": return never;
226
- case "False": return always;
227
- case "Not": return child.condition;
228
- case "Compare":
229
- if (child.value._tag === "Literal" && (child.op === "eq" || child.op === "ne")) return Object.freeze({
230
- ...child,
231
- op: child.op === "eq" ? "ne" : "eq"
232
- });
233
- return not(child);
234
- default: return not(child);
235
- }
236
- }
237
- case "In": return ast.values.length === 0 ? never : ast;
238
- default: return ast;
239
- }
240
- };
241
- /**
242
- * Puts the value of the principal into an operand. It gives `undefined` for a
243
- * principal field with no value. See {@link resolve}.
244
- */
245
- const bindOperand = (operand, principal) => {
246
- if (operand._tag === "Literal") return operand;
247
- const value = resolve(operand, principal);
248
- return value === void 0 ? void 0 : literal(value);
249
- };
250
- const expandUnder = (prefix, principal, path) => {
251
- if (path === void 0 || prefix.length > path.length) return never;
252
- const parts = [];
253
- prefix.forEach((operand, index) => {
254
- const value = resolve(operand, principal);
255
- const segment = path[index];
256
- if (value === void 0) parts.push(never);
257
- else if (typeof segment === "string") parts.push(segment === value ? always : never);
258
- else parts.push(Object.freeze({
259
- _tag: "Compare",
260
- op: "eq",
261
- field: segment.field,
262
- value: literal(value)
263
- }));
264
- });
265
- return and(...parts);
266
- };
267
- const bind = (ast, principal, path) => {
268
- switch (ast._tag) {
269
- case "Compare": {
270
- const value = bindOperand(ast.value, principal);
271
- return value === void 0 ? never : Object.freeze({
272
- ...ast,
273
- value
274
- });
275
- }
276
- case "In": return Object.freeze({
277
- ...ast,
278
- values: Object.freeze(ast.values.flatMap((operand) => {
279
- const value = bindOperand(operand, principal);
280
- return value === void 0 ? [] : [value];
281
- }))
282
- });
283
- case "Under": return expandUnder(ast.prefix, principal, path);
284
- case "And": return and(...ast.conditions.map((child) => bind(child, principal, path)));
285
- case "Or": return or(...ast.conditions.map((child) => bind(child, principal, path)));
286
- case "Not": return not(bind(ast.condition, principal, path));
287
- case "Predicate": return Object.freeze({
288
- _tag: "Predicate",
289
- name: ast.name,
290
- run: (value) => ast.run(value, principal)
291
- });
292
- default: return ast;
293
- }
294
- };
295
- /** @internal */
296
- const partialOf = (ast, input) => simplify(bind(ast, input.principal, input.path));
297
- /** @internal */
298
- const evaluate = dual(2, evaluateOf);
299
- /** @internal */
300
- const evaluateSync = dual(2, evaluateSyncOf);
301
- /** @internal */
302
- const partial = dual(2, partialOf);
303
- /** @internal */
304
- var Untranslatable = class extends Schema.TaggedError("@nmnmcc/ability/Condition/Untranslatable")("Untranslatable", { reason: Schema.String }) {};
305
- const foldNode = (ast, interpreter) => {
306
- switch (ast._tag) {
307
- case "True": return interpreter.true();
308
- case "False": return interpreter.false();
309
- case "Compare":
310
- if (ast.value._tag !== "Literal") throw Untranslatable.make({ reason: `The field "${ast.field}" is compared with a principal field. Call Condition.partial first.` });
311
- return interpreter.compare(ast.op, ast.field, ast.value.value);
312
- case "In": return interpreter.in(ast.field, ast.values.map((operand) => {
313
- if (operand._tag !== "Literal") throw Untranslatable.make({ reason: `The field "${ast.field}" uses a principal field. Call Condition.partial first.` });
314
- return operand.value;
315
- }));
316
- case "Exists": return interpreter.exists(ast.field);
317
- case "Under": throw Untranslatable.make({ reason: "An Under node needs the resource path. Call Condition.partial first." });
318
- case "And": return interpreter.and(ast.conditions.map((child) => foldNode(child, interpreter)));
319
- case "Or": return interpreter.or(ast.conditions.map((child) => foldNode(child, interpreter)));
320
- case "Not": return interpreter.not(foldNode(ast.condition, interpreter));
321
- case "Predicate":
322
- if (interpreter.predicate === void 0) throw Untranslatable.make({ reason: `The predicate "${ast.name}" can not become a query` });
323
- return interpreter.predicate(ast.name);
324
- }
325
- };
326
- /** @internal */
327
- const fold = dual(2, (ast, interpreter) => Effect.try({
328
- try: () => foldNode(ast, interpreter),
329
- catch: (cause) => {
330
- if (cause instanceof Untranslatable) return cause;
331
- throw cause;
332
- }
333
- }));
334
- /** @internal */
335
- const fields = (ast) => {
336
- const output = /* @__PURE__ */ new Set();
337
- const visit = (node) => {
338
- switch (node._tag) {
339
- case "Compare":
340
- case "In":
341
- case "Exists":
342
- output.add(node.field);
343
- return;
344
- case "And":
345
- case "Or":
346
- node.conditions.forEach(visit);
347
- return;
348
- case "Not":
349
- visit(node.condition);
350
- return;
351
- default: return;
352
- }
353
- };
354
- visit(ast);
355
- return Object.freeze(Array.from(output));
356
- };
357
- const ScalarSchema = Schema.Union([
358
- Schema.String,
359
- Schema.Finite,
360
- Schema.Boolean,
361
- Schema.Null
362
- ]);
363
- const OperandSchema = Schema.Union([Schema.TaggedStruct("Literal", { value: ScalarSchema }), Schema.TaggedStruct("Principal", { path: Schema.String })]);
364
- const Recursive = Schema.suspend(() => schema);
365
- /** @internal */
366
- const schema = Schema.Union([
367
- Schema.TaggedStruct("True", {}),
368
- Schema.TaggedStruct("False", {}),
369
- Schema.TaggedStruct("Compare", {
370
- op: Schema.Literals([
371
- "eq",
372
- "ne",
373
- "lt",
374
- "lte",
375
- "gt",
376
- "gte"
377
- ]),
378
- field: Schema.String,
379
- value: OperandSchema
380
- }),
381
- Schema.TaggedStruct("In", {
382
- field: Schema.String,
383
- values: Schema.Array(OperandSchema)
384
- }),
385
- Schema.TaggedStruct("Exists", { field: Schema.String }),
386
- Schema.TaggedStruct("Under", { prefix: Schema.Array(OperandSchema) }),
387
- Schema.TaggedStruct("And", { conditions: Schema.Array(Recursive) }),
388
- Schema.TaggedStruct("Or", { conditions: Schema.Array(Recursive) }),
389
- Schema.TaggedStruct("Not", { condition: Recursive })
390
- ]);
391
- export { Untranslatable, always, and, builder, condition_exports, evaluate, evaluateOf, evaluateSync, evaluateSyncOf, fields, fold, getField, hasPredicate, never, not, or, partial, partialOf, schema, simplify };
392
-
393
- //# sourceMappingURL=condition.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"condition.js","names":[],"sources":["../../src/internal/condition.ts"],"sourcesContent":["// A predicate keeps its error type and service type only in the public types.\n// Inside this file they are erased to `unknown`, so the language service check\n// for `unknown` in an Effect is off here.\n// @effect-diagnostics anyUnknownInErrorContext:off\nimport * as Effect from \"effect/Effect\"\nimport * as Equal from \"effect/Equal\"\nimport { dual } from \"effect/Function\"\nimport * as Predicate from \"effect/Predicate\"\nimport * as Schema from \"effect/Schema\"\nimport type * as Condition from \"../Condition.ts\"\nimport type * as Resource from \"../Resource.ts\"\n\ntype Ast = Condition.Ast\ntype Scalar = Condition.Scalar\n\n/** @internal */\nexport const always: Condition.True = Object.freeze({ _tag: \"True\" })\n\n/** @internal */\nexport const never: Condition.False = Object.freeze({ _tag: \"False\" })\n\nconst literal = (value: Scalar): Condition.Literal =>\n\tObject.freeze({ _tag: \"Literal\", value })\n\nconst isOperand = (u: unknown): u is Condition.Operand =>\n\tPredicate.hasProperty(u, \"_tag\") &&\n\t(u._tag === \"Literal\" || u._tag === \"Principal\")\n\nconst toOperand = (value: unknown): Condition.Operand =>\n\tisOperand(value) ? value : literal(value as Scalar)\n\nconst compare =\n\t(op: Condition.CompareOperator) =>\n\t(field: string, value: unknown): Condition.Compare =>\n\t\tObject.freeze({ _tag: \"Compare\", op, field, value: toOperand(value) })\n\n/** @internal */\nexport const and = (...conditions: ReadonlyArray<Ast>): Condition.And =>\n\tObject.freeze({ _tag: \"And\", conditions: Object.freeze([...conditions]) })\n\n/** @internal */\nexport const or = (...conditions: ReadonlyArray<Ast>): Condition.Or =>\n\tObject.freeze({ _tag: \"Or\", conditions: Object.freeze([...conditions]) })\n\n/** @internal */\nexport const not = (condition: Ast): Condition.Not =>\n\tObject.freeze({ _tag: \"Not\", condition })\n\n/** @internal */\nexport const builder = (): any =>\n\tObject.freeze({\n\t\teq: compare(\"eq\"),\n\t\tne: compare(\"ne\"),\n\t\tlt: compare(\"lt\"),\n\t\tlte: compare(\"lte\"),\n\t\tgt: compare(\"gt\"),\n\t\tgte: compare(\"gte\"),\n\t\tin: (field: string, values: ReadonlyArray<unknown>): Condition.In =>\n\t\t\tObject.freeze({\n\t\t\t\t_tag: \"In\",\n\t\t\t\tfield,\n\t\t\t\tvalues: Object.freeze(values.map(toOperand)),\n\t\t\t}),\n\t\texists: (field: string): Condition.Exists =>\n\t\t\tObject.freeze({ _tag: \"Exists\", field }),\n\t\tunder: (...prefix: ReadonlyArray<unknown>): Condition.Under =>\n\t\t\tObject.freeze({\n\t\t\t\t_tag: \"Under\",\n\t\t\t\tprefix: Object.freeze(prefix.map(toOperand)),\n\t\t\t}),\n\t\tprincipal: (path: string): Condition.PrincipalRef =>\n\t\t\tObject.freeze({ _tag: \"Principal\", path }),\n\t\tand,\n\t\tor,\n\t\tnot,\n\t\tpredicate: (\n\t\t\tname: string,\n\t\t\ttest: (\n\t\t\t\tvalue: unknown,\n\t\t\t\tprincipal: unknown,\n\t\t\t) => boolean | Effect.Effect<boolean, unknown, unknown>,\n\t\t): Condition.Predicate =>\n\t\t\tObject.freeze({\n\t\t\t\t_tag: \"Predicate\",\n\t\t\t\tname,\n\t\t\t\trun: (value: unknown, principal: unknown) =>\n\t\t\t\t\tEffect.suspend(() => {\n\t\t\t\t\t\tconst result = test(value, principal)\n\t\t\t\t\t\treturn Effect.isEffect(result) ? result : Effect.succeed(result)\n\t\t\t\t\t}),\n\t\t\t}),\n\t})\n\n/**\n * Gets a field of an object by a path with dots. A missing field, or a field\n * under a value that is not an object, gives `null`.\n *\n * @internal\n */\nexport const getField = (value: unknown, path: string): unknown => {\n\tlet cursor: unknown = value\n\tfor (const key of path.split(\".\")) {\n\t\tif (!Predicate.isObject(cursor) || !Object.hasOwn(cursor, key)) {\n\t\t\treturn null\n\t\t}\n\t\tcursor = (cursor as Record<string, unknown>)[key]\n\t}\n\treturn cursor === undefined ? null : cursor\n}\n\n/**\n * Gives the value of an operand. A principal field that is `null` or missing\n * gives `undefined`. No field of a resource is `undefined`, so a test with it\n * is never true. This keeps the check closed: a principal with no id never\n * matches a resource with no owner.\n */\nconst resolve = (operand: Condition.Operand, principal: unknown): unknown =>\n\toperand._tag === \"Literal\"\n\t\t? operand.value\n\t\t: (getField(principal, operand.path) ?? undefined)\n\nconst testCompare = (\n\top: Condition.CompareOperator,\n\tleft: unknown,\n\tright: unknown,\n): boolean => {\n\tif (right === undefined) {\n\t\treturn false\n\t}\n\tswitch (op) {\n\t\tcase \"eq\":\n\t\t\treturn left === right\n\t\tcase \"ne\":\n\t\t\treturn left !== right\n\t\tdefault: {\n\t\t\tconst ordered =\n\t\t\t\t(typeof left === \"number\" && typeof right === \"number\") ||\n\t\t\t\t(typeof left === \"string\" && typeof right === \"string\")\n\t\t\tif (!ordered) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst a = left as number | string\n\t\t\tconst b = right as number | string\n\t\t\tswitch (op) {\n\t\t\t\tcase \"lt\":\n\t\t\t\t\treturn a < b\n\t\t\t\tcase \"lte\":\n\t\t\t\t\treturn a <= b\n\t\t\t\tcase \"gt\":\n\t\t\t\t\treturn a > b\n\t\t\t\tcase \"gte\":\n\t\t\t\t\treturn a >= b\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Gives the values of a resource path. It gives `undefined` when the resource\n * has no path.\n */\nconst pathValues = (\n\tvalue: unknown,\n\tpath: ReadonlyArray<Resource.PathSegment> | undefined,\n): ReadonlyArray<unknown> | undefined =>\n\tpath?.map((segment) =>\n\t\ttypeof segment === \"string\" ? segment : getField(value, segment.field),\n\t)\n\nconst testUnder = (\n\tprefix: ReadonlyArray<Condition.Operand>,\n\tinput: Condition.Input,\n): boolean => {\n\tconst values = pathValues(input.value, input.path)\n\tif (values === undefined || prefix.length > values.length) {\n\t\treturn false\n\t}\n\treturn prefix.every(\n\t\t(operand, index) => resolve(operand, input.principal) === values[index],\n\t)\n}\n\n/** @internal */\nexport const hasPredicate = (ast: Ast): boolean => {\n\tswitch (ast._tag) {\n\t\tcase \"Predicate\":\n\t\t\treturn true\n\t\tcase \"And\":\n\t\tcase \"Or\":\n\t\t\treturn ast.conditions.some(hasPredicate)\n\t\tcase \"Not\":\n\t\t\treturn hasPredicate(ast.condition)\n\t\tdefault:\n\t\t\treturn false\n\t}\n}\n\n/** @internal */\nexport const evaluateSyncOf = (ast: Ast, input: Condition.Input): boolean => {\n\tswitch (ast._tag) {\n\t\tcase \"True\":\n\t\t\treturn true\n\t\tcase \"False\":\n\t\t\treturn false\n\t\tcase \"Compare\":\n\t\t\treturn testCompare(\n\t\t\t\tast.op,\n\t\t\t\tgetField(input.value, ast.field),\n\t\t\t\tresolve(ast.value, input.principal),\n\t\t\t)\n\t\tcase \"In\": {\n\t\t\tconst field = getField(input.value, ast.field)\n\t\t\treturn ast.values.some(\n\t\t\t\t(operand) => resolve(operand, input.principal) === field,\n\t\t\t)\n\t\t}\n\t\tcase \"Exists\":\n\t\t\treturn getField(input.value, ast.field) !== null\n\t\tcase \"Under\":\n\t\t\treturn testUnder(ast.prefix, input)\n\t\tcase \"And\":\n\t\t\treturn ast.conditions.every((child) => evaluateSyncOf(child, input))\n\t\tcase \"Or\":\n\t\t\treturn ast.conditions.some((child) => evaluateSyncOf(child, input))\n\t\tcase \"Not\":\n\t\t\treturn !evaluateSyncOf(ast.condition, input)\n\t\tcase \"Predicate\":\n\t\t\t// The types stop this. A predicate needs `evaluate`.\n\t\t\tthrow new Error(\n\t\t\t\t`The predicate \"${ast.name}\" needs an Effect. Use Condition.evaluate.`,\n\t\t\t)\n\t}\n}\n\n/** @internal */\nexport const evaluateOf = (\n\tast: Ast,\n\tinput: Condition.Input,\n): Effect.Effect<boolean, unknown, unknown> => {\n\tif (!hasPredicate(ast)) {\n\t\treturn Effect.sync(() => evaluateSyncOf(ast, input))\n\t}\n\tswitch (ast._tag) {\n\t\tcase \"Predicate\":\n\t\t\treturn ast.run(input.value, input.principal)\n\t\tcase \"Not\":\n\t\t\treturn Effect.map(evaluateOf(ast.condition, input), (value) => !value)\n\t\tcase \"And\":\n\t\t\treturn Effect.gen(function* () {\n\t\t\t\tfor (const child of ast.conditions) {\n\t\t\t\t\tif (!(yield* evaluateOf(child, input))) {\n\t\t\t\t\t\treturn false\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn true\n\t\t\t})\n\t\tcase \"Or\":\n\t\t\treturn Effect.gen(function* () {\n\t\t\t\tfor (const child of ast.conditions) {\n\t\t\t\t\tif (yield* evaluateOf(child, input)) {\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn false\n\t\t\t})\n\t\tdefault:\n\t\t\treturn Effect.sync(() => evaluateSyncOf(ast, input))\n\t}\n}\n\nconst dedupe = (conditions: ReadonlyArray<Ast>): ReadonlyArray<Ast> => {\n\tconst output: Array<Ast> = []\n\tfor (const condition of conditions) {\n\t\tif (!output.some((other) => Equal.equals(other, condition))) {\n\t\t\toutput.push(condition)\n\t\t}\n\t}\n\treturn output\n}\n\n/**\n * Removes the children that the other children make useless. In an `Or`,\n * `a OR (a AND b)` is `a`. In an `And`, `a AND (a OR b)` is `a`.\n */\nconst absorb = (\n\tinner: \"And\" | \"Or\",\n\tconditions: ReadonlyArray<Ast>,\n): ReadonlyArray<Ast> =>\n\tconditions.filter(\n\t\t(condition) =>\n\t\t\tcondition._tag !== inner ||\n\t\t\t!conditions.some(\n\t\t\t\t(other) =>\n\t\t\t\t\tother !== condition &&\n\t\t\t\t\tcondition.conditions.some((part) => Equal.equals(part, other)),\n\t\t\t),\n\t)\n\nconst flatten = (\n\ttag: \"And\" | \"Or\",\n\tconditions: ReadonlyArray<Ast>,\n): ReadonlyArray<Ast> =>\n\tconditions.flatMap((child) => {\n\t\tconst simple = simplify(child)\n\t\treturn simple._tag === tag ? simple.conditions : [simple]\n\t})\n\n/** @internal */\nexport const simplify = (ast: Ast): Ast => {\n\tswitch (ast._tag) {\n\t\tcase \"And\": {\n\t\t\tconst children = flatten(\"And\", ast.conditions).filter(\n\t\t\t\t(child) => child._tag !== \"True\",\n\t\t\t)\n\t\t\tif (children.some((child) => child._tag === \"False\")) {\n\t\t\t\treturn never\n\t\t\t}\n\t\t\tconst unique = absorb(\"Or\", dedupe(children))\n\t\t\tif (unique.length === 0) {\n\t\t\t\treturn always\n\t\t\t}\n\t\t\treturn unique.length === 1 ? unique[0]! : and(...unique)\n\t\t}\n\t\tcase \"Or\": {\n\t\t\tconst children = flatten(\"Or\", ast.conditions).filter(\n\t\t\t\t(child) => child._tag !== \"False\",\n\t\t\t)\n\t\t\tif (children.some((child) => child._tag === \"True\")) {\n\t\t\t\treturn always\n\t\t\t}\n\t\t\tconst unique = absorb(\"And\", dedupe(children))\n\t\t\tif (unique.length === 0) {\n\t\t\t\treturn never\n\t\t\t}\n\t\t\treturn unique.length === 1 ? unique[0]! : or(...unique)\n\t\t}\n\t\tcase \"Not\": {\n\t\t\tconst child = simplify(ast.condition)\n\t\t\tswitch (child._tag) {\n\t\t\t\tcase \"True\":\n\t\t\t\t\treturn never\n\t\t\t\tcase \"False\":\n\t\t\t\t\treturn always\n\t\t\t\tcase \"Not\":\n\t\t\t\t\treturn child.condition\n\t\t\t\tcase \"Compare\":\n\t\t\t\t\t// A principal field with no value makes `eq` and `ne` both false,\n\t\t\t\t\t// so only a fixed value lets `not eq` become `ne`.\n\t\t\t\t\tif (\n\t\t\t\t\t\tchild.value._tag === \"Literal\" &&\n\t\t\t\t\t\t(child.op === \"eq\" || child.op === \"ne\")\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\t\t...child,\n\t\t\t\t\t\t\top: child.op === \"eq\" ? \"ne\" : \"eq\",\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\treturn not(child)\n\t\t\t\tdefault:\n\t\t\t\t\treturn not(child)\n\t\t\t}\n\t\t}\n\t\tcase \"In\":\n\t\t\treturn ast.values.length === 0 ? never : ast\n\t\tdefault:\n\t\t\treturn ast\n\t}\n}\n\n/**\n * Puts the value of the principal into an operand. It gives `undefined` for a\n * principal field with no value. See {@link resolve}.\n */\nconst bindOperand = (\n\toperand: Condition.Operand,\n\tprincipal: unknown,\n): Condition.Literal | undefined => {\n\tif (operand._tag === \"Literal\") {\n\t\treturn operand\n\t}\n\tconst value = resolve(operand, principal)\n\treturn value === undefined ? undefined : literal(value as Scalar)\n}\n\nconst expandUnder = (\n\tprefix: ReadonlyArray<Condition.Operand>,\n\tprincipal: unknown,\n\tpath: ReadonlyArray<Resource.PathSegment> | undefined,\n): Ast => {\n\tif (path === undefined || prefix.length > path.length) {\n\t\treturn never\n\t}\n\tconst parts: Array<Ast> = []\n\tprefix.forEach((operand, index) => {\n\t\tconst value = resolve(operand, principal)\n\t\tconst segment = path[index]!\n\t\tif (value === undefined) {\n\t\t\tparts.push(never)\n\t\t} else if (typeof segment === \"string\") {\n\t\t\tparts.push(segment === value ? always : never)\n\t\t} else {\n\t\t\tparts.push(\n\t\t\t\tObject.freeze({\n\t\t\t\t\t_tag: \"Compare\",\n\t\t\t\t\top: \"eq\",\n\t\t\t\t\tfield: segment.field,\n\t\t\t\t\tvalue: literal(value as Scalar),\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t})\n\treturn and(...parts)\n}\n\nconst bind = (\n\tast: Ast,\n\tprincipal: unknown,\n\tpath: ReadonlyArray<Resource.PathSegment> | undefined,\n): Ast => {\n\tswitch (ast._tag) {\n\t\tcase \"Compare\": {\n\t\t\tconst value = bindOperand(ast.value, principal)\n\t\t\treturn value === undefined ? never : Object.freeze({ ...ast, value })\n\t\t}\n\t\tcase \"In\":\n\t\t\treturn Object.freeze({\n\t\t\t\t...ast,\n\t\t\t\tvalues: Object.freeze(\n\t\t\t\t\tast.values.flatMap((operand) => {\n\t\t\t\t\t\tconst value = bindOperand(operand, principal)\n\t\t\t\t\t\treturn value === undefined ? [] : [value]\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t})\n\t\tcase \"Under\":\n\t\t\treturn expandUnder(ast.prefix, principal, path)\n\t\tcase \"And\":\n\t\t\treturn and(...ast.conditions.map((child) => bind(child, principal, path)))\n\t\tcase \"Or\":\n\t\t\treturn or(...ast.conditions.map((child) => bind(child, principal, path)))\n\t\tcase \"Not\":\n\t\t\treturn not(bind(ast.condition, principal, path))\n\t\tcase \"Predicate\":\n\t\t\treturn Object.freeze({\n\t\t\t\t_tag: \"Predicate\",\n\t\t\t\tname: ast.name,\n\t\t\t\trun: (value: unknown) => ast.run(value, principal),\n\t\t\t})\n\t\tdefault:\n\t\t\treturn ast\n\t}\n}\n\n/** @internal */\nexport const partialOf = (\n\tast: Ast,\n\tinput: {\n\t\treadonly principal?: object | undefined\n\t\treadonly path?: ReadonlyArray<Resource.PathSegment> | undefined\n\t},\n): Ast => simplify(bind(ast, input.principal, input.path))\n\n/** @internal */\nexport const evaluate = dual(2, evaluateOf)\n\n/** @internal */\nexport const evaluateSync = dual(2, evaluateSyncOf)\n\n/** @internal */\nexport const partial = dual(2, partialOf)\n\n/** @internal */\nexport class Untranslatable extends Schema.TaggedError<Untranslatable>(\n\t\"@nmnmcc/ability/Condition/Untranslatable\",\n)(\"Untranslatable\", { reason: Schema.String }) {}\n\nconst foldNode = <A>(ast: Ast, interpreter: Condition.Interpreter<A>): A => {\n\tswitch (ast._tag) {\n\t\tcase \"True\":\n\t\t\treturn interpreter.true()\n\t\tcase \"False\":\n\t\t\treturn interpreter.false()\n\t\tcase \"Compare\":\n\t\t\tif (ast.value._tag !== \"Literal\") {\n\t\t\t\tthrow Untranslatable.make({\n\t\t\t\t\treason: `The field \"${ast.field}\" is compared with a principal field. Call Condition.partial first.`,\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn interpreter.compare(ast.op, ast.field, ast.value.value)\n\t\tcase \"In\":\n\t\t\treturn interpreter.in(\n\t\t\t\tast.field,\n\t\t\t\tast.values.map((operand) => {\n\t\t\t\t\tif (operand._tag !== \"Literal\") {\n\t\t\t\t\t\tthrow Untranslatable.make({\n\t\t\t\t\t\t\treason: `The field \"${ast.field}\" uses a principal field. Call Condition.partial first.`,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\treturn operand.value\n\t\t\t\t}),\n\t\t\t)\n\t\tcase \"Exists\":\n\t\t\treturn interpreter.exists(ast.field)\n\t\tcase \"Under\":\n\t\t\tthrow Untranslatable.make({\n\t\t\t\treason:\n\t\t\t\t\t\"An Under node needs the resource path. Call Condition.partial first.\",\n\t\t\t})\n\t\tcase \"And\":\n\t\t\treturn interpreter.and(\n\t\t\t\tast.conditions.map((child) => foldNode(child, interpreter)),\n\t\t\t)\n\t\tcase \"Or\":\n\t\t\treturn interpreter.or(\n\t\t\t\tast.conditions.map((child) => foldNode(child, interpreter)),\n\t\t\t)\n\t\tcase \"Not\":\n\t\t\treturn interpreter.not(foldNode(ast.condition, interpreter))\n\t\tcase \"Predicate\":\n\t\t\tif (interpreter.predicate === undefined) {\n\t\t\t\tthrow Untranslatable.make({\n\t\t\t\t\treason: `The predicate \"${ast.name}\" can not become a query`,\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn interpreter.predicate(ast.name)\n\t}\n}\n\n/** @internal */\nexport const fold = dual(\n\t2,\n\t<A>(\n\t\tast: Ast,\n\t\tinterpreter: Condition.Interpreter<A>,\n\t): Effect.Effect<A, Untranslatable> =>\n\t\tEffect.try({\n\t\t\ttry: () => foldNode(ast, interpreter),\n\t\t\tcatch: (cause) => {\n\t\t\t\tif (cause instanceof Untranslatable) {\n\t\t\t\t\treturn cause\n\t\t\t\t}\n\t\t\t\tthrow cause\n\t\t\t},\n\t\t}),\n)\n\n/** @internal */\nexport const fields = (ast: Ast): ReadonlyArray<string> => {\n\tconst output = new Set<string>()\n\tconst visit = (node: Ast): void => {\n\t\tswitch (node._tag) {\n\t\t\tcase \"Compare\":\n\t\t\tcase \"In\":\n\t\t\tcase \"Exists\":\n\t\t\t\toutput.add(node.field)\n\t\t\t\treturn\n\t\t\tcase \"And\":\n\t\t\tcase \"Or\":\n\t\t\t\tnode.conditions.forEach(visit)\n\t\t\t\treturn\n\t\t\tcase \"Not\":\n\t\t\t\tvisit(node.condition)\n\t\t\t\treturn\n\t\t\tdefault:\n\t\t\t\treturn\n\t\t}\n\t}\n\tvisit(ast)\n\treturn Object.freeze(Array.from(output))\n}\n\nconst ScalarSchema = Schema.Union([\n\tSchema.String,\n\tSchema.Finite,\n\tSchema.Boolean,\n\tSchema.Null,\n])\n\nconst OperandSchema = Schema.Union([\n\tSchema.TaggedStruct(\"Literal\", { value: ScalarSchema }),\n\tSchema.TaggedStruct(\"Principal\", { path: Schema.String }),\n])\n\nconst Recursive = Schema.suspend(\n\t(): Schema.Codec<Condition.Condition, Condition.Encoded> => schema,\n)\n\n/** @internal */\nexport const schema: Schema.Codec<Condition.Condition, Condition.Encoded> =\n\tSchema.Union([\n\t\tSchema.TaggedStruct(\"True\", {}),\n\t\tSchema.TaggedStruct(\"False\", {}),\n\t\tSchema.TaggedStruct(\"Compare\", {\n\t\t\top: Schema.Literals([\"eq\", \"ne\", \"lt\", \"lte\", \"gt\", \"gte\"]),\n\t\t\tfield: Schema.String,\n\t\t\tvalue: OperandSchema,\n\t\t}),\n\t\tSchema.TaggedStruct(\"In\", {\n\t\t\tfield: Schema.String,\n\t\t\tvalues: Schema.Array(OperandSchema),\n\t\t}),\n\t\tSchema.TaggedStruct(\"Exists\", { field: Schema.String }),\n\t\tSchema.TaggedStruct(\"Under\", { prefix: Schema.Array(OperandSchema) }),\n\t\tSchema.TaggedStruct(\"And\", { conditions: Schema.Array(Recursive) }),\n\t\tSchema.TaggedStruct(\"Or\", { conditions: Schema.Array(Recursive) }),\n\t\tSchema.TaggedStruct(\"Not\", { condition: Recursive }),\n\t]) as never\n"],"mappings":"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"}