@afora/core 0.0.6 → 0.0.8
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 +36 -7
- package/dist/core/application/start.d.ts +7 -0
- package/dist/core/application/types/application.interface.d.ts +47 -2
- package/dist/core/command/command.d.ts +11 -4
- package/dist/core/command/types/command.interface.d.ts +26 -0
- package/dist/core/entity/abstract-entity.d.ts +28 -1
- package/dist/core/entity/entity.d.ts +1 -1
- package/dist/core/entity/event.d.ts +13 -2
- package/dist/core/entity/exceptions.d.ts +8 -0
- package/dist/core/entity/types/entity.interface.d.ts +66 -2
- package/dist/core/entity/version.d.ts +13 -0
- package/dist/core/event-policy/event-policy.d.ts +25 -0
- package/dist/core/event-policy/exceptions.d.ts +11 -0
- package/dist/core/event-policy/publish.d.ts +17 -0
- package/dist/core/event-policy/publishers.d.ts +18 -0
- package/dist/core/event-policy/types/event-policy.interface.d.ts +72 -0
- package/dist/core/output/coerce.d.ts +9 -0
- package/dist/core/output/openapi-sink.d.ts +138 -38
- package/dist/core/output/status.d.ts +2 -1
- package/dist/core/parse/parse.d.ts +10 -0
- package/dist/core/parse/strip.d.ts +13 -0
- package/dist/core/property/input.d.ts +20 -0
- package/dist/core/record/plugin.d.ts +6 -2
- package/dist/core/repository/exceptions.d.ts +30 -0
- package/dist/core/repository/in-memory.d.ts +14 -1
- package/dist/core/repository/plan.d.ts +20 -0
- package/dist/core/repository/provider.d.ts +1 -1
- package/dist/core/repository/query.d.ts +9 -2
- package/dist/core/repository/repository.d.ts +40 -8
- package/dist/core/repository/state.d.ts +39 -2
- package/dist/core/repository/types/query.interface.d.ts +106 -5
- package/dist/core/repository/types/repository.interface.d.ts +113 -7
- package/dist/core/use-case/exceptions.d.ts +36 -0
- package/dist/core/use-case/plugin-catalog.d.ts +11 -0
- package/dist/core/use-case/plugin.d.ts +25 -0
- package/dist/core/use-case/steps/types/steps.interface.d.ts +23 -6
- package/dist/core/use-case/target.d.ts +9 -0
- package/dist/core/use-case/types/plugin.interface.d.ts +185 -0
- package/dist/experimental.js +3 -3
- package/dist/{index-3nd9bjnc.js → index-qxfkyd6k.js} +646 -635
- package/dist/{index-gbgc40xe.js → index-t5qwtyj5.js} +2798 -295
- package/dist/index.d.ts +35 -15
- package/dist/index.js +99 -15
- package/dist/std/blueprint-plugin.d.ts +6 -2
- package/dist/std/blueprint.d.ts +3 -0
- package/dist/std/command.d.ts +11 -0
- package/dist/std/entity.d.ts +2 -1
- package/dist/std/event-policies.d.ts +2 -0
- package/dist/std/properties/exceptions.d.ts +11 -0
- package/dist/std/properties/json.d.ts +54 -0
- package/dist/std/properties/password.d.ts +16 -1
- package/dist/std/properties/time.d.ts +4 -0
- package/dist/std/use-cases/auth.d.ts +5 -0
- package/dist/std/use-cases/crud.d.ts +25 -0
- package/dist/std/use-cases/index.d.ts +11 -0
- package/dist/std/use-cases/lifecycle.d.ts +13 -0
- package/dist/std/use-cases/shared.d.ts +88 -0
- package/dist/std/use-cases/types.d.ts +291 -0
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.js +355 -2
- package/dist/testing/memory-publisher.d.ts +16 -0
- package/dist/testing/provider-contract.d.ts +14 -0
- package/package.json +3 -2
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import type { BlueprintField } from "../../blueprint/types/blueprint.interface.js";
|
|
2
|
+
import type { AnyRepository, AnyRepositoryEntity, EntityInstanceOf } from "../../repository/types/repository.interface.js";
|
|
3
|
+
import type { Kind } from "../../symbols/kind.js";
|
|
4
|
+
import type { AnyUseCaseClass, UseCaseStepsSettings } from "../use-case.js";
|
|
5
|
+
/** What a use case plugin needs of the repository it is made for. */
|
|
6
|
+
export interface UseCasePluginRequirements {
|
|
7
|
+
/** The actions the repository must declare, e.g. `["findById", "update"]`. */
|
|
8
|
+
readonly actions?: readonly string[];
|
|
9
|
+
/** The record plugins the entity must have, by name. */
|
|
10
|
+
readonly plugins?: readonly string[];
|
|
11
|
+
}
|
|
12
|
+
/** What a key of the entity is, for a use case that reads or writes it. */
|
|
13
|
+
export interface UseCaseFieldPlan {
|
|
14
|
+
readonly key: string;
|
|
15
|
+
readonly field: BlueprintField;
|
|
16
|
+
/** One of the identity keys: `id`, `createdAt`, `updatedAt`, `deletedAt`. */
|
|
17
|
+
readonly identity: boolean;
|
|
18
|
+
/** The record plugin that adds the key, by name. */
|
|
19
|
+
readonly plugin: string | undefined;
|
|
20
|
+
readonly sensitive: boolean;
|
|
21
|
+
readonly unique: boolean;
|
|
22
|
+
readonly optional: boolean;
|
|
23
|
+
/** Whether the entity has `change.<key>`. */
|
|
24
|
+
readonly change: boolean;
|
|
25
|
+
readonly kind: "property" | "blueprint" | "list" | "record" | "entity" | "entity-list";
|
|
26
|
+
/** The entity class the key holds, for `entity` and `entity-list`. */
|
|
27
|
+
readonly related: AnyRepositoryEntity | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* What an input takes for the key: `<key>Id` and the `id` field of the
|
|
30
|
+
* entity it holds, for an entity; the property a `PropertyInput`
|
|
31
|
+
* accepts, for a property that declares one; else the key and the field.
|
|
32
|
+
*/
|
|
33
|
+
readonly input: {
|
|
34
|
+
readonly key: string;
|
|
35
|
+
readonly field: BlueprintField;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Turns what the input gave into what the entity stores, for a property
|
|
39
|
+
* that declares a `PropertyInput` (a plain password into its hash); gives
|
|
40
|
+
* `undefined` for `undefined`.
|
|
41
|
+
*/
|
|
42
|
+
readonly convert: ((value: unknown) => unknown) | undefined;
|
|
43
|
+
}
|
|
44
|
+
/** What `compile` gets of the repository a use case is made for. */
|
|
45
|
+
export interface UseCaseTargetInfo {
|
|
46
|
+
readonly repository: AnyRepository;
|
|
47
|
+
/** The name `repositoryOf` gave it. */
|
|
48
|
+
readonly repositoryName: string;
|
|
49
|
+
readonly entity: AnyRepositoryEntity;
|
|
50
|
+
/** The declared name of the entity, else the name of its class. */
|
|
51
|
+
readonly entityName: string;
|
|
52
|
+
readonly actions: readonly string[];
|
|
53
|
+
readonly deletion: "hard" | "soft";
|
|
54
|
+
/** Every key of the entity, in the order of its blueprint. */
|
|
55
|
+
readonly fields: readonly UseCaseFieldPlan[];
|
|
56
|
+
readonly changeKeys: readonly string[];
|
|
57
|
+
readonly uniqueKeys: readonly string[];
|
|
58
|
+
/** The field plan of `key`; throws `UseCaseUnavailable` when the entity has no such key. */
|
|
59
|
+
field(key: string): UseCaseFieldPlan;
|
|
60
|
+
/**
|
|
61
|
+
* The repository of the entity the key holds, with the `actions` it must
|
|
62
|
+
* declare; throws `UseCaseUnavailable` when the repository has no such
|
|
63
|
+
* relation or the related one lacks an action.
|
|
64
|
+
*/
|
|
65
|
+
relation(key: string, actions?: readonly string[]): AnyRepository;
|
|
66
|
+
/** Throws `UseCaseUnavailable` for this target, with `reason`. */
|
|
67
|
+
unavailable(reason: string): never;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The declaration a plugin compiles: what `useCaseOf` takes, with `steps`.
|
|
71
|
+
* The steps are data here, checked by `useCaseOf` when the class is made.
|
|
72
|
+
*/
|
|
73
|
+
export interface UseCaseCompilation extends Omit<UseCaseStepsSettings<any, any, any, any>, "steps"> {
|
|
74
|
+
readonly steps: readonly Readonly<Record<string, unknown>>[];
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The call signature of a plugin without one of its own: any repository,
|
|
78
|
+
* any options.
|
|
79
|
+
*/
|
|
80
|
+
export type UseCaseMaker = (repository: any, options?: any) => AnyUseCaseClass;
|
|
81
|
+
/** What `useCasePluginOf` takes, after the name. */
|
|
82
|
+
export interface UseCasePluginSettings {
|
|
83
|
+
/** A semantic version, e.g. `1.2.0`; `1.0.0` when left out. */
|
|
84
|
+
readonly version?: string;
|
|
85
|
+
/** What the use case does, for catalogs and tools. */
|
|
86
|
+
readonly description?: string;
|
|
87
|
+
readonly requires?: UseCasePluginRequirements;
|
|
88
|
+
/**
|
|
89
|
+
* The use case for `target` and `options`, as the settings of
|
|
90
|
+
* `useCaseOf` with `steps`. The options are the plain object the caller
|
|
91
|
+
* gave, `{}` when none.
|
|
92
|
+
*/
|
|
93
|
+
compile(target: UseCaseTargetInfo, options: Readonly<Record<string, unknown>>): UseCaseCompilation;
|
|
94
|
+
}
|
|
95
|
+
/** The plain, JSON form of a use case plugin, as `plugin.toJSON()` gives it. */
|
|
96
|
+
export interface UseCasePluginDescriptor {
|
|
97
|
+
readonly kind: "use-case-plugin";
|
|
98
|
+
readonly name: string;
|
|
99
|
+
readonly version: string;
|
|
100
|
+
readonly description?: string;
|
|
101
|
+
readonly requires: Required<UseCasePluginRequirements>;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* A use case that is made for a repository: its blueprints, dependencies and
|
|
105
|
+
* steps follow the entity, the actions and the plugins. Made by
|
|
106
|
+
* `useCasePluginOf`.
|
|
107
|
+
*/
|
|
108
|
+
export interface IUseCasePlugin<Name extends string = string, Make extends UseCaseMaker = UseCaseMaker> {
|
|
109
|
+
readonly [Kind]: "use-case-plugin";
|
|
110
|
+
readonly name: Name;
|
|
111
|
+
readonly version: string;
|
|
112
|
+
readonly description?: string;
|
|
113
|
+
readonly requires: Required<UseCasePluginRequirements>;
|
|
114
|
+
/**
|
|
115
|
+
* The use case class for a repository and options: the same class for
|
|
116
|
+
* the same repository and equal options. Throws `UseCaseUnavailable`
|
|
117
|
+
* when the repository or its entity lacks what the plugin requires.
|
|
118
|
+
*/
|
|
119
|
+
readonly make: Make;
|
|
120
|
+
toJSON(): UseCasePluginDescriptor;
|
|
121
|
+
}
|
|
122
|
+
/** Any use case plugin. */
|
|
123
|
+
export type AnyUseCasePlugin = IUseCasePlugin<string, any>;
|
|
124
|
+
/** Where a use case class made by a plugin comes from, as `useCaseOriginOf` gives it. */
|
|
125
|
+
export interface UseCaseOriginInfo {
|
|
126
|
+
readonly plugin: AnyUseCasePlugin;
|
|
127
|
+
readonly repository: AnyRepository;
|
|
128
|
+
readonly options: Readonly<Record<string, unknown>>;
|
|
129
|
+
}
|
|
130
|
+
/** @internal */
|
|
131
|
+
export type UseCasePluginsByName<Plugins extends readonly AnyUseCasePlugin[]> = {
|
|
132
|
+
readonly [Plugin in Plugins[number] as Plugin["name"]]: Plugin;
|
|
133
|
+
};
|
|
134
|
+
/** @internal The `make` of each plugin, by name. */
|
|
135
|
+
export type UseCaseContextOf<Plugins> = {
|
|
136
|
+
readonly [Name in keyof Plugins]: Plugins[Name] extends {
|
|
137
|
+
readonly make: infer Make;
|
|
138
|
+
} ? Make : never;
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* Use case plugins by name: what `commandBuilderOf` gives `useCases` to pick
|
|
142
|
+
* from, as `(ctx) => ({ create: ctx.create(Posts) })`. Made by
|
|
143
|
+
* `useCaseCatalogOf`.
|
|
144
|
+
*/
|
|
145
|
+
export interface IUseCaseCatalog<Plugins extends Readonly<Record<string, AnyUseCasePlugin>> = Readonly<Record<string, AnyUseCasePlugin>>> {
|
|
146
|
+
readonly [Kind]: "use-case-catalog";
|
|
147
|
+
readonly plugins: Plugins;
|
|
148
|
+
readonly list: readonly AnyUseCasePlugin[];
|
|
149
|
+
/** The `make` of each plugin, by name. */
|
|
150
|
+
readonly context: UseCaseContextOf<Plugins>;
|
|
151
|
+
/** The plugin of a name, or of a name and a version (`create@1.0.0`). */
|
|
152
|
+
resolve(reference: string): AnyUseCasePlugin;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* @internal The context of a list of catalogs: the `make` of every plugin,
|
|
156
|
+
* a later catalog winning a name.
|
|
157
|
+
*/
|
|
158
|
+
export type UseCasePluginContext<Catalogs extends readonly IUseCaseCatalog[]> = Catalogs extends readonly [
|
|
159
|
+
infer Head extends IUseCaseCatalog,
|
|
160
|
+
...infer Tail extends readonly IUseCaseCatalog[]
|
|
161
|
+
] ? Omit<Head["context"], keyof UseCasePluginContext<Tail>> & UseCasePluginContext<Tail> : Record<never, never>;
|
|
162
|
+
type ActionsOf<Repository> = Repository extends {
|
|
163
|
+
readonly actions: readonly (infer Action)[];
|
|
164
|
+
} ? Action : never;
|
|
165
|
+
/** The entity class of a repository. */
|
|
166
|
+
export type EntityOfRepository<Repository> = Repository extends {
|
|
167
|
+
readonly entity: infer Entity;
|
|
168
|
+
} ? Entity : never;
|
|
169
|
+
/** What the type of an argument shows when the repository lacks an action. */
|
|
170
|
+
export interface MissingRepositoryAction<Action extends string> {
|
|
171
|
+
readonly "this use case needs the repository to declare the action": Action;
|
|
172
|
+
}
|
|
173
|
+
/** What the type of an argument shows when the entity lacks a record plugin. */
|
|
174
|
+
export interface MissingRecordPlugin<Plugin extends string> {
|
|
175
|
+
readonly "this use case needs the entity to have the plugin": Plugin;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* The precondition of a use case plugin, in the type of its repository
|
|
179
|
+
* argument, written `repository: Repository & UseCaseTarget<Repository, ...>`:
|
|
180
|
+
* nothing when `Repository` declares every `Action` and its entities have
|
|
181
|
+
* the `Members` of the record plugin `Plugin`; else the type that names what
|
|
182
|
+
* is missing.
|
|
183
|
+
*/
|
|
184
|
+
export type UseCaseTarget<Repository, Action extends string, Members = unknown, Plugin extends string = never> = [Action] extends [ActionsOf<Repository>] ? EntityInstanceOf<EntityOfRepository<Repository>> extends Members ? unknown : MissingRecordPlugin<Plugin> : MissingRepositoryAction<Exclude<Action, ActionsOf<Repository>>>;
|
|
185
|
+
export {};
|
package/dist/experimental.js
CHANGED
|
@@ -6,11 +6,11 @@ import {
|
|
|
6
6
|
listOf2,
|
|
7
7
|
isBlueprintList2,
|
|
8
8
|
AbstractRecord2,
|
|
9
|
-
declareRecord,
|
|
10
9
|
UndeclaredBlueprintProperty2,
|
|
11
10
|
optionalOf2,
|
|
12
|
-
blueprintFromProperties
|
|
13
|
-
|
|
11
|
+
blueprintFromProperties,
|
|
12
|
+
declareRecord
|
|
13
|
+
} from "./index-qxfkyd6k.js";
|
|
14
14
|
|
|
15
15
|
// src/core/blueprint/slice.ts
|
|
16
16
|
function propertiesOfField(field) {
|