@nmnmcc/ability 1.0.1 → 2.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.
- package/README.md +112 -69
- package/dist/Authorizer.d.ts +43 -47
- package/dist/Authorizer.d.ts.map +1 -1
- package/dist/Authorizer.js +5 -290
- package/dist/Authorizer.js.map +1 -1
- package/dist/Condition.d.ts +164 -332
- package/dist/Condition.d.ts.map +1 -1
- package/dist/Condition.js +75 -890
- package/dist/Condition.js.map +1 -1
- package/dist/Decision.d.ts +13 -13
- package/dist/Decision.d.ts.map +1 -1
- package/dist/Decision.js.map +1 -1
- package/dist/Domain.d.ts +10 -21
- package/dist/Domain.d.ts.map +1 -1
- package/dist/Domain.js +4 -62
- package/dist/Domain.js.map +1 -1
- package/dist/HttpApi.d.ts +31 -7
- package/dist/HttpApi.d.ts.map +1 -1
- package/dist/HttpApi.js +25 -8
- package/dist/HttpApi.js.map +1 -1
- package/dist/Limits.d.ts +114 -0
- package/dist/Limits.d.ts.map +1 -0
- package/dist/Limits.js +132 -0
- package/dist/Limits.js.map +1 -0
- package/dist/Policy.d.ts +276 -269
- package/dist/Policy.d.ts.map +1 -1
- package/dist/Policy.js +73 -1177
- package/dist/Policy.js.map +1 -1
- package/dist/Resource.d.ts +4 -177
- package/dist/Resource.d.ts.map +1 -1
- package/dist/Resource.js +4 -803
- package/dist/Resource.js.map +1 -1
- package/dist/index.d.ts +3 -4
- package/dist/index.js +4 -5
- package/dist/internal/algebra.js +267 -0
- package/dist/internal/algebra.js.map +1 -0
- package/dist/internal/analysis.js +245 -0
- package/dist/internal/analysis.js.map +1 -0
- package/dist/internal/authorizer.d.ts +30 -0
- package/dist/internal/authorizer.d.ts.map +1 -0
- package/dist/internal/authorizer.js +221 -0
- package/dist/internal/authorizer.js.map +1 -0
- package/dist/internal/bind.js +311 -0
- package/dist/internal/bind.js.map +1 -0
- package/dist/internal/catalog.d.ts +56 -0
- package/dist/internal/catalog.d.ts.map +1 -0
- package/dist/internal/catalog.js +292 -0
- package/dist/internal/catalog.js.map +1 -0
- package/dist/internal/decide.js +166 -0
- package/dist/internal/decide.js.map +1 -0
- package/dist/internal/domain.js +32 -0
- package/dist/internal/domain.js.map +1 -0
- package/dist/internal/json.js +134 -0
- package/dist/internal/json.js.map +1 -0
- package/dist/internal/limits.d.ts +14 -0
- package/dist/internal/limits.d.ts.map +1 -0
- package/dist/internal/limits.js +43 -0
- package/dist/internal/limits.js.map +1 -0
- package/dist/internal/nodes.d.ts +121 -0
- package/dist/internal/nodes.d.ts.map +1 -0
- package/dist/internal/nodes.js +277 -0
- package/dist/internal/nodes.js.map +1 -0
- package/dist/internal/patterns.js +110 -0
- package/dist/internal/patterns.js.map +1 -0
- package/dist/internal/policy-json.js +265 -0
- package/dist/internal/policy-json.js.map +1 -0
- package/dist/internal/policy-nodes.d.ts +61 -0
- package/dist/internal/policy-nodes.d.ts.map +1 -0
- package/dist/internal/policy-nodes.js +146 -0
- package/dist/internal/policy-nodes.js.map +1 -0
- package/dist/internal/policy.d.ts +42 -0
- package/dist/internal/policy.d.ts.map +1 -0
- package/dist/internal/policy.js +124 -0
- package/dist/internal/policy.js.map +1 -0
- package/dist/internal/read.js +39 -0
- package/dist/internal/read.js.map +1 -0
- package/dist/internal/resource.js +115 -0
- package/dist/internal/resource.js.map +1 -0
- package/dist/internal/rule.d.ts +26 -0
- package/dist/internal/rule.d.ts.map +1 -0
- package/dist/internal/rule.js +103 -0
- package/dist/internal/rule.js.map +1 -0
- package/dist/internal/search.d.ts +22 -0
- package/dist/internal/search.d.ts.map +1 -0
- package/dist/internal/search.js +274 -0
- package/dist/internal/search.js.map +1 -0
- package/dist/internal/suggest.js +46 -0
- package/dist/internal/suggest.js.map +1 -0
- package/package.json +3 -4
- package/src/Authorizer.ts +67 -583
- package/src/Condition.ts +339 -2095
- package/src/Decision.ts +6 -5
- package/src/Domain.ts +12 -69
- package/src/HttpApi.ts +72 -10
- package/src/Limits.ts +132 -0
- package/src/Policy.ts +391 -2772
- package/src/Resource.ts +7 -1548
- package/src/index.ts +3 -9
- package/src/internal/algebra.ts +482 -0
- package/src/internal/analysis.ts +478 -0
- package/src/internal/authorizer.ts +418 -0
- package/src/internal/bind.ts +648 -0
- package/src/internal/catalog.ts +534 -0
- package/src/internal/decide.ts +402 -0
- package/src/internal/domain.ts +66 -0
- package/src/internal/json.ts +260 -0
- package/src/internal/limits.ts +78 -0
- package/src/internal/nodes.ts +404 -0
- package/src/internal/patterns.ts +211 -0
- package/src/internal/policy-json.ts +487 -0
- package/src/internal/policy-nodes.ts +207 -0
- package/src/internal/policy.ts +264 -0
- package/src/internal/read.ts +55 -0
- package/src/internal/resource.ts +180 -0
- package/src/internal/rule.ts +196 -0
- package/src/internal/search.ts +541 -0
- package/src/internal/suggest.ts +104 -0
- package/dist/Principal.d.ts +0 -35
- package/dist/Principal.d.ts.map +0 -1
- package/dist/Principal.js +0 -37
- package/dist/Principal.js.map +0 -1
- package/dist/Rule.d.ts +0 -275
- package/dist/Rule.d.ts.map +0 -1
- package/dist/Rule.js +0 -257
- package/dist/Rule.js.map +0 -1
- package/src/Principal.ts +0 -41
- package/src/Rule.ts +0 -683
package/dist/Condition.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Condition.js","names":["Resource.hasNoValue","Resource.hasValue","Resource.isPlainField","Resource.anyDomain","Resource.domainOf"],"sources":["../src/Condition.ts"],"sourcesContent":["/**\n * A condition is a test on a resource value. A rule applies only when its\n * condition is true.\n *\n * A condition is plain data: a tree of nodes. So you can:\n * - test it on a value with {@link evaluate};\n * - put the principal into it and make it smaller with {@link partial}, which\n * gives a \"residual\" condition: the part that still depends on the\n * resource;\n * - change it into a database query with {@link fold};\n * - keep it as JSON with {@link schema}.\n *\n * Make conditions with a {@link Builder}. A rule gives you a builder for its\n * resource, so the field names and the value types are checked.\n *\n * {@link Builder.predicate} is the one way out of plain data. A predicate runs\n * any `Effect`. Its error type and its service type go into the type of the\n * check. A rule with a predicate can not become JSON, and the type system\n * stops you when you try.\n *\n * @stability stable\n * @since 0.3.0\n */\n// A predicate keeps its error type and service type in the public types. The\n// code below works on the nodes with no types, where they are `unknown`, so\n// the language service check for `unknown` in an Effect is off here.\n// @effect-diagnostics anyUnknownInErrorContext:off\nimport * as Arr from \"effect/Array\"\nimport type * as BigDecimal from \"effect/BigDecimal\"\nimport type * as Cause from \"effect/Cause\"\nimport type * as Chunk from \"effect/Chunk\"\nimport type * as DateTime from \"effect/DateTime\"\nimport type * as Duration from \"effect/Duration\"\nimport type * as Redacted from \"effect/Redacted\"\nimport type * as Result from \"effect/Result\"\nimport type * as Context from \"effect/Context\"\nimport * as Data from \"effect/Data\"\nimport * as Effect from \"effect/Effect\"\nimport * as Option from \"effect/Option\"\nimport { dual } from \"effect/Function\"\nimport * as HashMap from \"effect/HashMap\"\nimport * as HashSet from \"effect/HashSet\"\nimport * as MutableHashMap from \"effect/MutableHashMap\"\nimport { hasProperty, isObject } from \"effect/Predicate\"\nimport * as Schema from \"effect/Schema\"\nimport * as SchemaIssue from \"effect/SchemaIssue\"\nimport * as SchemaTransformation from \"effect/SchemaTransformation\"\nimport * as Resource from \"./Resource.ts\"\n\n/**\n * A value that a condition can compare.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Scalar = string | number | boolean | null\n\n/**\n * A fixed value in a condition.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Literal {\n\treadonly _tag: \"Literal\"\n\treadonly value: Scalar\n}\n\n/**\n * A field of the principal. {@link partial} puts the value of the field in its\n * place.\n *\n * A principal field that is `null` or missing has no value. A `Compare`, `In`\n * or `Under` test with it is always false, also with `ne`. So a principal with\n * no id never matches a resource with no owner. `not` still turns false into\n * true.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface PrincipalRef {\n\treadonly _tag: \"Principal\"\n\treadonly path: string\n}\n\n/**\n * A field of the principal with a known value type `A`, from a principal of\n * the type `P`. The type fields are only in the types. A reference with no\n * type does not have them, so it can not stand for a field of any type. A\n * test with the reference reads a principal of the type `P`, so it can not go\n * into a rule of a domain with another principal. With no `P`, it is `never`,\n * and a test with the reference fits no rule.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Ref<A, P = never> = PrincipalRef & {\n\treadonly \"~Ref\": () => A\n\treadonly \"~Principal\": (principal: P) => void\n}\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Operand = Literal | PrincipalRef\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type CompareOperator = \"eq\" | \"ne\" | \"lt\" | \"lte\" | \"gt\" | \"gte\"\n\n/**\n * Always true.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface True {\n\treadonly _tag: \"True\"\n}\n\n/**\n * Always false.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface False {\n\treadonly _tag: \"False\"\n}\n\n/**\n * Compares a field with a value. A missing field has the value `null`. `lt`,\n * `lte`, `gt` and `gte` are false when the two sides are not both numbers or\n * both strings.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Compare {\n\treadonly _tag: \"Compare\"\n\treadonly op: CompareOperator\n\treadonly field: string\n\treadonly value: Operand\n}\n\n/**\n * True when a field is equal to one of the values.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface In {\n\treadonly _tag: \"In\"\n\treadonly field: string\n\treadonly values: ReadonlyArray<Operand>\n}\n\n/**\n * True when a field is not `null` and not missing.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Exists {\n\treadonly _tag: \"Exists\"\n\treadonly field: string\n}\n\n/**\n * True when the path of the resource starts with the prefix. A resource with\n * no path is never under a prefix.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Under {\n\treadonly _tag: \"Under\"\n\treadonly prefix: ReadonlyArray<Operand>\n}\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface And {\n\treadonly _tag: \"And\"\n\treadonly conditions: ReadonlyArray<Ast>\n}\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Or {\n\treadonly _tag: \"Or\"\n\treadonly conditions: ReadonlyArray<Ast>\n}\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Not {\n\treadonly _tag: \"Not\"\n\treadonly condition: Ast\n}\n\n/**\n * A test that runs an `Effect`. It can not become JSON or a query.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Predicate {\n\treadonly _tag: \"Predicate\"\n\treadonly name: string\n\t// A method, so the typed `run` of `PredicateCondition`, with inputs of the\n\t// type `never`, is a `run` of this node too.\n\trun(value: any, principal: any): Effect.Effect<boolean, unknown, unknown>\n}\n\n/**\n * The nodes of a condition, without types.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Ast =\n\tTrue | False | Compare | In | Exists | Under | And | Or | Not | Predicate\n\n/**\n * The type marker for a condition with a {@link Predicate}.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Opaque = \"Opaque\"\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Variance<E, R, O> {\n\treadonly E: () => E\n\treadonly R: () => R\n\treadonly O: () => O\n}\n\n/**\n * What the predicates of a condition read: a resource value of the type `V`\n * and a principal of the type `P`. It is only in the types.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport interface Reads<V, P> {\n\treadonly value: V\n\treadonly principal: P\n}\n\n/**\n * The type fields of a condition. They are only in the types.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport interface Marks<E, R, O, I> {\n\treadonly \"~Condition\": Variance<E, R, O>\n\t/** `I` is what the predicates read. See {@link Reads}. */\n\treadonly \"~Reads\": (reads: I) => void\n}\n\n/**\n * An `And` node with the types of its children.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport interface AndCondition<E, R, O, I> extends Marks<E, R, O, I> {\n\treadonly _tag: \"And\"\n\treadonly conditions: ReadonlyArray<Condition<E, R, O, I>>\n}\n\n/**\n * An `Or` node with the types of its children.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport interface OrCondition<E, R, O, I> extends Marks<E, R, O, I> {\n\treadonly _tag: \"Or\"\n\treadonly conditions: ReadonlyArray<Condition<E, R, O, I>>\n}\n\n/**\n * A `Not` node with the types of its child.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport interface NotCondition<E, R, O, I> extends Marks<E, R, O, I> {\n\treadonly _tag: \"Not\"\n\treadonly condition: Condition<E, R, O, I>\n}\n\n/**\n * A predicate node with its types. `\"~Predicate\"` is only in the types. It has\n * the type `O`, so a plain condition, with `O` as `never`, can not be a\n * predicate. The builder makes predicates with `O` as {@link Opaque}.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport interface PredicateCondition<E, R, O, I> extends Marks<E, R, O, I> {\n\treadonly _tag: \"Predicate\"\n\treadonly name: string\n\t/**\n\t * The test. Its inputs have the type `never`, so it can not be called with\n\t * a value that it does not read. Use {@link evaluate}, which checks the\n\t * input against `I`.\n\t */\n\treadonly run: PredicateRun<E, R, I>\n\treadonly \"~Predicate\": O\n}\n\n/**\n * The test of a predicate node. The type field `\"~Reads\"` is only in the\n * types. It ties the test to what it reads, so the test of one predicate can\n * not go into a node that says it reads other values.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport type PredicateRun<E, R, I> = ((\n\tvalue: never,\n\tprincipal: never,\n) => Effect.Effect<boolean, E, R>) & {\n\t// Required, so a plain function, with no such field, is not the test of a\n\t// predicate. Only the builder makes one.\n\treadonly \"~Reads\": (reads: I) => void\n}\n\n/**\n * A condition. `E` and `R` are the error type and the service type of its\n * predicates. `O` is {@link Opaque} when the condition has a predicate, and\n * `never` when it is plain data. `I` is what its predicates read. See\n * {@link Reads}.\n *\n * The type fields are only in the types. A plain node made by hand does not\n * have them, so it is not a condition. Use the builder. Each child of a node\n * is a condition with the same types, so a node can not hide the types of a\n * predicate inside it. A predicate is a condition only when `O` is\n * {@link Opaque}.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Condition<E = never, R = never, O = never, I = unknown> =\n\t| ((True | False | Compare | In | Exists | Under) & Marks<E, R, O, I>)\n\t| AndCondition<E, R, O, I>\n\t| OrCondition<E, R, O, I>\n\t| NotCondition<E, R, O, I>\n\t| PredicateCondition<E, R, O, I>\n\n/**\n * Any condition.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Any = Condition<any, any, any, any>\n\n/**\n * The error type of a condition.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type Error<C> = C extends {\n\treadonly \"~Condition\"?: Variance<infer E, infer _R, infer _O>\n}\n\t? E\n\t: never\n\n/**\n * The service type of a condition.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type Services<C> = C extends {\n\treadonly \"~Condition\"?: Variance<infer _E, infer R, infer _O>\n}\n\t? R\n\t: never\n\n/**\n * What the predicates of a condition read. For a union of conditions, it is\n * what all of them read.\n *\n * @stability stable\n * @category utility types\n * @since 1.0.0\n */\nexport type ReadsOf<C> = [C] extends [\n\t{ readonly \"~Reads\": (reads: infer I) => void },\n]\n\t? I\n\t: unknown\n\n/**\n * `unknown` when a condition is a condition of its own type fields: each of\n * its children has them too. A node made with a spread may keep the type\n * fields of another node, and then it is `never`, so the call stops.\n *\n * @stability stable\n * @category utility types\n * @since 1.0.0\n */\nexport type Checked<C> = [NotChecked<C>] extends [never] ? unknown : never\n\n/**\n * The members of a union of conditions that do not fit their own type fields.\n * Each member is checked alone, so a good member does not hide a bad one.\n */\ntype NotChecked<C> =\n\tC extends Condition<Error<C>, Services<C>, OpaqueOf<C>, ReadsOf<C>>\n\t\t? never\n\t\t: C\n\n/** Each condition, checked with {@link Checked}. */\ntype Consistent<Cs extends ReadonlyArray<Any>> = {\n\treadonly [K in keyof Cs]: Cs[K] & Checked<Cs[K]>\n}\n\n/**\n * {@link Opaque} when a condition has a predicate.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type OpaqueOf<C> = C extends {\n\treadonly \"~Condition\"?: Variance<infer _E, infer _R, infer O>\n}\n\t? O\n\t: never\n\ntype Leaf = string | number | boolean | bigint | symbol | null | undefined\n/**\n * Values of a class that keeps its data inside. A path does not go into them,\n * as in the field paths of a resource, so a field with such a value is one\n * field. A condition can test only if it exists.\n */\ntype Whole =\n\t| ReadonlyMap<unknown, unknown>\n\t| ReadonlySet<unknown>\n\t| HashMap.HashMap<unknown, unknown>\n\t| HashSet.HashSet<unknown>\n\t| Date\n\t| URL\n\t| Uint8Array\n\t| Option.Option<unknown>\n\t| BigDecimal.BigDecimal\n\t| Duration.Duration\n\t| DateTime.DateTime\n\t| Redacted.Redacted<unknown>\n\t| Chunk.Chunk<unknown>\n\t| Cause.Cause<unknown>\n\t| Result.Result<unknown, unknown>\n\t| File\n\t| FormData\n\t| RegExp\ntype PreviousDepth = [never, 0, 1, 2, 3]\ntype FieldPathInternal<T, Depth extends number, Arrays extends boolean> = [\n\tDepth,\n] extends [never]\n\t? never\n\t: {\n\t\t\t[K in keyof T & string]-?: NonNullable<T[K]> extends Leaf | Whole\n\t\t\t\t? K\n\t\t\t\t: NonNullable<T[K]> extends Function\n\t\t\t\t\t? never\n\t\t\t\t\t: NonNullable<T[K]> extends ReadonlyArray<unknown>\n\t\t\t\t\t\t? Arrays extends true\n\t\t\t\t\t\t\t? K\n\t\t\t\t\t\t\t: never\n\t\t\t\t\t\t: NonNullable<T[K]> extends object\n\t\t\t\t\t\t\t? `${K}.${FieldPathInternal<NonNullable<T[K]>, PreviousDepth[Depth], Arrays>}`\n\t\t\t\t\t\t\t: never\n\t\t}[keyof T & string]\n\n/**\n * The paths of the fields of `T` that hold one value, with dots for nested\n * fields. Arrays are left out. A map, a set, a date, a URL, a byte array, an\n * `Option` and the other value types of Effect, such as `BigDecimal` and\n * `Duration`, are one field, and a path does not go into them. The type goes down four levels, so type\n * checking stays fast. For a union of types, only the common fields are\n * paths.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type FieldPath<T> = [T] extends [object]\n\t? FieldPathInternal<T, 4, false>\n\t: never\n\n/**\n * The paths of the fields of `T` that a rule or a request may name, as in\n * `Rule.Options.fields`. They are the paths of {@link FieldPath}, and the\n * paths of arrays too: a rule may allow or deny a whole array field, and\n * `permittedFields` lists it.\n *\n * @stability stable\n * @category utility types\n * @since 1.0.0\n */\nexport type FieldSelector<T> = [T] extends [object]\n\t? FieldPathInternal<T, 4, true>\n\t: never\n\n/**\n * The value type that fits every field in `F`. For one field, it is the type\n * of the field. For a union of fields, it is the values that each of them can\n * hold, so a value of a union type can not test a field of another type. For\n * a union of data types, as for a rule on two kinds, it is the values that\n * the field can hold in each of them.\n *\n * @stability stable\n * @category utility types\n * @since 1.0.0\n */\nexport type FieldValue<Data, F extends string> = (\n\tData extends unknown\n\t\t? F extends unknown\n\t\t\t? (value: PathValue<Data, F>) => void\n\t\t\t: never\n\t\t: never\n) extends (value: infer V) => void\n\t? V\n\t: never\n\ntype Normalize<A> = Exclude<A, undefined> | (undefined extends A ? null : never)\n\n/**\n * The type of the field of `T` at `Path`. A field that may be missing may also\n * be `null`.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type PathValue<\n\tT,\n\tPath extends string,\n> = Path extends `${infer Head}.${infer Rest}`\n\t? Head extends keyof T\n\t\t? undefined extends T[Head]\n\t\t\t? PathValue<NonNullable<T[Head]>, Rest> | null\n\t\t\t: null extends T[Head]\n\t\t\t\t? PathValue<NonNullable<T[Head]>, Rest> | null\n\t\t\t\t: PathValue<T[Head], Rest>\n\t\t: never\n\t: Path extends keyof T\n\t\t? Normalize<T[Path]>\n\t\t: never\n\n/**\n * A value for a field of type `A`: a fixed value, or a field of the principal\n * with the same type.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type OperandOf<A, P = never> = Extract<A, Scalar> | Ref<A, P>\n\ntype ScalarPath<T> = {\n\t[F in FieldPath<T>]: PathValue<T, F> extends Scalar ? F : never\n}[FieldPath<T>]\n\ntype OrderedPath<T> = {\n\t[F in FieldPath<T>]: Exclude<PathValue<T, F>, null> extends number | string\n\t\t? F\n\t\t: never\n}[FieldPath<T>]\n\n/**\n * A test made by a {@link Builder}. It runs no code, but it keeps the value\n * type of its resource, so a test on the fields of one resource can not go\n * into a rule for another resource. A test with a field of the principal\n * keeps the principal type `P` too.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport type Test<Value, P = unknown> = Condition<\n\tnever,\n\tnever,\n\tnever,\n\tReads<Value, P>\n>\n\n/**\n * The principal type that a test reads: the principal of each field of the\n * principal in the values `V`, and `unknown` when there is none. A reference\n * from another builder keeps the principal of that builder.\n */\ntype PrincipalOf<V, _P> = [Extract<V, PrincipalRef>] extends [never]\n\t? unknown\n\t: [Extract<V, PrincipalRef>] extends [\n\t\t\t\t{ readonly \"~Principal\": (principal: infer Q) => void },\n\t\t ]\n\t\t? Q\n\t\t: unknown\n\n/**\n * Makes conditions for a resource with the data type `Data` and the value type\n * `Value`, and a principal with the type `P`.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Builder<Data, Value, P> {\n\t/** The field is equal to the value. */\n\treadonly eq: <\n\t\tconst F extends FieldPath<Data>,\n\t\tconst V extends OperandOf<FieldValue<Data, F>, any>,\n\t>(\n\t\tfield: F,\n\t\tvalue: V,\n\t) => Test<Value, PrincipalOf<V, P>>\n\t/** The field is not equal to the value. */\n\treadonly ne: <\n\t\tconst F extends FieldPath<Data>,\n\t\tconst V extends OperandOf<FieldValue<Data, F>, any>,\n\t>(\n\t\tfield: F,\n\t\tvalue: V,\n\t) => Test<Value, PrincipalOf<V, P>>\n\treadonly lt: <\n\t\tconst F extends OrderedPath<Data>,\n\t\tconst V extends OperandOf<Exclude<FieldValue<Data, F>, null>, any>,\n\t>(\n\t\tfield: F,\n\t\tvalue: V,\n\t) => Test<Value, PrincipalOf<V, P>>\n\treadonly lte: <\n\t\tconst F extends OrderedPath<Data>,\n\t\tconst V extends OperandOf<Exclude<FieldValue<Data, F>, null>, any>,\n\t>(\n\t\tfield: F,\n\t\tvalue: V,\n\t) => Test<Value, PrincipalOf<V, P>>\n\treadonly gt: <\n\t\tconst F extends OrderedPath<Data>,\n\t\tconst V extends OperandOf<Exclude<FieldValue<Data, F>, null>, any>,\n\t>(\n\t\tfield: F,\n\t\tvalue: V,\n\t) => Test<Value, PrincipalOf<V, P>>\n\treadonly gte: <\n\t\tconst F extends OrderedPath<Data>,\n\t\tconst V extends OperandOf<Exclude<FieldValue<Data, F>, null>, any>,\n\t>(\n\t\tfield: F,\n\t\tvalue: V,\n\t) => Test<Value, PrincipalOf<V, P>>\n\t/** The field is equal to one of the values. */\n\treadonly in: <\n\t\tconst F extends FieldPath<Data>,\n\t\tconst Vs extends ReadonlyArray<OperandOf<FieldValue<Data, F>, any>>,\n\t>(\n\t\tfield: F,\n\t\tvalues: Vs,\n\t) => Test<Value, PrincipalOf<Vs[number], P>>\n\t/** The field has a value that is not `null`. */\n\treadonly exists: <const F extends FieldPath<Data>>(field: F) => Test<Value>\n\t/** The path of the resource starts with these parts. */\n\treadonly under: <\n\t\tconst Ps extends ReadonlyArray<string | null | Ref<string | null, any>>,\n\t>(\n\t\t...prefix: Ps\n\t) => Test<Value, PrincipalOf<Ps[number], P>>\n\t/**\n\t * A field of the principal, to use as a value. The field must have a\n\t * {@link Scalar} type.\n\t */\n\treadonly principal: <const F extends ScalarPath<P>>(\n\t\tfield: F,\n\t) => Ref<PathValue<P, F>, P>\n\treadonly and: <const Cs extends ReadonlyArray<Any>>(\n\t\t...conditions: Consistent<Cs>\n\t) => Condition<\n\t\tError<Cs[number]>,\n\t\tServices<Cs[number]>,\n\t\tOpaqueOf<Cs[number]>,\n\t\tReadsOf<Cs[number]>\n\t>\n\treadonly or: <const Cs extends ReadonlyArray<Any>>(\n\t\t...conditions: Consistent<Cs>\n\t) => Condition<\n\t\tError<Cs[number]>,\n\t\tServices<Cs[number]>,\n\t\tOpaqueOf<Cs[number]>,\n\t\tReadsOf<Cs[number]>\n\t>\n\treadonly not: <C extends Any>(\n\t\tcondition: C & Checked<C>,\n\t) => Condition<Error<C>, Services<C>, OpaqueOf<C>, ReadsOf<C>>\n\t/**\n\t * A test that runs any code. It may give a boolean or an `Effect`. A\n\t * condition with a predicate can not become JSON or a query.\n\t */\n\treadonly predicate: <E = never, R = never>(\n\t\tname: string,\n\t\ttest: (\n\t\t\tvalue: Value,\n\t\t\tprincipal: P,\n\t\t) => boolean | Effect.Effect<boolean, E, R>,\n\t) => Condition<E, R, Opaque, Reads<Value, P>>\n}\n\nconst nodes = Data.taggedEnum<Ast>()\nconst operands = Data.taggedEnum<Operand>()\n\nconst literal = (value: Scalar): Literal => operands.Literal({ value })\n\nconst isOperand = (u: unknown): u is Operand =>\n\thasProperty(u, \"_tag\") && (u._tag === \"Literal\" || u._tag === \"Principal\")\n\nconst toOperand = (value: unknown): Operand =>\n\tisOperand(value) ? value : literal(value as Scalar)\n\nconst compare =\n\t(op: CompareOperator) =>\n\t(field: string, value: unknown): Compare =>\n\t\tnodes.Compare({ op, field, value: toOperand(value) })\n\n// A list of conditions goes in as an array, not as arguments: a call may take\n// only so many arguments, and a decoded condition may have more children.\n// The list is copied, so a later change to the array of a caller does not\n// change the condition.\nconst andOf = (conditions: ReadonlyArray<Ast>): Ast =>\n\tnodes.And({ conditions: Arr.copy(conditions) })\n\nconst orOf = (conditions: ReadonlyArray<Ast>): Ast =>\n\tnodes.Or({ conditions: Arr.copy(conditions) })\n\nconst makeAnd = (...conditions: ReadonlyArray<Ast>): Ast => andOf(conditions)\n\nconst makeOr = (...conditions: ReadonlyArray<Ast>): Ast => orOf(conditions)\n\nconst makeNot = (condition: Ast): Ast => nodes.Not({ condition })\n\nconst makePredicate = (\n\tname: string,\n\trun: (value: unknown, principal: unknown) => Effect.Effect<boolean, any, any>,\n): Ast => nodes.Predicate({ name, run })\n\nconst sharedBuilder: Builder<any, any, any> = {\n\teq: compare(\"eq\"),\n\tne: compare(\"ne\"),\n\tlt: compare(\"lt\"),\n\tlte: compare(\"lte\"),\n\tgt: compare(\"gt\"),\n\tgte: compare(\"gte\"),\n\tin: (field: string, values: ReadonlyArray<unknown>) =>\n\t\tnodes.In({ field, values: values.map(toOperand) }),\n\texists: (field: string) => nodes.Exists({ field }),\n\tunder: (...prefix: ReadonlyArray<unknown>) =>\n\t\tnodes.Under({ prefix: prefix.map(toOperand) }),\n\tprincipal: (path: string) => operands.Principal({ path }),\n\tand: makeAnd,\n\tor: makeOr,\n\tnot: makeNot,\n\tpredicate: (\n\t\tname: string,\n\t\ttest: (\n\t\t\tvalue: unknown,\n\t\t\tprincipal: unknown,\n\t\t) => boolean | Effect.Effect<boolean, unknown, unknown>,\n\t) =>\n\t\tmakePredicate(name, (value, principal) =>\n\t\t\tEffect.suspend(() => {\n\t\t\t\tconst result = test(value, principal)\n\t\t\t\treturn Effect.isEffect(result) ? result : Effect.succeed(result)\n\t\t\t}),\n\t\t),\n} as never\n\n/**\n * Makes a builder. Rules give you a builder with the right types, so you do not\n * often need this.\n *\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const builder = <Data, Value, P>(): Builder<Data, Value, P> =>\n\tsharedBuilder\n\n/**\n * Always true.\n *\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const always: Condition = nodes.True() as Condition\n\n/**\n * Always false.\n *\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const never: Condition = nodes.False() as Condition\n\n/**\n * True when all the conditions are true. With no conditions, it is true.\n *\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const and: <const Cs extends ReadonlyArray<Any>>(\n\t...conditions: Consistent<Cs>\n) => Condition<\n\tError<Cs[number]>,\n\tServices<Cs[number]>,\n\tOpaqueOf<Cs[number]>,\n\tReadsOf<Cs[number]>\n> = makeAnd as never\n\n/**\n * The same as {@link and}, for a list of conditions of one type. Use it for a\n * long list: a function call may take only so many arguments.\n *\n * @stability stable\n * @category combinators\n * @since 1.0.0\n */\nexport const andAll: <C extends Any>(\n\tconditions: ReadonlyArray<C & Checked<C>>,\n) => Condition<Error<C>, Services<C>, OpaqueOf<C>, ReadsOf<C>> = andOf as never\n\n/**\n * The same as {@link or}, for a list of conditions of one type. Use it for a\n * long list: a function call may take only so many arguments.\n *\n * @stability stable\n * @category combinators\n * @since 1.0.0\n */\nexport const orAll: <C extends Any>(\n\tconditions: ReadonlyArray<C & Checked<C>>,\n) => Condition<Error<C>, Services<C>, OpaqueOf<C>, ReadsOf<C>> = orOf as never\n\n/**\n * True when one of the conditions is true. With no conditions, it is false.\n *\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const or: <const Cs extends ReadonlyArray<Any>>(\n\t...conditions: Consistent<Cs>\n) => Condition<\n\tError<Cs[number]>,\n\tServices<Cs[number]>,\n\tOpaqueOf<Cs[number]>,\n\tReadsOf<Cs[number]>\n> = makeOr as never\n\n/**\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const not: <C extends Any>(\n\tcondition: C & Checked<C>,\n) => Condition<Error<C>, Services<C>, OpaqueOf<C>, ReadsOf<C>> =\n\tmakeNot as never\n\n/**\n * The data that a condition needs for a test.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Input {\n\t/** The resource value. */\n\treadonly value: object\n\t/**\n\t * The principal. Without it, a principal field has no value. See\n\t * {@link PrincipalRef}.\n\t */\n\treadonly principal?: object | undefined\n\t/** The path of the resource. Without it, `Under` is false. */\n\treadonly path?: ReadonlyArray<Resource.PathSegment> | undefined\n}\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/**\n * Tests if an object has a field. A field may be the object's own, or come\n * from its class, as a getter does: `Schema.is` reads such a field too. A\n * name that every object has from `Object.prototype`, such as `constructor`\n * or `toString`, is a field only when the object gives it another value, as\n * its own or from its class.\n */\nconst hasField = (value: object, key: string): boolean => {\n\tif (Object.hasOwn(value, key)) {\n\t\treturn true\n\t}\n\t// `__proto__` reads the prototype of every object, so only an own one is a\n\t// field.\n\tif (key === \"__proto__\" || !(key in value)) {\n\t\treturn false\n\t}\n\treturn (\n\t\t!(key in Object.prototype) ||\n\t\t(value as Record<string, unknown>)[key] !==\n\t\t\t(Object.prototype as Record<string, unknown>)[key]\n\t)\n}\n\nconst getField = (value: unknown, path: string): unknown =>\n\tOption.match(\n\t\tArr.reduce(path.split(\".\"), Option.some(value), (cursor, key) =>\n\t\t\tOption.flatMap(cursor, (current) =>\n\t\t\t\tisObject(current) && hasField(current, key)\n\t\t\t\t\t? Option.some((current as Record<string, unknown>)[key])\n\t\t\t\t\t: Option.none(),\n\t\t\t),\n\t\t),\n\t\t{\n\t\t\tonNone: () => null,\n\t\t\tonSome: (field) => (field === undefined ? null : field),\n\t\t},\n\t)\n\n// Any number is a scalar, also `Infinity` and `NaN`: a principal field may\n// hold them, and a test compares them as a fixed value of a condition does.\nconst isScalar = (value: unknown): value is Scalar =>\n\ttypeof value === \"string\" ||\n\ttypeof value === \"boolean\" ||\n\ttypeof value === \"number\"\n\n/**\n * Gives the value of an operand. A principal field that is `null`, missing, or\n * not a {@link Scalar} gives `undefined`. No field of a resource is\n * `undefined`, so a test with it is never true. This keeps the check closed: a\n * principal with no id never matches a resource with no owner. It also keeps\n * other values, such as a `bigint`, out of the residual condition.\n */\nconst resolve = (operand: Operand, principal: unknown): unknown => {\n\tif (operand._tag === \"Literal\") {\n\t\treturn operand.value\n\t}\n\tconst value = getField(principal, operand.path)\n\treturn isScalar(value) ? value : undefined\n}\n\nconst testCompare = (\n\top: 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 = (prefix: ReadonlyArray<Operand>, input: Input): boolean => {\n\tconst values = pathValues(input.value, input.path)\n\tif (values === undefined || prefix.length > values.length) {\n\t\treturn false\n\t}\n\t// An operand with no value never matches, also a hole in a path that gives\n\t// `undefined` too.\n\treturn prefix.every((operand, index) => {\n\t\tconst value = resolve(operand, input.principal)\n\t\treturn value !== undefined && value === values[index]\n\t})\n}\n\n/**\n * True when a condition has a {@link Predicate}.\n *\n * @stability stable\n * @category predicates\n * @since 1.0.0\n */\nexport const hasPredicate = (condition: Ast): boolean =>\n\thasPredicateIn(condition, new Map())\n\n// One node may be a child of many nodes. Each walk below keeps its work on a\n// node in a memo that the walk makes for itself, so a condition with shared\n// children takes time for its nodes, not for its paths. No memo lives longer\n// than one call.\n\n/**\n * Gives the answer for a key from the memo, or works it out and keeps it.\n *\n * A memo keyed by a node is a native `Map`, because it must find a node by\n * the node itself. An Effect `HashMap` finds a key by `Equal`, and the nodes\n * are Effect data, so it would hash the whole structure of a node, and a\n * shared child again for each path to it.\n */\nconst remember = <K, A>(memo: Map<K, A>, key: K, work: () => A): A => {\n\t// A result may be `undefined`, as the result of a fold may be, so the test\n\t// asks for the key.\n\tif (memo.has(key)) {\n\t\treturn memo.get(key) as A\n\t}\n\tconst result = work()\n\tmemo.set(key, result)\n\treturn result\n}\n\nconst hasPredicateIn = (ast: Ast, memo: Map<Ast, boolean>): boolean =>\n\tremember(memo, ast, () => {\n\t\tswitch (ast._tag) {\n\t\t\tcase \"Predicate\":\n\t\t\t\treturn true\n\t\t\tcase \"And\":\n\t\t\tcase \"Or\":\n\t\t\t\treturn Arr.some(ast.conditions, (child) => hasPredicateIn(child, memo))\n\t\t\tcase \"Not\":\n\t\t\t\treturn hasPredicateIn(ast.condition, memo)\n\t\t\tdefault:\n\t\t\t\treturn false\n\t\t}\n\t})\n\nconst provideAst = (\n\tast: Ast,\n\tcontext: Context.Context<never>,\n\tdone: Map<Ast, Ast> = new Map(),\n\tpredicates: Map<Ast, boolean> = new Map(),\n): Ast =>\n\t!hasPredicateIn(ast, predicates)\n\t\t? ast\n\t\t: remember(done, ast, () => {\n\t\t\t\tconst provide = (child: Ast) =>\n\t\t\t\t\tprovideAst(child, context, done, predicates)\n\t\t\t\tswitch (ast._tag) {\n\t\t\t\t\tcase \"Predicate\":\n\t\t\t\t\t\treturn makePredicate(ast.name, (value, principal) =>\n\t\t\t\t\t\t\tEffect.provideContext(ast.run(value, principal), context),\n\t\t\t\t\t\t)\n\t\t\t\t\tcase \"And\":\n\t\t\t\t\t\treturn andOf(Arr.map(ast.conditions, provide))\n\t\t\t\t\tcase \"Or\":\n\t\t\t\t\t\treturn orOf(Arr.map(ast.conditions, provide))\n\t\t\t\t\tcase \"Not\":\n\t\t\t\t\t\treturn makeNot(provide(ast.condition))\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn ast\n\t\t\t\t}\n\t\t\t})\n\n/**\n * Gives the services in `context` to every predicate of a condition, so the\n * condition needs no services when it runs.\n *\n * @stability stable\n * @category services\n * @since 1.0.0\n */\nexport const provideContext: {\n\t<R>(\n\t\tcontext: Context.Context<R>,\n\t): <E, O, I>(condition: Condition<E, R, O, I>) => Condition<E, never, O, I>\n\t<E, R, O, I>(\n\t\tcondition: Condition<E, R, O, I>,\n\t\tcontext: Context.Context<R>,\n\t): Condition<E, never, O, I>\n} = dual(2, provideAst) as never\n\nconst evaluateSyncAst = (ast: Ast, input: Input): boolean =>\n\tevaluateSyncNode(ast, input, new Map())\n\nconst evaluateSyncNode = (\n\tast: Ast,\n\tinput: Input,\n\tdone: Map<Ast, boolean>,\n): boolean => remember(done, ast, () => evaluateSyncOnce(ast, input, done))\n\nconst evaluateSyncOnce = (\n\tast: Ast,\n\tinput: Input,\n\tdone: Map<Ast, boolean>,\n): 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 Arr.every(ast.conditions, (child) =>\n\t\t\t\tevaluateSyncNode(child, input, done),\n\t\t\t)\n\t\tcase \"Or\":\n\t\t\treturn Arr.some(ast.conditions, (child) =>\n\t\t\t\tevaluateSyncNode(child, input, done),\n\t\t\t)\n\t\tcase \"Not\":\n\t\t\treturn !evaluateSyncNode(ast.condition, input, done)\n\t\tcase \"Predicate\":\n\t\t\t// The types stop this. A predicate needs `evaluate`.\n\t\t\tthrow new globalThis.Error(\n\t\t\t\t`The predicate \"${ast.name}\" needs an Effect. Use Condition.evaluate.`,\n\t\t\t)\n\t}\n}\n\nconst evaluateAst = (\n\tast: Ast,\n\tinput: Input,\n\tpredicates: Map<Ast, boolean> = new Map(),\n): Effect.Effect<boolean, unknown, unknown> => {\n\tif (!hasPredicateIn(ast, predicates)) {\n\t\treturn Effect.sync(() => evaluateSyncAst(ast, input))\n\t}\n\tconst evaluate = (child: Ast) => evaluateAst(child, input, predicates)\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(evaluate(ast.condition), (value) => !value)\n\t\tcase \"And\":\n\t\t\t// The children run in order, until one is false.\n\t\t\treturn Effect.map(\n\t\t\t\tEffect.findFirst(ast.conditions, (child) =>\n\t\t\t\t\tEffect.map(evaluate(child), (value) => !value),\n\t\t\t\t),\n\t\t\t\tOption.isNone,\n\t\t\t)\n\t\tcase \"Or\":\n\t\t\t// The children run in order, until one is true.\n\t\t\treturn Effect.map(\n\t\t\t\tEffect.findFirst(ast.conditions, evaluate),\n\t\t\t\tOption.isSome,\n\t\t\t)\n\t\tdefault:\n\t\t\treturn Effect.sync(() => evaluateSyncAst(ast, input))\n\t}\n}\n\n/**\n * The input of {@link evaluate} that the predicates of a condition need: a\n * value and a principal of the types in `I`. See {@link Reads}.\n */\ntype ReadsInput<I> =\n\tI extends Reads<infer V, infer P>\n\t\t? { readonly value: V } & (unknown extends P\n\t\t\t\t? unknown\n\t\t\t\t: { readonly principal: P })\n\t\t: unknown\n\n/**\n * `unknown` when `In` gives what `I` reads, and `never` when it does not. For\n * a union, each member must give it, so the test is not split over the union.\n */\ntype ReadsFrom<I, In> = [In] extends [ReadsInput<I>] ? unknown : never\n\n/**\n * Tests a condition on a value. A predicate may fail with its error. When the\n * condition has a predicate, the input must have the value and the principal\n * that the predicate reads.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const evaluate: {\n\t<In extends Input>(\n\t\tinput: In,\n\t): <E, R, O, I>(\n\t\tcondition: Condition<E, R, O, I> & ReadsFrom<I, In>,\n\t) => Effect.Effect<boolean, E, R>\n\t<E, R, O, I, In extends Input>(\n\t\tcondition: Condition<E, R, O, I>,\n\t\tinput: In & ReadsInput<I>,\n\t): Effect.Effect<boolean, E, R>\n} = dual(2, evaluateAst) as never\n\n/**\n * Tests a condition with no predicate on a value, at once.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const evaluateSync: {\n\t// The input must have the value that the condition reads, as in\n\t// `evaluate`. A residual of one kind can not test a value of another kind.\n\t<In extends Input>(\n\t\tinput: In,\n\t): <I>(\n\t\tcondition: Condition<never, never, never, I> & ReadsFrom<I, In>,\n\t) => boolean\n\t<I, In extends Input>(\n\t\tcondition: Condition<never, never, never, I>,\n\t\tinput: In & ReadsInput<I>,\n\t): boolean\n} = dual(2, evaluateSyncAst)\n\n/**\n * The memo of one simplification. One node may be a child of many nodes, so\n * the work on each node is done one time. The memo lives only as long as the\n * work that made it.\n */\ninterface Memo {\n\t/** The simple form of each node. */\n\treadonly simple: Map<Ast, Ast>\n\treadonly predicates: Map<Ast, boolean>\n\t/** A number for each node. Two nodes with one structure get one number. */\n\treadonly ids: Map<Ast, number>\n\treadonly structures: MutableHashMap.MutableHashMap<string, number>\n}\n\nconst makeMemo = (): Memo => ({\n\tsimple: new Map(),\n\tpredicates: new Map(),\n\tids: new Map(),\n\tstructures: MutableHashMap.empty(),\n})\n\nconst literalText = (value: Scalar): string =>\n\t// JSON gives `null` for `Infinity`, `-Infinity` and `NaN`, so a number is\n\t// given as its own text.\n\ttypeof value === \"number\"\n\t\t? `n${Object.is(value, -0) ? \"-0\" : String(value)}`\n\t\t: `${typeof value}:${JSON.stringify(value)}`\n\nconst operandText = (operand: Operand): string =>\n\toperand._tag === \"Literal\"\n\t\t? `L${literalText(operand.value)}`\n\t\t: `R${JSON.stringify(operand.path)}`\n\nconst structureText = (ast: Ast, memo: Memo): string | undefined => {\n\tconst id = (child: Ast) => structureId(child, memo)\n\tswitch (ast._tag) {\n\t\tcase \"True\":\n\t\tcase \"False\":\n\t\t\treturn ast._tag\n\t\tcase \"Compare\":\n\t\t\treturn `C${ast.op}:${JSON.stringify(ast.field)}:${operandText(ast.value)}`\n\t\tcase \"In\":\n\t\t\treturn `I${JSON.stringify(ast.field)}:${Arr.map(ast.values, operandText).join(\",\")}`\n\t\tcase \"Exists\":\n\t\t\treturn `E${JSON.stringify(ast.field)}`\n\t\tcase \"Under\":\n\t\t\treturn `U${Arr.map(ast.prefix, operandText).join(\",\")}`\n\t\tcase \"And\":\n\t\tcase \"Or\":\n\t\t\treturn `${ast._tag}:${Arr.map(ast.conditions, id).join(\",\")}`\n\t\tcase \"Not\":\n\t\t\treturn `N${String(id(ast.condition))}`\n\t\tcase \"Predicate\":\n\t\t\t// A predicate is equal only to itself.\n\t\t\treturn undefined\n\t}\n}\n\n/**\n * Gives the number of the structure of a node. Two nodes with the same\n * structure get the same number, so a set of numbers finds an equal node at\n * once. The hash of Effect data would walk a shared child again for each path\n * to it. A new number is the count of the numbered nodes, so it is new.\n */\nconst structureId = (ast: Ast, memo: Memo): number =>\n\tremember(memo.ids, ast, () => {\n\t\tconst text = structureText(ast, memo)\n\t\tconst fresh = memo.ids.size\n\t\tif (text === undefined) {\n\t\t\treturn fresh\n\t\t}\n\t\treturn Option.getOrElse(MutableHashMap.get(memo.structures, text), () => {\n\t\t\tMutableHashMap.set(memo.structures, text, fresh)\n\t\t\treturn fresh\n\t\t})\n\t})\n\nconst dedupe = (\n\tconditions: ReadonlyArray<Ast>,\n\tmemo: Memo,\n): ReadonlyArray<Ast> => {\n\tconst ids = Arr.map(conditions, (condition) => structureId(condition, memo))\n\t// The first place of each number. The entries go in from the end, so the\n\t// first place is the one that stays.\n\tconst first = HashMap.fromIterable(\n\t\tArr.reverse(Arr.map(ids, (id, index) => [id, index] as const)),\n\t)\n\treturn Arr.filter(conditions, (_, index) =>\n\t\tOption.contains(HashMap.get(first, ids[index]!), index),\n\t)\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`. The\n * children are already without copies.\n */\nconst absorb = (\n\tinner: \"And\" | \"Or\",\n\tconditions: ReadonlyArray<Ast>,\n\tmemo: Memo,\n): ReadonlyArray<Ast> => {\n\tconst all = HashSet.fromIterable(\n\t\tArr.map(conditions, (condition) => structureId(condition, memo)),\n\t)\n\treturn Arr.filter(\n\t\tconditions,\n\t\t(condition) =>\n\t\t\tcondition._tag !== inner ||\n\t\t\t!Arr.some(condition.conditions, (part) =>\n\t\t\t\tHashSet.has(all, structureId(part, memo)),\n\t\t\t),\n\t)\n}\n\n/**\n * Removes children that do not change the result. A predicate may fail, and it\n * may give another answer when it runs again. So when a child has a predicate,\n * every child stays, and each one runs in its place.\n */\nconst reduce = (\n\tinner: \"And\" | \"Or\",\n\tconditions: ReadonlyArray<Ast>,\n\tmemo: Memo,\n): ReadonlyArray<Ast> =>\n\tArr.some(conditions, (condition) =>\n\t\thasPredicateIn(condition, memo.predicates),\n\t)\n\t\t? conditions\n\t\t: absorb(inner, dedupe(conditions, memo), memo)\n\n/**\n * Puts the children of a child of the same kind into the node. A child with a\n * predicate stays one child: its children all stay anyway, and one shared\n * child would come again for each path to it, so the node could grow without\n * end.\n */\nconst flatten = (\n\ttag: \"And\" | \"Or\",\n\tconditions: ReadonlyArray<Ast>,\n\tmemo: Memo,\n): ReadonlyArray<Ast> =>\n\tArr.flatMap(conditions, (child) => {\n\t\tconst simple = simplifyIn(child, memo)\n\t\treturn simple._tag === tag && !hasPredicateIn(simple, memo.predicates)\n\t\t\t? simple.conditions\n\t\t\t: [simple]\n\t})\n\n/**\n * Gives the result of an `And` with a `False` child, or of an `Or` with a\n * `True` child. The children are tested in order, so a predicate before the\n * constant still runs, and it may fail. When there is such a predicate, the\n * children before the constant stay, so the failure is not lost. The other\n * children stay too, because they decide if the predicate runs.\n */\nconst shortCircuit = (\n\ttag: \"And\" | \"Or\",\n\tchildren: ReadonlyArray<Ast>,\n\tindex: number,\n\tmemo: Memo,\n): Ast => {\n\tconst constant = tag === \"And\" ? never : always\n\tconst neutral = tag === \"And\" ? \"True\" : \"False\"\n\tconst before = Arr.filter(\n\t\tArr.take(children, index),\n\t\t(child) => child._tag !== neutral,\n\t)\n\tif (!Arr.some(before, (child) => hasPredicateIn(child, memo.predicates))) {\n\t\treturn constant\n\t}\n\treturn tag === \"And\"\n\t\t? andOf([...before, constant])\n\t\t: orOf([...before, constant])\n}\n\nconst simplifyIn = (ast: Ast, memo: Memo): Ast =>\n\tremember(memo.simple, ast, () => {\n\t\tconst result = simplifyNode(ast, memo)\n\t\t// The simple form of a simple node is the node itself.\n\t\tmemo.simple.set(result, result)\n\t\treturn result\n\t})\n\nconst simplifyJunction = (\n\ttag: \"And\" | \"Or\",\n\tconditions: ReadonlyArray<Ast>,\n\tmemo: Memo,\n): Ast => {\n\tconst constant = tag === \"And\" ? \"False\" : \"True\"\n\tconst neutral = tag === \"And\" ? \"True\" : \"False\"\n\tconst flat = flatten(tag, conditions, memo)\n\treturn Option.match(\n\t\tArr.findFirstIndex(flat, (child) => child._tag === constant),\n\t\t{\n\t\t\tonSome: (stop) => shortCircuit(tag, flat, stop, memo),\n\t\t\tonNone: () => {\n\t\t\t\tconst unique = reduce(\n\t\t\t\t\ttag === \"And\" ? \"Or\" : \"And\",\n\t\t\t\t\tArr.filter(flat, (child) => child._tag !== neutral),\n\t\t\t\t\tmemo,\n\t\t\t\t)\n\t\t\t\treturn unique.length === 0\n\t\t\t\t\t? tag === \"And\"\n\t\t\t\t\t\t? always\n\t\t\t\t\t\t: never\n\t\t\t\t\t: unique.length === 1\n\t\t\t\t\t\t? unique[0]!\n\t\t\t\t\t\t: tag === \"And\"\n\t\t\t\t\t\t\t? andOf(unique)\n\t\t\t\t\t\t\t: orOf(unique)\n\t\t\t},\n\t\t},\n\t)\n}\n\nconst simplifyNode = (ast: Ast, memo: Memo): Ast => {\n\tswitch (ast._tag) {\n\t\tcase \"And\":\n\t\tcase \"Or\":\n\t\t\treturn simplifyJunction(ast._tag, ast.conditions, memo)\n\t\tcase \"Not\": {\n\t\t\tconst child = simplifyIn(ast.condition, memo)\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 nodes.Compare({\n\t\t\t\t\t\t\top: child.op === \"eq\" ? \"ne\" : \"eq\",\n\t\t\t\t\t\t\tfield: child.field,\n\t\t\t\t\t\t\tvalue: child.value,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\treturn makeNot(child)\n\t\t\t\tdefault:\n\t\t\t\t\treturn makeNot(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\nconst simplifyAst = (ast: Ast): Ast => simplifyIn(ast, makeMemo())\n\n/**\n * Makes a condition smaller without a change to its meaning. It removes `True`\n * and `False` from `And` and `Or`, joins nested `And` and `Or` nodes, and\n * removes double `Not` nodes.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const simplify: <E, R, O, I>(\n\tcondition: Condition<E, R, O, I>,\n) => Condition<E, R, O, I> = simplifyAst as never\n\n/**\n * Makes a {@link simplify} function that keeps its work for the parts it has\n * seen. Use one for many calls on conditions that share parts, such as the\n * steps of one residual condition. Do not keep it for long: it keeps every\n * part that it has seen.\n *\n * @stability stable\n * @category evaluation\n * @since 1.0.0\n */\nexport const simplifier = (): (<E, R, O, I>(\n\tcondition: Condition<E, R, O, I>,\n) => Condition<E, R, O, I>) => {\n\tconst memo = makeMemo()\n\treturn ((ast: Ast) => simplifyIn(ast, memo)) as never\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: Operand,\n\tprincipal: unknown,\n): 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<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 = Arr.map(prefix, (operand, index): Ast => {\n\t\tconst value = resolve(operand, principal)\n\t\tconst segment = path[index]!\n\t\treturn value === undefined\n\t\t\t? never\n\t\t\t: typeof segment === \"string\"\n\t\t\t\t? segment === value\n\t\t\t\t\t? always\n\t\t\t\t\t: never\n\t\t\t\t: nodes.Compare({\n\t\t\t\t\t\top: \"eq\",\n\t\t\t\t\t\tfield: segment.field,\n\t\t\t\t\t\tvalue: literal(value as Scalar),\n\t\t\t\t\t})\n\t})\n\treturn andOf(parts)\n}\n\nconst bind = (\n\tast: Ast,\n\tprincipal: unknown,\n\tpath: ReadonlyArray<Resource.PathSegment> | undefined,\n\tdone: Map<Ast, Ast> = new Map(),\n): Ast => remember(done, ast, () => bindOnce(ast, principal, path, done))\n\nconst bindOnce = (\n\tast: Ast,\n\tprincipal: unknown,\n\tpath: ReadonlyArray<Resource.PathSegment> | undefined,\n\tdone: Map<Ast, Ast>,\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\n\t\t\t\t? never\n\t\t\t\t: nodes.Compare({ op: ast.op, field: ast.field, value })\n\t\t}\n\t\tcase \"In\":\n\t\t\treturn nodes.In({\n\t\t\t\tfield: ast.field,\n\t\t\t\tvalues: ast.values.flatMap((operand) => {\n\t\t\t\t\tconst value = bindOperand(operand, principal)\n\t\t\t\t\treturn value === undefined ? [] : [value]\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 andOf(\n\t\t\t\tast.conditions.map((child) => bind(child, principal, path, done)),\n\t\t\t)\n\t\tcase \"Or\":\n\t\t\treturn orOf(\n\t\t\t\tast.conditions.map((child) => bind(child, principal, path, done)),\n\t\t\t)\n\t\tcase \"Not\":\n\t\t\treturn makeNot(bind(ast.condition, principal, path, done))\n\t\tcase \"Predicate\":\n\t\t\treturn makePredicate(ast.name, (value) => ast.run(value, principal))\n\t\tdefault:\n\t\t\treturn ast\n\t}\n}\n\ninterface PartialInput {\n\treadonly principal?: object | undefined\n\treadonly path?: ReadonlyArray<Resource.PathSegment> | undefined\n}\n\n/**\n * The principal that {@link partial} must get for the predicates of a\n * condition. A predicate keeps the principal that it gets, so the principal\n * must have the type that the predicate reads.\n */\ntype PrincipalInput<I> =\n\tI extends Reads<infer _V, infer P>\n\t\t? unknown extends P\n\t\t\t? unknown\n\t\t\t: { readonly principal: P }\n\t\t: unknown\n\n/** `unknown` when `In` gives what `I` reads, and `never` when it does not. */\ntype PrincipalFrom<I, In> = [In] extends [PrincipalInput<I>] ? unknown : never\n\n/** What a condition reads after {@link partial}: the value, and no principal. */\ntype Bound<I> = I extends Reads<infer V, infer _P> ? Reads<V, unknown> : I\n\n/**\n * Puts the principal into a condition and expands `Under` with the path of the\n * resource. The result is simplified. It has no principal fields and no\n * `Under` nodes. It is `True` or `False` when the answer does not depend on the\n * resource value.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const partial: {\n\t<In extends PartialInput>(\n\t\tinput: In,\n\t): <E, R, O, I>(\n\t\tcondition: Condition<E, R, O, I> & PrincipalFrom<I, In>,\n\t) => Condition<E, R, O, Bound<I>>\n\t<E, R, O, I>(\n\t\tcondition: Condition<E, R, O, I>,\n\t\tinput: PartialInput & PrincipalInput<I>,\n\t): Condition<E, R, O, Bound<I>>\n} = dual(\n\t2,\n\t(\n\t\tast: Ast,\n\t\tinput: {\n\t\t\treadonly principal?: object | undefined\n\t\t\treadonly path?: ReadonlyArray<Resource.PathSegment> | undefined\n\t\t},\n\t): Ast => simplifyAst(bind(ast, input.principal, input.path)),\n)\n\n/**\n * The functions that change each node of a condition into another form, such\n * as a database query.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Interpreter<A> {\n\treadonly true: () => A\n\treadonly false: () => A\n\treadonly compare: (op: CompareOperator, field: string, value: Scalar) => A\n\treadonly in: (field: string, values: ReadonlyArray<Scalar>) => A\n\treadonly exists: (field: string) => A\n\treadonly and: (conditions: ReadonlyArray<A>) => A\n\treadonly or: (conditions: ReadonlyArray<A>) => A\n\treadonly not: (condition: A) => A\n\t/** Optional. Without it, a predicate makes `fold` fail. */\n\treadonly predicate?: (name: string) => A\n}\n\n/**\n * The error when `fold` can not change a node.\n *\n * @stability stable\n * @category errors\n * @since 0.3.0\n */\nexport class Untranslatable extends Schema.TaggedError<Untranslatable>(\n\t\"@nmnmcc/ability/Condition/Untranslatable\",\n)(\"Untranslatable\", { reason: Schema.String }) {}\n\nconst literalValue = (operand: Operand, field: string): Scalar => {\n\tif (operand._tag !== \"Literal\") {\n\t\tthrow Untranslatable.make({\n\t\t\treason: `The field \"${field}\" uses a principal field. Call Condition.partial first.`,\n\t\t})\n\t}\n\treturn operand.value\n}\n\n/**\n * Folds one node. The memo keeps the result of each node, so a node that is a\n * child of many nodes is folded one time.\n */\nconst foldAst = <A>(\n\tast: Ast,\n\tinterpreter: Interpreter<A>,\n\tdone: Map<Ast, A> = new Map(),\n): A => remember(done, ast, () => foldOnce(ast, interpreter, done))\n\nconst foldOnce = <A>(\n\tast: Ast,\n\tinterpreter: Interpreter<A>,\n\tdone: Map<Ast, A>,\n): 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\treturn interpreter.compare(\n\t\t\t\tast.op,\n\t\t\t\tast.field,\n\t\t\t\tliteralValue(ast.value, ast.field),\n\t\t\t)\n\t\tcase \"In\":\n\t\t\treturn interpreter.in(\n\t\t\t\tast.field,\n\t\t\t\tast.values.map((operand) => literalValue(operand, ast.field)),\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\tArr.map(ast.conditions, (child) => foldAst(child, interpreter, done)),\n\t\t\t)\n\t\tcase \"Or\":\n\t\t\treturn interpreter.or(\n\t\t\t\tArr.map(ast.conditions, (child) => foldAst(child, interpreter, done)),\n\t\t\t)\n\t\tcase \"Not\":\n\t\t\treturn interpreter.not(foldAst(ast.condition, interpreter, done))\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/**\n * Changes a condition into another form with an interpreter. Call\n * {@link partial} first: `fold` fails on principal fields and on `Under`\n * nodes, and on predicates when the interpreter has no `predicate` function.\n *\n * @stability stable\n * @category converting\n * @since 0.3.0\n */\nexport const fold: {\n\t<A>(\n\t\tinterpreter: Interpreter<A>,\n\t): (condition: Any) => Effect.Effect<A, Untranslatable>\n\t<A>(\n\t\tcondition: Any,\n\t\tinterpreter: Interpreter<A>,\n\t): Effect.Effect<A, Untranslatable>\n} = dual(\n\t2,\n\t<A>(\n\t\tast: Ast,\n\t\tinterpreter: Interpreter<A>,\n\t): Effect.Effect<A, Untranslatable> =>\n\t\tEffect.try({\n\t\t\ttry: () => foldAst(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/**\n * The fields that a condition uses.\n *\n * @stability stable\n * @category getters\n * @since 0.3.0\n */\nexport const fields = (condition: Ast): ReadonlyArray<string> =>\n\tfieldsIn(condition, new Map())\n\n/**\n * The fields of a node, in the order that they first come. A `HashSet` would\n * not keep that order, so it only says which fields came before.\n */\n/** Leaves out each string that came before, in linear time. */\nconst dedupeStrings = (values: ReadonlyArray<string>): ReadonlyArray<string> =>\n\tArr.flatten(\n\t\tArr.mapAccum(values, HashSet.empty<string>(), (seen, value) => [\n\t\t\tHashSet.add(seen, value),\n\t\t\tHashSet.has(seen, value) ? [] : [value],\n\t\t])[1],\n\t)\n\nconst fieldsIn = (\n\tast: Ast,\n\tmemo: Map<Ast, ReadonlyArray<string>>,\n): ReadonlyArray<string> =>\n\tremember(memo, ast, () => {\n\t\tswitch (ast._tag) {\n\t\t\tcase \"Compare\":\n\t\t\tcase \"In\":\n\t\t\tcase \"Exists\":\n\t\t\t\treturn [ast.field]\n\t\t\tcase \"And\":\n\t\t\tcase \"Or\":\n\t\t\t\treturn dedupeStrings(\n\t\t\t\t\tArr.flatMap(ast.conditions, (child) => fieldsIn(child, memo)),\n\t\t\t\t)\n\t\t\tcase \"Not\":\n\t\t\t\treturn fieldsIn(ast.condition, memo)\n\t\t\tdefault:\n\t\t\t\treturn []\n\t\t}\n\t})\n\n// Satisfiability\n\n/**\n * Values of fields, as a nested object. A field that is not in it may have any\n * value. A value with parts that the search does not look into, such as a\n * date, is an empty object.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport interface Example {\n\treadonly [field: string]: unknown\n}\n\n/**\n * The answer of {@link satisfiable}:\n * - `Satisfiable`: some value makes the condition true. `example` is one.\n * - `Unsatisfiable`: no value makes the condition true.\n * - `Unknown`: the search can not say. The condition has a predicate, the\n * search went past its budget, or it set two fields that the Schema ties\n * together, as below a union or a field that may be missing.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport type Satisfiability = Data.TaggedEnum<{\n\tSatisfiable: { readonly example: Example }\n\tUnsatisfiable: {}\n\tUnknown: { readonly reason: \"predicate\" | \"budget\" | \"schema\" }\n}>\n\nconst satisfiability = Data.taggedEnum<Satisfiability>()\n\n/**\n * The options of {@link satisfiable}.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport interface SatisfiableOptions {\n\t/**\n\t * The Schema of the values. It gives the domain of each field. Without\n\t * it, a field may have any value.\n\t */\n\treadonly schema?: Schema.Top | undefined\n\t/** The most nodes that the search may visit. The default is 1000000. */\n\treadonly budget?: number | undefined\n}\n\n/** Stands for a value with parts, such as a struct or a date. */\nconst opaque: object = Object.freeze({})\n\n/** Marks a field that a step of the search did not fix. */\nconst free: unique symbol = Symbol(\"free\")\n\n/** The least number that is greater than `value`. */\nconst nextUp = (value: number): number => {\n\tif (Number.isNaN(value) || value === Infinity) {\n\t\treturn value\n\t}\n\tif (value === 0) {\n\t\treturn Number.MIN_VALUE\n\t}\n\tconst view = new DataView(new ArrayBuffer(8))\n\tview.setFloat64(0, value)\n\tconst bits = view.getBigUint64(0)\n\tview.setBigUint64(0, value > 0 ? bits + 1n : bits - 1n)\n\treturn view.getFloat64(0)\n}\n\n/**\n * Gives one number from each part of the number line that the constants\n * make: each constant, and one number between each two neighbours when there\n * is one. The ends of the domain are in the list too.\n */\nconst numberCells = (\n\tkind: \"integer\" | \"finite\" | \"any\",\n\tconstants: ReadonlyArray<number>,\n): ReadonlyArray<number> => {\n\tconst integer = kind === \"integer\"\n\tconst low = integer\n\t\t? Number.MIN_SAFE_INTEGER\n\t\t: kind === \"finite\"\n\t\t\t? -Number.MAX_VALUE\n\t\t\t: -Infinity\n\tconst high = integer\n\t\t? Number.MAX_SAFE_INTEGER\n\t\t: kind === \"finite\"\n\t\t\t? Number.MAX_VALUE\n\t\t\t: Infinity\n\tconst known: ReadonlyArray<number> = Arr.filter(\n\t\tconstants,\n\t\t(value: number) => !Number.isNaN(value),\n\t)\n\tconst points = Arr.filter(\n\t\tArr.flatMap(known, (value: number) =>\n\t\t\tinteger && Number.isFinite(value)\n\t\t\t\t? [Math.floor(value), Math.ceil(value)]\n\t\t\t\t: [value],\n\t\t),\n\t\t(value: number) => value >= low && value <= high,\n\t)\n\t// `0` and `-0` are one point: every test gives the same answer for both,\n\t// and `===` calls them equal.\n\tconst ordered: Array<number> = [low, high, ...points].sort((a, b) => a - b)\n\tconst sorted = Arr.dedupeAdjacentWith(\n\t\tordered,\n\t\t(a: number, b: number) => a === b,\n\t)\n\tconst cells = Arr.flatMap(sorted, (value, index) => {\n\t\tconst after = sorted[index + 1]\n\t\tconst between = integer ? value + 1 : nextUp(value)\n\t\treturn after !== undefined && between < after ? [value, between] : [value]\n\t})\n\treturn kind === \"any\" ? Arr.append(cells, Number.NaN) : cells\n}\n\n/**\n * Gives one string from each part that the constants make. Strings are in the\n * order of their UTF-16 code units, as `<` sees them. The least string after\n * `a` is `a + \"\\0\"`, so there is a string between `a` and `b` exactly when\n * `b` is not `a + \"\\0\"`.\n */\nconst stringCells = (\n\tconstants: ReadonlyArray<string>,\n): ReadonlyArray<string> => {\n\tconst ordered: Array<string> = [...constants].sort()\n\tconst sorted = Arr.dedupeAdjacentWith(\n\t\tordered,\n\t\t(a: string, b: string) => a === b,\n\t)\n\tif (sorted.length === 0) {\n\t\treturn [\"\"]\n\t}\n\treturn [\n\t\t...(sorted[0] === \"\" ? [] : [\"\"]),\n\t\t...Arr.flatMap(sorted, (value, index) => {\n\t\t\tconst next = `${value}\\0`\n\t\t\treturn next === sorted[index + 1] ? [value] : [value, next]\n\t\t}),\n\t]\n}\n\n/**\n * Gives one value from each cell of a field. Each test of a field compares it\n * with constants, so the constants cut the domain into a few cells, and every\n * test gives the same answer for all the values of one cell.\n */\nconst cellsOf = (\n\tdomain: Resource.FieldDomain,\n\tconstants: ReadonlyArray<Scalar>,\n): ReadonlyArray<unknown> =>\n\tdedupeCells([\n\t\t...(domain.null ? [null] : []),\n\t\t...(domain.object ? [opaque] : []),\n\t\t...(domain.boolean ? [true, false] : []),\n\t\t...(domain.string\n\t\t\t? stringCells(Arr.filter(constants, (value) => typeof value === \"string\"))\n\t\t\t: []),\n\t\t...(domain.number === \"none\"\n\t\t\t? []\n\t\t\t: numberCells(\n\t\t\t\t\tdomain.number,\n\t\t\t\t\tArr.filter(constants, (value) => typeof value === \"number\"),\n\t\t\t\t)),\n\t\t...domain.literals,\n\t])\n\n/**\n * A text for a cell. Two cells get one text when every test gives the same\n * answer for them: `0` and `-0` are one, and `NaN` is one.\n */\nconst cellText = (cell: unknown): string =>\n\tcell === opaque\n\t\t? \"opaque\"\n\t\t: typeof cell === \"number\"\n\t\t\t? `number:${Object.is(cell, -0) ? \"0\" : String(cell)}`\n\t\t\t: `${typeof cell}:${String(cell)}`\n\n/**\n * Keeps the first cell of each text, in order. A map from each text to its\n * first place does it in one pass. A test of each pair would take a very long\n * time for many constants.\n */\nconst dedupeCells = (cells: ReadonlyArray<unknown>): ReadonlyArray<unknown> => {\n\tconst texts = Arr.map(cells, cellText)\n\tconst first = HashMap.fromIterable(\n\t\tArr.reverse(Arr.map(texts, (text, index) => [text, index] as const)),\n\t)\n\treturn Arr.filter(cells, (_, index) =>\n\t\tOption.contains(HashMap.get(first, texts[index]!), index),\n\t)\n}\n\nclass OutOfBudget {}\n\n/** What one search keeps for all its steps. It lives only as long as the search. */\ninterface Search {\n\t/** The memo of the simplification and of the numbers of structures. */\n\treadonly memo: Memo\n\treadonly cells: (field: string) => ReadonlyArray<unknown>\n\t/**\n\t * The texts of the values of each `In` test, so one test of a value does\n\t * not read every value of the test. See `cellText`.\n\t */\n\treadonly members: Map<Ast, HashSet.HashSet<string>>\n\treadonly budget: number\n}\n\n/** What a search has done up to now. Each step gives a new one. */\ninterface SearchState {\n\treadonly steps: number\n\t/** The numbers of the conditions that the search found to be unsatisfiable. */\n\treadonly failed: HashSet.HashSet<number>\n}\n\ninterface Found {\n\treadonly assignment: Option.Option<ReadonlyArray<readonly [string, unknown]>>\n\treadonly state: SearchState\n}\n\nconst literalOf = (operand: Operand): Scalar => {\n\tif (operand._tag !== \"Literal\") {\n\t\tthrow new Error(\n\t\t\t\"Condition.satisfiable needs a condition with no principal fields. Call Condition.partial first.\",\n\t\t)\n\t}\n\treturn operand.value\n}\n\n/**\n * The value of the field `name` after `field` gets `value`. A field below\n * `field` is `null` when `value` is not a value with parts.\n */\nconst fixedValue = (\n\tname: string,\n\tfield: string,\n\tvalue: unknown,\n): unknown | typeof free =>\n\tname === field\n\t\t? value\n\t\t: name.startsWith(`${field}.`)\n\t\t\t? value === opaque\n\t\t\t\t? free\n\t\t\t\t: null\n\t\t\t: free\n\nconst testFixed = (\n\tast: Compare | In | Exists,\n\tvalue: unknown,\n\tsearch: Search,\n): boolean => {\n\tswitch (ast._tag) {\n\t\tcase \"Compare\":\n\t\t\treturn testCompare(ast.op, value, literalOf(ast.value))\n\t\tcase \"In\":\n\t\t\t// `===` finds no `NaN`, so the set has none, and `NaN` is in no test.\n\t\t\treturn (\n\t\t\t\t!Number.isNaN(value) &&\n\t\t\t\tHashSet.has(\n\t\t\t\t\tremember(search.members, ast, () =>\n\t\t\t\t\t\tHashSet.fromIterable(\n\t\t\t\t\t\t\tArr.map(\n\t\t\t\t\t\t\t\tArr.filter(\n\t\t\t\t\t\t\t\t\tArr.map(ast.values, literalOf),\n\t\t\t\t\t\t\t\t\t(literal) => !Number.isNaN(literal),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tcellText,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\tcellText(value),\n\t\t\t\t)\n\t\t\t)\n\t\tcase \"Exists\":\n\t\t\treturn value !== null\n\t}\n}\n\n/**\n * Puts one value into a field, and into the fields below it. The memo has a\n * node for each node that the step visits, so its size is the work of the\n * step.\n */\nconst fix = (\n\tast: Ast,\n\tfield: string,\n\tvalue: unknown,\n\tsearch: Search,\n\tdone: Map<Ast, Ast>,\n): Ast =>\n\tremember(done, ast, () => {\n\t\tconst fixChild = (child: Ast) => fix(child, field, value, search, done)\n\t\tswitch (ast._tag) {\n\t\t\tcase \"Compare\":\n\t\t\tcase \"In\":\n\t\t\tcase \"Exists\": {\n\t\t\t\tconst known = fixedValue(ast.field, field, value)\n\t\t\t\treturn known === free\n\t\t\t\t\t? ast\n\t\t\t\t\t: testFixed(ast, known, search)\n\t\t\t\t\t\t? always\n\t\t\t\t\t\t: never\n\t\t\t}\n\t\t\tcase \"And\":\n\t\t\t\treturn andOf(Arr.map(ast.conditions, fixChild))\n\t\t\tcase \"Or\":\n\t\t\t\treturn orOf(Arr.map(ast.conditions, fixChild))\n\t\t\tcase \"Not\":\n\t\t\t\treturn makeNot(fixChild(ast.condition))\n\t\t\tdefault:\n\t\t\t\treturn ast\n\t\t}\n\t})\n\n/**\n * Counts the tests of each field. Each node is visited one time, so the work\n * is the number of nodes, and the walk gives that work back for the budget.\n * The counts and the seen nodes are a memo of this walk only.\n */\nconst countFields = (\n\tast: Ast,\n): {\n\treadonly counts: MutableHashMap.MutableHashMap<string, number>\n\treadonly work: number\n} => {\n\tconst counts = MutableHashMap.empty<string, number>()\n\t// A native set: it must find a node by the node itself. See `remember`.\n\tconst seen = new Set<Ast>()\n\tconst visit = (node: Ast): void => {\n\t\tif (seen.has(node)) {\n\t\t\treturn\n\t\t}\n\t\tseen.add(node)\n\t\tswitch (node._tag) {\n\t\t\tcase \"Compare\":\n\t\t\tcase \"In\":\n\t\t\tcase \"Exists\":\n\t\t\t\tMutableHashMap.set(\n\t\t\t\t\tcounts,\n\t\t\t\t\tnode.field,\n\t\t\t\t\tOption.getOrElse(MutableHashMap.get(counts, node.field), () => 0) + 1,\n\t\t\t\t)\n\t\t\t\treturn\n\t\t\tcase \"And\":\n\t\t\tcase \"Or\":\n\t\t\t\treturn Arr.forEach(node.conditions, visit)\n\t\t\tcase \"Not\":\n\t\t\t\treturn visit(node.condition)\n\t\t\tdefault:\n\t\t\t\treturn\n\t\t}\n\t}\n\tvisit(ast)\n\treturn { counts, work: seen.size }\n}\n\n/**\n * Picks the next field to split on. A field comes before the fields below it,\n * so a value of a field can fix them. Then a field in more tests comes first,\n * and then the first name in order, so the choice is the same each time.\n */\nconst nextField = (\n\tcounts: MutableHashMap.MutableHashMap<string, number>,\n): string => {\n\tconst depth = (field: string) => field.split(\".\").length\n\tconst [first, ...rest] = Array.from(counts)\n\treturn Arr.reduce(rest, first!, (best, next) =>\n\t\tdepth(next[0]) < depth(best[0]) ||\n\t\t(depth(next[0]) === depth(best[0]) &&\n\t\t\t(next[1] > best[1] || (next[1] === best[1] && next[0] < best[0])))\n\t\t\t? next\n\t\t\t: best,\n\t)[0]\n}\n\n/**\n * Finds values of the fields that make the condition true. It splits on one\n * field at a time, and tries one value from each cell of the field.\n */\nconst searchAst = (\n\tast: Ast,\n\tsearch: Search,\n\tstate: SearchState,\n\tassignment: ReadonlyArray<readonly [string, unknown]>,\n): Found => {\n\tconst current = simplifyIn(ast, search.memo)\n\tif (current._tag === \"True\") {\n\t\treturn { assignment: Option.some(assignment), state }\n\t}\n\tif (current._tag === \"False\") {\n\t\treturn { assignment: Option.none(), state }\n\t}\n\t// A condition with the same structure has the same free fields, so its\n\t// answer is the same.\n\tconst id = structureId(current, search.memo)\n\tif (HashSet.has(state.failed, id)) {\n\t\treturn { assignment: Option.none(), state }\n\t}\n\t// Counting the fields reads the whole condition, so the budget counts it.\n\tconst counted = countFields(current)\n\tif (state.steps + counted.work > search.budget) {\n\t\tthrow new OutOfBudget()\n\t}\n\tconst field = nextField(counted.counts)\n\tconst cells = search.cells(field)\n\t// The cells are tried in order, until one gives values. A fold over the\n\t// cells does no work after a found answer, and it does not grow the stack\n\t// with the number of cells.\n\tconst result = Arr.reduce(\n\t\tcells,\n\t\t{ assignment: Option.none(), state } as Found,\n\t\t(before, cell): Found => {\n\t\t\tif (Option.isSome(before.assignment)) {\n\t\t\t\treturn before\n\t\t\t}\n\t\t\tconst done = new Map<Ast, Ast>()\n\t\t\tconst fixed = fix(current, field, cell, search, done)\n\t\t\tconst steps = before.state.steps + done.size\n\t\t\tif (steps > search.budget) {\n\t\t\t\tthrow new OutOfBudget()\n\t\t\t}\n\t\t\treturn searchAst(fixed, search, { ...before.state, steps }, [\n\t\t\t\t...assignment,\n\t\t\t\t[field, cell],\n\t\t\t])\n\t\t},\n\t)\n\treturn Option.isSome(result.assignment)\n\t\t? result\n\t\t: {\n\t\t\t\tassignment: Option.none(),\n\t\t\t\tstate: {\n\t\t\t\t\t...result.state,\n\t\t\t\t\tfailed: HashSet.add(result.state.failed, id),\n\t\t\t\t},\n\t\t\t}\n}\n\n/**\n * Puts a value at a path in an object, and gives a new object. A value with\n * parts (`opaque`) becomes an empty object, and it keeps an object that is\n * there.\n */\nconst setPath = (\n\troot: Readonly<Record<string, unknown>>,\n\tnames: ReadonlyArray<string>,\n\tvalue: unknown,\n): Readonly<Record<string, unknown>> => {\n\tconst [name, ...rest] = names\n\tif (name === undefined) {\n\t\treturn root\n\t}\n\t// Only an own field counts, as a condition reads it. An inherited one,\n\t// such as `__proto__`, is not a field of the example.\n\tconst inner = Object.hasOwn(root, name) ? root[name] : undefined\n\tif (rest.length === 0) {\n\t\treturn value === opaque && isObject(inner)\n\t\t\t? root\n\t\t\t: { ...root, [name]: value === opaque ? {} : value }\n\t}\n\tconst base =\n\t\tisObject(inner) && inner !== opaque\n\t\t\t? (inner as Readonly<Record<string, unknown>>)\n\t\t\t: {}\n\treturn { ...root, [name]: setPath(base, rest, value) }\n}\n\nconst exampleOf = (\n\tassignment: ReadonlyArray<readonly [string, unknown]>,\n): Example =>\n\tArr.reduce(\n\t\tassignment,\n\t\t{} as Readonly<Record<string, unknown>>,\n\t\t(root, [field, value]) => setPath(root, field.split(\".\"), value),\n\t)\n\n/**\n * The constants that the tests of each field use. A set keeps each constant\n * one time, so a shared node does not make the list grow for each path to it.\n */\ntype FieldConstants = HashMap.HashMap<string, HashSet.HashSet<Scalar>>\n\nconst addConstants = (\n\tleft: FieldConstants,\n\tright: FieldConstants,\n): FieldConstants =>\n\tHashMap.reduce(right, left, (all, values, field) =>\n\t\tHashMap.set(\n\t\t\tall,\n\t\t\tfield,\n\t\t\tHashSet.union(\n\t\t\t\tOption.getOrElse(HashMap.get(all, field), HashSet.empty),\n\t\t\t\tvalues,\n\t\t\t),\n\t\t),\n\t)\n\nconst constantsOf = (\n\tast: Ast,\n\tmemo: Map<Ast, FieldConstants> = new Map(),\n): FieldConstants =>\n\tremember(memo, ast, (): FieldConstants => {\n\t\tswitch (ast._tag) {\n\t\t\tcase \"Compare\":\n\t\t\t\treturn HashMap.make([ast.field, HashSet.make(literalOf(ast.value))])\n\t\t\tcase \"In\":\n\t\t\t\treturn HashMap.make([\n\t\t\t\t\tast.field,\n\t\t\t\t\tHashSet.fromIterable(Arr.map(ast.values, literalOf)),\n\t\t\t\t])\n\t\t\tcase \"Exists\":\n\t\t\t\treturn HashMap.make([ast.field, HashSet.empty<Scalar>()])\n\t\t\tcase \"Under\":\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Condition.satisfiable needs a condition with no Under nodes. Call Condition.partial first.\",\n\t\t\t\t)\n\t\t\tcase \"And\":\n\t\t\tcase \"Or\":\n\t\t\t\treturn Arr.reduce(ast.conditions, HashMap.empty(), (all, child) =>\n\t\t\t\t\taddConstants(all, constantsOf(child, memo)),\n\t\t\t\t)\n\t\t\tcase \"Not\":\n\t\t\t\treturn constantsOf(ast.condition, memo)\n\t\t\tdefault:\n\t\t\t\treturn HashMap.empty()\n\t\t}\n\t})\n\n/**\n * The most fields that the search of {@link satisfiable} takes. Past it, the\n * answer is `Unknown` with the reason `\"budget\"`.\n */\nconst maxSearchFields = 256\n\n/**\n * The most parts of a field path that the search of {@link satisfiable}\n * takes. Past it, the answer is `Unknown` with the reason `\"budget\"`.\n */\nconst maxSearchParts = 256\n\nconst satisfiableAst = (\n\tast: Ast,\n\toptions: SatisfiableOptions = {},\n): Satisfiability => {\n\tif (hasPredicate(ast)) {\n\t\treturn satisfiability.Unknown({ reason: \"predicate\" })\n\t}\n\tconst schema = options.schema\n\tconst tested = fields(ast)\n\t// A Schema with no value has no value that the condition is true for.\n\tif (schema !== undefined && Resource.hasNoValue(schema)) {\n\t\treturn satisfiability.Unsatisfiable()\n\t}\n\t// The search finds values for the fields that the condition tests. A value\n\t// needs the other required fields too, and a check that the search can\n\t// not see may stop every value of one of them. So a \"yes\" needs a Schema\n\t// that surely has a value.\n\tconst complete = schema === undefined || Resource.hasValue(schema)\n\t// The model of the values of a field is exact only for a plain scalar\n\t// field. For another field, a value may have data that the Schema does not\n\t// show, so the search can not say.\n\tif (\n\t\tschema !== undefined &&\n\t\t!Arr.every(tested, (field) => Resource.isPlainField(schema, field))\n\t) {\n\t\treturn satisfiability.Unknown({ reason: \"schema\" })\n\t}\n\t// The search calls itself one time for each field that it fixes, and it\n\t// makes an example with a step for each part of a path. So a condition\n\t// with very many fields, or a very long path, could fill the stack.\n\tif (\n\t\ttested.length > maxSearchFields ||\n\t\tArr.some(\n\t\t\ttested,\n\t\t\t(field) => field.split(\".\", maxSearchParts + 1).length > maxSearchParts,\n\t\t)\n\t) {\n\t\treturn satisfiability.Unknown({ reason: \"budget\" })\n\t}\n\tconst constants = constantsOf(ast)\n\t// The cells of each field. A field name is a string, so an Effect map\n\t// finds it.\n\tconst cells = MutableHashMap.empty<string, ReadonlyArray<unknown>>()\n\tconst search: Search = {\n\t\tmemo: makeMemo(),\n\t\tmembers: new Map(),\n\t\tcells: (field) =>\n\t\t\tOption.getOrElse(MutableHashMap.get(cells, field), () => {\n\t\t\t\t// The cells come from the constants, so many constants are work\n\t\t\t\t// that the budget must count before the cells are made.\n\t\t\t\tconst known = HashMap.get(constants, field)\n\t\t\t\tif (\n\t\t\t\t\tOption.isSome(known) &&\n\t\t\t\t\tHashSet.size(known.value) > (options.budget ?? 1_000_000)\n\t\t\t\t) {\n\t\t\t\t\tthrow new OutOfBudget()\n\t\t\t\t}\n\t\t\t\tconst found = cellsOf(\n\t\t\t\t\tschema === undefined\n\t\t\t\t\t\t? Resource.anyDomain\n\t\t\t\t\t\t: Resource.domainOf(schema, field),\n\t\t\t\t\tArray.from(\n\t\t\t\t\t\tOption.getOrElse(HashMap.get(constants, field), HashSet.empty),\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t\tMutableHashMap.set(cells, field, found)\n\t\t\t\treturn found\n\t\t\t}),\n\t\tbudget: options.budget ?? 1_000_000,\n\t}\n\ttry {\n\t\tconst found = searchAst(\n\t\t\tast,\n\t\t\tsearch,\n\t\t\t{ steps: 0, failed: HashSet.empty() },\n\t\t\t[],\n\t\t)\n\t\treturn Option.match(found.assignment, {\n\t\t\tonNone: () => satisfiability.Unsatisfiable(),\n\t\t\tonSome: (assignment) =>\n\t\t\t\tcomplete\n\t\t\t\t\t? satisfiability.Satisfiable({ example: exampleOf(assignment) })\n\t\t\t\t\t: satisfiability.Unknown({ reason: \"schema\" }),\n\t\t})\n\t} catch (error) {\n\t\tif (error instanceof OutOfBudget) {\n\t\t\treturn satisfiability.Unknown({ reason: \"budget\" })\n\t\t}\n\t\tthrow error\n\t}\n}\n\n/**\n * Tests if some value makes a condition true, and gives such a value.\n *\n * Call {@link partial} first: the condition must have no principal fields and\n * no `Under` nodes. A condition with a predicate gives `Unknown`.\n *\n * With `options.schema`, each field of the condition must be a plain scalar\n * field of the Schema (see `Resource.isPlainField`). Else the answer is\n * `Unknown` with the reason `\"schema\"`: for another field, a value may have\n * data that the Schema does not show, so the model of its values is not\n * exact.\n *\n * The answer is exact. Each test of a condition compares one field with\n * constants, so the constants cut the values of each field into a few cells.\n * The search tries one value from each cell, one field at a time. The values\n * of a field come from the Schema in `options.schema`: its literals, `null`\n * for a nullable or optional field, and finite or integer numbers. A field\n * with another Schema check is not a plain field, so the search never tries a\n * value that such a check stops.\n *\n * The problem is as hard as boolean satisfiability, so the search has a\n * budget. Past it, the answer is `Unknown`. A condition with more than 256\n * fields, or with a field path of more than 256 parts, gives `Unknown` too.\n *\n * @stability stable\n * @category evaluation\n * @since 1.0.0\n */\nexport const satisfiable: {\n\t(options?: SatisfiableOptions): (condition: Any) => Satisfiability\n\t(condition: Any, options?: SatisfiableOptions): Satisfiability\n} = dual(\n\t(args) => isObject(args[0]) && hasProperty(args[0], \"_tag\"),\n\tsatisfiableAst,\n) as never\n\nconst operandJson = (operand: Operand): unknown =>\n\toperand._tag === \"Literal\" &&\n\ttypeof operand.value === \"number\" &&\n\t!Number.isFinite(operand.value)\n\t\t? { ...operand, value: { nonFinite: String(operand.value) } }\n\t\t: operand\n\nconst jsonIn = (ast: Ast, done: Map<Ast, unknown>): unknown =>\n\tremember(done, ast, (): unknown => {\n\t\tswitch (ast._tag) {\n\t\t\tcase \"Compare\":\n\t\t\t\treturn { ...ast, value: operandJson(ast.value) }\n\t\t\tcase \"In\":\n\t\t\t\treturn { ...ast, values: Arr.map(ast.values, operandJson) }\n\t\t\tcase \"Under\":\n\t\t\t\treturn { ...ast, prefix: Arr.map(ast.prefix, operandJson) }\n\t\t\tcase \"And\":\n\t\t\tcase \"Or\":\n\t\t\t\treturn {\n\t\t\t\t\t...ast,\n\t\t\t\t\tconditions: Arr.map(ast.conditions, (child) => jsonIn(child, done)),\n\t\t\t\t}\n\t\t\tcase \"Not\":\n\t\t\t\treturn { ...ast, condition: jsonIn(ast.condition, done) }\n\t\t\tdefault:\n\t\t\t\treturn ast\n\t\t}\n\t})\n\n/**\n * Gives a condition as a value that `JSON.stringify` keeps with no loss. JSON\n * has no `Infinity`, `-Infinity` or `NaN`: it writes `null` in their place,\n * and a test with `null` has another meaning. Such a number becomes an object\n * that {@link schema} does not decode, so a policy with it fails to load and\n * never gives a wrong answer.\n *\n * @stability stable\n * @category conversions\n * @since 1.0.0\n */\nexport const toJsonValue = (condition: Ast): unknown =>\n\tjsonIn(condition, new Map())\n\n/**\n * The JSON form of a condition with no predicate.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Encoded =\n\tExclude<Ast, Predicate | And | Or | Not> | EncodedAnd | EncodedOr | EncodedNot\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface EncodedAnd {\n\treadonly _tag: \"And\"\n\treadonly conditions: ReadonlyArray<Encoded>\n}\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface EncodedOr {\n\treadonly _tag: \"Or\"\n\treadonly conditions: ReadonlyArray<Encoded>\n}\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface EncodedNot {\n\treadonly _tag: \"Not\"\n\treadonly condition: Encoded\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\n/**\n * A condition with no predicate, that may read any values. It is the type of\n * {@link schema}: a decoded condition reads nothing, so it fits any rule, and\n * any plain condition, such as one from a builder or a residual, may be\n * encoded.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\n// `any` for what it reads: the field is contravariant, so no other type both\n// takes every condition and fits every rule.\nexport type PlainCondition = Condition<never, never, never, any>\n\nconst Recursive = Schema.suspend(\n\t(): Schema.Codec<PlainCondition, Encoded> => shape,\n)\n\n/**\n * The most levels of objects and arrays in the JSON form of a condition. The\n * Schema of a condition calls itself for each level, so a much deeper input\n * could fill the stack before it fails.\n */\nconst maxJsonDepth = 1000\n\n/**\n * The most objects and arrays in the JSON form of an input, with a shared one\n * counted for each place. The decoder writes out a shared one each time, so\n * an input with few objects may give a very large tree.\n */\nconst maxInputNodes = 1_000_000\n\n/** The size and the height of a value, in objects and arrays. */\ninterface Measure {\n\treadonly size: number\n\treadonly height: number\n}\n\n/**\n * Measures a value, or gives `undefined` when it is higher than `levels`. A\n * shared object is measured one time. The walk stops at that height, so it\n * does not fill the stack itself. The memo is a native `Map`, because it\n * must find an object by the object itself.\n */\nconst measure = (\n\tinput: unknown,\n\tlevels: number,\n\tmemo: Map<object, Measure | { readonly failed: number }>,\n): Measure | undefined => {\n\tif (typeof input !== \"object\" || input === null) {\n\t\treturn { size: 0, height: 0 }\n\t}\n\tconst cached = memo.get(input)\n\t// A value that was too high for some levels is too high for fewer.\n\tif (\n\t\tcached !== undefined &&\n\t\t(\"failed\" in cached ? levels <= cached.failed : true)\n\t) {\n\t\treturn \"failed\" in cached || cached.height > levels ? undefined : cached\n\t}\n\t// After the first child that is too high, the fold measures no more\n\t// children. The walk has few frames for each level, so it does not fill\n\t// the stack at the most levels.\n\t// An input with a key that a loop over the keys does not see, or with a\n\t// getter, may give the decoder more than the measure sees. Such an input\n\t// is not plain data, so it fails.\n\tconst result =\n\t\tlevels === 0 || !isPlainData(input)\n\t\t\t? undefined\n\t\t\t: Arr.reduce(\n\t\t\t\t\tObject.values(input),\n\t\t\t\t\t{ size: 1, height: 1 } as Measure | undefined,\n\t\t\t\t\t(total, child) => {\n\t\t\t\t\t\tconst measured =\n\t\t\t\t\t\t\ttotal === undefined ? undefined : measure(child, levels - 1, memo)\n\t\t\t\t\t\treturn total === undefined || measured === undefined\n\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\tsize: total.size + measured.size,\n\t\t\t\t\t\t\t\t\theight: Math.max(total.height, 1 + measured.height),\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t)\n\tmemo.set(input, result ?? { failed: levels })\n\treturn result\n}\n\n/**\n * Tests if each own key of an object is a plain data key that a loop over the\n * keys sees. The `length` of an array is the one key that is not seen. The\n * decoder reads keys of the prototypes too, so a prototype other than the\n * one of a plain object or an array may have only methods, as the prototype\n * of a class has.\n */\nconst isPlainData = (input: object): boolean =>\n\tArr.every(Reflect.ownKeys(input), (key) => {\n\t\tconst property = Object.getOwnPropertyDescriptor(input, key)\n\t\treturn (\n\t\t\tproperty !== undefined &&\n\t\t\t\"value\" in property &&\n\t\t\t(property.enumerable === true ||\n\t\t\t\t(Array.isArray(input) && key === \"length\"))\n\t\t)\n\t}) && hasOnlyMethods(Object.getPrototypeOf(input))\n\n/** Tests if the prototypes from `prototype` up have only methods. */\nconst hasOnlyMethods = (prototype: unknown): boolean =>\n\tprototype === null ||\n\tprototype === Object.prototype ||\n\tprototype === Array.prototype ||\n\t(typeof prototype === \"object\" &&\n\t\tArr.every(Reflect.ownKeys(prototype), (key) => {\n\t\t\tconst property = Object.getOwnPropertyDescriptor(prototype, key)\n\t\t\treturn (\n\t\t\t\ttypeof key === \"symbol\" ||\n\t\t\t\tkey === \"constructor\" ||\n\t\t\t\t(property !== undefined &&\n\t\t\t\t\t\"value\" in property &&\n\t\t\t\t\ttypeof property.value === \"function\")\n\t\t\t)\n\t\t}) &&\n\t\thasOnlyMethods(Object.getPrototypeOf(prototype)))\n\n/** Tests if a value is low and small enough to decode. */\nconst fitsLimits = (input: unknown): string | true => {\n\tconst measured = measure(input, maxJsonDepth, new Map())\n\treturn measured === undefined\n\t\t? `A condition may have at most ${String(maxJsonDepth)} levels of JSON`\n\t\t: measured.size > maxInputNodes\n\t\t\t? `A condition may have at most ${String(maxInputNodes)} objects and arrays in JSON`\n\t\t\t: true\n}\n\n/** The shape of a condition, with no check of its depth. */\nconst shape: Schema.Codec<PlainCondition, Encoded> = Schema.Union([\n\tSchema.TaggedStruct(\"True\", {}),\n\tSchema.TaggedStruct(\"False\", {}),\n\tSchema.TaggedStruct(\"Compare\", {\n\t\top: Schema.Literals([\"eq\", \"ne\", \"lt\", \"lte\", \"gt\", \"gte\"]),\n\t\tfield: Schema.String,\n\t\tvalue: OperandSchema,\n\t}),\n\tSchema.TaggedStruct(\"In\", {\n\t\tfield: Schema.String,\n\t\tvalues: Schema.Array(OperandSchema),\n\t}),\n\tSchema.TaggedStruct(\"Exists\", { field: Schema.String }),\n\tSchema.TaggedStruct(\"Under\", { prefix: Schema.Array(OperandSchema) }),\n\tSchema.TaggedStruct(\"And\", { conditions: Schema.Array(Recursive) }),\n\tSchema.TaggedStruct(\"Or\", { conditions: Schema.Array(Recursive) }),\n\tSchema.TaggedStruct(\"Not\", { condition: Recursive }),\n]) as never\n\n/**\n * The Schema of a condition with no predicate. It checks the shape only. Use\n * `Policy.schema` to check the field names against a domain too.\n *\n * @stability stable\n * @category schemas\n * @since 0.3.0\n */\nexport const schema: Schema.Codec<PlainCondition, Encoded> =\n\t// The input is any value until the checks of `shape` run, so this guard\n\t// says yes to every object.\n\tSchema.declare(\n\t\t(input): input is Encoded => typeof input === \"object\" && input !== null,\n\t).pipe(\n\t\tSchema.check(Schema.makeFilter(fitsLimits)),\n\t\tSchema.decodeTo(shape, SchemaTransformation.passthrough()),\n\t\t// A condition may use one child in many places, and its JSON form\n\t\t// writes it out each time. An encode runs this step first, so a small\n\t\t// condition with a very large JSON form fails before it is written out.\n\t\tSchema.decodeTo(\n\t\t\tSchema.declare((input): input is PlainCondition =>\n\t\t\t\tisPlainNode(input, new Map(), 0),\n\t\t\t),\n\t\t\tSchemaTransformation.transformEffect({\n\t\t\t\tdecode: (condition: PlainCondition) => Effect.succeed(condition),\n\t\t\t\tencode: (condition: PlainCondition, options) =>\n\t\t\t\t\tjsonSize(condition as Ast, new Map()) > maxJsonNodes\n\t\t\t\t\t\t? Effect.fail(\n\t\t\t\t\t\t\t\tnew SchemaIssue.InvalidValue(\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tmessage: `The JSON form of this condition would have more than ${String(maxJsonNodes)} nodes`,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tcondition,\n\t\t\t\t\t\t\t\t\toptions,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: Effect.succeed(condition),\n\t\t\t}),\n\t\t),\n\t)\n\nconst compareOperators = HashSet.make(\"eq\", \"ne\", \"lt\", \"lte\", \"gt\", \"gte\")\n\n/**\n * Tests if a value is an operand. With `json`, its number must be finite, as\n * the JSON form holds only such numbers.\n */\nconst isOperandValue = (operand: unknown, json: boolean): boolean =>\n\thasProperty(operand, \"_tag\") &&\n\t(operand._tag === \"Principal\"\n\t\t? hasProperty(operand, \"path\") && typeof operand.path === \"string\"\n\t\t: operand._tag === \"Literal\" &&\n\t\t\thasProperty(operand, \"value\") &&\n\t\t\t(operand.value === null ||\n\t\t\t\ttypeof operand.value === \"string\" ||\n\t\t\t\ttypeof operand.value === \"boolean\" ||\n\t\t\t\t(typeof operand.value === \"number\" &&\n\t\t\t\t\t(!json || Number.isFinite(operand.value)))))\n\nconst isOperandList = (values: unknown, json: boolean): boolean =>\n\tArray.isArray(values) &&\n\tArr.every(values, (operand) => isOperandValue(operand, json))\n\n/**\n * Tests if a value is a whole condition with no predicate, as the JSON form\n * holds it. A shared node is tested one time. A node deeper than\n * `maxJsonDepth` is not taken, so the walk does not fill the stack.\n */\nconst isPlainNode = (\n\tinput: unknown,\n\tmemo: Map<unknown, boolean>,\n\tdepth: number,\n\t// `true` for a tree in memory: it may have predicates and any number.\n\tpredicates = false,\n): boolean =>\n\tdepth <= maxJsonDepth &&\n\thasProperty(input, \"_tag\") &&\n\tremember(memo, input, () => {\n\t\tconst child = (node: unknown) =>\n\t\t\tisPlainNode(node, memo, depth + 1, predicates)\n\t\tswitch (input._tag) {\n\t\t\tcase \"Predicate\":\n\t\t\t\treturn (\n\t\t\t\t\tpredicates &&\n\t\t\t\t\thasProperty(input, \"name\") &&\n\t\t\t\t\ttypeof input.name === \"string\" &&\n\t\t\t\t\thasProperty(input, \"run\") &&\n\t\t\t\t\ttypeof input.run === \"function\"\n\t\t\t\t)\n\t\t\tcase \"True\":\n\t\t\tcase \"False\":\n\t\t\t\treturn true\n\t\t\tcase \"Compare\":\n\t\t\t\treturn (\n\t\t\t\t\thasProperty(input, \"op\") &&\n\t\t\t\t\ttypeof input.op === \"string\" &&\n\t\t\t\t\tHashSet.has(compareOperators, input.op) &&\n\t\t\t\t\thasProperty(input, \"field\") &&\n\t\t\t\t\ttypeof input.field === \"string\" &&\n\t\t\t\t\thasProperty(input, \"value\") &&\n\t\t\t\t\tisOperandValue(input.value, !predicates)\n\t\t\t\t)\n\t\t\tcase \"In\":\n\t\t\t\treturn (\n\t\t\t\t\thasProperty(input, \"field\") &&\n\t\t\t\t\ttypeof input.field === \"string\" &&\n\t\t\t\t\thasProperty(input, \"values\") &&\n\t\t\t\t\tisOperandList(input.values, !predicates)\n\t\t\t\t)\n\t\t\tcase \"Exists\":\n\t\t\t\treturn hasProperty(input, \"field\") && typeof input.field === \"string\"\n\t\t\tcase \"Under\":\n\t\t\t\treturn (\n\t\t\t\t\thasProperty(input, \"prefix\") &&\n\t\t\t\t\tisOperandList(input.prefix, !predicates)\n\t\t\t\t)\n\t\t\tcase \"And\":\n\t\t\tcase \"Or\":\n\t\t\t\treturn (\n\t\t\t\t\thasProperty(input, \"conditions\") &&\n\t\t\t\t\tArray.isArray(input.conditions) &&\n\t\t\t\t\tArr.every(input.conditions, child)\n\t\t\t\t)\n\t\t\tcase \"Not\":\n\t\t\t\treturn hasProperty(input, \"condition\") && child(input.condition)\n\t\t\tdefault:\n\t\t\t\treturn false\n\t\t}\n\t})\n\n/**\n * Tests if a value is a whole condition tree: each node has a known tag and\n * the fields of that tag. A predicate node needs a name and a test. A tree\n * deeper than 1000 levels is not taken.\n *\n * @stability stable\n * @category guards\n * @since 1.0.0\n */\nexport const isAst = (u: unknown): u is Ast =>\n\tisPlainNode(u, new Map(), 0, true)\n\n/** The most nodes of the JSON form of a condition. */\nconst maxJsonNodes = 100_000\n\n/**\n * The number of nodes of the JSON form of a condition. A shared child counts\n * one time for each place.\n */\nconst jsonSize = (ast: Ast, memo: Map<Ast, number>): number =>\n\tremember(memo, ast, () => {\n\t\tswitch (ast._tag) {\n\t\t\tcase \"And\":\n\t\t\tcase \"Or\":\n\t\t\t\treturn Arr.reduce(\n\t\t\t\t\tast.conditions,\n\t\t\t\t\t1,\n\t\t\t\t\t(size, child) => size + jsonSize(child, memo),\n\t\t\t\t)\n\t\t\tcase \"Not\":\n\t\t\t\treturn 1 + jsonSize(ast.condition, memo)\n\t\t\tdefault:\n\t\t\t\treturn 1\n\t\t}\n\t})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Condition.js","names":["Nodes.literal","Nodes.Compare","Nodes.And","Nodes.Or","Nodes.Not","Nodes.In","Nodes.Exists","Nodes.Under","Nodes.principalRef","Nodes.Predicate","Nodes.always","Nodes.never","Nodes.toNode","Algebra.provide","Algebra.evaluate","Algebra.evaluateSync","Algebra.simplify","Algebra.partial","Algebra.fields","Search.satisfiable","Search.kindsIn","Catalog.catalogOf","Nodes.isNode","Json.decode","Json.toJson"],"sources":["../src/Condition.ts"],"sourcesContent":["/**\n * A condition is a test on a resource value. A rule applies only when its\n * condition is true.\n *\n * A condition is plain data: a tree of nodes. So you can:\n * - test it on a value with {@link evaluate};\n * - put the principal into it and make it smaller with {@link partial}, which\n * gives a \"residual\" condition: the part that still depends on the\n * resource;\n * - change it into a database query with {@link fold};\n * - keep it as JSON with {@link schema}.\n *\n * Make conditions with a {@link Builder}. A rule gives you a builder for its\n * resource, so the field names and the value types are checked.\n *\n * {@link Builder.predicate} is the one way out of plain data. A predicate runs\n * any `Effect`. Its error type and its service type go into the type of the\n * check. A rule with a predicate can not become JSON, and the type system\n * stops you when you try.\n *\n * @stability stable\n * @since 0.3.0\n */\n// A predicate keeps its error type and service type in the public types. The\n// code below works on the nodes with no types, where they are `unknown`, so\n// the language service check for `unknown` in an Effect is off here.\n// @effect-diagnostics anyUnknownInErrorContext:off\nimport * as Arr from \"effect/Array\"\nimport type * as BigDecimal from \"effect/BigDecimal\"\nimport type * as Cause from \"effect/Cause\"\nimport type * as Chunk from \"effect/Chunk\"\nimport type * as DateTime from \"effect/DateTime\"\nimport type * as Duration from \"effect/Duration\"\nimport type * as Exit from \"effect/Exit\"\nimport type * as HashMap from \"effect/HashMap\"\nimport type * as HashSet from \"effect/HashSet\"\nimport type * as Option from \"effect/Option\"\nimport type * as Redacted from \"effect/Redacted\"\nimport type * as Context from \"effect/Context\"\nimport * as Effect from \"effect/Effect\"\nimport { dual } from \"effect/Function\"\nimport { hasProperty } from \"effect/Predicate\"\nimport * as Schema from \"effect/Schema\"\nimport * as SchemaIssue from \"effect/SchemaIssue\"\nimport * as SchemaTransformation from \"effect/SchemaTransformation\"\nimport * as Result from \"effect/Result\"\nimport * as Algebra from \"./internal/algebra.ts\"\nimport * as Catalog from \"./internal/catalog.ts\"\nimport * as Json from \"./internal/json.ts\"\nimport * as Nodes from \"./internal/nodes.ts\"\nimport * as Search from \"./internal/search.ts\"\nimport * as Resource from \"./Resource.ts\"\n\n/**\n * A value that a condition can compare.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Scalar = Nodes.Scalar\n\n/**\n * A fixed value in a condition.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Literal = Nodes.Literal\n\n/**\n * A field of the principal. {@link partial} puts the value of the field in its\n * place.\n *\n * A principal field that is `null` or missing has no value. A `Compare`, `In`\n * or `Under` test with it is always false, also with `ne`. So a principal with\n * no id never matches a resource with no owner. `not` still turns false into\n * true.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type PrincipalRef = Nodes.PrincipalRef\n\n/**\n * A field of the principal with a known value type `A`, from a principal of\n * the type `P`. The type fields are only in the types. A test with the\n * reference reads a principal of the type `P`, so it can not go into a rule\n * of a domain with another principal.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Ref<A, P = never> = PrincipalRef & {\n\treadonly \"~Ref\": () => A\n\treadonly \"~Principal\": (principal: P) => void\n}\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Operand = Literal | PrincipalRef\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type CompareOperator = Nodes.CompareOperator\n\n/**\n * Always true.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type True = Nodes.True\n\n/**\n * Always false.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type False = Nodes.False\n\n/**\n * Compares a field with a value. A missing field has the value `null`. `lt`,\n * `lte`, `gt` and `gte` are false when the two sides are not both numbers or\n * both strings.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Compare = Nodes.Compare\n\n/**\n * True when a field is equal to one of the values.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type In = Nodes.In\n\n/**\n * True when a field is not `null` and not missing.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Exists = Nodes.Exists\n\n/**\n * True when the path of the resource starts with the prefix. A resource with\n * no path is never under a prefix.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Under = Nodes.Under\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type And = Nodes.And\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Or = Nodes.Or\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Not = Nodes.Not\n\n/**\n * A test that runs an `Effect`. It can not become JSON or a query.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Predicate = Nodes.Predicate\n\n/**\n * The nodes of a condition, without types. Each node is a class, and only the\n * builder, the functions of this module and the Schema make one. So a plain\n * object, or a spread of a node, is not a node.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Ast = Nodes.Node\n\n/**\n * The mark of a condition with a predicate. `E` and `R` are the error type\n * and the service type of its predicates.\n *\n * @stability stable\n * @category models\n * @since 2.0.0\n */\nexport interface Opaque<out E = never, out R = never> {\n\treadonly \"~Opaque\": { readonly E: E; readonly R: R }\n}\n\n/**\n * The error type of the predicates of a mark `X`. A mark that may be\n * anything, as `unknown`, may have any error.\n *\n * @stability stable\n * @category utility types\n * @since 2.0.0\n */\nexport type ErrorOf<X> = unknown extends X\n\t? unknown\n\t: X extends Opaque<infer E, infer _R>\n\t\t? E\n\t\t: never\n\n/**\n * The service type of the predicates of a mark `X`. A mark that may be\n * anything, as `unknown`, may need any service.\n *\n * @stability stable\n * @category utility types\n * @since 2.0.0\n */\nexport type ServicesOf<X> = unknown extends X\n\t? unknown\n\t: X extends Opaque<infer _E, infer R>\n\t\t? R\n\t\t: never\n\n/**\n * The mark `X` with no services.\n *\n * @stability stable\n * @category utility types\n * @since 2.0.0\n */\nexport type Provided<X> = unknown extends X\n\t? Opaque<unknown>\n\t: X extends Opaque<infer E, infer _R>\n\t\t? Opaque<E>\n\t\t: never\n\n/**\n * What the predicates of a condition read: a resource value of the type `V`\n * and a principal of the type `P`. It is only in the types.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport interface Reads<V, P> {\n\treadonly value: V\n\treadonly principal: P\n}\n\n/**\n * A condition. `I` is what its tests read: see {@link Reads}. `X` is\n * {@link Opaque} when the condition has a predicate, and `never` when it is\n * plain data. A plain condition can become JSON or a query.\n *\n * The two type fields are only in the types. `I` goes into a function as an\n * input, so a condition that reads a `Post` does not fit a rule for a\n * `Comment`. `X` comes out of a function, so a plain condition fits where a\n * condition with predicates may go.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Condition<I = unknown, X = never> = Ast & {\n\treadonly \"~Reads\": (reads: I) => void\n\treadonly \"~Opaque\": () => X\n}\n\n/**\n * Any condition.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Any = Condition<any, any>\n\n/**\n * What the tests of a condition read. For a union of conditions, it is what\n * all of them read.\n *\n * @stability stable\n * @category utility types\n * @since 1.0.0\n */\nexport type ReadsOf<C> = [C] extends [\n\t{ readonly \"~Reads\": (reads: infer I) => void },\n]\n\t? I\n\t: unknown\n\n/**\n * The mark of a condition: {@link Opaque} when it has a predicate.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type OpaqueOf<C> = C extends { readonly \"~Opaque\": () => infer X }\n\t? X\n\t: never\n\ntype Leaf = string | number | boolean | bigint | symbol | null | undefined\n/**\n * Values of a class that keeps its data inside. A path does not go into them,\n * as in the field paths of a resource, so a field with such a value is one\n * field. A condition can test only if it exists.\n */\ntype Whole =\n\t| ReadonlyMap<unknown, unknown>\n\t| ReadonlySet<unknown>\n\t| HashMap.HashMap<unknown, unknown>\n\t| HashSet.HashSet<unknown>\n\t| Date\n\t| URL\n\t| Uint8Array\n\t| Option.Option<unknown>\n\t| BigDecimal.BigDecimal\n\t| Duration.Duration\n\t| DateTime.DateTime\n\t| Redacted.Redacted<unknown>\n\t| Chunk.Chunk<unknown>\n\t| Cause.Cause<unknown>\n\t| Result.Result<unknown, unknown>\n\t| Exit.Exit<unknown, unknown>\n\t| File\n\t| FormData\n\t| RegExp\n\t| URLSearchParams\ntype PreviousDepth = [never, 0, 1, 2, 3]\ntype FieldPathInternal<\n\tT,\n\tDepth extends number,\n\tArrays extends boolean,\n\tParents extends boolean = false,\n> = [Depth] extends [never]\n\t? never\n\t: {\n\t\t\t[K in keyof T & string]-?: PathsOf<\n\t\t\t\tK,\n\t\t\t\tNonNullable<T[K]>,\n\t\t\t\tDepth,\n\t\t\t\tArrays,\n\t\t\t\tParents\n\t\t\t>\n\t\t}[keyof T & string]\n\n/**\n * The paths of one field `K` with the values `V`. Each kind of value in `V`\n * gives its own paths, so a field that holds a string or a struct is a field,\n * and the fields of the struct are fields too. A function is no field.\n */\ntype PathsOf<\n\tK extends string,\n\tV,\n\tDepth extends number,\n\tArrays extends boolean,\n\tParents extends boolean,\n> =\n\t// A field that is only ever `null` or missing is a field too.\n\t| ([V] extends [never] ? K : never)\n\t| ([Extract<V, Leaf | Whole>] extends [never] ? never : K)\n\t| ([Extract<V, ReadonlyArray<unknown>>] extends [never]\n\t\t\t? never\n\t\t\t: Arrays extends true\n\t\t\t\t? K\n\t\t\t\t: never)\n\t| ObjectPaths<\n\t\t\tK,\n\t\t\tExclude<V, Leaf | Whole | Function | ReadonlyArray<unknown>>,\n\t\t\tDepth,\n\t\t\tArrays,\n\t\t\tParents\n\t >\n\n/** The paths of a field `K` that holds the objects `O`, and of the fields below. */\ntype ObjectPaths<\n\tK extends string,\n\tO,\n\tDepth extends number,\n\tArrays extends boolean,\n\tParents extends boolean,\n> = [O] extends [never]\n\t? never\n\t: // A record is one field to a rule or a request, as `permittedFields`\n\t\t// lists it.\n\t\t| (Parents extends true\n\t\t\t\t? K\n\t\t\t\t: Arrays extends true\n\t\t\t\t\t? string extends keyof O\n\t\t\t\t\t\t? K\n\t\t\t\t\t\t: never\n\t\t\t\t\t: never)\n\t\t| `${K}.${FieldPathInternal<O, PreviousDepth[Depth], Arrays, Parents>}`\n\n/**\n * The paths of the fields of `T` that hold one value, with dots for nested\n * fields. Arrays are left out. A map, a set, a date, a URL, a byte array, an\n * `Option` and the other value types of Effect, such as `BigDecimal` and\n * `Duration`, are one field, and a path does not go into them. The type goes down four levels, so type\n * checking stays fast. For a union of types, only the common fields are\n * paths.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type FieldPath<T> = [T] extends [object]\n\t? FieldPathInternal<T, 4, false>\n\t: never\n\n/**\n * The paths of the fields of `T` that a rule or a request may name, as in\n * `Rule.Options.fields`. They are the paths of {@link FieldPath}, and the\n * paths of arrays too: a rule may allow or deny a whole array field, and\n * `permittedFields` lists it.\n *\n * @stability stable\n * @category utility types\n * @since 1.0.0\n */\nexport type FieldSelector<T> = [T] extends [object]\n\t? FieldPathInternal<T, 4, true>\n\t: never\n\n/**\n * The names that the `fields` of a rule may have: the paths of\n * {@link FieldSelector}, and the paths of the structs above them. A name of a\n * struct covers the fields below it.\n *\n * @stability stable\n * @category utility types\n * @since 2.0.0\n */\nexport type FieldName<T> = [T] extends [object]\n\t? FieldPathInternal<T, 4, true, true>\n\t: never\n\n/**\n * The value type that fits every field in `F`. For one field, it is the type\n * of the field. For a union of fields, it is the values that each of them can\n * hold, so a value of a union type can not test a field of another type. For\n * a union of data types, as for a rule on two kinds, it is the values that\n * the field can hold in each of them.\n *\n * @stability stable\n * @category utility types\n * @since 1.0.0\n */\nexport type FieldValue<Data, F extends string> = (\n\tData extends unknown\n\t\t? F extends unknown\n\t\t\t? (value: PathValue<Data, F>) => void\n\t\t\t: never\n\t\t: never\n) extends (value: infer V) => void\n\t? V\n\t: never\n\ntype Normalize<A> = Exclude<A, undefined> | (undefined extends A ? null : never)\n\n/**\n * The type of the field of `T` at `Path`. A field that may be missing may also\n * be `null`.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type PathValue<\n\tT,\n\tPath extends string,\n> = Path extends `${infer Head}.${infer Rest}`\n\t? Head extends keyof T\n\t\t? undefined extends T[Head]\n\t\t\t? PathValue<NonNullable<T[Head]>, Rest> | null\n\t\t\t: null extends T[Head]\n\t\t\t\t? PathValue<NonNullable<T[Head]>, Rest> | null\n\t\t\t\t: PathValue<T[Head], Rest>\n\t\t: never\n\t: Path extends keyof T\n\t\t? Normalize<T[Path]>\n\t\t: never\n\n/**\n * A value for a field of type `A`: a fixed value, or a field of the principal\n * with the same type.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type OperandOf<A, P = never> = Extract<A, Scalar> | Ref<A, P>\n\ntype ScalarPath<T> = {\n\t[F in FieldPath<T>]: PathValue<T, F> extends Scalar ? F : never\n}[FieldPath<T>]\n\ntype OrderedPath<T> = {\n\t[F in FieldPath<T>]: Exclude<PathValue<T, F>, null> extends number | string\n\t\t? F\n\t\t: never\n}[FieldPath<T>]\n\n/**\n * A test made by a {@link Builder}. It runs no code, but it keeps the value\n * type of its resource, so a test on the fields of one resource can not go\n * into a rule for another resource. A test with a field of the principal\n * keeps the principal type `P` too.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport type Test<Value, P = unknown> = Condition<Reads<Value, P>>\n\n/**\n * The principal type that a test reads: the principal of each field of the\n * principal in the values `V`, and `unknown` when there is none. A reference\n * from another builder keeps the principal of that builder.\n */\ntype PrincipalOf<V, _P> = [Extract<V, PrincipalRef>] extends [never]\n\t? unknown\n\t: [Extract<V, PrincipalRef>] extends [\n\t\t\t\t{ readonly \"~Principal\": (principal: infer Q) => void },\n\t\t ]\n\t\t? Q\n\t\t: unknown\n\n/**\n * Makes conditions for a resource with the data type `Data` and the value type\n * `Value`, and a principal with the type `P`.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Builder<Data, Value, P> {\n\t/** The field is equal to the value. */\n\treadonly eq: <\n\t\tconst F extends FieldPath<Data>,\n\t\tconst V extends OperandOf<FieldValue<Data, F>, any>,\n\t>(\n\t\tfield: F,\n\t\tvalue: V,\n\t) => Test<Value, PrincipalOf<V, P>>\n\t/** The field is not equal to the value. */\n\treadonly ne: <\n\t\tconst F extends FieldPath<Data>,\n\t\tconst V extends OperandOf<FieldValue<Data, F>, any>,\n\t>(\n\t\tfield: F,\n\t\tvalue: V,\n\t) => Test<Value, PrincipalOf<V, P>>\n\treadonly lt: <\n\t\tconst F extends OrderedPath<Data>,\n\t\tconst V extends OperandOf<Exclude<FieldValue<Data, F>, null>, any>,\n\t>(\n\t\tfield: F,\n\t\tvalue: V,\n\t) => Test<Value, PrincipalOf<V, P>>\n\treadonly lte: <\n\t\tconst F extends OrderedPath<Data>,\n\t\tconst V extends OperandOf<Exclude<FieldValue<Data, F>, null>, any>,\n\t>(\n\t\tfield: F,\n\t\tvalue: V,\n\t) => Test<Value, PrincipalOf<V, P>>\n\treadonly gt: <\n\t\tconst F extends OrderedPath<Data>,\n\t\tconst V extends OperandOf<Exclude<FieldValue<Data, F>, null>, any>,\n\t>(\n\t\tfield: F,\n\t\tvalue: V,\n\t) => Test<Value, PrincipalOf<V, P>>\n\treadonly gte: <\n\t\tconst F extends OrderedPath<Data>,\n\t\tconst V extends OperandOf<Exclude<FieldValue<Data, F>, null>, any>,\n\t>(\n\t\tfield: F,\n\t\tvalue: V,\n\t) => Test<Value, PrincipalOf<V, P>>\n\t/** The field is equal to one of the values. */\n\treadonly in: <\n\t\tconst F extends FieldPath<Data>,\n\t\tconst Vs extends ReadonlyArray<OperandOf<FieldValue<Data, F>, any>>,\n\t>(\n\t\tfield: F,\n\t\tvalues: Vs,\n\t) => Test<Value, PrincipalOf<Vs[number], P>>\n\t/** The field has a value that is not `null`. */\n\treadonly exists: <const F extends FieldPath<Data>>(field: F) => Test<Value>\n\t/** The path of the resource starts with these parts. */\n\treadonly under: <\n\t\tconst Ps extends ReadonlyArray<string | null | Ref<string | null, any>>,\n\t>(\n\t\t...prefix: Ps\n\t) => Test<Value, PrincipalOf<Ps[number], P>>\n\t/**\n\t * A field of the principal, to use as a value. The field must have a\n\t * {@link Scalar} type.\n\t */\n\treadonly principal: <const F extends ScalarPath<P>>(\n\t\tfield: F,\n\t) => Ref<PathValue<P, F>, P>\n\treadonly and: <const Cs extends ReadonlyArray<Any>>(\n\t\t...conditions: Cs\n\t) => Condition<ReadsOf<Cs[number]>, OpaqueOf<Cs[number]>>\n\treadonly or: <const Cs extends ReadonlyArray<Any>>(\n\t\t...conditions: Cs\n\t) => Condition<ReadsOf<Cs[number]>, OpaqueOf<Cs[number]>>\n\treadonly not: <C extends Any>(\n\t\tcondition: C,\n\t) => Condition<ReadsOf<C>, OpaqueOf<C>>\n\t/**\n\t * A test that runs any code. It may give a boolean or an `Effect`. A\n\t * condition with a predicate can not become JSON or a query.\n\t */\n\treadonly predicate: <E = never, R = never>(\n\t\tname: string,\n\t\ttest: (\n\t\t\tvalue: Value,\n\t\t\tprincipal: P,\n\t\t) => boolean | Effect.Effect<boolean, E, R>,\n\t) => Condition<Reads<Value, P>, Opaque<E, R>>\n}\n\nconst isOperand = (u: unknown): u is Operand =>\n\thasProperty(u, \"_tag\") && (u._tag === \"Literal\" || u._tag === \"Principal\")\n\nconst toOperand = (value: unknown): Operand =>\n\tisOperand(value) ? value : Nodes.literal(value as Scalar)\n\nconst compare =\n\t(op: CompareOperator) =>\n\t(field: string, value: unknown): Ast =>\n\t\tnew Nodes.Compare({ op, field, value: toOperand(value) })\n\n// A list of conditions goes in as an array, not as arguments: a call may take\n// only so many arguments, and a decoded condition may have more children.\n// The constructor copies the list, so a later change to the array of a caller\n// does not change the condition.\nconst andOf = (conditions: ReadonlyArray<Ast>): Ast =>\n\tnew Nodes.And(conditions as ReadonlyArray<Nodes.Node>)\n\nconst orOf = (conditions: ReadonlyArray<Ast>): Ast =>\n\tnew Nodes.Or(conditions as ReadonlyArray<Nodes.Node>)\n\nconst makeNot = (condition: Ast): Ast => new Nodes.Not(condition as Nodes.Node)\n\nconst sharedBuilder: Builder<any, any, any> = {\n\teq: compare(\"eq\"),\n\tne: compare(\"ne\"),\n\tlt: compare(\"lt\"),\n\tlte: compare(\"lte\"),\n\tgt: compare(\"gt\"),\n\tgte: compare(\"gte\"),\n\tin: (field: string, values: ReadonlyArray<unknown>) =>\n\t\tnew Nodes.In({ field, values: Arr.map(Array.from(values), toOperand) }),\n\texists: (field: string) => new Nodes.Exists({ field }),\n\tunder: (...prefix: ReadonlyArray<unknown>) =>\n\t\tnew Nodes.Under({ prefix: Arr.map(prefix, toOperand) }),\n\tprincipal: (path: string) => Nodes.principalRef(path),\n\tand: (...conditions: ReadonlyArray<Ast>) => andOf(conditions),\n\tor: (...conditions: ReadonlyArray<Ast>) => orOf(conditions),\n\tnot: makeNot,\n\tpredicate: (\n\t\tname: string,\n\t\ttest: (\n\t\t\tvalue: unknown,\n\t\t\tprincipal: unknown,\n\t\t) => boolean | Effect.Effect<boolean, unknown, unknown>,\n\t) =>\n\t\tnew Nodes.Predicate({\n\t\t\tname,\n\t\t\trun: (value, principal) =>\n\t\t\t\tEffect.suspend(() => {\n\t\t\t\t\tconst result = test(value, principal)\n\t\t\t\t\treturn Effect.isEffect(result) ? result : Effect.succeed(result)\n\t\t\t\t}),\n\t\t}),\n} as never\n\n/**\n * Makes a builder. Rules give you a builder with the right types, so you do not\n * often need this.\n *\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const builder = <Data, Value, P>(): Builder<Data, Value, P> =>\n\tsharedBuilder\n\n/**\n * Always true.\n *\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const always: Condition = Nodes.always as never\n\n/**\n * Always false.\n *\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const never: Condition = Nodes.never as never\n\n/**\n * True when all the conditions are true. With no conditions, it is true.\n *\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const and: <const Cs extends ReadonlyArray<Any>>(\n\t...conditions: Cs\n) => Condition<ReadsOf<Cs[number]>, OpaqueOf<Cs[number]>> = ((\n\t...conditions: ReadonlyArray<Ast>\n) => andOf(conditions)) as never\n\n/**\n * The same as {@link and}, for a list of conditions of one type. Use it for a\n * long list: a function call may take only so many arguments.\n *\n * @stability stable\n * @category combinators\n * @since 1.0.0\n */\nexport const andAll: <C extends Any>(\n\tconditions: ReadonlyArray<C>,\n) => Condition<ReadsOf<C>, OpaqueOf<C>> = andOf as never\n\n/**\n * The same as {@link or}, for a list of conditions of one type. Use it for a\n * long list: a function call may take only so many arguments.\n *\n * @stability stable\n * @category combinators\n * @since 1.0.0\n */\nexport const orAll: <C extends Any>(\n\tconditions: ReadonlyArray<C>,\n) => Condition<ReadsOf<C>, OpaqueOf<C>> = orOf as never\n\n/**\n * True when one of the conditions is true. With no conditions, it is false.\n *\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const or: <const Cs extends ReadonlyArray<Any>>(\n\t...conditions: Cs\n) => Condition<ReadsOf<Cs[number]>, OpaqueOf<Cs[number]>> = ((\n\t...conditions: ReadonlyArray<Ast>\n) => orOf(conditions)) as never\n\n/**\n * @stability stable\n * @category combinators\n * @since 0.3.0\n */\nexport const not: <C extends Any>(\n\tcondition: C,\n) => Condition<ReadsOf<C>, OpaqueOf<C>> = makeNot as never\n\n/**\n * The data that a condition needs for a test.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Input {\n\t/** The resource value. */\n\treadonly value: object\n\t/**\n\t * The principal. Without it, a principal field has no value. See\n\t * {@link PrincipalRef}.\n\t */\n\treadonly principal?: object | undefined\n\t/** The path of the resource. Without it, `Under` is false. */\n\treadonly path?: ReadonlyArray<Resource.PathSegment> | undefined\n}\n\n/** Gives a condition as a node. A value that no constructor made is a defect. */\nconst nodeOf = (condition: Ast): Nodes.Node => Nodes.toNode(condition)\n\n/**\n * Gives the services in `context` to every predicate of a condition, so the\n * condition needs no services when it runs.\n *\n * @stability stable\n * @category services\n * @since 1.0.0\n */\nexport const provideContext: {\n\t<R>(\n\t\tcontext: Context.Context<R>,\n\t): <I, X>(\n\t\tcondition: Condition<I, X> &\n\t\t\t([ServicesOf<X>] extends [R] ? unknown : never),\n\t) => Condition<I, Provided<X>>\n\t<I, X>(\n\t\tcondition: Condition<I, X>,\n\t\tcontext: Context.Context<ServicesOf<X>>,\n\t): Condition<I, Provided<X>>\n} = dual(2, (condition: Ast, context: Context.Context<never>): Ast =>\n\tAlgebra.provide(nodeOf(condition), context),\n) as never\n\n/**\n * The input of {@link evaluate} that the predicates of a condition need: a\n * value and a principal of the types in `I`. See {@link Reads}.\n */\ntype ReadsInput<I> =\n\tI extends Reads<infer V, infer P>\n\t\t? { readonly value: V } & (unknown extends P\n\t\t\t\t? unknown\n\t\t\t\t: { readonly principal: P })\n\t\t: unknown\n\n/**\n * Tests a condition on a value. A predicate may fail with its error. When the\n * condition has a predicate, the input must have the value and the principal\n * that the predicate reads.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const evaluate: <I, X, In extends Input>(\n\tcondition: Condition<I, X>,\n\tinput: In & ReadsInput<I>,\n) => Effect.Effect<boolean, ErrorOf<X>, ServicesOf<X>> = ((\n\tcondition: Ast,\n\tinput: Input,\n): Effect.Effect<boolean, unknown, unknown> =>\n\tEffect.suspend(() => Algebra.evaluate(nodeOf(condition), input))) as never\n\n/**\n * Tests a condition with no predicate on a value, at once.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const evaluateSync: <I, In extends Input>(\n\tcondition: Condition<I>,\n\tinput: In & ReadsInput<I>,\n) => boolean = (condition: Ast, input: Input): boolean =>\n\tAlgebra.evaluateSync(nodeOf(condition), input)\n\n/**\n * Makes a condition smaller without a change to its meaning. It removes `True`\n * and `False` from `And` and `Or`, joins nested `And` and `Or` nodes, and\n * removes double `Not` nodes and copies of a child.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const simplify: <I, X>(condition: Condition<I, X>) => Condition<I, X> =\n\t((condition: Ast) => condition.pipe(nodeOf, Algebra.simplify)) as never\n\ninterface PartialInput {\n\treadonly principal?: object | undefined\n\treadonly path?: ReadonlyArray<Resource.PathSegment> | undefined\n}\n\n/**\n * The principal that {@link partial} must get for the predicates of a\n * condition. A predicate keeps the principal that it gets, so the principal\n * must have the type that the predicate reads.\n */\ntype PrincipalInput<I> =\n\tI extends Reads<infer _V, infer P>\n\t\t? unknown extends P\n\t\t\t? unknown\n\t\t\t: { readonly principal: P }\n\t\t: unknown\n\n/** What a condition reads after {@link partial}: the value, and no principal. */\ntype Bound<I> = I extends Reads<infer V, infer _P> ? Reads<V, unknown> : I\n\n/**\n * Puts the principal into a condition and expands `Under` with the path of the\n * resource. The result is simplified. It has no principal fields and no\n * `Under` nodes. It is `True` or `False` when the answer does not depend on the\n * resource value.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const partial: <I, X>(\n\tcondition: Condition<I, X>,\n\tinput: PartialInput & PrincipalInput<I>,\n) => Condition<Bound<I>, X> = ((condition: Ast, input: PartialInput): Ast =>\n\tAlgebra.partial(nodeOf(condition), input)) as never\n\n/**\n * The functions that change each node of a condition into another form, such\n * as a database query.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Interpreter<A> {\n\treadonly true: () => A\n\treadonly false: () => A\n\treadonly compare: (op: CompareOperator, field: string, value: Scalar) => A\n\treadonly in: (field: string, values: ReadonlyArray<Scalar>) => A\n\treadonly exists: (field: string) => A\n\treadonly and: (conditions: ReadonlyArray<A>) => A\n\treadonly or: (conditions: ReadonlyArray<A>) => A\n\treadonly not: (condition: A) => A\n\t/** Optional. Without it, a predicate makes `fold` fail. */\n\treadonly predicate?: (name: string) => A\n}\n\n/**\n * The error when `fold` can not change a node.\n *\n * @stability stable\n * @category errors\n * @since 0.3.0\n */\nexport class Untranslatable extends Schema.TaggedError<Untranslatable>(\n\t\"@nmnmcc/ability/Condition/Untranslatable\",\n)(\"Untranslatable\", { reason: Schema.String }) {}\n\nconst literalValue = (operand: Operand, field: string): Scalar => {\n\tif (operand._tag !== \"Literal\") {\n\t\tthrow Untranslatable.make({\n\t\t\treason: `The field \"${field}\" uses a principal field. Call Condition.partial first.`,\n\t\t})\n\t}\n\treturn operand.value\n}\n\n/** Folds a condition. A shared child is folded again for each place. */\nconst foldNode = <A>(node: Nodes.Node, interpreter: Interpreter<A>): A => {\n\tswitch (node._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\treturn interpreter.compare(\n\t\t\t\tnode.op,\n\t\t\t\tnode.field,\n\t\t\t\tliteralValue(node.value, node.field),\n\t\t\t)\n\t\tcase \"In\":\n\t\t\treturn interpreter.in(\n\t\t\t\tnode.field,\n\t\t\t\tArr.map(node.values, (operand) => literalValue(operand, node.field)),\n\t\t\t)\n\t\tcase \"Exists\":\n\t\t\treturn interpreter.exists(node.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\tArr.map(node.conditions, (child) => foldNode(child, interpreter)),\n\t\t\t)\n\t\tcase \"Or\":\n\t\t\treturn interpreter.or(\n\t\t\t\tArr.map(node.conditions, (child) => foldNode(child, interpreter)),\n\t\t\t)\n\t\tcase \"Not\":\n\t\t\treturn interpreter.not(foldNode(node.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 \"${node.name}\" can not become a query`,\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn interpreter.predicate(node.name)\n\t}\n}\n\n/**\n * Changes a condition into another form with an interpreter. Call\n * {@link partial} first: `fold` fails on principal fields and on `Under`\n * nodes, and on predicates when the interpreter has no `predicate` function.\n *\n * @stability stable\n * @category converting\n * @since 0.3.0\n */\nexport const fold: {\n\t<A>(\n\t\tinterpreter: Interpreter<A>,\n\t): (condition: Any) => Effect.Effect<A, Untranslatable>\n\t<A>(\n\t\tcondition: Any,\n\t\tinterpreter: Interpreter<A>,\n\t): Effect.Effect<A, Untranslatable>\n} = dual(\n\t2,\n\t<A>(\n\t\tcondition: Ast,\n\t\tinterpreter: Interpreter<A>,\n\t): Effect.Effect<A, Untranslatable> =>\n\t\tEffect.try({\n\t\t\ttry: () => foldNode(nodeOf(condition), 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/**\n * The fields that a condition uses, in the order that they first come.\n *\n * @stability stable\n * @category getters\n * @since 0.3.0\n */\nexport const fields = (condition: Ast): ReadonlyArray<string> =>\n\tcondition.pipe(nodeOf, Algebra.fields)\n\n// Satisfiability\n\n/**\n * Values of fields, as a nested object. A field that is not in it may have any\n * value. A value with parts that the search does not look into, such as a\n * date, is an empty object.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport type Example = Search.Example\n\n/**\n * The answer of {@link satisfiable}:\n * - `Satisfiable`: some value makes the condition true. `example` is one.\n * - `Unsatisfiable`: no value makes the condition true.\n * - `Unknown`: the search can not say. The condition has a predicate, or\n * the search went past its budget.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport type Satisfiability = Search.Satisfiability\n\n/**\n * The options of {@link satisfiable}.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\nexport interface SatisfiableOptions {\n\t/**\n\t * The Schema of the values. Its shape gives the kinds of values of each\n\t * field. Without it, a field may have any value.\n\t */\n\treadonly schema?: Schema.Top | undefined\n\t/** The most steps that the search may take. The default is 1000000. */\n\treadonly budget?: number | undefined\n}\n\n/**\n * Tests if some value makes a condition true, and gives such a value.\n *\n * Call {@link partial} first: the condition must have no principal fields and\n * no `Under` nodes. A condition with a predicate gives `Unknown`.\n *\n * Each test of a condition compares one field with constants, so the\n * constants cut the values of each field into a few cells. The search tries\n * one value from each cell, one field at a time. The values of a field come\n * from the shape of the Schema in `options.schema`: its literals, `null` for\n * a nullable or optional field, and finite or integer numbers.\n *\n * The search reads the shape of the Schema, not its other checks, such as a\n * minimum length. So `Unsatisfiable` holds for every value of the Schema. A\n * `Satisfiable` example fits the shape, but a check may still stop it.\n *\n * The problem is as hard as boolean satisfiability, so the search has a\n * budget. Past it, the answer is `Unknown`. A condition with more than 256\n * fields gives `Unknown` too.\n *\n * @stability stable\n * @category evaluation\n * @since 1.0.0\n */\nexport const satisfiable = (\n\tcondition: Any,\n\toptions: SatisfiableOptions = {},\n): Satisfiability =>\n\tSearch.satisfiable(\n\t\tnodeOf(condition),\n\t\tSearch.kindsIn(\n\t\t\toptions.schema === undefined\n\t\t\t\t? undefined\n\t\t\t\t: Catalog.catalogOf(options.schema.ast),\n\t\t),\n\t\toptions.budget,\n\t)\n\n/**\n * The JSON form of an operand.\n *\n * @stability stable\n * @category models\n * @since 2.0.0\n */\nexport type EncodedOperand =\n\t| { readonly _tag: \"Literal\"; readonly value: Scalar }\n\t| { readonly _tag: \"Principal\"; readonly path: string }\n\n/**\n * The JSON form of a condition with no predicate.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Encoded =\n\t| { readonly _tag: \"True\" }\n\t| { readonly _tag: \"False\" }\n\t| {\n\t\t\treadonly _tag: \"Compare\"\n\t\t\treadonly op: CompareOperator\n\t\t\treadonly field: string\n\t\t\treadonly value: EncodedOperand\n\t }\n\t| {\n\t\t\treadonly _tag: \"In\"\n\t\t\treadonly field: string\n\t\t\treadonly values: ReadonlyArray<EncodedOperand>\n\t }\n\t| { readonly _tag: \"Exists\"; readonly field: string }\n\t| { readonly _tag: \"Under\"; readonly prefix: ReadonlyArray<EncodedOperand> }\n\t| {\n\t\t\treadonly _tag: \"And\" | \"Or\"\n\t\t\treadonly conditions: ReadonlyArray<Encoded>\n\t }\n\t| { readonly _tag: \"Not\"; readonly condition: Encoded }\n\n/**\n * A condition with no predicate, that may read any values. It is the type of\n * {@link schema}: a decoded condition reads nothing, so it fits any rule, and\n * any plain condition, such as one from a builder or a residual, may be\n * encoded.\n *\n * @stability stable\n * @category models\n * @since 1.0.0\n */\n// `any` for what it reads: the field is contravariant, so no other type both\n// takes every condition and fits every rule.\nexport type PlainCondition = Condition<any>\n\n/**\n * The Schema of a condition with no predicate. It checks the shape only. Use\n * `Policy.schema` to check the field names against a domain too.\n *\n * The decoder takes at most 500 levels of conditions, and at most 1000000\n * objects and array items, with a shared object counted for each place. It\n * reads only the own data fields of the input.\n *\n * @stability stable\n * @category schemas\n * @since 0.3.0\n */\nexport const schema: Schema.Codec<PlainCondition, Encoded> =\n\tSchema.Unknown.pipe(\n\t\tSchema.decodeTo(\n\t\t\tSchema.declare(\n\t\t\t\t(input): input is PlainCondition =>\n\t\t\t\t\tNodes.isNode(input) && !input.opaque,\n\t\t\t),\n\t\t\tSchemaTransformation.transformEffect({\n\t\t\t\tdecode: (input: unknown, options) =>\n\t\t\t\t\tResult.match(Json.decode(input), {\n\t\t\t\t\t\tonSuccess: (node) => Effect.succeed(node as never),\n\t\t\t\t\t\tonFailure: (problem) =>\n\t\t\t\t\t\t\tEffect.fail(\n\t\t\t\t\t\t\t\tnew SchemaIssue.Pointer(\n\t\t\t\t\t\t\t\t\tproblem.path,\n\t\t\t\t\t\t\t\t\tnew SchemaIssue.InvalidValue(\n\t\t\t\t\t\t\t\t\t\t{ message: problem.message },\n\t\t\t\t\t\t\t\t\t\tinput,\n\t\t\t\t\t\t\t\t\t\toptions,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t}),\n\t\t\t\tencode: (condition: PlainCondition) =>\n\t\t\t\t\tEffect.sync(() => Json.toJson(condition as never)),\n\t\t\t}),\n\t\t),\n\t) as never\n"],"mappings":"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"}
|
package/dist/Decision.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AnyRule } from "./Policy.js";
|
|
2
2
|
import * as Data from "effect/Data";
|
|
3
3
|
declare namespace Decision_d_exports {
|
|
4
4
|
export { Allow, Decision, Deny, NotApplicable, isAllow, isDeny, isNotApplicable, match, reason };
|
|
@@ -11,11 +11,11 @@ declare namespace Decision_d_exports {
|
|
|
11
11
|
export type Decision = Data.TaggedEnum<{
|
|
12
12
|
Allow: {
|
|
13
13
|
/** The rule that gave the answer, when a rule gave it. */
|
|
14
|
-
readonly rule?:
|
|
14
|
+
readonly rule?: AnyRule;
|
|
15
15
|
};
|
|
16
16
|
Deny: {
|
|
17
17
|
/** The rule that gave the answer, when a rule gave it. */
|
|
18
|
-
readonly rule?:
|
|
18
|
+
readonly rule?: AnyRule;
|
|
19
19
|
readonly reason?: string;
|
|
20
20
|
};
|
|
21
21
|
NotApplicable: {};
|
|
@@ -26,7 +26,7 @@ export type Decision = Data.TaggedEnum<{
|
|
|
26
26
|
* @since 0.3.0
|
|
27
27
|
*/
|
|
28
28
|
export declare const Allow: (args: {
|
|
29
|
-
readonly rule?:
|
|
29
|
+
readonly rule?: AnyRule;
|
|
30
30
|
}) => Decision;
|
|
31
31
|
/**
|
|
32
32
|
* @stability stable
|
|
@@ -34,7 +34,7 @@ export declare const Allow: (args: {
|
|
|
34
34
|
* @since 0.3.0
|
|
35
35
|
*/
|
|
36
36
|
export declare const Deny: (args: {
|
|
37
|
-
readonly rule?:
|
|
37
|
+
readonly rule?: AnyRule;
|
|
38
38
|
readonly reason?: string;
|
|
39
39
|
}) => Decision;
|
|
40
40
|
/**
|
|
@@ -77,10 +77,10 @@ export declare const isNotApplicable: (decision: Decision) => decision is Extrac
|
|
|
77
77
|
export declare const match: {
|
|
78
78
|
<Cases extends { readonly [Tag in "Allow" | "Deny" | "NotApplicable"]: (args: Extract<{
|
|
79
79
|
readonly _tag: "Allow";
|
|
80
|
-
readonly rule?:
|
|
80
|
+
readonly rule?: AnyRule;
|
|
81
81
|
} | {
|
|
82
82
|
readonly _tag: "Deny";
|
|
83
|
-
readonly rule?:
|
|
83
|
+
readonly rule?: AnyRule;
|
|
84
84
|
readonly reason?: string;
|
|
85
85
|
} | {
|
|
86
86
|
readonly _tag: "NotApplicable";
|
|
@@ -88,20 +88,20 @@ export declare const match: {
|
|
|
88
88
|
readonly _tag: Tag;
|
|
89
89
|
}>) => any; }>(cases: Cases): (value: {
|
|
90
90
|
readonly _tag: "Allow";
|
|
91
|
-
readonly rule?:
|
|
91
|
+
readonly rule?: AnyRule;
|
|
92
92
|
} | {
|
|
93
93
|
readonly _tag: "Deny";
|
|
94
|
-
readonly rule?:
|
|
94
|
+
readonly rule?: AnyRule;
|
|
95
95
|
readonly reason?: string;
|
|
96
96
|
} | {
|
|
97
97
|
readonly _tag: "NotApplicable";
|
|
98
98
|
}) => import("effect/Unify").Unify<ReturnType<Cases["Allow" | "Deny" | "NotApplicable"]>>;
|
|
99
99
|
<Cases extends { readonly [Tag in "Allow" | "Deny" | "NotApplicable"]: (args: Extract<{
|
|
100
100
|
readonly _tag: "Allow";
|
|
101
|
-
readonly rule?:
|
|
101
|
+
readonly rule?: AnyRule;
|
|
102
102
|
} | {
|
|
103
103
|
readonly _tag: "Deny";
|
|
104
|
-
readonly rule?:
|
|
104
|
+
readonly rule?: AnyRule;
|
|
105
105
|
readonly reason?: string;
|
|
106
106
|
} | {
|
|
107
107
|
readonly _tag: "NotApplicable";
|
|
@@ -109,10 +109,10 @@ export declare const match: {
|
|
|
109
109
|
readonly _tag: Tag;
|
|
110
110
|
}>) => any; }>(value: {
|
|
111
111
|
readonly _tag: "Allow";
|
|
112
|
-
readonly rule?:
|
|
112
|
+
readonly rule?: AnyRule;
|
|
113
113
|
} | {
|
|
114
114
|
readonly _tag: "Deny";
|
|
115
|
-
readonly rule?:
|
|
115
|
+
readonly rule?: AnyRule;
|
|
116
116
|
readonly reason?: string;
|
|
117
117
|
} | {
|
|
118
118
|
readonly _tag: "NotApplicable";
|
package/dist/Decision.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Decision.d.ts","names":["
|
|
1
|
+
{"version":3,"file":"Decision.d.ts","names":["Policy.AnyRule"],"sources":["../src/Decision.ts"],"mappings":";;;;;;;;;;YAqBY,WAAW,KAAK;EAC3B;;aAEU,OAAOA;;EAEjB;;aAEU,OAAOA;aACP;;EAEV;;;;;;;qBAgBY,QAAQ;WAAiB,OAAOA;MAAqB;;;;;;qBAQrD,OAAO;WACV,OAAOA;WACP;MACJ;;;;;;qBAOO,eAAe;;;;;;qBAOf,UACZ,UAAU,aACN,YAAY,QAAQ;WAAqB;;;;;;;qBAOjC,SACZ,UAAU,aACN,YAAY,QAAQ;WAAqB;;;;;;;qBAOjC,kBACZ,UAAU,aACN,YAAY,QAAQ;WAAqB;;;;;;;;;qBAUjC;;;aA9EK,OAAAA;;;aAIA,OAAAA;aACE;;;;;;;;;;;;;;;;;aALF,OAAAA;;;aAIA,OAAAA;aACE;;;;;;;;;;;;;;;;;;;;;;;;qBAmFP,SAAM,UAAc"}
|
package/dist/Decision.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Decision.js","names":[],"sources":["../src/Decision.ts"],"sourcesContent":["/**\n * A decision is the answer of a policy to a request:\n * - `Allow`: a rule lets the principal do the act.\n * - `Deny`: a rule stops the principal.\n * - `NotApplicable`: no rule gives an answer.\n *\n * `NotApplicable` is not the same as `Deny`. A check treats it as a \"no\", but\n * an `Authorizer` with a decider asks the decider first. See\n * `Authorizer.Options.decider`.\n *\n * @stability stable\n * @since 0.3.0\n */\nimport * as Data from \"effect/Data\"\nimport type * as
|
|
1
|
+
{"version":3,"file":"Decision.js","names":[],"sources":["../src/Decision.ts"],"sourcesContent":["/**\n * A decision is the answer of a policy to a request:\n * - `Allow`: a rule lets the principal do the act.\n * - `Deny`: a rule stops the principal.\n * - `NotApplicable`: no rule gives an answer.\n *\n * `NotApplicable` is not the same as `Deny`. A check treats it as a \"no\", but\n * an `Authorizer` with a decider asks the decider first. See\n * `Authorizer.Options.decider`.\n *\n * @stability stable\n * @since 0.3.0\n */\nimport * as Data from \"effect/Data\"\nimport type * as Policy from \"./Policy.ts\"\n\n/**\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Decision = Data.TaggedEnum<{\n\tAllow: {\n\t\t/** The rule that gave the answer, when a rule gave it. */\n\t\treadonly rule?: Policy.AnyRule\n\t}\n\tDeny: {\n\t\t/** The rule that gave the answer, when a rule gave it. */\n\t\treadonly rule?: Policy.AnyRule\n\t\treadonly reason?: string\n\t}\n\tNotApplicable: {}\n}>\n\nconst {\n\t$is,\n\t$match,\n\tAllow: allow,\n\tDeny: deny,\n\tNotApplicable: notApplicable,\n} = Data.taggedEnum<Decision>()\n\n/**\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const Allow: (args: { readonly rule?: Policy.AnyRule }) => Decision =\n\tallow\n\n/**\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const Deny: (args: {\n\treadonly rule?: Policy.AnyRule\n\treadonly reason?: string\n}) => Decision = deny\n\n/**\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const NotApplicable: Decision = notApplicable()\n\n/**\n * @stability stable\n * @category guards\n * @since 0.3.0\n */\nexport const isAllow: (\n\tdecision: Decision,\n) => decision is Extract<Decision, { readonly _tag: \"Allow\" }> = $is(\"Allow\")\n\n/**\n * @stability stable\n * @category guards\n * @since 0.3.0\n */\nexport const isDeny: (\n\tdecision: Decision,\n) => decision is Extract<Decision, { readonly _tag: \"Deny\" }> = $is(\"Deny\")\n\n/**\n * @stability stable\n * @category guards\n * @since 0.3.0\n */\nexport const isNotApplicable: (\n\tdecision: Decision,\n) => decision is Extract<Decision, { readonly _tag: \"NotApplicable\" }> =\n\t$is(\"NotApplicable\")\n\n/**\n * Matches each kind of decision.\n *\n * @stability stable\n * @category pattern matching\n * @since 0.3.0\n */\nexport const match = $match\n\n/**\n * The reason of a decision: the reason of a `Deny`, or the reason of the rule\n * that gave the answer.\n *\n * @stability stable\n * @category getters\n * @since 0.3.0\n */\nexport const reason = (decision: Decision): string | undefined =>\n\tdecision._tag === \"Deny\"\n\t\t? (decision.reason ?? decision.rule?.reason)\n\t\t: decision._tag === \"Allow\"\n\t\t\t? decision.rule?.reason\n\t\t\t: undefined\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,MAAM,EACL,KACA,QACA,OAAO,OACP,MAAM,MACN,eAAe,kBACZ,KAAK,WAAqB;;;;;;AAO9B,MAAa,QACZ;;;;;;AAOD,MAAa,OAGI;;;;;;AAOjB,MAAa,gBAA0B,cAAc;;;;;;AAOrD,MAAa,UAEoD,IAAI,OAAO;;;;;;AAO5E,MAAa,SAEmD,IAAI,MAAM;;;;;;AAO1E,MAAa,kBAGZ,IAAI,eAAe;;;;;;;;AASpB,MAAa,QAAQ;;;;;;;;;AAUrB,MAAa,UAAU,aACtB,SAAS,SAAS,SACd,SAAS,UAAU,SAAS,MAAM,SACnC,SAAS,SAAS,UACjB,SAAS,MAAM,SACf,KAAA"}
|
package/dist/Domain.d.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
+
import { Catalog } from "./internal/catalog.js";
|
|
1
2
|
import { Action, Any as Any$1, Data, Descriptor, Kind as Kind$1, Resource, Value } from "./Resource.js";
|
|
2
|
-
import { Any as Any$2 } from "./Principal.js";
|
|
3
3
|
import * as Schema from "effect/Schema";
|
|
4
4
|
import * as HashMap from "effect/HashMap";
|
|
5
5
|
declare namespace Domain_d_exports {
|
|
6
|
-
export { ActionOf, Any, AnyAction, AnyValue, CommonAction, DataOf, Domain, Kind, Meta, Principal, ResourceOf, Resources, ValueOf,
|
|
6
|
+
export { ActionOf, Any, AnyAction, AnyValue, CommonAction, DataOf, Domain, Kind, Meta, Principal, ResourceOf, Resources, ValueOf, make };
|
|
7
7
|
}
|
|
8
|
+
/** The Schema of a principal: a Schema of objects, such as a `Schema.Class`. */
|
|
9
|
+
type PrincipalSchema = Schema.Top & {
|
|
10
|
+
readonly Type: object;
|
|
11
|
+
};
|
|
8
12
|
/**
|
|
9
13
|
* A domain. `P` is the type of the principal, `Resources` is the union of the
|
|
10
14
|
* resources, and `Meta` is the type of the extra data that a rule may keep.
|
|
@@ -14,7 +18,9 @@ declare namespace Domain_d_exports {
|
|
|
14
18
|
* @since 0.3.0
|
|
15
19
|
*/
|
|
16
20
|
export interface Domain<P extends object, Resources extends Any$1, Meta> {
|
|
17
|
-
readonly principal:
|
|
21
|
+
readonly principal: PrincipalSchema;
|
|
22
|
+
/** The catalog of the data fields of the principal. */
|
|
23
|
+
readonly principalCatalog: Catalog;
|
|
18
24
|
/** The descriptor of each resource, by its kind name. */
|
|
19
25
|
readonly resources: HashMap.HashMap<string, Descriptor>;
|
|
20
26
|
readonly meta: Schema.Top | undefined;
|
|
@@ -132,27 +138,10 @@ export type AnyValue<D> = Value<Resources<D>>;
|
|
|
132
138
|
* @category constructors
|
|
133
139
|
* @since 0.3.0
|
|
134
140
|
*/
|
|
135
|
-
export declare const make: <P extends
|
|
141
|
+
export declare const make: <P extends PrincipalSchema, const Resources extends ReadonlyArray<Any$1>, M extends Schema.Codec<any, any, never, never> = Schema.Never>(options: {
|
|
136
142
|
readonly principal: P;
|
|
137
143
|
readonly resources: Resources;
|
|
138
144
|
readonly meta?: M;
|
|
139
145
|
}) => Domain<P["Type"], Resources[number], M["Type"]>;
|
|
140
|
-
/**
|
|
141
|
-
* Gives the descriptor of the resource with a kind name, or `undefined` when
|
|
142
|
-
* the domain has no such resource.
|
|
143
|
-
*
|
|
144
|
-
* @stability stable
|
|
145
|
-
* @category getters
|
|
146
|
-
* @since 1.0.0
|
|
147
|
-
*/
|
|
148
|
-
export declare const descriptorOf: (domain: Any, kind: string) => Descriptor | undefined;
|
|
149
|
-
/**
|
|
150
|
-
* Tests if a value is a domain.
|
|
151
|
-
*
|
|
152
|
-
* @stability stable
|
|
153
|
-
* @category guards
|
|
154
|
-
* @since 0.3.0
|
|
155
|
-
*/
|
|
156
|
-
export declare const isDomain: (u: unknown) => u is Any;
|
|
157
146
|
export { Domain_d_exports };
|
|
158
147
|
//# sourceMappingURL=Domain.d.ts.map
|
package/dist/Domain.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Domain.d.ts","names":["Resource.Any","
|
|
1
|
+
{"version":3,"file":"Domain.d.ts","names":["Resource.Any","Catalog.Catalog","Resource.Descriptor","Resource.Kind","Resource.Resource","Resource.Action","Resource.Data","Resource.Value"],"sources":["../src/Domain.ts"],"mappings":";;;;;;;;KAuBK,kBAAkB,OAAO;WAAiB;;;;;;;;;;iBAU9B,OAChB,kBACA,kBAAkBA,OAClB;WAES,WAAW;;WAEX,kBAAkBC;;WAElB,WAAW,QAAQ,gBAAgBC;WACnC,MAAM,OAAO;WACb;aACC,WAAW;aACX,WAAW;aACX,MAAM;;;;;;;;;;YAWL,MAAM;;;;;;;;YASN,UAAU,KAAK,UAAU,aAAa,eAAe;;;;;;;;YASrD,UAAU,KAAK,UAAU,kBAAkB,UAAU;;;;;;;;YASrD,KAAK,KAAK,UAAU,uBAAuB,KAAK;;;;;;;;YAShD,KAAK,KAAKC,OAAc,UAAU;;;;;;;;YASlC,WAAW,GAAG,oBACzB,UAAU,kBAAiB,KACxB,UAAUC,SAAkB,oBAC3B;;;;;;;;YAWO,SAAS,GAAG,oBAAoBC,OAAgB,WAAW,GAAG;;;;;;;;;;YAW9D,aAAa,GAAG,qBAC3B,qBAAqB,QAAQ,SAAS,GAAG,+BAC/B,cAAc,cACtB;;;;;;;;YAUS,UAAU,KAAKA,OAAgB,UAAU;;;;;;;;YASzC,OAAO,GAAG,oBAAoBC,KAAc,WAAW,GAAG;;;;;;;;YAS1D,QAAQ,GAAG,oBAAoBC,MAAe,WAAW,GAAG;;;;;;;;YAS5D,SAAS,KAAKA,MAAe,UAAU;;;;;;;;;;;qBAYtC,OACZ,UAAU,uBACJ,kBAAkB,cAAcP,QACtC,UAAU,OAAO,gCAAgC,OAAO,OACvD;WACQ,WAAW;WACX,WAAW;WACX,OAAO;MACX,OAAO,WAAW,mBAAmB"}
|