@nmnmcc/ability 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +322 -469
  2. package/dist/Authorizer.d.ts +216 -0
  3. package/dist/Authorizer.d.ts.map +1 -0
  4. package/dist/Authorizer.js +55 -0
  5. package/dist/Authorizer.js.map +1 -0
  6. package/dist/Condition.d.ts +536 -0
  7. package/dist/Condition.d.ts.map +1 -0
  8. package/dist/Condition.js +141 -0
  9. package/dist/Condition.js.map +1 -0
  10. package/dist/Decision.d.ts +131 -0
  11. package/dist/Decision.d.ts.map +1 -0
  12. package/dist/Decision.js +83 -0
  13. package/dist/Decision.js.map +1 -0
  14. package/dist/Domain.d.ts +148 -0
  15. package/dist/Domain.d.ts.map +1 -0
  16. package/dist/Domain.js +34 -0
  17. package/dist/Domain.js.map +1 -0
  18. package/dist/HttpApi.d.ts +129 -0
  19. package/dist/HttpApi.d.ts.map +1 -0
  20. package/dist/HttpApi.js +95 -0
  21. package/dist/HttpApi.js.map +1 -0
  22. package/dist/Policy.d.ts +429 -0
  23. package/dist/Policy.d.ts.map +1 -0
  24. package/dist/Policy.js +162 -0
  25. package/dist/Policy.js.map +1 -0
  26. package/dist/Principal.d.ts +35 -0
  27. package/dist/Principal.d.ts.map +1 -0
  28. package/dist/Principal.js +37 -0
  29. package/dist/Principal.js.map +1 -0
  30. package/dist/Resource.d.ts +213 -0
  31. package/dist/Resource.d.ts.map +1 -0
  32. package/dist/Resource.js +71 -0
  33. package/dist/Resource.js.map +1 -0
  34. package/dist/Rule.d.ts +189 -0
  35. package/dist/Rule.d.ts.map +1 -0
  36. package/dist/Rule.js +50 -0
  37. package/dist/Rule.js.map +1 -0
  38. package/dist/_virtual/_rolldown/runtime.js +1 -2
  39. package/dist/index.d.ts +9 -3
  40. package/dist/index.js +9 -3
  41. package/dist/internal/authorizer.d.ts +28 -0
  42. package/dist/internal/authorizer.d.ts.map +1 -0
  43. package/dist/internal/authorizer.js +153 -0
  44. package/dist/internal/authorizer.js.map +1 -0
  45. package/dist/internal/condition.d.ts +11 -0
  46. package/dist/internal/condition.d.ts.map +1 -0
  47. package/dist/internal/condition.js +393 -0
  48. package/dist/internal/condition.js.map +1 -0
  49. package/dist/internal/domain.js +34 -0
  50. package/dist/internal/domain.js.map +1 -0
  51. package/dist/internal/httpApi.js +41 -0
  52. package/dist/internal/httpApi.js.map +1 -0
  53. package/dist/internal/policy.js +524 -0
  54. package/dist/internal/policy.js.map +1 -0
  55. package/dist/internal/resource.js +66 -0
  56. package/dist/internal/resource.js.map +1 -0
  57. package/dist/internal/rule.js +131 -0
  58. package/dist/internal/rule.js.map +1 -0
  59. package/package.json +61 -72
  60. package/src/Authorizer.ts +330 -0
  61. package/src/Condition.ts +706 -0
  62. package/src/Decision.ts +117 -0
  63. package/src/Domain.ts +189 -0
  64. package/src/HttpApi.ts +148 -0
  65. package/src/Policy.ts +575 -0
  66. package/src/Principal.ts +41 -0
  67. package/src/Resource.ts +290 -0
  68. package/src/Rule.ts +265 -0
  69. package/src/index.ts +57 -0
  70. package/src/internal/authorizer.ts +271 -0
  71. package/src/internal/condition.ts +607 -0
  72. package/src/internal/domain.ts +56 -0
  73. package/src/internal/httpApi.ts +84 -0
  74. package/src/internal/policy.ts +815 -0
  75. package/src/internal/resource.ts +98 -0
  76. package/src/internal/rule.ts +203 -0
  77. package/dist/Ability.d.ts +0 -491
  78. package/dist/Ability.js +0 -207
  79. package/dist/AbilityExtra.d.ts +0 -79
  80. package/dist/AbilityExtra.js +0 -187
  81. package/dist/internal/ability.d.ts +0 -90
  82. package/dist/internal/ability.js +0 -550
  83. package/dist/internal/serializable.js +0 -22
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Condition.js","names":["internal.builder","internal.always","internal.never","internal.and","internal.or","internal.not","internal.evaluate","internal.evaluateSync","internal.partial","internal.simplify","internal.Untranslatable","internal.fold","internal.fields","internal.schema"],"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 */\nimport type * as Effect from \"effect/Effect\"\nimport type * as Schema from \"effect/Schema\"\nimport * as internal from \"./internal/condition.ts\"\nimport type * 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.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Ref<A> = PrincipalRef & { readonly \"~Ref\"?: () => A }\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\treadonly run: (\n\t\tvalue: any,\n\t\tprincipal: any,\n\t) => 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 * 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.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Condition<E = never, R = never, O = never> = Ast & {\n\treadonly \"~Condition\"?: Variance<E, R, O>\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, 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 * {@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\ntype PreviousDepth = [never, 0, 1, 2, 3]\ntype FieldPathInternal<T, Depth extends number> = [Depth] extends [never]\n\t? never\n\t: {\n\t\t\t[K in keyof T & string]-?: NonNullable<T[K]> extends Leaf\n\t\t\t\t? K\n\t\t\t\t: NonNullable<T[K]> extends ReadonlyArray<unknown> | Function\n\t\t\t\t\t? never\n\t\t\t\t\t: NonNullable<T[K]> extends object\n\t\t\t\t\t\t? `${K}.${FieldPathInternal<NonNullable<T[K]>, PreviousDepth[Depth]>}`\n\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. 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>\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> = Extract<A, Scalar> | Ref<A>\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 * 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: <const F extends FieldPath<Data>>(\n\t\tfield: F,\n\t\tvalue: OperandOf<PathValue<Data, F>>,\n\t) => Condition\n\t/** The field is not equal to the value. */\n\treadonly ne: <const F extends FieldPath<Data>>(\n\t\tfield: F,\n\t\tvalue: OperandOf<PathValue<Data, F>>,\n\t) => Condition\n\treadonly lt: <const F extends OrderedPath<Data>>(\n\t\tfield: F,\n\t\tvalue: OperandOf<Exclude<PathValue<Data, F>, null>>,\n\t) => Condition\n\treadonly lte: <const F extends OrderedPath<Data>>(\n\t\tfield: F,\n\t\tvalue: OperandOf<Exclude<PathValue<Data, F>, null>>,\n\t) => Condition\n\treadonly gt: <const F extends OrderedPath<Data>>(\n\t\tfield: F,\n\t\tvalue: OperandOf<Exclude<PathValue<Data, F>, null>>,\n\t) => Condition\n\treadonly gte: <const F extends OrderedPath<Data>>(\n\t\tfield: F,\n\t\tvalue: OperandOf<Exclude<PathValue<Data, F>, null>>,\n\t) => Condition\n\t/** The field is equal to one of the values. */\n\treadonly in: <const F extends FieldPath<Data>>(\n\t\tfield: F,\n\t\tvalues: ReadonlyArray<OperandOf<PathValue<Data, F>>>,\n\t) => Condition\n\t/** The field has a value that is not `null`. */\n\treadonly exists: <const F extends FieldPath<Data>>(field: F) => Condition\n\t/** The path of the resource starts with these parts. */\n\treadonly under: (\n\t\t...prefix: ReadonlyArray<string | null | Ref<string | null>>\n\t) => Condition\n\t/** A field of the principal, to use as a value. */\n\treadonly principal: <const F extends FieldPath<P>>(\n\t\tfield: F,\n\t) => Ref<PathValue<P, F>>\n\treadonly and: <const Cs extends ReadonlyArray<Any>>(\n\t\t...conditions: Cs\n\t) => Condition<Error<Cs[number]>, Services<Cs[number]>, OpaqueOf<Cs[number]>>\n\treadonly or: <const Cs extends ReadonlyArray<Any>>(\n\t\t...conditions: Cs\n\t) => Condition<Error<Cs[number]>, Services<Cs[number]>, OpaqueOf<Cs[number]>>\n\treadonly not: <C extends Any>(\n\t\tcondition: C,\n\t) => Condition<Error<C>, Services<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<E, R, Opaque>\n}\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\tinternal.builder\n\n/**\n * Always true.\n *\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const always: Condition = internal.always\n\n/**\n * Always false.\n *\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const never: Condition = internal.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<Error<Cs[number]>, Services<Cs[number]>, OpaqueOf<Cs[number]>> =\n\tinternal.and 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<Error<Cs[number]>, Services<Cs[number]>, OpaqueOf<Cs[number]>> =\n\tinternal.or 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<Error<C>, Services<C>, OpaqueOf<C>> = internal.not 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 * Tests a condition on a value. A predicate may fail with its error.\n *\n * @stability stable\n * @category evaluation\n * @since 0.3.0\n */\nexport const evaluate: {\n\t(\n\t\tinput: Input,\n\t): <E, R, O>(condition: Condition<E, R, O>) => Effect.Effect<boolean, E, R>\n\t<E, R, O>(\n\t\tcondition: Condition<E, R, O>,\n\t\tinput: Input,\n\t): Effect.Effect<boolean, E, R>\n} = internal.evaluate 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(input: Input): (condition: Condition) => boolean\n\t(condition: Condition, input: Input): boolean\n} = internal.evaluateSync\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(input: {\n\t\treadonly principal?: object | undefined\n\t\treadonly path?: ReadonlyArray<Resource.PathSegment> | undefined\n\t}): <E, R, O>(condition: Condition<E, R, O>) => Condition<E, R, O>\n\t<E, R, O>(\n\t\tcondition: Condition<E, R, O>,\n\t\tinput: {\n\t\t\treadonly principal?: object | undefined\n\t\t\treadonly path?: ReadonlyArray<Resource.PathSegment> | undefined\n\t\t},\n\t): Condition<E, R, O>\n} = internal.partial as never\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>(\n\tcondition: Condition<E, R, O>,\n) => Condition<E, R, O> = internal.simplify 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 const Untranslatable: typeof internal.Untranslatable =\n\tinternal.Untranslatable\n\n/**\n * @stability stable\n * @category errors\n * @since 0.3.0\n */\nexport type Untranslatable = internal.Untranslatable\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} = internal.fold\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: Any) => ReadonlyArray<string> = internal.fields\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\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<Condition, Encoded> = internal.schema\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAocA,MAAa,UACZA;;;;;;;;AASD,MAAa,SAAoBC;;;;;;;;AASjC,MAAa,QAAmBC;;;;;;;;AAShC,MAAa,MAGZC;;;;;;;;AASD,MAAa,KAGZC;;;;;;AAOD,MAAa,MAEwCC;;;;;;;;AA4BrD,MAAa,WAQTC;;;;;;;;AASJ,MAAa,eAGTC;;;;;;;;;;;AAYJ,MAAa,UAYTC;;;;;;;;;;AAWJ,MAAa,WAEaC;;;;;;;;AA8B1B,MAAa,iBACZC;;;;;;;;;;AAkBD,MAAa,OAQTC;;;;;;;;AASJ,MAAa,SAAoDC;;;;;;;;;AAkDjE,MAAa,SAA2CC"}
@@ -0,0 +1,131 @@
1
+ import { Any } from "./Rule.js";
2
+ import * as Data from "effect/Data";
3
+ declare namespace Decision_d_exports {
4
+ export { Allow, Decision, Deny, NotApplicable, isAllow, isDeny, isNotApplicable, match, reason };
5
+ }
6
+ /**
7
+ * @stability stable
8
+ * @category models
9
+ * @since 0.3.0
10
+ */
11
+ export type Decision = Data.TaggedEnum<{
12
+ Allow: {
13
+ /** The rule that gave the answer, when a rule gave it. */
14
+ readonly rule?: Any;
15
+ };
16
+ Deny: {
17
+ /** The rule that gave the answer, when a rule gave it. */
18
+ readonly rule?: Any;
19
+ readonly reason?: string;
20
+ };
21
+ NotApplicable: {};
22
+ }>;
23
+ /**
24
+ * @stability stable
25
+ * @category constructors
26
+ * @since 0.3.0
27
+ */
28
+ export declare const Allow: (args: {
29
+ readonly rule?: Any;
30
+ }) => Decision;
31
+ /**
32
+ * @stability stable
33
+ * @category constructors
34
+ * @since 0.3.0
35
+ */
36
+ export declare const Deny: (args: {
37
+ readonly rule?: Any;
38
+ readonly reason?: string;
39
+ }) => Decision;
40
+ /**
41
+ * @stability stable
42
+ * @category constructors
43
+ * @since 0.3.0
44
+ */
45
+ export declare const NotApplicable: Decision;
46
+ /**
47
+ * @stability stable
48
+ * @category guards
49
+ * @since 0.3.0
50
+ */
51
+ export declare const isAllow: (decision: Decision) => decision is Extract<Decision, {
52
+ readonly _tag: "Allow";
53
+ }>;
54
+ /**
55
+ * @stability stable
56
+ * @category guards
57
+ * @since 0.3.0
58
+ */
59
+ export declare const isDeny: (decision: Decision) => decision is Extract<Decision, {
60
+ readonly _tag: "Deny";
61
+ }>;
62
+ /**
63
+ * @stability stable
64
+ * @category guards
65
+ * @since 0.3.0
66
+ */
67
+ export declare const isNotApplicable: (decision: Decision) => decision is Extract<Decision, {
68
+ readonly _tag: "NotApplicable";
69
+ }>;
70
+ /**
71
+ * Matches each kind of decision.
72
+ *
73
+ * @stability stable
74
+ * @category pattern matching
75
+ * @since 0.3.0
76
+ */
77
+ export declare const match: {
78
+ <Cases extends { readonly [Tag in "Allow" | "Deny" | "NotApplicable"]: (args: Extract<{
79
+ readonly _tag: "Allow";
80
+ readonly rule?: Any;
81
+ } | {
82
+ readonly _tag: "Deny";
83
+ readonly rule?: Any;
84
+ readonly reason?: string;
85
+ } | {
86
+ readonly _tag: "NotApplicable";
87
+ }, {
88
+ readonly _tag: Tag;
89
+ }>) => any; }>(cases: Cases): (value: {
90
+ readonly _tag: "Allow";
91
+ readonly rule?: Any;
92
+ } | {
93
+ readonly _tag: "Deny";
94
+ readonly rule?: Any;
95
+ readonly reason?: string;
96
+ } | {
97
+ readonly _tag: "NotApplicable";
98
+ }) => import("effect/Unify").Unify<ReturnType<Cases["Allow" | "Deny" | "NotApplicable"]>>;
99
+ <Cases extends { readonly [Tag in "Allow" | "Deny" | "NotApplicable"]: (args: Extract<{
100
+ readonly _tag: "Allow";
101
+ readonly rule?: Any;
102
+ } | {
103
+ readonly _tag: "Deny";
104
+ readonly rule?: Any;
105
+ readonly reason?: string;
106
+ } | {
107
+ readonly _tag: "NotApplicable";
108
+ }, {
109
+ readonly _tag: Tag;
110
+ }>) => any; }>(value: {
111
+ readonly _tag: "Allow";
112
+ readonly rule?: Any;
113
+ } | {
114
+ readonly _tag: "Deny";
115
+ readonly rule?: Any;
116
+ readonly reason?: string;
117
+ } | {
118
+ readonly _tag: "NotApplicable";
119
+ }, cases: Cases): import("effect/Unify").Unify<ReturnType<Cases["Allow" | "Deny" | "NotApplicable"]>>;
120
+ };
121
+ /**
122
+ * The reason of a decision: the reason of a `Deny`, or the reason of the rule
123
+ * that gave the answer.
124
+ *
125
+ * @stability stable
126
+ * @category getters
127
+ * @since 0.3.0
128
+ */
129
+ export declare const reason: (decision: Decision) => string | undefined;
130
+ export { Decision_d_exports };
131
+ //# sourceMappingURL=Decision.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Decision.d.ts","names":["Rule.Any"],"sources":["../src/Decision.ts"],"mappings":";;;;;;;;;;YAqBY,WAAW,KAAK;EAC3B;;aAEU,OAAOA;;EAEjB;;aAEU,OAAOA;aACP;;EAEV;;;;;;;qBAgBY,QAAQ;WAAiB,OAAOA;MAAe;;;;;;qBAO/C,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;;;aA7EK,OAAAA;;;aAIA,OAAAA;aACE;;;;;;;;;;;;;;;;;aALF,OAAAA;;;aAIA,OAAAA;aACE;;;;;;;;;;;;;;;;;;;;;;;;qBAkFP,SAAM,UAAc"}
@@ -0,0 +1,83 @@
1
+ import { __exportAll } from "./_virtual/_rolldown/runtime.js";
2
+ import * as Data from "effect/Data";
3
+ // src/Decision.ts
4
+ /**
5
+ * A decision is the answer of a policy to a request:
6
+ * - `Allow`: a rule lets the principal do the act.
7
+ * - `Deny`: a rule stops the principal.
8
+ * - `NotApplicable`: no rule gives an answer.
9
+ *
10
+ * `NotApplicable` is not the same as `Deny`. A check treats it as a "no", but
11
+ * an `Authorizer` with a decider asks the decider first. See
12
+ * `Authorizer.Options.decider`.
13
+ *
14
+ * @stability stable
15
+ * @since 0.3.0
16
+ */
17
+ var Decision_exports = /* @__PURE__ */ __exportAll({
18
+ Allow: () => Allow,
19
+ Deny: () => Deny,
20
+ NotApplicable: () => NotApplicable,
21
+ isAllow: () => isAllow,
22
+ isDeny: () => isDeny,
23
+ isNotApplicable: () => isNotApplicable,
24
+ match: () => match,
25
+ reason: () => reason
26
+ });
27
+ const { $is, $match, Allow: allow, Deny: deny, NotApplicable: notApplicable } = Data.taggedEnum();
28
+ /**
29
+ * @stability stable
30
+ * @category constructors
31
+ * @since 0.3.0
32
+ */
33
+ const Allow = allow;
34
+ /**
35
+ * @stability stable
36
+ * @category constructors
37
+ * @since 0.3.0
38
+ */
39
+ const Deny = deny;
40
+ /**
41
+ * @stability stable
42
+ * @category constructors
43
+ * @since 0.3.0
44
+ */
45
+ const NotApplicable = notApplicable();
46
+ /**
47
+ * @stability stable
48
+ * @category guards
49
+ * @since 0.3.0
50
+ */
51
+ const isAllow = $is("Allow");
52
+ /**
53
+ * @stability stable
54
+ * @category guards
55
+ * @since 0.3.0
56
+ */
57
+ const isDeny = $is("Deny");
58
+ /**
59
+ * @stability stable
60
+ * @category guards
61
+ * @since 0.3.0
62
+ */
63
+ const isNotApplicable = $is("NotApplicable");
64
+ /**
65
+ * Matches each kind of decision.
66
+ *
67
+ * @stability stable
68
+ * @category pattern matching
69
+ * @since 0.3.0
70
+ */
71
+ const match = $match;
72
+ /**
73
+ * The reason of a decision: the reason of a `Deny`, or the reason of the rule
74
+ * that gave the answer.
75
+ *
76
+ * @stability stable
77
+ * @category getters
78
+ * @since 0.3.0
79
+ */
80
+ const reason = (decision) => decision._tag === "Deny" ? decision.reason ?? decision.rule?.reason : decision._tag === "Allow" ? decision.rule?.reason : void 0;
81
+ export { Allow, Decision_exports, Deny, NotApplicable, isAllow, isDeny, isNotApplicable, match, reason };
82
+
83
+ //# sourceMappingURL=Decision.js.map
@@ -0,0 +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 Rule from \"./Rule.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?: Rule.Any\n\t}\n\tDeny: {\n\t\t/** The rule that gave the answer, when a rule gave it. */\n\t\treadonly rule?: Rule.Any\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?: Rule.Any }) => Decision = allow\n\n/**\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const Deny: (args: {\n\treadonly rule?: Rule.Any\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,QAA0D;;;;;;AAOvE,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"}
@@ -0,0 +1,148 @@
1
+ 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
+ import * as Schema from "effect/Schema";
4
+ declare namespace Domain_d_exports {
5
+ export { ActionOf, Any, AnyAction, AnyValue, DataOf, Domain, Kind, Meta, Principal, ResourceOf, Resources, TypeId, ValueOf, isDomain, make };
6
+ }
7
+ /**
8
+ * @stability stable
9
+ * @category type IDs
10
+ * @since 0.3.0
11
+ */
12
+ export declare const TypeId: "~@nmnmcc/ability/Domain";
13
+ /**
14
+ * @stability stable
15
+ * @category type IDs
16
+ * @since 0.3.0
17
+ */
18
+ export type TypeId = typeof TypeId;
19
+ /**
20
+ * A domain. `P` is the type of the principal, `Resources` is the union of the
21
+ * resources, and `Meta` is the type of the extra data that a rule may keep.
22
+ *
23
+ * @stability stable
24
+ * @category models
25
+ * @since 0.3.0
26
+ */
27
+ export interface Domain<P extends object, Resources extends Any$1, Meta> {
28
+ readonly [TypeId]: TypeId;
29
+ readonly principal: Any$2;
30
+ readonly resources: ReadonlyMap<string, Descriptor>;
31
+ readonly meta: Schema.Top | undefined;
32
+ readonly "~Domain"?: {
33
+ readonly Principal: P;
34
+ readonly Resources: Resources;
35
+ readonly Meta: Meta;
36
+ };
37
+ }
38
+ /**
39
+ * Any domain.
40
+ *
41
+ * @stability stable
42
+ * @category models
43
+ * @since 0.3.0
44
+ */
45
+ export type Any = Domain<any, any, any>;
46
+ /**
47
+ * The type of the principal of a domain.
48
+ *
49
+ * @stability stable
50
+ * @category utility types
51
+ * @since 0.3.0
52
+ */
53
+ export type Principal<D> = D extends Domain<infer P, any, any> ? P : never;
54
+ /**
55
+ * The union of the resources of a domain.
56
+ *
57
+ * @stability stable
58
+ * @category utility types
59
+ * @since 0.3.0
60
+ */
61
+ export type Resources<D> = D extends Domain<any, infer R, any> ? R : never;
62
+ /**
63
+ * The type of the extra data that a rule of the domain may keep.
64
+ *
65
+ * @stability stable
66
+ * @category utility types
67
+ * @since 0.3.0
68
+ */
69
+ export type Meta<D> = D extends Domain<any, any, infer M> ? M : never;
70
+ /**
71
+ * The kind names of a domain.
72
+ *
73
+ * @stability stable
74
+ * @category utility types
75
+ * @since 0.3.0
76
+ */
77
+ export type Kind<D> = Kind$1<Resources<D>>;
78
+ /**
79
+ * The resource of a domain with the kind `K`.
80
+ *
81
+ * @stability stable
82
+ * @category utility types
83
+ * @since 0.3.0
84
+ */
85
+ export type ResourceOf<D, K extends string> = Resources<D> extends (infer R) ? R extends Resource<K, any, any, any> ? R : never : never;
86
+ /**
87
+ * The actions of the resource with the kind `K`.
88
+ *
89
+ * @stability stable
90
+ * @category utility types
91
+ * @since 0.3.0
92
+ */
93
+ export type ActionOf<D, K extends string> = Action<ResourceOf<D, K>>;
94
+ /**
95
+ * All the actions of all the resources of a domain.
96
+ *
97
+ * @stability stable
98
+ * @category utility types
99
+ * @since 0.3.0
100
+ */
101
+ export type AnyAction<D> = Action<Resources<D>>;
102
+ /**
103
+ * The data type of the resource with the kind `K`.
104
+ *
105
+ * @stability stable
106
+ * @category utility types
107
+ * @since 0.3.0
108
+ */
109
+ export type DataOf<D, K extends string> = Data<ResourceOf<D, K>>;
110
+ /**
111
+ * The value type of the resource with the kind `K`.
112
+ *
113
+ * @stability stable
114
+ * @category utility types
115
+ * @since 0.3.0
116
+ */
117
+ export type ValueOf<D, K extends string> = Value<ResourceOf<D, K>>;
118
+ /**
119
+ * The union of the value types of all the resources of a domain.
120
+ *
121
+ * @stability stable
122
+ * @category utility types
123
+ * @since 0.3.0
124
+ */
125
+ export type AnyValue<D> = Value<Resources<D>>;
126
+ /**
127
+ * Makes a domain. Each resource must have its own kind name. Give `meta` when
128
+ * rules must keep extra data, such as the scope of a grant.
129
+ *
130
+ * @stability stable
131
+ * @category constructors
132
+ * @since 0.3.0
133
+ */
134
+ export declare const make: <P extends Any$2, const Resources extends ReadonlyArray<Any$1>, M extends Schema.Top = Schema.Never>(options: {
135
+ readonly principal: P;
136
+ readonly resources: Resources;
137
+ readonly meta?: M;
138
+ }) => Domain<P["Type"], Resources[number], M["Type"]>;
139
+ /**
140
+ * Tests if a value is a domain.
141
+ *
142
+ * @stability stable
143
+ * @category guards
144
+ * @since 0.3.0
145
+ */
146
+ export declare const isDomain: (u: unknown) => u is Any;
147
+ export { Domain_d_exports };
148
+ //# sourceMappingURL=Domain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Domain.d.ts","names":["Resource.Any","PrincipalSchema.Any","Resource.Descriptor","Resource.Kind","Resource.Resource","Resource.Action","Resource.Data","Resource.Value"],"sources":["../src/Domain.ts"],"mappings":";;;;;;;;;;;qBA0Ba;;;;;;YAOD,gBAAgB;;;;;;;;;iBAUX,OAChB,kBACA,kBAAkBA,OAClB;YAEU,SAAS;WACV,WAAWC;WACX,WAAW,oBAAoBC;WAC/B,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;;;;;;;;YAS9D,UAAU,KAAKA,OAAgB,UAAU;;;;;;;;YASzC,OAAO,GAAG,oBAAoBC,KAAc,WAAW,GAAG;;;;;;;;YAS1D,QAAQ,GAAG,oBAAoBC,MAAe,WAAW,GAAG;;;;;;;;YAS5D,SAAS,KAAKA,MAAe,UAAU;;;;;;;;;qBAUtC,OACZ,UAAUN,aACJ,kBAAkB,cAAcD,QACtC,UAAU,OAAO,MAAM,OAAO,OAC7B;WACQ,WAAW;WACX,WAAW;WACX,OAAO;MACX,OAAO,WAAW,mBAAmB;;;;;;;;qBAS9B,WAAW,eAAe,KAAK"}
package/dist/Domain.js ADDED
@@ -0,0 +1,34 @@
1
+ import { __exportAll } from "./_virtual/_rolldown/runtime.js";
2
+ import { TypeId as TypeId$1, isDomain as isDomain$1, make as make$1 } from "./internal/domain.js";
3
+ // src/Domain.ts
4
+ var Domain_exports = /* @__PURE__ */ __exportAll({
5
+ TypeId: () => TypeId,
6
+ isDomain: () => isDomain,
7
+ make: () => make
8
+ });
9
+ /**
10
+ * @stability stable
11
+ * @category type IDs
12
+ * @since 0.3.0
13
+ */
14
+ const TypeId = TypeId$1;
15
+ /**
16
+ * Makes a domain. Each resource must have its own kind name. Give `meta` when
17
+ * rules must keep extra data, such as the scope of a grant.
18
+ *
19
+ * @stability stable
20
+ * @category constructors
21
+ * @since 0.3.0
22
+ */
23
+ const make = make$1;
24
+ /**
25
+ * Tests if a value is a domain.
26
+ *
27
+ * @stability stable
28
+ * @category guards
29
+ * @since 0.3.0
30
+ */
31
+ const isDomain = isDomain$1;
32
+ export { Domain_exports, TypeId, isDomain, make };
33
+
34
+ //# sourceMappingURL=Domain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Domain.js","names":["internal.TypeId","internal.make","internal.isDomain"],"sources":["../src/Domain.ts"],"sourcesContent":["/**\n * A domain puts together the principal and all the resources of an\n * application. All other modules get their types from the domain. A rule may\n * only use the actions of its resource. A condition may only use the fields of\n * its resource and of the principal.\n *\n * @example\n * ```ts\n * import { Domain } from \"@nmnmcc/ability\"\n *\n * const App = Domain.make({ principal: Caller, resources: [Bot, Trigger] })\n * ```\n *\n * @stability stable\n * @since 0.3.0\n */\nimport type * as Schema from \"effect/Schema\"\nimport * as internal from \"./internal/domain.ts\"\nimport type * as PrincipalSchema from \"./Principal.ts\"\nimport type * as Resource from \"./Resource.ts\"\n\n/**\n * @stability stable\n * @category type IDs\n * @since 0.3.0\n */\nexport const TypeId: \"~@nmnmcc/ability/Domain\" = internal.TypeId\n\n/**\n * @stability stable\n * @category type IDs\n * @since 0.3.0\n */\nexport type TypeId = typeof TypeId\n\n/**\n * A domain. `P` is the type of the principal, `Resources` is the union of the\n * resources, and `Meta` is the type of the extra data that a rule may keep.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport interface Domain<\n\tP extends object,\n\tResources extends Resource.Any,\n\tMeta,\n> {\n\treadonly [TypeId]: TypeId\n\treadonly principal: PrincipalSchema.Any\n\treadonly resources: ReadonlyMap<string, Resource.Descriptor>\n\treadonly meta: Schema.Top | undefined\n\treadonly \"~Domain\"?: {\n\t\treadonly Principal: P\n\t\treadonly Resources: Resources\n\t\treadonly Meta: Meta\n\t}\n}\n\n/**\n * Any domain.\n *\n * @stability stable\n * @category models\n * @since 0.3.0\n */\nexport type Any = Domain<any, any, any>\n\n/**\n * The type of the principal of a domain.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type Principal<D> = D extends Domain<infer P, any, any> ? P : never\n\n/**\n * The union of the resources of a domain.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type Resources<D> = D extends Domain<any, infer R, any> ? R : never\n\n/**\n * The type of the extra data that a rule of the domain may keep.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type Meta<D> = D extends Domain<any, any, infer M> ? M : never\n\n/**\n * The kind names of a domain.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type Kind<D> = Resource.Kind<Resources<D>>\n\n/**\n * The resource of a domain with the kind `K`.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type ResourceOf<D, K extends string> =\n\tResources<D> extends infer R\n\t\t? R extends Resource.Resource<K, any, any, any>\n\t\t\t? R\n\t\t\t: never\n\t\t: never\n\n/**\n * The actions of the resource with the kind `K`.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type ActionOf<D, K extends string> = Resource.Action<ResourceOf<D, K>>\n\n/**\n * All the actions of all the resources of a domain.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type AnyAction<D> = Resource.Action<Resources<D>>\n\n/**\n * The data type of the resource with the kind `K`.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type DataOf<D, K extends string> = Resource.Data<ResourceOf<D, K>>\n\n/**\n * The value type of the resource with the kind `K`.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type ValueOf<D, K extends string> = Resource.Value<ResourceOf<D, K>>\n\n/**\n * The union of the value types of all the resources of a domain.\n *\n * @stability stable\n * @category utility types\n * @since 0.3.0\n */\nexport type AnyValue<D> = Resource.Value<Resources<D>>\n\n/**\n * Makes a domain. Each resource must have its own kind name. Give `meta` when\n * rules must keep extra data, such as the scope of a grant.\n *\n * @stability stable\n * @category constructors\n * @since 0.3.0\n */\nexport const make: <\n\tP extends PrincipalSchema.Any,\n\tconst Resources extends ReadonlyArray<Resource.Any>,\n\tM extends Schema.Top = Schema.Never,\n>(options: {\n\treadonly principal: P\n\treadonly resources: Resources\n\treadonly meta?: M\n}) => Domain<P[\"Type\"], Resources[number], M[\"Type\"]> = internal.make\n\n/**\n * Tests if a value is a domain.\n *\n * @stability stable\n * @category guards\n * @since 0.3.0\n */\nexport const isDomain: (u: unknown) => u is Any = internal.isDomain\n"],"mappings":";;;;;;;;;;;;;AA0BA,MAAa,SAAoCA;;;;;;;;;AAiJjD,MAAa,OAQ2CC;;;;;;;;AASxD,MAAa,WAAqCC"}
@@ -0,0 +1,129 @@
1
+ import { ActionOf, Any, Kind, ValueOf } from "./Domain.js";
2
+ import { Forbidden, Pending, PolicyUnavailable } from "./internal/authorizer.js";
3
+ import { AnyServiceClass } from "./Authorizer.js";
4
+ import * as Context from "effect/Context";
5
+ import * as Effect from "effect/Effect";
6
+ import * as Layer from "effect/Layer";
7
+ /**
8
+ * One check that an endpoint needs: an action on a kind of resource. With
9
+ * `load`, the middleware loads the resource value from the path parameters
10
+ * and checks the action on that value. Without `load`, it checks the action
11
+ * on the kind.
12
+ *
13
+ * @stability unstable
14
+ * @category models
15
+ * @since 0.3.0
16
+ */
17
+ export interface Requirement {
18
+ readonly action: string;
19
+ readonly kind: string;
20
+ readonly load?: (params: Readonly<Record<string, string | undefined>>) => Effect.Effect<object, unknown, unknown>;
21
+ }
22
+ declare const Required_base: Context.ServiceClass<Required, "@nmnmcc/ability/HttpApi/Required", readonly Requirement[]>;
23
+ /**
24
+ * The checks that an endpoint needs.
25
+ *
26
+ * @stability unstable
27
+ * @category annotations
28
+ * @since 0.3.0
29
+ */
30
+ export declare class Required extends Required_base {}
31
+ declare const GroupRequired_base: Context.ServiceClass<GroupRequired, "@nmnmcc/ability/HttpApi/GroupRequired", {
32
+ readonly read: ReadonlyArray<Requirement>;
33
+ readonly write: ReadonlyArray<Requirement>;
34
+ }>;
35
+ /**
36
+ * The checks for every endpoint of a group with no {@link Required}
37
+ * annotation. `read` is for GET requests. `write` is for all other methods.
38
+ *
39
+ * @stability unstable
40
+ * @category annotations
41
+ * @since 0.3.0
42
+ */
43
+ export declare class GroupRequired extends GroupRequired_base {}
44
+ /**
45
+ * Makes a {@link Requirement} with the types of an authorizer. The action must
46
+ * be an action of the kind, and `load` must give a value of the kind.
47
+ *
48
+ * `load` may fail. Its errors must be errors of the middleware, and the
49
+ * services that it needs must be given to {@link layer}.
50
+ *
51
+ * @stability unstable
52
+ * @category constructors
53
+ * @since 0.3.0
54
+ */
55
+ export declare const requires: <A extends {
56
+ readonly domain: Any;
57
+ }, const K extends Kind<A["domain"]>>(authorizer: A, action: ActionOf<A["domain"], K>, kind: K, load?: (params: Readonly<Record<string, string | undefined>>) => Effect.Effect<ValueOf<A["domain"], K>, unknown, unknown>) => Requirement;
58
+ /**
59
+ * The errors of the middleware, with HTTP status codes: 403 for
60
+ * `Forbidden`, 503 for `PolicyUnavailable`, and 409 for `Pending`.
61
+ *
62
+ * @stability unstable
63
+ * @category errors
64
+ * @since 0.3.0
65
+ */
66
+ export declare const errors: readonly [import("effect/Schema").decodeTo<import("effect/Schema").declareConstructor<Forbidden, {
67
+ readonly _tag: "Forbidden";
68
+ readonly action: string;
69
+ readonly kind: string;
70
+ readonly field?: string;
71
+ readonly reason?: string;
72
+ }, readonly [import("effect/Schema").TaggedStruct<"Forbidden", {
73
+ readonly action: import("effect/Schema").String;
74
+ readonly kind: import("effect/Schema").String;
75
+ readonly field: import("effect/Schema").optionalKey<import("effect/Schema").String>;
76
+ readonly reason: import("effect/Schema").optionalKey<import("effect/Schema").String>;
77
+ }>], {
78
+ readonly _tag: "Forbidden";
79
+ readonly action: string;
80
+ readonly kind: string;
81
+ readonly field?: string;
82
+ readonly reason?: string;
83
+ }>, import("effect/Schema").TaggedStruct<"Forbidden", {
84
+ readonly action: import("effect/Schema").String;
85
+ readonly kind: import("effect/Schema").String;
86
+ readonly field: import("effect/Schema").optionalKey<import("effect/Schema").String>;
87
+ readonly reason: import("effect/Schema").optionalKey<import("effect/Schema").String>;
88
+ }>, never, never>, import("effect/Schema").decodeTo<import("effect/Schema").declareConstructor<PolicyUnavailable, {
89
+ readonly _tag: "PolicyUnavailable";
90
+ readonly cause: import("effect/Schema").Json;
91
+ }, readonly [import("effect/Schema").TaggedStruct<"PolicyUnavailable", {
92
+ readonly cause: import("effect/Schema").Defect;
93
+ }>], {
94
+ readonly _tag: "PolicyUnavailable";
95
+ readonly cause: unknown;
96
+ }>, import("effect/Schema").TaggedStruct<"PolicyUnavailable", {
97
+ readonly cause: import("effect/Schema").Defect;
98
+ }>, never, never>, import("effect/Schema").decodeTo<import("effect/Schema").declareConstructor<Pending, {
99
+ readonly _tag: "Pending";
100
+ readonly ticket: string;
101
+ readonly reason?: string;
102
+ }, readonly [import("effect/Schema").TaggedStruct<"Pending", {
103
+ readonly ticket: import("effect/Schema").String;
104
+ readonly reason: import("effect/Schema").optionalKey<import("effect/Schema").String>;
105
+ }>], {
106
+ readonly _tag: "Pending";
107
+ readonly ticket: string;
108
+ readonly reason?: string;
109
+ }>, import("effect/Schema").TaggedStruct<"Pending", {
110
+ readonly ticket: import("effect/Schema").String;
111
+ readonly reason: import("effect/Schema").optionalKey<import("effect/Schema").String>;
112
+ }>, never, never>];
113
+ /**
114
+ * Makes the layer of an authorization middleware. The middleware reads the
115
+ * {@link Required} and {@link GroupRequired} annotations and checks each
116
+ * requirement with the authorizer.
117
+ *
118
+ * The layer takes the authorizer when it is built. The middleware must
119
+ * require the services of the authorizer, such as the identity of the
120
+ * caller. `R` is the type of the services that the `load` functions need. The
121
+ * layer takes them when it is built too.
122
+ *
123
+ * @stability unstable
124
+ * @category layers
125
+ * @since 0.3.0
126
+ */
127
+ export declare const layer: <Self, Id extends string, A extends AnyServiceClass, R = never>(middleware: Context.ServiceClass<Self, Id, any>, authorizer: A) => Layer.Layer<Self, never, (A extends Context.Key<infer I, any> ? I : never) | R>;
128
+ export {};
129
+ //# sourceMappingURL=HttpApi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HttpApi.d.ts","names":["Domain.Any","Domain.Kind","Domain.ActionOf","Domain.ValueOf","_$__internal_authorizer_ts0.Forbidden","_$__internal_authorizer_ts0.PolicyUnavailable","_$__internal_authorizer_ts0.Pending","Authorizer.AnyServiceClass"],"sources":["../src/HttpApi.ts"],"mappings":";;;;;;;;;;;;;;;;iBAgDiB;WACP;WACA;WACA,QACR,QAAQ,SAAS,wCACb,OAAO;;;;;;;;;;qBAUA,iBAAiB;;WAgBb,MAAA,cAAc;WACb,OAAA,cAAc;;;;;;;;;;qBAJnB,sBAAsB;;;;;;;;;;;;qBAmBtB,WACZ;WAAqB,QAAQA;SACvB,UAAUC,KAAY,cAE5B,YAAY,GACZ,QAAQC,SAAgB,aAAa,IACrC,MAAM,GACN,QACC,QAAQ,SAAS,wCACb,OAAO,OAAOC,QAAe,aAAa,0BAC3C;;;;;;;;;qBAUQ,0CAAM,iCAAA,mBAANC;;;;;;;;;;;;;;;;;;;;;;2C,oDAAMC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAoBN,QACZ,MACA,mBACA,UAAUE,iBACV,WAEA,YAAY,QAAQ,aAAa,MAAM,UACvC,YAAY,MACR,MAAM,MACV,cAEC,UAAU,QAAQ,UAAU,UAAU,aAAa"}