@afora/core 0.0.3 → 0.0.5

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.
@@ -40,6 +40,15 @@ export declare const ApplicationNotStarted: import("../../index.js").DeclaredExc
40
40
  /** The application, or none when `useApplication()` found none started. */
41
41
  readonly application?: string;
42
42
  }>;
43
+ /**
44
+ * A repository read or wrote through a provider of `providersOf` made by
45
+ * `providerFrom` outside an application: an application that registers the
46
+ * storage makes it on start, and its bound repositories use it.
47
+ */
48
+ export declare const ProviderNotBound: import("../../index.js").DeclaredExceptionClass<{
49
+ /** The key of the provider in its storage. */
50
+ readonly provider: string;
51
+ }>;
43
52
  /**
44
53
  * `app.start()` was called while another application is the started one of
45
54
  * the process; `start({ replace: true })` stops it and takes its place.
@@ -0,0 +1,46 @@
1
+ import type { IRepositoryProvider } from "../repository/types/repository.interface.js";
2
+ import { Kind } from "../symbols/kind.js";
3
+ import { type ProviderFactory } from "./start.js";
4
+ /**
5
+ * One provider of a storage made by `providersOf`, e.g. `Providers.audit`:
6
+ * what a repository (`repositoryOf({ provider: Providers.audit })`) or an
7
+ * application (`provider: Providers.main`) names. Each application that
8
+ * registers the storage reads and writes through its own instance of it.
9
+ */
10
+ export type ProviderSlot<Key extends string = string> = IRepositoryProvider & {
11
+ readonly [Kind]: "provider-slot";
12
+ /** Its key in the storage. */
13
+ readonly key: Key;
14
+ };
15
+ /** The providers of `providersOf`, by key. */
16
+ export type ProviderStorage<Keys extends string = string> = {
17
+ readonly [Key in Keys]: ProviderSlot<Key>;
18
+ } & {
19
+ readonly [Kind]: "provider-storage";
20
+ };
21
+ /** What a slot stands for. */
22
+ interface SlotEntry {
23
+ readonly key: string;
24
+ readonly storage: object;
25
+ readonly value: IRepositoryProvider | ProviderFactory;
26
+ }
27
+ /**
28
+ * Named providers, declared once in a module of their own so that
29
+ * repositories can name one before any application exists, e.g.
30
+ * `const Providers = providersOf({ main: providerFrom(Database, ...), audit: auditProvider() })`,
31
+ * then `repositoryOf({ ..., provider: Providers.audit })` and
32
+ * `applicationOf({ providers: Providers, provider: Providers.main, ... })`.
33
+ * Each value is a provider or a factory of `providerFrom`; an application
34
+ * that registers the storage makes each factory on `start()`, its own
35
+ * instance (an application that extends it shares them).
36
+ */
37
+ export declare function providersOf<const Entries extends Readonly<Record<string, IRepositoryProvider | ProviderFactory>>>(entries: Entries): ProviderStorage<keyof Entries & string>;
38
+ /** Whether `value` is a provider of a storage made by `providersOf`. */
39
+ export declare function isProviderSlot(value: unknown): value is ProviderSlot;
40
+ /** Whether `value` is a storage made by `providersOf`. */
41
+ export declare function isProviderStorage(value: unknown): value is ProviderStorage;
42
+ /** The slots of `storage`, in the order of its keys. @internal */
43
+ export declare function slotsOf(storage: ProviderStorage): readonly ProviderSlot[];
44
+ /** What `slot` stands for. @internal */
45
+ export declare function slotEntry(slot: ProviderSlot): SlotEntry;
46
+ export {};
@@ -1,6 +1,8 @@
1
1
  import { type AnyEnvironment, type EnvironmentDependencies, type MergedEnvironment } from "../environment/environment.js";
2
+ import type { LogSettings } from "../logger/logger.js";
2
3
  import type { IRepositoryProvider } from "../repository/types/repository.interface.js";
3
4
  import { Kind } from "../symbols/kind.js";
5
+ import type { ApplicationContext } from "./types/application.interface.js";
4
6
  /**
5
7
  * A provider an application creates when it starts, from the variables of
6
8
  * its environments: what `providerFrom` makes.
@@ -10,6 +12,8 @@ export interface ProviderFactory<Environment extends EnvironmentDependencies = E
10
12
  /** The environments whose variables `create` gets, as a list. */
11
13
  readonly environments: readonly AnyEnvironment[];
12
14
  readonly create: (env: MergedEnvironment<Environment>) => IRepositoryProvider | Promise<IRepositoryProvider>;
15
+ /** Whether `create` takes the context of the application instead of variables. */
16
+ readonly withContext: boolean;
13
17
  }
14
18
  /**
15
19
  * A provider made on `app.start()`: `create` gets the variables of
@@ -18,6 +22,26 @@ export interface ProviderFactory<Environment extends EnvironmentDependencies = E
18
22
  * `providerFrom(Database, (env) => drizzleProvider({ db: connect(env.DATABASE_URL), tables }))`.
19
23
  */
20
24
  export declare function providerFrom<const Environment extends EnvironmentDependencies>(environmentDependencies: Environment, create: (env: MergedEnvironment<Environment>) => IRepositoryProvider | Promise<IRepositoryProvider>): ProviderFactory<Environment>;
25
+ /**
26
+ * A provider made on `app.start()` from the context of the application:
27
+ * `ctx.env(Database)` gives the variables of a registered environment and
28
+ * `ctx.logger` its logger, e.g.
29
+ * `providerFrom((ctx) => drizzleProvider({ db: connect(ctx.env(Database).DATABASE_URL), tables }))`.
30
+ */
31
+ export declare function providerFrom(create: (context: ApplicationContext) => IRepositoryProvider | Promise<IRepositoryProvider>): ProviderFactory<readonly []>;
32
+ /** A `log` an application makes on `app.start()`: what `logFrom` makes. */
33
+ export interface LogFactory {
34
+ readonly [Kind]: "log-factory";
35
+ readonly create: (context: ApplicationContext) => LogSettings | Promise<LogSettings>;
36
+ }
37
+ /**
38
+ * A `log` made on `app.start()` from the context of the application, before
39
+ * its provider, e.g. `logFrom((ctx) => ({ level: ctx.env(Logging).LOG_LEVEL,
40
+ * providers: [jsonLogProvider()] }))`. Until then the application logs nothing.
41
+ */
42
+ export declare function logFrom(create: (context: ApplicationContext) => LogSettings | Promise<LogSettings>): LogFactory;
43
+ /** Whether `value` was made by `logFrom`. */
44
+ export declare function isLogFactory(value: unknown): value is LogFactory;
21
45
  /** Whether `value` was made by `providerFrom`. */
22
46
  export declare function isProviderFactory(value: unknown): value is ProviderFactory;
23
47
  /**
@@ -36,7 +60,7 @@ export declare function deferredEnvironments(provider: unknown): readonly AnyEnv
36
60
  * environments (already validated by the caller); later calls give the same.
37
61
  * @internal
38
62
  */
39
- export declare function startDeferred(provider: IRepositoryProvider): Promise<IRepositoryProvider> | undefined;
63
+ export declare function startDeferred(provider: IRepositoryProvider, context: ApplicationContext): Promise<IRepositoryProvider> | undefined;
40
64
  /**
41
65
  * Closes the provider made on start and forgets it, so that calls throw
42
66
  * `ApplicationNotStarted` again; a provider that is not deferred is closed.
@@ -1,6 +1,7 @@
1
1
  import type { AnyCommand } from "../../command/types/command.interface.js";
2
2
  import type { AnyEnvironment, EnvironmentValue } from "../../environment/environment.js";
3
3
  import type { ExceptionLayers } from "../../exception/enums/exception-layers.js";
4
+ import type { ILogger, LogLevel, LogSettings } from "../../logger/logger.js";
4
5
  import type { AnyOutput, StageDescription } from "../../output/types/output.interface.js";
5
6
  import type { RecordPluginDescriptor } from "../../record/types/plugin.interface.js";
6
7
  import type { ProviderDescription } from "../../repository/types/query.interface.js";
@@ -8,7 +9,8 @@ import type { AnyRepository, IRepositoryProvider } from "../../repository/types/
8
9
  import type { Kind } from "../../symbols/kind.js";
9
10
  import type { UseCaseStepDescription } from "../../use-case/steps/types/steps.interface.js";
10
11
  import type { AnyExceptionClass, AnyUseCaseClass } from "../../use-case/use-case.js";
11
- import type { ProviderFactory } from "../start.js";
12
+ import type { ProviderSlot, ProviderStorage } from "../providers.js";
13
+ import type { LogFactory, ProviderFactory } from "../start.js";
12
14
  type Named<Value> = Readonly<Record<string, Value>>;
13
15
  /** The declarations of an application, by name, one collection for each kind. */
14
16
  export interface ApplicationCollections {
@@ -52,9 +54,40 @@ export interface ApplicationSettings<Name extends string, Extended extends reado
52
54
  * The provider of the repositories that did not declare one; the
53
55
  * repositories of the application read and write through it. With
54
56
  * `providerFrom`, it is made by `app.start()` from the variables of its
55
- * environments, and calls before that throw `ApplicationNotStarted`.
57
+ * environments, and calls before that throw `ApplicationNotStarted`. A
58
+ * provider of `providers` (`Providers.main`) names the instance this
59
+ * application makes of it.
56
60
  */
57
61
  readonly provider?: IRepositoryProvider | ProviderFactory;
62
+ /**
63
+ * Named providers made by `providersOf`, which repositories name
64
+ * (`repositoryOf({ provider: Providers.audit })`). The application makes
65
+ * its own instance of each `providerFrom` on `start()` and binds the
66
+ * repositories to it; an application that extends it shares them.
67
+ */
68
+ readonly providers?: ProviderStorage;
69
+ /**
70
+ * How it logs: the providers its lines go to and the lowest level kept.
71
+ * Use cases, commands and repository calls of the application are logged
72
+ * through it, and a use case gets it as its `Logger` dependency. Without
73
+ * it, the one of the last extended application that has one; none by default.
74
+ */
75
+ readonly log?: LogSettings | LogFactory;
76
+ }
77
+ /**
78
+ * What an application gives the factories it runs on start (`providerFrom`,
79
+ * `logFrom`) and your code (`app.context`).
80
+ */
81
+ export interface ApplicationContext {
82
+ /** The name of the application. */
83
+ readonly name: string;
84
+ /**
85
+ * The variables of an environment registered in the application, typed by
86
+ * its blueprint; one that is not registered throws `UnregisteredApplicationReference`.
87
+ */
88
+ env<Environment extends AnyEnvironment>(environment: Environment): EnvironmentValue<Environment>;
89
+ /** Its logger; a `log` of `logFrom` writes nothing before `start()`. */
90
+ readonly logger: ILogger;
58
91
  }
59
92
  type UnionToIntersection<Union> = (Union extends unknown ? (value: Union) => void : never) extends (value: infer Intersection) => void ? Intersection : never;
60
93
  /**
@@ -72,6 +105,10 @@ export interface IApplication<Name extends string, Collections extends Applicati
72
105
  readonly extends: readonly AnyApplication[];
73
106
  /** The default provider of its repositories, if any. */
74
107
  readonly provider: IRepositoryProvider | undefined;
108
+ /** Logs through the providers of its `log`; writes nothing without one. */
109
+ readonly logger: ILogger;
110
+ /** Its context: its name, the variables of its environments and its logger. */
111
+ readonly context: ApplicationContext;
75
112
  readonly properties: Collections["properties"];
76
113
  readonly blueprints: Collections["blueprints"];
77
114
  readonly records: Collections["records"];
@@ -136,6 +173,8 @@ export interface IApplication<Name extends string, Collections extends Applicati
136
173
  get<UseCase extends AnyUseCaseClass>(useCase: UseCase): UseCase;
137
174
  /** The bound version of a repository registered in the application. */
138
175
  get<Repository extends AnyRepository>(repository: Repository): Repository;
176
+ /** The instance this application reads and writes through for a provider of its `providers`. */
177
+ get(provider: ProviderSlot): IRepositoryProvider;
139
178
  /** Whether `start()` completed and `stop()` was not called since. */
140
179
  readonly started: boolean;
141
180
  }
@@ -223,7 +262,8 @@ export interface RecordDescription {
223
262
  }
224
263
  /** What a use case depends on, by the name it has in the application. */
225
264
  export interface UseCaseDependencyDescription {
226
- readonly kind: "use-case" | "repository" | "environment";
265
+ /** `logger` is the core's `Logger`, whose `ref` is always `"Logger"`. */
266
+ readonly kind: "use-case" | "repository" | "environment" | "logger";
227
267
  readonly ref: string;
228
268
  }
229
269
  /** A use case: its metadata, fields and what it depends on. */
@@ -306,13 +346,37 @@ export interface ExceptionDescription {
306
346
  readonly layer: ExceptionLayers;
307
347
  readonly message?: string;
308
348
  }
349
+ /** How `describe` gives the `log` of an application. */
350
+ export interface LogDescription {
351
+ readonly level: LogLevel;
352
+ /** The name of each provider made by `logProviderOf` with one; `opaque` otherwise (and for a `logFrom` before start). */
353
+ readonly providers: readonly ({
354
+ readonly kind: "log-provider";
355
+ readonly name: string;
356
+ } | {
357
+ readonly kind: "opaque";
358
+ })[];
359
+ }
360
+ /** How `describe` names a provider of `providersOf`: by its key. */
361
+ export interface ProviderReference {
362
+ readonly kind: "ref";
363
+ readonly key: string;
364
+ }
309
365
  /** The graph `describe` gives: every declaration by name, with its origin in `from`. */
310
366
  export interface ApplicationDescription {
311
367
  readonly name: string;
312
368
  /** The names of the applications it extends directly. */
313
369
  readonly extends: readonly string[];
314
370
  /** The provider of the application (or of the last extended one), present only when configured. */
315
- readonly provider?: ProviderDescription;
371
+ readonly provider?: ProviderDescription | ProviderReference;
372
+ /** Its providers of `providersOf` (inherited ones included), by key; present only when it has some. */
373
+ readonly providers?: Readonly<Record<string, ProviderDescription & {
374
+ readonly from: string;
375
+ }>>;
376
+ /** Its `log` (or the one of the last extended application), present only when configured. */
377
+ readonly log?: LogDescription | {
378
+ readonly kind: "opaque";
379
+ };
316
380
  readonly properties: Readonly<Record<string, PropertyDescription & {
317
381
  readonly from: string;
318
382
  }>>;
@@ -335,8 +399,8 @@ export interface ApplicationDescription {
335
399
  readonly relations: readonly string[];
336
400
  /** The names of its `environmentDependencies`. */
337
401
  readonly environments: readonly string[];
338
- /** Its own provider, present only when it declared one. */
339
- readonly provider?: ProviderDescription;
402
+ /** Its own provider, present only when it declared one; a provider of `providersOf` by its key. */
403
+ readonly provider?: ProviderDescription | ProviderReference;
340
404
  }>>;
341
405
  readonly useCases: Readonly<Record<string, UseCaseDescription>>;
342
406
  readonly commands: Readonly<Record<string, CommandDescription>>;
@@ -1,6 +1,7 @@
1
1
  import type { BlueprintInput, IBlueprint, IBlueprintCollection } from "../../blueprint/types/blueprint.interface.js";
2
2
  import type { EntityEvent } from "../../entity/event.js";
3
3
  import type { AnyEnvironment, EnvironmentDependencies, MergedEnvironment } from "../../environment/environment.js";
4
+ import type { ILogger } from "../../logger/logger.js";
4
5
  import type { Kind } from "../../symbols/kind.js";
5
6
  import type { AnyUseCaseClass, UseCaseInput, UseCaseOptions, UseCaseResponse } from "../../use-case/use-case.js";
6
7
  /** The use cases of a command, by operation name. */
@@ -13,6 +14,11 @@ export interface CommandEventInfo {
13
14
  readonly context: unknown;
14
15
  /** The variables of the command's environments, with the `env` of the call over them. */
15
16
  readonly env: Readonly<Record<string, unknown>>;
17
+ /**
18
+ * The logger of the application that bound the command, else the started
19
+ * application's; a logger that writes nothing without either.
20
+ */
21
+ readonly logger: ILogger;
16
22
  }
17
23
  /** Handles all the events of a call, once it succeeded. */
18
24
  export type CommandEventHandler = (events: readonly EntityEvent[], info: CommandEventInfo) => void | Promise<void>;
@@ -1,3 +1,4 @@
1
+ import { type ILogger } from "../logger/logger.js";
1
2
  /** A class made by `entityOf`, including subclasses. */
2
3
  export declare const EntityClassBrand: unique symbol;
3
4
  export type AnyEntityClass = (abstract new (value: never) => object) & {
@@ -9,11 +10,20 @@ export interface EventDefinition {
9
10
  readonly name: string;
10
11
  readonly [EventBrand]: true;
11
12
  }
13
+ /** What the handler of an event gets next to the entity. */
14
+ export interface EventHandlerContext {
15
+ /**
16
+ * The logger of the application whose command raised the event; else the
17
+ * started application's; a logger that writes nothing without either.
18
+ */
19
+ readonly logger: ILogger;
20
+ }
12
21
  /** One queued occurrence, referencing the original entity rather than a snapshot. */
13
22
  export interface EntityEvent<Entity = object> {
14
23
  readonly name: string;
15
24
  readonly entity: Entity;
16
- handle(): Promise<void>;
25
+ /** Runs the handler; `logger` replaces the one it would get. */
26
+ handle(context?: Partial<EventHandlerContext>): Promise<void>;
17
27
  }
18
28
  export type EntityEventReference = EventDefinition | readonly EventDefinition[] | (() => EventDefinition | readonly EventDefinition[]);
19
29
  export interface EntityEvents {
@@ -23,7 +33,7 @@ export interface EntityEvents {
23
33
  }
24
34
  export declare const EntityEventSettings: unique symbol;
25
35
  /** Defines an event without executing its handler. */
26
- export declare function eventOf<Class extends AnyEntityClass>(name: string, entityClass: Class, handler: (entity: InstanceType<Class>) => Promise<void>): EventDefinition;
36
+ export declare function eventOf<Class extends AnyEntityClass>(name: string, entityClass: Class, handler: (entity: InstanceType<Class>, context: EventHandlerContext) => Promise<void>): EventDefinition;
27
37
  export declare function enqueueEvent(entity: object, event: EventDefinition): void;
28
38
  export declare function pullEntityEvents<Entity extends object>(entity: Entity): EntityEvent<Entity>[];
29
39
  export declare function enqueueLifecycle(entity: object, cycle: keyof EntityEvents): void;
@@ -0,0 +1,4 @@
1
+ /** `logProviderOf`, `logFrom` or the `log` of an application got something it cannot use. */
2
+ export declare const InvalidLogDeclaration: import("../../index.js").DeclaredExceptionClass<{
3
+ readonly reason: string;
4
+ }>;
@@ -0,0 +1,106 @@
1
+ import { Kind } from "../symbols/kind.js";
2
+ /** What a log line carries besides its event. */
3
+ export type LogFields = Readonly<Record<string, unknown>>;
4
+ export type LogLevel = "debug" | "info" | "warn" | "error";
5
+ export declare const LogLevels: readonly LogLevel[];
6
+ /** What logs: an application, a use case through its `Logger` dependency, your code. */
7
+ export interface ILogger {
8
+ debug(event: string, fields?: LogFields): void;
9
+ info(event: string, fields?: LogFields): void;
10
+ warn(event: string, fields?: LogFields): void;
11
+ error(event: string, fields?: LogFields): void;
12
+ }
13
+ /** One line, as a log provider gets it. */
14
+ export interface LogEntry {
15
+ /** ISO 8601. */
16
+ readonly at: string;
17
+ readonly level: LogLevel;
18
+ readonly event: string;
19
+ readonly fields: LogFields;
20
+ /** The name of the application that logged it. */
21
+ readonly application: string;
22
+ }
23
+ /**
24
+ * Where lines go: the console, JSON on stdout, a log service, memory. An
25
+ * application writes each line to every provider of its `log`.
26
+ */
27
+ export interface ILogProvider {
28
+ write(entry: LogEntry): void | Promise<void>;
29
+ /** Called on `app.stop()`, to send what is still buffered. */
30
+ flush?(): Promise<void>;
31
+ }
32
+ /** The `log` of an application. */
33
+ export interface LogSettings {
34
+ /** Lines below it are dropped. `"info"` by default. */
35
+ readonly level?: LogLevel;
36
+ readonly providers: readonly ILogProvider[];
37
+ }
38
+ /** What `logProviderOf` takes. */
39
+ export interface LogProviderSettings<Provider extends ILogProvider> {
40
+ /** Shown by `app.describe()`; anonymous providers are opaque. */
41
+ readonly name?: string;
42
+ readonly write: Provider["write"];
43
+ readonly flush?: Provider["flush"];
44
+ }
45
+ /** A log provider, checked, and named for `describe()` when `name` is given. */
46
+ export declare function logProviderOf(settings: LogProviderSettings<ILogProvider>): ILogProvider;
47
+ /** The name `logProviderOf` gave a provider, if any. */
48
+ export declare function logProviderNameOf(provider: ILogProvider): string | undefined;
49
+ /** A readable line on the console, by level: for local development. */
50
+ export declare function consoleLogProvider(): ILogProvider;
51
+ /** One JSON object per line on stdout: for Lambda, containers, CloudWatch. */
52
+ export declare function jsonLogProvider(): ILogProvider;
53
+ /** A provider that keeps the lines, for tests. */
54
+ export interface MemoryLogProvider extends ILogProvider {
55
+ readonly entries: readonly LogEntry[];
56
+ clear(): void;
57
+ }
58
+ /** Keeps every line in `entries`, for tests. */
59
+ export declare function memoryLogProvider(): MemoryLogProvider;
60
+ /** Throws unless `settings` is a usable `log`; gives it with the default level. */
61
+ export declare function checkLogSettings(settings: unknown): Required<LogSettings>;
62
+ /** A logger that writes nothing. */
63
+ export declare const silentLogger: ILogger;
64
+ /**
65
+ * The logger of an application: drops what is below `level`, writes the rest
66
+ * to every provider, and never lets a provider break the call or the others.
67
+ * `settings` can be set later (a `log` made on start) and unset on stop.
68
+ */
69
+ export declare function applicationLogger(application: string): {
70
+ logger: ILogger;
71
+ readonly settings: Required<LogSettings> | undefined;
72
+ set(settings: Required<LogSettings> | undefined): void;
73
+ flush(): Promise<void>;
74
+ };
75
+ /**
76
+ * The `Logger` dependency of a use case: `dependencies: { logger: Logger }`
77
+ * gives an `ILogger`, the one of the application it runs in.
78
+ */
79
+ export interface LoggerDeclaration {
80
+ readonly [Kind]: "logger";
81
+ }
82
+ export declare const Logger: LoggerDeclaration;
83
+ export declare function isLoggerDeclaration(value: unknown): value is LoggerDeclaration;
84
+ /** Whether `value` can stand for a logger (an override in `execute`). */
85
+ export declare function isLogger(value: unknown): value is ILogger;
86
+ /**
87
+ * Carries the logger of an application, when it has a `log`: on the
88
+ * application and on the use case classes it binds.
89
+ */
90
+ export declare const ApplicationLoggerKey: unique symbol;
91
+ /**
92
+ * The logger a call writes to: the one its scope carries, else the one of
93
+ * the application its class was bound by, else the started application's.
94
+ */
95
+ export declare function resolveLogger(scoped: ILogger | undefined, owner: unknown): ILogger | undefined;
96
+ /** Milliseconds, for timing; `Date.now` where there is no `performance`. */
97
+ export declare function clock(): number;
98
+ export declare function elapsed(since: number): number;
99
+ /**
100
+ * Logs a failure once: the same exception passes through every use case and
101
+ * command up the call, each wrapping it. `warn` for a declared exception,
102
+ * `error` for an unexpected one, with its trace.
103
+ */
104
+ export declare function logFailure(logger: ILogger | undefined, event: string, fields: LogFields, error: unknown): void;
105
+ /** Writes one line; a logger that throws never breaks the call it logs. */
106
+ export declare function writeLog(logger: ILogger | undefined, level: LogLevel, event: string, fields: LogFields): void;
@@ -39,6 +39,7 @@ export interface RepositoryInspection {
39
39
  export declare function inspectRepository(repository: unknown): RepositoryInspection | undefined;
40
40
  /**
41
41
  * A repository sharing the declaration of `repository` that reads and writes
42
- * through `provider`, unless it declared a provider of its own.
42
+ * through `provider`, unless it declared a provider of its own; a declared
43
+ * provider found in `instances` is replaced by its value.
43
44
  */
44
- export declare function bindRepository<Repository extends object>(repository: Repository, provider: IRepositoryProvider): Repository;
45
+ export declare function bindRepository<Repository extends object>(repository: Repository, provider: IRepositoryProvider | undefined, instances?: ReadonlyMap<object, IRepositoryProvider>): Repository;
@@ -1,3 +1,4 @@
1
+ import type { ILogger } from "../logger/logger.js";
1
2
  import type { IRepositoryProvider } from "../repository/types/repository.interface.js";
2
3
  /**
3
4
  * What a call carries to its repositories, internal: the providers that
@@ -11,6 +12,8 @@ export interface ExecutionScope {
11
12
  * loads, by environment: a use case that declares it gets these.
12
13
  */
13
14
  readonly environments?: ReadonlyMap<object, Readonly<Record<string, unknown>>>;
15
+ /** The logger of the application running the call, given by its command. */
16
+ readonly logger?: ILogger;
14
17
  }
15
18
  /**
16
19
  * Key of the constructor options (and of the repository view) that carries
@@ -2,6 +2,7 @@ import type { AnyBlueprint, BlueprintInput, BlueprintValue, IBlueprint, IBluepri
2
2
  import type { EntityEvent } from "../entity/event.js";
3
3
  import { type AnyEnvironment, type EnvironmentValue } from "../environment/environment.js";
4
4
  import { type DeclaredExceptionClass } from "../exception/exception.js";
5
+ import { type ILogger, type LoggerDeclaration } from "../logger/logger.js";
5
6
  import type { AnyRepository } from "../repository/types/repository.interface.js";
6
7
  import { Kind } from "../symbols/kind.js";
7
8
  import type { UseCaseStep } from "./steps/types/steps.interface.js";
@@ -26,9 +27,9 @@ export interface AnyUseCaseClass {
26
27
  export type AnyExceptionClass = DeclaredExceptionClass<any>;
27
28
  /**
28
29
  * What a use case can depend on: another use case, a repository made by
29
- * `repositoryOf`, or an environment made by `environmentOf`.
30
+ * `repositoryOf`, an environment made by `environmentOf`, or `Logger`.
30
31
  */
31
- export type UseCaseDependency = AnyUseCaseClass | AnyRepository | AnyEnvironment;
32
+ export type UseCaseDependency = AnyUseCaseClass | AnyRepository | AnyEnvironment | LoggerDeclaration;
32
33
  export type UseCaseCollection = Readonly<Record<string, UseCaseDependency>>;
33
34
  type Declaration = {
34
35
  readonly blueprint: AnyBlueprint;
@@ -55,9 +56,9 @@ export type UseCaseOptions<Context extends IBlueprintCollection | undefined = un
55
56
  type OptionsArgs<Context extends IBlueprintCollection | undefined> = Context extends IBlueprintCollection ? [options: UseCaseOptions<Context>] : [];
56
57
  /**
57
58
  * What a use case gets for a dependency: a function for a use case, the
58
- * repository itself, or the variables of an environment.
59
+ * repository itself, the variables of an environment, or an `ILogger`.
59
60
  */
60
- export type DependencyOf<Dependency> = Dependency extends AnyUseCaseClass ? (input: UseCaseInput<Dependency>) => Promise<UseCaseResponse<Dependency>> : Dependency extends AnyEnvironment ? EnvironmentValue<Dependency> : Dependency;
61
+ export type DependencyOf<Dependency> = Dependency extends AnyUseCaseClass ? (input: UseCaseInput<Dependency>) => Promise<UseCaseResponse<Dependency>> : Dependency extends AnyEnvironment ? EnvironmentValue<Dependency> : Dependency extends LoggerDeclaration ? ILogger : Dependency;
61
62
  export type DependencyFunctions<Dependencies extends UseCaseCollection> = {
62
63
  readonly [Key in keyof Dependencies]: DependencyOf<Dependencies[Key]>;
63
64
  };