@nmnmcc/ability 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +353 -170
  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 -4
  40. package/dist/index.js +9 -4
  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 -74
  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 -516
  78. package/dist/Ability.js +0 -211
  79. package/dist/AbilityExtra.d.ts +0 -79
  80. package/dist/AbilityExtra.js +0 -195
  81. package/dist/AbilityRef.d.ts +0 -110
  82. package/dist/AbilityRef.js +0 -160
  83. package/dist/internal/ability.d.ts +0 -114
  84. package/dist/internal/ability.js +0 -624
  85. package/dist/internal/serializable.js +0 -22
@@ -0,0 +1,706 @@
1
+ /**
2
+ * A condition is a test on a resource value. A rule applies only when its
3
+ * condition is true.
4
+ *
5
+ * A condition is plain data: a tree of nodes. So you can:
6
+ * - test it on a value with {@link evaluate};
7
+ * - put the principal into it and make it smaller with {@link partial}, which
8
+ * gives a "residual" condition: the part that still depends on the
9
+ * resource;
10
+ * - change it into a database query with {@link fold};
11
+ * - keep it as JSON with {@link schema}.
12
+ *
13
+ * Make conditions with a {@link Builder}. A rule gives you a builder for its
14
+ * resource, so the field names and the value types are checked.
15
+ *
16
+ * {@link Builder.predicate} is the one way out of plain data. A predicate runs
17
+ * any `Effect`. Its error type and its service type go into the type of the
18
+ * check. A rule with a predicate can not become JSON, and the type system
19
+ * stops you when you try.
20
+ *
21
+ * @stability stable
22
+ * @since 0.3.0
23
+ */
24
+ import type * as Effect from "effect/Effect"
25
+ import type * as Schema from "effect/Schema"
26
+ import * as internal from "./internal/condition.ts"
27
+ import type * as Resource from "./Resource.ts"
28
+
29
+ /**
30
+ * A value that a condition can compare.
31
+ *
32
+ * @stability stable
33
+ * @category models
34
+ * @since 0.3.0
35
+ */
36
+ export type Scalar = string | number | boolean | null
37
+
38
+ /**
39
+ * A fixed value in a condition.
40
+ *
41
+ * @stability stable
42
+ * @category models
43
+ * @since 0.3.0
44
+ */
45
+ export interface Literal {
46
+ readonly _tag: "Literal"
47
+ readonly value: Scalar
48
+ }
49
+
50
+ /**
51
+ * A field of the principal. {@link partial} puts the value of the field in its
52
+ * place.
53
+ *
54
+ * A principal field that is `null` or missing has no value. A `Compare`, `In`
55
+ * or `Under` test with it is always false, also with `ne`. So a principal with
56
+ * no id never matches a resource with no owner. `not` still turns false into
57
+ * true.
58
+ *
59
+ * @stability stable
60
+ * @category models
61
+ * @since 0.3.0
62
+ */
63
+ export interface PrincipalRef {
64
+ readonly _tag: "Principal"
65
+ readonly path: string
66
+ }
67
+
68
+ /**
69
+ * A field of the principal with a known value type.
70
+ *
71
+ * @stability stable
72
+ * @category models
73
+ * @since 0.3.0
74
+ */
75
+ export type Ref<A> = PrincipalRef & { readonly "~Ref"?: () => A }
76
+
77
+ /**
78
+ * @stability stable
79
+ * @category models
80
+ * @since 0.3.0
81
+ */
82
+ export type Operand = Literal | PrincipalRef
83
+
84
+ /**
85
+ * @stability stable
86
+ * @category models
87
+ * @since 0.3.0
88
+ */
89
+ export type CompareOperator = "eq" | "ne" | "lt" | "lte" | "gt" | "gte"
90
+
91
+ /**
92
+ * Always true.
93
+ *
94
+ * @stability stable
95
+ * @category models
96
+ * @since 0.3.0
97
+ */
98
+ export interface True {
99
+ readonly _tag: "True"
100
+ }
101
+
102
+ /**
103
+ * Always false.
104
+ *
105
+ * @stability stable
106
+ * @category models
107
+ * @since 0.3.0
108
+ */
109
+ export interface False {
110
+ readonly _tag: "False"
111
+ }
112
+
113
+ /**
114
+ * Compares a field with a value. A missing field has the value `null`. `lt`,
115
+ * `lte`, `gt` and `gte` are false when the two sides are not both numbers or
116
+ * both strings.
117
+ *
118
+ * @stability stable
119
+ * @category models
120
+ * @since 0.3.0
121
+ */
122
+ export interface Compare {
123
+ readonly _tag: "Compare"
124
+ readonly op: CompareOperator
125
+ readonly field: string
126
+ readonly value: Operand
127
+ }
128
+
129
+ /**
130
+ * True when a field is equal to one of the values.
131
+ *
132
+ * @stability stable
133
+ * @category models
134
+ * @since 0.3.0
135
+ */
136
+ export interface In {
137
+ readonly _tag: "In"
138
+ readonly field: string
139
+ readonly values: ReadonlyArray<Operand>
140
+ }
141
+
142
+ /**
143
+ * True when a field is not `null` and not missing.
144
+ *
145
+ * @stability stable
146
+ * @category models
147
+ * @since 0.3.0
148
+ */
149
+ export interface Exists {
150
+ readonly _tag: "Exists"
151
+ readonly field: string
152
+ }
153
+
154
+ /**
155
+ * True when the path of the resource starts with the prefix. A resource with
156
+ * no path is never under a prefix.
157
+ *
158
+ * @stability stable
159
+ * @category models
160
+ * @since 0.3.0
161
+ */
162
+ export interface Under {
163
+ readonly _tag: "Under"
164
+ readonly prefix: ReadonlyArray<Operand>
165
+ }
166
+
167
+ /**
168
+ * @stability stable
169
+ * @category models
170
+ * @since 0.3.0
171
+ */
172
+ export interface And {
173
+ readonly _tag: "And"
174
+ readonly conditions: ReadonlyArray<Ast>
175
+ }
176
+
177
+ /**
178
+ * @stability stable
179
+ * @category models
180
+ * @since 0.3.0
181
+ */
182
+ export interface Or {
183
+ readonly _tag: "Or"
184
+ readonly conditions: ReadonlyArray<Ast>
185
+ }
186
+
187
+ /**
188
+ * @stability stable
189
+ * @category models
190
+ * @since 0.3.0
191
+ */
192
+ export interface Not {
193
+ readonly _tag: "Not"
194
+ readonly condition: Ast
195
+ }
196
+
197
+ /**
198
+ * A test that runs an `Effect`. It can not become JSON or a query.
199
+ *
200
+ * @stability stable
201
+ * @category models
202
+ * @since 0.3.0
203
+ */
204
+ export interface Predicate {
205
+ readonly _tag: "Predicate"
206
+ readonly name: string
207
+ readonly run: (
208
+ value: any,
209
+ principal: any,
210
+ ) => Effect.Effect<boolean, unknown, unknown>
211
+ }
212
+
213
+ /**
214
+ * The nodes of a condition, without types.
215
+ *
216
+ * @stability stable
217
+ * @category models
218
+ * @since 0.3.0
219
+ */
220
+ export type Ast =
221
+ True | False | Compare | In | Exists | Under | And | Or | Not | Predicate
222
+
223
+ /**
224
+ * The type marker for a condition with a {@link Predicate}.
225
+ *
226
+ * @stability stable
227
+ * @category models
228
+ * @since 0.3.0
229
+ */
230
+ export type Opaque = "Opaque"
231
+
232
+ /**
233
+ * @stability stable
234
+ * @category models
235
+ * @since 0.3.0
236
+ */
237
+ export interface Variance<E, R, O> {
238
+ readonly E: () => E
239
+ readonly R: () => R
240
+ readonly O: () => O
241
+ }
242
+
243
+ /**
244
+ * A condition. `E` and `R` are the error type and the service type of its
245
+ * predicates. `O` is {@link Opaque} when the condition has a predicate, and
246
+ * `never` when it is plain data.
247
+ *
248
+ * @stability stable
249
+ * @category models
250
+ * @since 0.3.0
251
+ */
252
+ export type Condition<E = never, R = never, O = never> = Ast & {
253
+ readonly "~Condition"?: Variance<E, R, O>
254
+ }
255
+
256
+ /**
257
+ * Any condition.
258
+ *
259
+ * @stability stable
260
+ * @category models
261
+ * @since 0.3.0
262
+ */
263
+ export type Any = Condition<any, any, any>
264
+
265
+ /**
266
+ * The error type of a condition.
267
+ *
268
+ * @stability stable
269
+ * @category utility types
270
+ * @since 0.3.0
271
+ */
272
+ export type Error<C> = C extends {
273
+ readonly "~Condition"?: Variance<infer E, infer _R, infer _O>
274
+ }
275
+ ? E
276
+ : never
277
+
278
+ /**
279
+ * The service type of a condition.
280
+ *
281
+ * @stability stable
282
+ * @category utility types
283
+ * @since 0.3.0
284
+ */
285
+ export type Services<C> = C extends {
286
+ readonly "~Condition"?: Variance<infer _E, infer R, infer _O>
287
+ }
288
+ ? R
289
+ : never
290
+
291
+ /**
292
+ * {@link Opaque} when a condition has a predicate.
293
+ *
294
+ * @stability stable
295
+ * @category utility types
296
+ * @since 0.3.0
297
+ */
298
+ export type OpaqueOf<C> = C extends {
299
+ readonly "~Condition"?: Variance<infer _E, infer _R, infer O>
300
+ }
301
+ ? O
302
+ : never
303
+
304
+ type Leaf = string | number | boolean | bigint | symbol | null | undefined
305
+ type PreviousDepth = [never, 0, 1, 2, 3]
306
+ type FieldPathInternal<T, Depth extends number> = [Depth] extends [never]
307
+ ? never
308
+ : {
309
+ [K in keyof T & string]-?: NonNullable<T[K]> extends Leaf
310
+ ? K
311
+ : NonNullable<T[K]> extends ReadonlyArray<unknown> | Function
312
+ ? never
313
+ : NonNullable<T[K]> extends object
314
+ ? `${K}.${FieldPathInternal<NonNullable<T[K]>, PreviousDepth[Depth]>}`
315
+ : never
316
+ }[keyof T & string]
317
+
318
+ /**
319
+ * The paths of the fields of `T` that hold one value, with dots for nested
320
+ * fields. Arrays are left out. The type goes down four levels, so type
321
+ * checking stays fast. For a union of types, only the common fields are
322
+ * paths.
323
+ *
324
+ * @stability stable
325
+ * @category utility types
326
+ * @since 0.3.0
327
+ */
328
+ export type FieldPath<T> = [T] extends [object]
329
+ ? FieldPathInternal<T, 4>
330
+ : never
331
+
332
+ type Normalize<A> = Exclude<A, undefined> | (undefined extends A ? null : never)
333
+
334
+ /**
335
+ * The type of the field of `T` at `Path`. A field that may be missing may also
336
+ * be `null`.
337
+ *
338
+ * @stability stable
339
+ * @category utility types
340
+ * @since 0.3.0
341
+ */
342
+ export type PathValue<
343
+ T,
344
+ Path extends string,
345
+ > = Path extends `${infer Head}.${infer Rest}`
346
+ ? Head extends keyof T
347
+ ? undefined extends T[Head]
348
+ ? PathValue<NonNullable<T[Head]>, Rest> | null
349
+ : null extends T[Head]
350
+ ? PathValue<NonNullable<T[Head]>, Rest> | null
351
+ : PathValue<T[Head], Rest>
352
+ : never
353
+ : Path extends keyof T
354
+ ? Normalize<T[Path]>
355
+ : never
356
+
357
+ /**
358
+ * A value for a field of type `A`: a fixed value, or a field of the principal
359
+ * with the same type.
360
+ *
361
+ * @stability stable
362
+ * @category models
363
+ * @since 0.3.0
364
+ */
365
+ export type OperandOf<A> = Extract<A, Scalar> | Ref<A>
366
+
367
+ type OrderedPath<T> = {
368
+ [F in FieldPath<T>]: Exclude<PathValue<T, F>, null> extends number | string
369
+ ? F
370
+ : never
371
+ }[FieldPath<T>]
372
+
373
+ /**
374
+ * Makes conditions for a resource with the data type `Data` and the value type
375
+ * `Value`, and a principal with the type `P`.
376
+ *
377
+ * @stability stable
378
+ * @category models
379
+ * @since 0.3.0
380
+ */
381
+ export interface Builder<Data, Value, P> {
382
+ /** The field is equal to the value. */
383
+ readonly eq: <const F extends FieldPath<Data>>(
384
+ field: F,
385
+ value: OperandOf<PathValue<Data, F>>,
386
+ ) => Condition
387
+ /** The field is not equal to the value. */
388
+ readonly ne: <const F extends FieldPath<Data>>(
389
+ field: F,
390
+ value: OperandOf<PathValue<Data, F>>,
391
+ ) => Condition
392
+ readonly lt: <const F extends OrderedPath<Data>>(
393
+ field: F,
394
+ value: OperandOf<Exclude<PathValue<Data, F>, null>>,
395
+ ) => Condition
396
+ readonly lte: <const F extends OrderedPath<Data>>(
397
+ field: F,
398
+ value: OperandOf<Exclude<PathValue<Data, F>, null>>,
399
+ ) => Condition
400
+ readonly gt: <const F extends OrderedPath<Data>>(
401
+ field: F,
402
+ value: OperandOf<Exclude<PathValue<Data, F>, null>>,
403
+ ) => Condition
404
+ readonly gte: <const F extends OrderedPath<Data>>(
405
+ field: F,
406
+ value: OperandOf<Exclude<PathValue<Data, F>, null>>,
407
+ ) => Condition
408
+ /** The field is equal to one of the values. */
409
+ readonly in: <const F extends FieldPath<Data>>(
410
+ field: F,
411
+ values: ReadonlyArray<OperandOf<PathValue<Data, F>>>,
412
+ ) => Condition
413
+ /** The field has a value that is not `null`. */
414
+ readonly exists: <const F extends FieldPath<Data>>(field: F) => Condition
415
+ /** The path of the resource starts with these parts. */
416
+ readonly under: (
417
+ ...prefix: ReadonlyArray<string | null | Ref<string | null>>
418
+ ) => Condition
419
+ /** A field of the principal, to use as a value. */
420
+ readonly principal: <const F extends FieldPath<P>>(
421
+ field: F,
422
+ ) => Ref<PathValue<P, F>>
423
+ readonly and: <const Cs extends ReadonlyArray<Any>>(
424
+ ...conditions: Cs
425
+ ) => Condition<Error<Cs[number]>, Services<Cs[number]>, OpaqueOf<Cs[number]>>
426
+ readonly or: <const Cs extends ReadonlyArray<Any>>(
427
+ ...conditions: Cs
428
+ ) => Condition<Error<Cs[number]>, Services<Cs[number]>, OpaqueOf<Cs[number]>>
429
+ readonly not: <C extends Any>(
430
+ condition: C,
431
+ ) => Condition<Error<C>, Services<C>, OpaqueOf<C>>
432
+ /**
433
+ * A test that runs any code. It may give a boolean or an `Effect`. A
434
+ * condition with a predicate can not become JSON or a query.
435
+ */
436
+ readonly predicate: <E = never, R = never>(
437
+ name: string,
438
+ test: (
439
+ value: Value,
440
+ principal: P,
441
+ ) => boolean | Effect.Effect<boolean, E, R>,
442
+ ) => Condition<E, R, Opaque>
443
+ }
444
+
445
+ /**
446
+ * Makes a builder. Rules give you a builder with the right types, so you do not
447
+ * often need this.
448
+ *
449
+ * @stability stable
450
+ * @category constructors
451
+ * @since 0.3.0
452
+ */
453
+ export const builder: <Data, Value, P>() => Builder<Data, Value, P> =
454
+ internal.builder
455
+
456
+ /**
457
+ * Always true.
458
+ *
459
+ * @stability stable
460
+ * @category constructors
461
+ * @since 0.3.0
462
+ */
463
+ export const always: Condition = internal.always
464
+
465
+ /**
466
+ * Always false.
467
+ *
468
+ * @stability stable
469
+ * @category constructors
470
+ * @since 0.3.0
471
+ */
472
+ export const never: Condition = internal.never
473
+
474
+ /**
475
+ * True when all the conditions are true. With no conditions, it is true.
476
+ *
477
+ * @stability stable
478
+ * @category combinators
479
+ * @since 0.3.0
480
+ */
481
+ export const and: <const Cs extends ReadonlyArray<Any>>(
482
+ ...conditions: Cs
483
+ ) => Condition<Error<Cs[number]>, Services<Cs[number]>, OpaqueOf<Cs[number]>> =
484
+ internal.and as never
485
+
486
+ /**
487
+ * True when one of the conditions is true. With no conditions, it is false.
488
+ *
489
+ * @stability stable
490
+ * @category combinators
491
+ * @since 0.3.0
492
+ */
493
+ export const or: <const Cs extends ReadonlyArray<Any>>(
494
+ ...conditions: Cs
495
+ ) => Condition<Error<Cs[number]>, Services<Cs[number]>, OpaqueOf<Cs[number]>> =
496
+ internal.or as never
497
+
498
+ /**
499
+ * @stability stable
500
+ * @category combinators
501
+ * @since 0.3.0
502
+ */
503
+ export const not: <C extends Any>(
504
+ condition: C,
505
+ ) => Condition<Error<C>, Services<C>, OpaqueOf<C>> = internal.not as never
506
+
507
+ /**
508
+ * The data that a condition needs for a test.
509
+ *
510
+ * @stability stable
511
+ * @category models
512
+ * @since 0.3.0
513
+ */
514
+ export interface Input {
515
+ /** The resource value. */
516
+ readonly value: object
517
+ /**
518
+ * The principal. Without it, a principal field has no value. See
519
+ * {@link PrincipalRef}.
520
+ */
521
+ readonly principal?: object | undefined
522
+ /** The path of the resource. Without it, `Under` is false. */
523
+ readonly path?: ReadonlyArray<Resource.PathSegment> | undefined
524
+ }
525
+
526
+ /**
527
+ * Tests a condition on a value. A predicate may fail with its error.
528
+ *
529
+ * @stability stable
530
+ * @category evaluation
531
+ * @since 0.3.0
532
+ */
533
+ export const evaluate: {
534
+ (
535
+ input: Input,
536
+ ): <E, R, O>(condition: Condition<E, R, O>) => Effect.Effect<boolean, E, R>
537
+ <E, R, O>(
538
+ condition: Condition<E, R, O>,
539
+ input: Input,
540
+ ): Effect.Effect<boolean, E, R>
541
+ } = internal.evaluate as never
542
+
543
+ /**
544
+ * Tests a condition with no predicate on a value, at once.
545
+ *
546
+ * @stability stable
547
+ * @category evaluation
548
+ * @since 0.3.0
549
+ */
550
+ export const evaluateSync: {
551
+ (input: Input): (condition: Condition) => boolean
552
+ (condition: Condition, input: Input): boolean
553
+ } = internal.evaluateSync
554
+
555
+ /**
556
+ * Puts the principal into a condition and expands `Under` with the path of the
557
+ * resource. The result is simplified. It has no principal fields and no
558
+ * `Under` nodes. It is `True` or `False` when the answer does not depend on the
559
+ * resource value.
560
+ *
561
+ * @stability stable
562
+ * @category evaluation
563
+ * @since 0.3.0
564
+ */
565
+ export const partial: {
566
+ (input: {
567
+ readonly principal?: object | undefined
568
+ readonly path?: ReadonlyArray<Resource.PathSegment> | undefined
569
+ }): <E, R, O>(condition: Condition<E, R, O>) => Condition<E, R, O>
570
+ <E, R, O>(
571
+ condition: Condition<E, R, O>,
572
+ input: {
573
+ readonly principal?: object | undefined
574
+ readonly path?: ReadonlyArray<Resource.PathSegment> | undefined
575
+ },
576
+ ): Condition<E, R, O>
577
+ } = internal.partial as never
578
+
579
+ /**
580
+ * Makes a condition smaller without a change to its meaning. It removes `True`
581
+ * and `False` from `And` and `Or`, joins nested `And` and `Or` nodes, and
582
+ * removes double `Not` nodes.
583
+ *
584
+ * @stability stable
585
+ * @category evaluation
586
+ * @since 0.3.0
587
+ */
588
+ export const simplify: <E, R, O>(
589
+ condition: Condition<E, R, O>,
590
+ ) => Condition<E, R, O> = internal.simplify as never
591
+
592
+ /**
593
+ * The functions that change each node of a condition into another form, such
594
+ * as a database query.
595
+ *
596
+ * @stability stable
597
+ * @category models
598
+ * @since 0.3.0
599
+ */
600
+ export interface Interpreter<A> {
601
+ readonly true: () => A
602
+ readonly false: () => A
603
+ readonly compare: (op: CompareOperator, field: string, value: Scalar) => A
604
+ readonly in: (field: string, values: ReadonlyArray<Scalar>) => A
605
+ readonly exists: (field: string) => A
606
+ readonly and: (conditions: ReadonlyArray<A>) => A
607
+ readonly or: (conditions: ReadonlyArray<A>) => A
608
+ readonly not: (condition: A) => A
609
+ /** Optional. Without it, a predicate makes `fold` fail. */
610
+ readonly predicate?: (name: string) => A
611
+ }
612
+
613
+ /**
614
+ * The error when `fold` can not change a node.
615
+ *
616
+ * @stability stable
617
+ * @category errors
618
+ * @since 0.3.0
619
+ */
620
+ export const Untranslatable: typeof internal.Untranslatable =
621
+ internal.Untranslatable
622
+
623
+ /**
624
+ * @stability stable
625
+ * @category errors
626
+ * @since 0.3.0
627
+ */
628
+ export type Untranslatable = internal.Untranslatable
629
+
630
+ /**
631
+ * Changes a condition into another form with an interpreter. Call
632
+ * {@link partial} first: `fold` fails on principal fields and on `Under`
633
+ * nodes, and on predicates when the interpreter has no `predicate` function.
634
+ *
635
+ * @stability stable
636
+ * @category converting
637
+ * @since 0.3.0
638
+ */
639
+ export const fold: {
640
+ <A>(
641
+ interpreter: Interpreter<A>,
642
+ ): (condition: Any) => Effect.Effect<A, Untranslatable>
643
+ <A>(
644
+ condition: Any,
645
+ interpreter: Interpreter<A>,
646
+ ): Effect.Effect<A, Untranslatable>
647
+ } = internal.fold
648
+
649
+ /**
650
+ * The fields that a condition uses.
651
+ *
652
+ * @stability stable
653
+ * @category getters
654
+ * @since 0.3.0
655
+ */
656
+ export const fields: (condition: Any) => ReadonlyArray<string> = internal.fields
657
+
658
+ /**
659
+ * The JSON form of a condition with no predicate.
660
+ *
661
+ * @stability stable
662
+ * @category models
663
+ * @since 0.3.0
664
+ */
665
+ export type Encoded =
666
+ Exclude<Ast, Predicate | And | Or | Not> | EncodedAnd | EncodedOr | EncodedNot
667
+
668
+ /**
669
+ * @stability stable
670
+ * @category models
671
+ * @since 0.3.0
672
+ */
673
+ export interface EncodedAnd {
674
+ readonly _tag: "And"
675
+ readonly conditions: ReadonlyArray<Encoded>
676
+ }
677
+
678
+ /**
679
+ * @stability stable
680
+ * @category models
681
+ * @since 0.3.0
682
+ */
683
+ export interface EncodedOr {
684
+ readonly _tag: "Or"
685
+ readonly conditions: ReadonlyArray<Encoded>
686
+ }
687
+
688
+ /**
689
+ * @stability stable
690
+ * @category models
691
+ * @since 0.3.0
692
+ */
693
+ export interface EncodedNot {
694
+ readonly _tag: "Not"
695
+ readonly condition: Encoded
696
+ }
697
+
698
+ /**
699
+ * The Schema of a condition with no predicate. It checks the shape only. Use
700
+ * `Policy.schema` to check the field names against a domain too.
701
+ *
702
+ * @stability stable
703
+ * @category schemas
704
+ * @since 0.3.0
705
+ */
706
+ export const schema: Schema.Codec<Condition, Encoded> = internal.schema