@afora/core 0.0.3 → 0.0.4

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.
@@ -10,6 +10,7 @@ import {
10
10
  isRecordClass2,
11
11
  recordFieldOf2,
12
12
  isBlueprintList2,
13
+ UNEXPECTED_ERROR2,
13
14
  Exception2,
14
15
  isDeclaredException,
15
16
  declaredMessageOf,
@@ -50,17 +51,37 @@ __export(exports_environment, {
50
51
  loadEnvironments: () => loadEnvironments
51
52
  });
52
53
 
53
- // src/core/entity/exceptions.ts
54
+ // src/core/application/exceptions.ts
54
55
  var exports_exceptions4 = {};
55
56
  __export(exports_exceptions4, {
57
+ ApplicationAlreadyStarted: () => ApplicationAlreadyStarted2,
58
+ ApplicationConflict: () => ApplicationConflict2,
59
+ ApplicationNotStarted: () => ApplicationNotStarted2,
60
+ DuplicateApplicationDeclaration: () => DuplicateApplicationDeclaration2,
61
+ InvalidApplicationDeclaration: () => InvalidApplicationDeclaration2,
62
+ InvalidApplicationEnvironment: () => InvalidApplicationEnvironment2,
63
+ UnregisteredApplicationReference: () => UnregisteredApplicationReference2,
64
+ UnregisteredRepositoryDependency: () => UnregisteredRepositoryDependency2,
65
+ UnregisteredUseCaseDependency: () => UnregisteredUseCaseDependency2
66
+ });
67
+
68
+ // src/core/logger/exceptions.ts
69
+ var exports_exceptions5 = {};
70
+ __export(exports_exceptions5, {
71
+ InvalidLogDeclaration: () => InvalidLogDeclaration2
72
+ });
73
+
74
+ // src/core/entity/exceptions.ts
75
+ var exports_exceptions6 = {};
76
+ __export(exports_exceptions6, {
56
77
  DeletedEntity: () => DeletedEntity2,
57
78
  ImmutableEntityKey: () => ImmutableEntityKey2,
58
79
  ReservedEntityKey: () => ReservedEntityKey2
59
80
  });
60
81
 
61
82
  // src/core/repository/exceptions.ts
62
- var exports_exceptions5 = {};
63
- __export(exports_exceptions5, {
83
+ var exports_exceptions7 = {};
84
+ __export(exports_exceptions7, {
64
85
  InvalidRepositoryData: () => InvalidRepositoryData2,
65
86
  InvalidRepositoryDeclaration: () => InvalidRepositoryDeclaration2,
66
87
  InvalidRepositoryEntity: () => InvalidRepositoryEntity2,
@@ -82,14 +103,14 @@ __export(exports_use_case, {
82
103
  });
83
104
 
84
105
  // src/core/use-case/exceptions.ts
85
- var exports_exceptions6 = {};
86
- __export(exports_exceptions6, {
106
+ var exports_exceptions8 = {};
107
+ __export(exports_exceptions8, {
87
108
  InvalidUseCaseStep: () => InvalidUseCaseStep2
88
109
  });
89
110
 
90
111
  // src/core/command/exceptions.ts
91
- var exports_exceptions7 = {};
92
- __export(exports_exceptions7, {
112
+ var exports_exceptions9 = {};
113
+ __export(exports_exceptions9, {
93
114
  CommandEventFailed: () => CommandEventFailed2,
94
115
  InvalidCommandContext: () => InvalidCommandContext2,
95
116
  InvalidCommandDeclaration: () => InvalidCommandDeclaration2,
@@ -97,29 +118,15 @@ __export(exports_exceptions7, {
97
118
  UnknownCommandOperation: () => UnknownCommandOperation2
98
119
  });
99
120
 
100
- // src/core/application/exceptions.ts
101
- var exports_exceptions8 = {};
102
- __export(exports_exceptions8, {
103
- ApplicationAlreadyStarted: () => ApplicationAlreadyStarted2,
104
- ApplicationConflict: () => ApplicationConflict2,
105
- ApplicationNotStarted: () => ApplicationNotStarted2,
106
- DuplicateApplicationDeclaration: () => DuplicateApplicationDeclaration2,
107
- InvalidApplicationDeclaration: () => InvalidApplicationDeclaration2,
108
- InvalidApplicationEnvironment: () => InvalidApplicationEnvironment2,
109
- UnregisteredApplicationReference: () => UnregisteredApplicationReference2,
110
- UnregisteredRepositoryDependency: () => UnregisteredRepositoryDependency2,
111
- UnregisteredUseCaseDependency: () => UnregisteredUseCaseDependency2
112
- });
113
-
114
121
  // src/core/openapi/exceptions.ts
115
- var exports_exceptions9 = {};
116
- __export(exports_exceptions9, {
122
+ var exports_exceptions10 = {};
123
+ __export(exports_exceptions10, {
117
124
  InvalidOpenAPIModel: () => InvalidOpenAPIModel2
118
125
  });
119
126
 
120
127
  // src/core/output/exceptions.ts
121
- var exports_exceptions10 = {};
122
- __export(exports_exceptions10, {
128
+ var exports_exceptions11 = {};
129
+ __export(exports_exceptions11, {
123
130
  DuplicateOperation: () => DuplicateOperation2,
124
131
  InvalidOutputStage: () => InvalidOutputStage2
125
132
  });
@@ -209,6 +216,281 @@ function guard2(scope, run, resolve) {
209
216
  }
210
217
  }
211
218
 
219
+ // src/core/application/exceptions.ts
220
+ var InvalidApplicationDeclaration2 = exceptionOf2({
221
+ layer: "application" /* Application */,
222
+ name: "InvalidApplicationDeclaration",
223
+ message: ({ reason }) => reason
224
+ });
225
+ var DuplicateApplicationDeclaration2 = exceptionOf2({
226
+ layer: "application" /* Application */,
227
+ name: "DuplicateApplicationDeclaration",
228
+ message: ({
229
+ first,
230
+ second
231
+ }) => `The same object is registered as ${first} and as ${second}.`
232
+ });
233
+ var ApplicationConflict2 = exceptionOf2({
234
+ layer: "application" /* Application */,
235
+ name: "ApplicationConflict",
236
+ message: ({
237
+ reason
238
+ }) => reason
239
+ });
240
+ var UnregisteredApplicationReference2 = exceptionOf2({
241
+ layer: "application" /* Application */,
242
+ name: "UnregisteredApplicationReference",
243
+ message: ({
244
+ holder,
245
+ reference
246
+ }) => `${holder} holds ${reference}, which is not registered in the application.`
247
+ });
248
+ var UnregisteredRepositoryDependency2 = exceptionOf2({
249
+ layer: "application" /* Application */,
250
+ name: "UnregisteredRepositoryDependency",
251
+ message: ({
252
+ repository,
253
+ dependency
254
+ }) => `Repository ${repository} depends on ${dependency}, which is not registered in the application.`
255
+ });
256
+ var UnregisteredUseCaseDependency2 = exceptionOf2({
257
+ layer: "application" /* Application */,
258
+ name: "UnregisteredUseCaseDependency",
259
+ message: ({
260
+ useCase,
261
+ dependency
262
+ }) => `Use case ${useCase} depends on ${dependency}, which is not registered in the application.`
263
+ });
264
+ var ApplicationNotStarted2 = exceptionOf2({
265
+ layer: "application" /* Application */,
266
+ name: "ApplicationNotStarted",
267
+ message: ({
268
+ application
269
+ }) => application === undefined ? "No application is started: call await app.start() first." : `The application "${application}" is not started: call await app.start() first.`
270
+ });
271
+ var ApplicationAlreadyStarted2 = exceptionOf2({
272
+ layer: "application" /* Application */,
273
+ name: "ApplicationAlreadyStarted",
274
+ message: ({
275
+ current,
276
+ attempted
277
+ }) => `The application "${current}" is already started, so "${attempted}" cannot be: stop it, or call start({ replace: true }).`
278
+ });
279
+ var InvalidApplicationEnvironment2 = exceptionOf2({
280
+ layer: "environment" /* Environment */,
281
+ name: "InvalidApplicationEnvironment",
282
+ message: ({
283
+ environments
284
+ }) => `Invalid environment variables: ${Object.entries(environments).map(([name, keys]) => `${name} (${keys.join(", ")})`).join("; ")}.`
285
+ });
286
+
287
+ // src/core/application/registry.ts
288
+ var SLOT = Symbol.for("afora.application");
289
+ function slot() {
290
+ const global = globalThis;
291
+ global[SLOT] ??= { current: undefined };
292
+ return global[SLOT];
293
+ }
294
+ function useApplication2() {
295
+ const { current } = slot();
296
+ if (current === undefined) {
297
+ throw new ApplicationNotStarted2({ source: "useApplication", details: {} });
298
+ }
299
+ return current;
300
+ }
301
+ function resetApplication2() {
302
+ slot().current = undefined;
303
+ }
304
+ function startedApplication() {
305
+ return slot().current;
306
+ }
307
+ function setStartedApplication(application) {
308
+ slot().current = application;
309
+ }
310
+
311
+ // src/core/logger/exceptions.ts
312
+ var InvalidLogDeclaration2 = exceptionOf2({
313
+ layer: "application" /* Application */,
314
+ name: "InvalidLogDeclaration",
315
+ message: ({ reason }) => reason
316
+ });
317
+
318
+ // src/core/logger/logger.ts
319
+ var LogLevels2 = Object.freeze([
320
+ "debug",
321
+ "info",
322
+ "warn",
323
+ "error"
324
+ ]);
325
+ var names = new WeakMap;
326
+ var invalid = (reason) => {
327
+ throw new InvalidLogDeclaration2({ source: "log", details: { reason } });
328
+ };
329
+ function logProviderOf2(settings) {
330
+ if (!settings || typeof settings.write !== "function") {
331
+ invalid("Expected a log provider with a write function.");
332
+ }
333
+ if (settings.flush !== undefined && typeof settings.flush !== "function") {
334
+ invalid("Expected flush to be a function.");
335
+ }
336
+ if (settings.name !== undefined && (typeof settings.name !== "string" || settings.name.trim() === "")) {
337
+ invalid("Expected the name of a log provider to be a non-empty string.");
338
+ }
339
+ const provider = Object.freeze({
340
+ write: settings.write,
341
+ ...settings.flush ? { flush: settings.flush } : {}
342
+ });
343
+ if (settings.name)
344
+ names.set(provider, settings.name);
345
+ return provider;
346
+ }
347
+ function logProviderNameOf(provider) {
348
+ return names.get(provider);
349
+ }
350
+ var fieldsText = (fields) => Object.keys(fields).length > 0 ? ` ${JSON.stringify(fields)}` : "";
351
+ function consoleLogProvider2() {
352
+ return logProviderOf2({
353
+ name: "console",
354
+ write: ({ at, level, event, fields, application }) => {
355
+ const line = `${at} ${level.toUpperCase()} [${application}] ${event}${fieldsText(fields)}`;
356
+ (level === "debug" ? console.debug : level === "info" ? console.info : level === "warn" ? console.warn : console.error)(line);
357
+ }
358
+ });
359
+ }
360
+ function jsonLogProvider2() {
361
+ return logProviderOf2({
362
+ name: "json",
363
+ write: (entry) => {
364
+ console.log(JSON.stringify({
365
+ at: entry.at,
366
+ level: entry.level,
367
+ application: entry.application,
368
+ event: entry.event,
369
+ ...entry.fields
370
+ }));
371
+ }
372
+ });
373
+ }
374
+ function memoryLogProvider2() {
375
+ const entries = [];
376
+ const provider = Object.freeze({
377
+ write: (entry) => {
378
+ entries.push(entry);
379
+ },
380
+ entries,
381
+ clear: () => {
382
+ entries.length = 0;
383
+ }
384
+ });
385
+ names.set(provider, "memory");
386
+ return provider;
387
+ }
388
+ function checkLogSettings(settings) {
389
+ if (typeof settings !== "object" || settings === null) {
390
+ return invalid("Expected `log` to be { level?, providers }.");
391
+ }
392
+ const { level = "info", providers } = settings;
393
+ if (!LogLevels2.includes(level)) {
394
+ invalid(`Expected the log level to be one of ${LogLevels2.join(", ")}.`);
395
+ }
396
+ if (!Array.isArray(providers) || providers.some((provider) => typeof provider !== "object" || provider === null || typeof provider.write !== "function")) {
397
+ invalid("Expected `log.providers` to be a list of log providers.");
398
+ }
399
+ return Object.freeze({ level, providers: Object.freeze([...providers]) });
400
+ }
401
+ var silentLogger = Object.freeze({
402
+ debug: () => {},
403
+ info: () => {},
404
+ warn: () => {},
405
+ error: () => {}
406
+ });
407
+ var rank = (level) => LogLevels2.indexOf(level);
408
+ function applicationLogger(application) {
409
+ let current;
410
+ const write = (level) => (event, fields = {}) => {
411
+ if (!current || rank(level) < rank(current.level))
412
+ return;
413
+ const entry = Object.freeze({
414
+ at: new Date().toISOString(),
415
+ level,
416
+ event,
417
+ fields,
418
+ application
419
+ });
420
+ for (const provider of current.providers) {
421
+ try {
422
+ const written = provider.write(entry);
423
+ if (written && typeof written.catch === "function") {
424
+ written.catch(() => {});
425
+ }
426
+ } catch {}
427
+ }
428
+ };
429
+ const logger = Object.freeze({
430
+ debug: write("debug"),
431
+ info: write("info"),
432
+ warn: write("warn"),
433
+ error: write("error")
434
+ });
435
+ return {
436
+ logger,
437
+ get settings() {
438
+ return current;
439
+ },
440
+ set(settings) {
441
+ current = settings;
442
+ },
443
+ async flush() {
444
+ await Promise.all((current?.providers ?? []).map((provider) => Promise.resolve().then(() => provider.flush?.()).catch(() => {})));
445
+ }
446
+ };
447
+ }
448
+ var Logger2 = Object.freeze({
449
+ [Kind2]: "logger"
450
+ });
451
+ function isLoggerDeclaration(value) {
452
+ return value === Logger2;
453
+ }
454
+ function isLogger(value) {
455
+ return typeof value === "object" && value !== null && ["debug", "info", "warn", "error"].every((level) => typeof value[level] === "function");
456
+ }
457
+ var ApplicationLoggerKey = Symbol("afora.application.logger");
458
+ function resolveLogger(scoped, owner) {
459
+ return scoped ?? owner?.[ApplicationLoggerKey] ?? startedApplication()?.[ApplicationLoggerKey];
460
+ }
461
+ function clock() {
462
+ return globalThis.performance?.now() ?? Date.now();
463
+ }
464
+ function elapsed(since) {
465
+ return Math.round(clock() - since);
466
+ }
467
+ var logged = new WeakSet;
468
+ function logFailure(logger, event, fields, error) {
469
+ if (!logger)
470
+ return;
471
+ const exception = error instanceof Exception2 ? error : undefined;
472
+ const key = exception?.origin ?? error;
473
+ if (typeof key === "object" && key !== null) {
474
+ if (logged.has(key))
475
+ return;
476
+ logged.add(key);
477
+ }
478
+ const unexpected = !exception || exception.origin.name === UNEXPECTED_ERROR2;
479
+ try {
480
+ logger[unexpected ? "error" : "warn"](event, {
481
+ ...fields,
482
+ exception: exception ? exception.toJSON() : { message: error instanceof Error ? error.message : String(error) }
483
+ });
484
+ } catch {}
485
+ }
486
+ function writeLog(logger, level, event, fields) {
487
+ if (!logger)
488
+ return;
489
+ try {
490
+ logger[level](event, fields);
491
+ } catch {}
492
+ }
493
+
212
494
  // src/core/entity/exceptions.ts
213
495
  var ReservedEntityKey2 = exceptionOf2({
214
496
  layer: "entity" /* Entity */,
@@ -291,8 +573,10 @@ function eventOf2(name, entityClass, handler) {
291
573
  return Object.freeze({
292
574
  name,
293
575
  entity,
294
- async handle() {
295
- await handler(entity);
576
+ async handle(context) {
577
+ await handler(entity, {
578
+ logger: context?.logger ?? resolveLogger(undefined, undefined) ?? silentLogger
579
+ });
296
580
  }
297
581
  });
298
582
  });
@@ -473,7 +757,7 @@ function frozenJson(value, subject, fail, seen = new Set) {
473
757
  // src/core/repository/provider.ts
474
758
  var descriptions = new WeakMap;
475
759
  var opaque = Object.freeze({ kind: "opaque" });
476
- function invalid(reason) {
760
+ function invalid2(reason) {
477
761
  throw new InvalidRepositoryDeclaration2({
478
762
  source: "providerOf",
479
763
  details: { reason }
@@ -481,13 +765,13 @@ function invalid(reason) {
481
765
  }
482
766
  function providerOf2(settings) {
483
767
  if (!settings || typeof settings.name !== "string" || settings.name.trim().length === 0 || typeof settings.create !== "function")
484
- invalid("Expected a provider name and create function.");
485
- const options = frozenJson(settings.options ?? {}, "Provider options", invalid);
768
+ invalid2("Expected a provider name and create function.");
769
+ const options = frozenJson(settings.options ?? {}, "Provider options", invalid2);
486
770
  if (options === null || typeof options !== "object" || Array.isArray(options))
487
- invalid("Provider options must be an object.");
771
+ invalid2("Provider options must be an object.");
488
772
  const provider = settings.create(options);
489
773
  if (!provider || typeof provider !== "object" || ["findOne", "findMany", "insert", "update", "remove", "count"].some((key) => typeof provider[key] !== "function"))
490
- invalid("Expected a repository provider from create.");
774
+ invalid2("Expected a repository provider from create.");
491
775
  descriptions.set(provider, Object.freeze({
492
776
  kind: "provider",
493
777
  name: settings.name,
@@ -576,11 +860,11 @@ function matchesQuery(data, query) {
576
860
  function codePoints(text) {
577
861
  return Array.from(text, (char) => char.codePointAt(0));
578
862
  }
579
- function rank(value) {
863
+ function rank2(value) {
580
864
  return value instanceof Date ? 1 : { number: 0, bigint: 0, string: 2, boolean: 3 }[typeof value] ?? 4;
581
865
  }
582
866
  function compareScalars(a, b) {
583
- const [left, right] = [rank(a), rank(b)];
867
+ const [left, right] = [rank2(a), rank2(b)];
584
868
  if (left !== right)
585
869
  return left - right;
586
870
  if (typeof a === "string" && typeof b === "string") {
@@ -1138,25 +1422,25 @@ function unknownAction(entity, action, methods) {
1138
1422
  }
1139
1423
  return `"${action}" is not an action of ${entity}.`;
1140
1424
  }
1141
- function invalid2(source, reason) {
1425
+ function invalid3(source, reason) {
1142
1426
  throw new InvalidRepositoryDeclaration2({ source, details: { reason } });
1143
1427
  }
1144
1428
  function repositoryOf2(settings) {
1145
1429
  const { entity, actions, environmentDependencies } = settings ?? {};
1146
1430
  if (!isEntityClass2(entity) || !(EntityUniqueKeys2 in entity)) {
1147
- invalid2("repositoryOf", "Expected an entity class made by entityOf.");
1431
+ invalid3("repositoryOf", "Expected an entity class made by entityOf.");
1148
1432
  }
1149
1433
  const name = `${entity.name}Repository`;
1150
1434
  const deletion = settings.deletion ?? "hard";
1151
1435
  if (deletion !== "hard" && deletion !== "soft") {
1152
- invalid2(name, 'Expected deletion to be "hard" or "soft".');
1436
+ invalid3(name, 'Expected deletion to be "hard" or "soft".');
1153
1437
  }
1154
1438
  const provider = settings.provider ?? inMemoryProvider2();
1155
1439
  if (!Array.isArray(actions) || actions.length === 0) {
1156
- invalid2(name, "Expected a list of actions.");
1440
+ invalid3(name, "Expected a list of actions.");
1157
1441
  }
1158
1442
  if (environmentDependencies !== undefined && !isEnvironment2(environmentDependencies) && !(Array.isArray(environmentDependencies) && environmentDependencies.every(isEnvironment2))) {
1159
- invalid2(name, "Expected environments made by environmentOf.");
1443
+ invalid3(name, "Expected environments made by environmentOf.");
1160
1444
  }
1161
1445
  const relations = relationsOf(name, entity, settings.relations);
1162
1446
  const unique = entity[EntityUniqueKeys2];
@@ -1182,12 +1466,12 @@ function repositoryOf2(settings) {
1182
1466
  for (const name_ of new Set(actions)) {
1183
1467
  const method = typeof name_ === "string" ? methods.get(name_) : undefined;
1184
1468
  if (!method)
1185
- invalid2(name, unknownAction(entity.name, String(name_), methods));
1469
+ invalid3(name, unknownAction(entity.name, String(name_), methods));
1186
1470
  const [kind, implementation] = method;
1187
1471
  const needs = deletion === "soft" && kind === "delete" ? ["findOne", "update"] : NEEDS[kind] ?? [];
1188
1472
  for (const need of needs) {
1189
1473
  if (typeof provider?.[need] !== "function") {
1190
- invalid2(name, `The provider has no "${need}" for "${name_}".`);
1474
+ invalid3(name, `The provider has no "${need}" for "${name_}".`);
1191
1475
  }
1192
1476
  }
1193
1477
  Object.defineProperty(DeclaredRepository.prototype, name_, {
@@ -1211,7 +1495,7 @@ function repositoryOf2(settings) {
1211
1495
  }
1212
1496
  function RepositoryOf2(repository) {
1213
1497
  if (!isRepository2(repository)) {
1214
- invalid2("RepositoryOf", "Expected a repository made by repositoryOf.");
1498
+ invalid3("RepositoryOf", "Expected a repository made by repositoryOf.");
1215
1499
  }
1216
1500
  return repository.constructor;
1217
1501
  }
@@ -1719,6 +2003,9 @@ var InvalidUseCaseDependencies2 = exceptionOf2({
1719
2003
  name: "InvalidUseCaseDependencies",
1720
2004
  message: "Dependency overrides must contain only declared names: functions for use cases, objects of methods for repositories, and valid variables for environments."
1721
2005
  });
2006
+ function loggerOfCall(state) {
2007
+ return resolveLogger(state.scope?.logger, state.owner);
2008
+ }
1722
2009
  var states2 = new WeakMap;
1723
2010
  function invalidValue(issues, source, phase) {
1724
2011
  throw new Exception2({
@@ -1773,6 +2060,7 @@ function methodNamesOf(repository) {
1773
2060
  }
1774
2061
  function bindRepository2(repository, overrides, state, source) {
1775
2062
  const Entity = repository.entity;
2063
+ const repositoryName = Entity.name;
1776
2064
  const bound = Object.create(null);
1777
2065
  const view = new Proxy(Object.create(repository), {
1778
2066
  get: (_target, key, receiver) => {
@@ -1793,7 +2081,14 @@ function bindRepository2(repository, overrides, state, source) {
1793
2081
  bound[name] = async (...args) => {
1794
2082
  if (!state.active)
1795
2083
  throw new InvalidUseCaseDependencies2({ source });
2084
+ const started = clock();
1796
2085
  const result = await method.apply(receiver, args);
2086
+ writeLog(loggerOfCall(state), "debug", "repository", {
2087
+ repository: repositoryName,
2088
+ method: name,
2089
+ useCase: source,
2090
+ ms: elapsed(started)
2091
+ });
1797
2092
  for (const arg of args)
1798
2093
  pullEntities(arg, Entity, state.events);
1799
2094
  pullEntities(result, Entity, state.events);
@@ -1828,6 +2123,8 @@ function narrowedContext(Child, parent) {
1828
2123
  return picked;
1829
2124
  }
1830
2125
  function isOverrideOf(dependency, value) {
2126
+ if (isLoggerDeclaration(dependency))
2127
+ return isLogger(value);
1831
2128
  if (isRepository2(dependency) || isEnvironment2(dependency)) {
1832
2129
  return typeof value === "object" && value !== null && !Array.isArray(value);
1833
2130
  }
@@ -1873,7 +2170,8 @@ class AbstractUseCase2 {
1873
2170
  started: false,
1874
2171
  active: false,
1875
2172
  events: [],
1876
- dependencies: Object.create(null)
2173
+ dependencies: Object.create(null),
2174
+ owner: this.constructor
1877
2175
  };
1878
2176
  states2.set(this, state);
1879
2177
  for (const [key, dependency] of Object.entries(declaration.dependencies)) {
@@ -1881,6 +2179,13 @@ class AbstractUseCase2 {
1881
2179
  state.dependencies[key] = bindRepository2(dependency, undefined, state, source);
1882
2180
  continue;
1883
2181
  }
2182
+ if (isLoggerDeclaration(dependency)) {
2183
+ Object.defineProperty(state.dependencies, key, {
2184
+ get: () => loggerOfCall(state) ?? silentLogger,
2185
+ enumerable: true
2186
+ });
2187
+ continue;
2188
+ }
1884
2189
  if (isEnvironment2(dependency)) {
1885
2190
  Object.defineProperty(state.dependencies, key, {
1886
2191
  get: () => state.scope?.environments?.get(dependency) ?? dependency.load(),
@@ -1925,6 +2230,10 @@ class AbstractUseCase2 {
1925
2230
  dependencies[key] = bindRepository2(dependency, substitute, state, source);
1926
2231
  continue;
1927
2232
  }
2233
+ if (isLoggerDeclaration(dependency)) {
2234
+ dependencies[key] = substitute;
2235
+ continue;
2236
+ }
1928
2237
  if (isEnvironment2(dependency)) {
1929
2238
  const parsed = dependency.blueprint.safeParse(substitute);
1930
2239
  if (parsed.issues)
@@ -1949,13 +2258,22 @@ class AbstractUseCase2 {
1949
2258
  }
1950
2259
  state.resolved = Object.freeze(dependencies);
1951
2260
  state.active = true;
2261
+ const started = clock();
1952
2262
  try {
1953
2263
  const result = await guard2({ layer: "use-case" /* UseCase */, source }, () => implementation.call(this, state.resolved));
1954
2264
  const parsed = declaration.response.safeParse(result);
1955
2265
  if (parsed.issues)
1956
2266
  invalidValue(parsed.issues, source, "response");
1957
2267
  collectEvents(declaration.response, parsed.value, state.events);
2268
+ writeLog(loggerOfCall(state), "debug", "use-case", {
2269
+ useCase: source,
2270
+ outcome: "ok",
2271
+ ms: elapsed(started)
2272
+ });
1958
2273
  return parsed.value;
2274
+ } catch (error) {
2275
+ logFailure(loggerOfCall(state), "use-case-failed", { useCase: source, ms: elapsed(started) }, error);
2276
+ throw error;
1959
2277
  } finally {
1960
2278
  state.active = false;
1961
2279
  state.resolved = undefined;
@@ -1981,7 +2299,7 @@ function useCaseOf2(settings) {
1981
2299
  throw new InvalidUseCaseDeclaration2({
1982
2300
  source: typeof name === "string" ? name : "useCaseOf",
1983
2301
  details: {
1984
- reason: "Expected a name, input and response blueprints, and UseCase classes, repositories or environments as dependencies."
2302
+ reason: "Expected a name, input and response blueprints, and UseCase classes, repositories, environments or Logger as dependencies."
1985
2303
  }
1986
2304
  });
1987
2305
  }
@@ -2037,7 +2355,7 @@ function useCaseOf2(settings) {
2037
2355
  return DeclaredUseCase;
2038
2356
  }
2039
2357
  function isDependency(value) {
2040
- return isUseCaseClass2(value) || isRepository2(value) || isEnvironment2(value);
2358
+ return isUseCaseClass2(value) || isRepository2(value) || isEnvironment2(value) || isLoggerDeclaration(value);
2041
2359
  }
2042
2360
  function isUseCaseClass2(value) {
2043
2361
  return typeof value === "function" && value.prototype instanceof AbstractUseCase2 && value[Kind2] === "use-case" && typeof value.prototype.execute === "function";
@@ -2283,9 +2601,16 @@ function commandOf2(settings) {
2283
2601
  given = narrowed(UseCase, callContext);
2284
2602
  }
2285
2603
  const overrides = options?.env === undefined ? undefined : callEnvironment(where, environments, options.env);
2286
- const withEnvironments = (scope) => overrides === undefined || overrides.byEnvironment.size === 0 ? scope : {
2287
- providers: scope?.providers ?? new Map,
2288
- environments: overrides.byEnvironment
2604
+ const logger = resolveLogger(undefined, UseCase);
2605
+ const withEnvironments = (scope) => {
2606
+ const environmentsOfCall = overrides === undefined || overrides.byEnvironment.size === 0 ? scope?.environments : overrides.byEnvironment;
2607
+ if (!environmentsOfCall && !logger)
2608
+ return scope;
2609
+ return {
2610
+ providers: scope?.providers ?? new Map,
2611
+ ...environmentsOfCall ? { environments: environmentsOfCall } : {},
2612
+ ...logger ? { logger } : {}
2613
+ };
2289
2614
  };
2290
2615
  const run = async (declared) => {
2291
2616
  const scope = withEnvironments(declared);
@@ -2294,11 +2619,20 @@ function commandOf2(settings) {
2294
2619
  return { value, events: useCase.pullEvents() };
2295
2620
  };
2296
2621
  const provider = providerOfCall();
2297
- const outcome = await guard2({ layer: "command" /* Command */, source: where }, () => provider?.transaction ? provider.transaction((scoped) => run({ providers: new Map([[provider, scoped]]) })) : run(undefined));
2622
+ const started = clock();
2623
+ const outcome = await guard2({ layer: "command" /* Command */, source: where }, () => provider?.transaction ? provider.transaction((scoped) => run({ providers: new Map([[provider, scoped]]) })) : run(undefined)).catch((error) => {
2624
+ logFailure(logger, "command-failed", { command: where, ms: elapsed(started) }, error);
2625
+ throw error;
2626
+ });
2627
+ writeLog(logger, "debug", "command", {
2628
+ command: where,
2629
+ ms: elapsed(started)
2630
+ });
2298
2631
  return {
2299
2632
  ...outcome,
2300
2633
  context: callContext,
2301
- env: () => overrides?.merged ?? loadEnvironments(environments)
2634
+ env: () => overrides?.merged ?? loadEnvironments(environments),
2635
+ logger: logger ?? silentLogger
2302
2636
  };
2303
2637
  };
2304
2638
  const command = {
@@ -2325,13 +2659,15 @@ function commandOf2(settings) {
2325
2659
  value,
2326
2660
  events: raised,
2327
2661
  context: callContext,
2328
- env
2662
+ env,
2663
+ logger
2329
2664
  } = await perform(op, input, options);
2330
2665
  await applyPolicy(command, events, onEventError, {
2331
2666
  operation: op,
2332
2667
  raised,
2333
2668
  context: callContext,
2334
- env
2669
+ env,
2670
+ logger
2335
2671
  });
2336
2672
  return value;
2337
2673
  }
@@ -2351,7 +2687,8 @@ async function applyPolicy(command, policy, onEventError, call) {
2351
2687
  context: call.context,
2352
2688
  get env() {
2353
2689
  return call.env();
2354
- }
2690
+ },
2691
+ logger: call.logger
2355
2692
  };
2356
2693
  if (typeof policy === "function") {
2357
2694
  try {
@@ -2367,7 +2704,7 @@ async function applyPolicy(command, policy, onEventError, call) {
2367
2704
  }
2368
2705
  for (const [index, event] of raised.entries()) {
2369
2706
  try {
2370
- await event.handle();
2707
+ await event.handle({ logger: call.logger });
2371
2708
  } catch (cause) {
2372
2709
  if (!onEventError) {
2373
2710
  throw new CommandEventFailed2({
@@ -2402,74 +2739,6 @@ function isCommand2(value) {
2402
2739
  return typeof value === "object" && value !== null && value[Kind2] === "command";
2403
2740
  }
2404
2741
 
2405
- // src/core/application/exceptions.ts
2406
- var InvalidApplicationDeclaration2 = exceptionOf2({
2407
- layer: "application" /* Application */,
2408
- name: "InvalidApplicationDeclaration",
2409
- message: ({ reason }) => reason
2410
- });
2411
- var DuplicateApplicationDeclaration2 = exceptionOf2({
2412
- layer: "application" /* Application */,
2413
- name: "DuplicateApplicationDeclaration",
2414
- message: ({
2415
- first,
2416
- second
2417
- }) => `The same object is registered as ${first} and as ${second}.`
2418
- });
2419
- var ApplicationConflict2 = exceptionOf2({
2420
- layer: "application" /* Application */,
2421
- name: "ApplicationConflict",
2422
- message: ({
2423
- reason
2424
- }) => reason
2425
- });
2426
- var UnregisteredApplicationReference2 = exceptionOf2({
2427
- layer: "application" /* Application */,
2428
- name: "UnregisteredApplicationReference",
2429
- message: ({
2430
- holder,
2431
- reference
2432
- }) => `${holder} holds ${reference}, which is not registered in the application.`
2433
- });
2434
- var UnregisteredRepositoryDependency2 = exceptionOf2({
2435
- layer: "application" /* Application */,
2436
- name: "UnregisteredRepositoryDependency",
2437
- message: ({
2438
- repository,
2439
- dependency
2440
- }) => `Repository ${repository} depends on ${dependency}, which is not registered in the application.`
2441
- });
2442
- var UnregisteredUseCaseDependency2 = exceptionOf2({
2443
- layer: "application" /* Application */,
2444
- name: "UnregisteredUseCaseDependency",
2445
- message: ({
2446
- useCase,
2447
- dependency
2448
- }) => `Use case ${useCase} depends on ${dependency}, which is not registered in the application.`
2449
- });
2450
- var ApplicationNotStarted2 = exceptionOf2({
2451
- layer: "application" /* Application */,
2452
- name: "ApplicationNotStarted",
2453
- message: ({
2454
- application
2455
- }) => application === undefined ? "No application is started: call await app.start() first." : `The application "${application}" is not started: call await app.start() first.`
2456
- });
2457
- var ApplicationAlreadyStarted2 = exceptionOf2({
2458
- layer: "application" /* Application */,
2459
- name: "ApplicationAlreadyStarted",
2460
- message: ({
2461
- current,
2462
- attempted
2463
- }) => `The application "${current}" is already started, so "${attempted}" cannot be: stop it, or call start({ replace: true }).`
2464
- });
2465
- var InvalidApplicationEnvironment2 = exceptionOf2({
2466
- layer: "environment" /* Environment */,
2467
- name: "InvalidApplicationEnvironment",
2468
- message: ({
2469
- environments
2470
- }) => `Invalid environment variables: ${Object.entries(environments).map(([name, keys]) => `${name} (${keys.join(", ")})`).join("; ")}.`
2471
- });
2472
-
2473
2742
  // src/core/openapi/exceptions.ts
2474
2743
  var InvalidOpenAPIModel2 = exceptionOf2({
2475
2744
  layer: "output" /* Output */,
@@ -2502,18 +2771,19 @@ function isExportedException(Declared) {
2502
2771
  if (!collected) {
2503
2772
  collected = true;
2504
2773
  for (const module of [
2505
- exports_exceptions8,
2506
- exports_exceptions2,
2507
- exports_exceptions7,
2508
2774
  exports_exceptions4,
2509
- exports_environment,
2775
+ exports_exceptions2,
2510
2776
  exports_exceptions9,
2777
+ exports_exceptions6,
2778
+ exports_environment,
2779
+ exports_exceptions5,
2511
2780
  exports_exceptions10,
2781
+ exports_exceptions11,
2512
2782
  exports_exceptions3,
2513
2783
  exports_exceptions,
2514
- exports_exceptions5,
2784
+ exports_exceptions7,
2515
2785
  exports_use_case,
2516
- exports_exceptions6
2786
+ exports_exceptions8
2517
2787
  ]) {
2518
2788
  markExported(...Object.values(module));
2519
2789
  }
@@ -2635,28 +2905,28 @@ function toOpenAPI2(modelOrModels, { refPrefix = "#/components/schemas/" } = {})
2635
2905
  var descriptions2 = new WeakMap;
2636
2906
  var factories = new WeakMap;
2637
2907
  var opaque2 = Object.freeze({ kind: "opaque" });
2638
- function invalid3(source, reason) {
2908
+ function invalid4(source, reason) {
2639
2909
  throw new InvalidOutputStage2({ source, details: { reason } });
2640
2910
  }
2641
2911
  function optionsOf(name, given, validate) {
2642
- const options = frozenJson(given ?? {}, "Stage options", (reason) => invalid3(name, reason));
2912
+ const options = frozenJson(given ?? {}, "Stage options", (reason) => invalid4(name, reason));
2643
2913
  if (options === null || typeof options !== "object" || Array.isArray(options)) {
2644
- invalid3(name, "Stage options must be an object.");
2914
+ invalid4(name, "Stage options must be an object.");
2645
2915
  }
2646
2916
  const reason = validate?.(options);
2647
2917
  if (reason !== undefined)
2648
- invalid3(name, reason);
2918
+ invalid4(name, reason);
2649
2919
  return options;
2650
2920
  }
2651
2921
  function checkName(source, name) {
2652
2922
  if (typeof name !== "string" || !name.trim()) {
2653
- invalid3(source, "Expected the stage name to be a non-empty string.");
2923
+ invalid4(source, "Expected the stage name to be a non-empty string.");
2654
2924
  }
2655
2925
  }
2656
2926
  function transformOf2(settings) {
2657
2927
  checkName("transformOf", settings?.name);
2658
2928
  if (typeof settings.apply !== "function") {
2659
- invalid3(settings.name, "Expected apply to be a function.");
2929
+ invalid4(settings.name, "Expected apply to be a function.");
2660
2930
  }
2661
2931
  const { name, apply, validate } = settings;
2662
2932
  const factory = (given) => {
@@ -2680,7 +2950,7 @@ function transformOf2(settings) {
2680
2950
  function sinkOf2(settings) {
2681
2951
  checkName("sinkOf", settings?.name);
2682
2952
  if (typeof settings.build !== "function") {
2683
- invalid3(settings.name, "Expected build to be a function.");
2953
+ invalid4(settings.name, "Expected build to be a function.");
2684
2954
  }
2685
2955
  const { name, build, validate } = settings;
2686
2956
  const factory = (given) => {
@@ -2718,10 +2988,10 @@ function stageCatalogOf2(...stages) {
2718
2988
  for (const factory of stages) {
2719
2989
  const known = factories.get(factory);
2720
2990
  if (!known) {
2721
- invalid3("catalog", "A catalog takes factories made by `transformOf` or `sinkOf`.");
2991
+ invalid4("catalog", "A catalog takes factories made by `transformOf` or `sinkOf`.");
2722
2992
  }
2723
2993
  if (Object.hasOwn(byName, known.name)) {
2724
- invalid3(known.name, "The catalog has another stage with its name.");
2994
+ invalid4(known.name, "The catalog has another stage with its name.");
2725
2995
  }
2726
2996
  byName[known.name] = factory;
2727
2997
  }
@@ -2732,7 +3002,7 @@ function stageCatalogOf2(...stages) {
2732
3002
  resolve(name, options) {
2733
3003
  const factory = Object.hasOwn(byName, name) ? byName[name] : undefined;
2734
3004
  if (!factory)
2735
- invalid3("catalog", `Unknown stage "${name}".`);
3005
+ invalid4("catalog", `Unknown stage "${name}".`);
2736
3006
  return factory(options);
2737
3007
  }
2738
3008
  });
@@ -2742,38 +3012,38 @@ function stageCatalogOf2(...stages) {
2742
3012
  function isApplicationLike(value) {
2743
3013
  return typeof value === "object" && value !== null && value[Kind2] === "application";
2744
3014
  }
2745
- function invalid4(source, reason) {
3015
+ function invalid5(source, reason) {
2746
3016
  throw new InvalidOutputStage2({ source, details: { reason } });
2747
3017
  }
2748
3018
  var PATCHABLE = ["meta", "tags", "description", "deprecated", "invoke"];
2749
3019
  function operationOf2(operation, patch) {
2750
3020
  const source = operation?.id ?? "operationOf";
2751
3021
  if (operation?.kind !== "operation" || operation.version !== 1) {
2752
- invalid4(source, "Expected an operation descriptor.");
3022
+ invalid5(source, "Expected an operation descriptor.");
2753
3023
  }
2754
3024
  if (typeof patch !== "object" || patch === null || Array.isArray(patch)) {
2755
- invalid4(source, "Expected the patch to be an object.");
3025
+ invalid5(source, "Expected the patch to be an object.");
2756
3026
  }
2757
3027
  for (const key of Reflect.ownKeys(patch)) {
2758
3028
  if (typeof key !== "string" || !PATCHABLE.includes(key)) {
2759
- invalid4(source, `"${String(key)}" cannot be patched; only ${PATCHABLE.join(", ")} can.`);
3029
+ invalid5(source, `"${String(key)}" cannot be patched; only ${PATCHABLE.join(", ")} can.`);
2760
3030
  }
2761
3031
  }
2762
3032
  const { meta, tags, description, deprecated, invoke } = patch;
2763
3033
  if ("meta" in patch && (typeof meta !== "object" || meta === null || Array.isArray(meta))) {
2764
- invalid4(source, "Expected meta to be an object.");
3034
+ invalid5(source, "Expected meta to be an object.");
2765
3035
  }
2766
3036
  if ("tags" in patch && (!Array.isArray(tags) || tags.some((tag) => typeof tag !== "string"))) {
2767
- invalid4(source, "Expected tags to be a list of strings.");
3037
+ invalid5(source, "Expected tags to be a list of strings.");
2768
3038
  }
2769
3039
  if ("description" in patch && description !== undefined && typeof description !== "string") {
2770
- invalid4(source, "Expected description to be a string.");
3040
+ invalid5(source, "Expected description to be a string.");
2771
3041
  }
2772
3042
  if ("deprecated" in patch && typeof deprecated !== "boolean") {
2773
- invalid4(source, "Expected deprecated to be a boolean.");
3043
+ invalid5(source, "Expected deprecated to be a boolean.");
2774
3044
  }
2775
3045
  if ("invoke" in patch && typeof invoke !== "function") {
2776
- invalid4(source, "Expected invoke to be a function.");
3046
+ invalid5(source, "Expected invoke to be a function.");
2777
3047
  }
2778
3048
  return Object.freeze({
2779
3049
  ...operation,
@@ -2814,25 +3084,25 @@ function statusesOf(name, statuses) {
2814
3084
  if (statuses === undefined)
2815
3085
  return Object.freeze({});
2816
3086
  if (typeof statuses !== "object" || statuses === null || Array.isArray(statuses)) {
2817
- invalid4(name, "Expected statuses to be a map of exception names to statuses.");
3087
+ invalid5(name, "Expected statuses to be a map of exception names to statuses.");
2818
3088
  }
2819
3089
  for (const [exception, status] of Object.entries(statuses)) {
2820
3090
  if (!exception || typeof status !== "number" || !Number.isInteger(status) || status < 400 || status > 599) {
2821
- invalid4(name, `Expected the status of "${exception}" to be an integer between 400 and 599.`);
3091
+ invalid5(name, `Expected the status of "${exception}" to be an integer between 400 and 599.`);
2822
3092
  }
2823
3093
  }
2824
3094
  return Object.freeze({ ...statuses });
2825
3095
  }
2826
3096
  function checkPipe(name, pipe) {
2827
3097
  if (!Array.isArray(pipe))
2828
- invalid4(name, "Expected pipe to be a list of stages.");
3098
+ invalid5(name, "Expected pipe to be a list of stages.");
2829
3099
  const stages = pipe;
2830
3100
  stages.forEach((stage, index) => {
2831
3101
  if (!isStage(stage)) {
2832
- invalid4(name, `Expected pipe[${index}] to be a transform or sink stage.`);
3102
+ invalid5(name, `Expected pipe[${index}] to be a transform or sink stage.`);
2833
3103
  }
2834
3104
  if (stage.kind === "sink" && index !== stages.length - 1) {
2835
- invalid4(name, `The sink at pipe[${index}] must be the last stage.`);
3105
+ invalid5(name, `The sink at pipe[${index}] must be the last stage.`);
2836
3106
  }
2837
3107
  });
2838
3108
  return Object.freeze([...stages]);
@@ -2848,7 +3118,7 @@ function transformed(name, operations, transforms, context) {
2848
3118
  if (result === null)
2849
3119
  continue;
2850
3120
  if (typeof result !== "object" || result?.kind !== "operation" || result.id !== operation.id) {
2851
- invalid4(name, `A transform must return the operation "${operation.id}" or null.`);
3121
+ invalid5(name, `A transform must return the operation "${operation.id}" or null.`);
2852
3122
  }
2853
3123
  next.push(result);
2854
3124
  }
@@ -2873,7 +3143,7 @@ function make(name, commands, operations, stages, statuses) {
2873
3143
  return built.value;
2874
3144
  const sink = stages.at(-1);
2875
3145
  if (sink?.kind !== "sink") {
2876
- invalid4(name || "output", "The pipe has no sink to build.");
3146
+ invalid5(name || "output", "The pipe has no sink to build.");
2877
3147
  }
2878
3148
  built = { value: sink.build(operations, context) };
2879
3149
  return built.value;
@@ -2882,7 +3152,7 @@ function make(name, commands, operations, stages, statuses) {
2882
3152
  const next = checkPipe(name || "output", more);
2883
3153
  const last = next.at(-1);
2884
3154
  if (stages.at(-1)?.kind === "sink") {
2885
- invalid4(name || "output", "Cannot add stages after the sink.");
3155
+ invalid5(name || "output", "Cannot add stages after the sink.");
2886
3156
  }
2887
3157
  const ops = transformed(name, operations, next, context);
2888
3158
  if (last?.kind === "sink") {
@@ -2896,11 +3166,11 @@ function make(name, commands, operations, stages, statuses) {
2896
3166
  function outputOf2(settings) {
2897
3167
  const { name, commands } = settings ?? {};
2898
3168
  if (typeof name !== "string" || !name.trim()) {
2899
- invalid4("outputOf", "Expected name to be a non-empty string.");
3169
+ invalid5("outputOf", "Expected name to be a non-empty string.");
2900
3170
  }
2901
3171
  const sources = Array.isArray(commands) ? commands : [commands];
2902
3172
  if (!Array.isArray(commands) && isCommand2(commands) || sources.some((entry) => !isCommand2(entry) && !isApplicationLike(entry))) {
2903
- invalid4(name, "Expected commands to be a list of commands made by commandOf or applications.");
3173
+ invalid5(name, "Expected commands to be a list of commands made by commandOf or applications.");
2904
3174
  }
2905
3175
  const flat = [
2906
3176
  ...new Set(sources.flatMap((entry) => isCommand2(entry) ? [entry] : Object.values(entry.commands)))
@@ -2944,32 +3214,16 @@ function describeSteps(steps, names) {
2944
3214
  });
2945
3215
  }
2946
3216
 
2947
- // src/core/application/registry.ts
2948
- var SLOT = Symbol.for("afora.application");
2949
- function slot() {
2950
- const global = globalThis;
2951
- global[SLOT] ??= { current: undefined };
2952
- return global[SLOT];
2953
- }
2954
- function useApplication2() {
2955
- const { current } = slot();
2956
- if (current === undefined) {
2957
- throw new ApplicationNotStarted2({ source: "useApplication", details: {} });
2958
- }
2959
- return current;
2960
- }
2961
- function resetApplication2() {
2962
- slot().current = undefined;
2963
- }
2964
- function startedApplication() {
2965
- return slot().current;
2966
- }
2967
- function setStartedApplication(application) {
2968
- slot().current = application;
2969
- }
2970
-
2971
3217
  // src/core/application/start.ts
2972
3218
  function providerFrom2(environmentDependencies, create) {
3219
+ if (typeof environmentDependencies === "function" && create === undefined) {
3220
+ return Object.freeze({
3221
+ [Kind2]: "provider-factory",
3222
+ environments: Object.freeze([]),
3223
+ create: environmentDependencies,
3224
+ withContext: true
3225
+ });
3226
+ }
2973
3227
  const list = isEnvironment2(environmentDependencies) ? [environmentDependencies] : Array.isArray(environmentDependencies) ? [...environmentDependencies] : [null];
2974
3228
  if (!list.every(isEnvironment2) || new Set(list).size !== list.length || typeof create !== "function") {
2975
3229
  throw new InvalidApplicationDeclaration2({
@@ -2982,9 +3236,22 @@ function providerFrom2(environmentDependencies, create) {
2982
3236
  return Object.freeze({
2983
3237
  [Kind2]: "provider-factory",
2984
3238
  environments: Object.freeze(list),
2985
- create
3239
+ create,
3240
+ withContext: false
2986
3241
  });
2987
3242
  }
3243
+ function logFrom2(create) {
3244
+ if (typeof create !== "function") {
3245
+ throw new InvalidApplicationDeclaration2({
3246
+ source: "logFrom",
3247
+ details: { reason: "Expected logFrom to take a create function." }
3248
+ });
3249
+ }
3250
+ return Object.freeze({ [Kind2]: "log-factory", create });
3251
+ }
3252
+ function isLogFactory2(value) {
3253
+ return typeof value === "object" && value !== null && value[Kind2] === "log-factory";
3254
+ }
2988
3255
  function isProviderFactory2(value) {
2989
3256
  return typeof value === "object" && value !== null && value[Kind2] === "provider-factory";
2990
3257
  }
@@ -3041,12 +3308,12 @@ function isDeferredProvider(provider) {
3041
3308
  function deferredEnvironments(provider) {
3042
3309
  return (typeof provider === "object" && provider !== null ? deferred.get(provider)?.factory.environments : undefined) ?? [];
3043
3310
  }
3044
- function startDeferred(provider) {
3311
+ function startDeferred(provider, context) {
3045
3312
  const state = deferred.get(provider);
3046
3313
  if (!state)
3047
3314
  return;
3048
3315
  state.starting ??= (async () => {
3049
- const made = await state.factory.create(loadEnvironments(state.factory.environments));
3316
+ const made = await state.factory.create(state.factory.withContext ? context : loadEnvironments(state.factory.environments));
3050
3317
  if (typeof made !== "object" || made === null) {
3051
3318
  state.starting = undefined;
3052
3319
  throw new InvalidApplicationDeclaration2({
@@ -3099,6 +3366,7 @@ var KEYS = [
3099
3366
  "exceptions"
3100
3367
  ];
3101
3368
  var internals = new WeakMap;
3369
+ var logSettings = new WeakMap;
3102
3370
  var KIND_OF = {
3103
3371
  properties: "property",
3104
3372
  blueprints: "blueprint",
@@ -3114,7 +3382,7 @@ var KIND_OF = {
3114
3382
  function isApplication2(value) {
3115
3383
  return typeof value === "object" && value !== null && value[Kind2] === "application";
3116
3384
  }
3117
- function invalid5(source, reason) {
3385
+ function invalid6(source, reason) {
3118
3386
  throw new InvalidApplicationDeclaration2({ source, details: { reason } });
3119
3387
  }
3120
3388
  function isOfKind(collection, value) {
@@ -3199,7 +3467,7 @@ function resolve(settings) {
3199
3467
  for (const other of settings.extends ?? []) {
3200
3468
  const resolved = internals.get(other);
3201
3469
  if (!resolved)
3202
- invalid5(source, "Expected `extends` to hold applications.");
3470
+ invalid6(source, "Expected `extends` to hold applications.");
3203
3471
  for (const key of KEYS) {
3204
3472
  for (const entry of resolved[key].values())
3205
3473
  add(entry);
@@ -3210,15 +3478,15 @@ function resolve(settings) {
3210
3478
  if (declared === undefined)
3211
3479
  continue;
3212
3480
  if (typeof declared !== "object" || declared === null || Array.isArray(declared)) {
3213
- invalid5(source, `Expected ${collection} to be an object of declarations.`);
3481
+ invalid6(source, `Expected ${collection} to be an object of declarations.`);
3214
3482
  }
3215
3483
  for (const [name, value] of Object.entries(declared)) {
3216
3484
  if (!isOfKind(collection, value)) {
3217
- invalid5(source, `${collection}.${name} is not a ${KIND_OF[collection]} (${collection} takes ${KIND_OF[collection]} declarations).`);
3485
+ invalid6(source, `${collection}.${name} is not a ${KIND_OF[collection]} (${collection} takes ${KIND_OF[collection]} declarations).`);
3218
3486
  }
3219
3487
  const declaredName = collection === "useCases" ? value.useCaseName : collection === "commands" ? value.commandName : collection === "outputs" ? value.outputName : collection === "exceptions" ? value.name : name;
3220
3488
  if (declaredName !== name) {
3221
- invalid5(source, `${collection}.${name} must be keyed by its name, "${declaredName}".`);
3489
+ invalid6(source, `${collection}.${name} must be keyed by its name, "${declaredName}".`);
3222
3490
  }
3223
3491
  add({
3224
3492
  collection,
@@ -3339,7 +3607,7 @@ function validateOutputs(source, registry) {
3339
3607
  for (const entry of registry.outputs.values()) {
3340
3608
  const output = entry.value;
3341
3609
  if (!output.outputName) {
3342
- invalid5(source, `outputs.${entry.name} has no name (an output made by pipe cannot be registered).`);
3610
+ invalid6(source, `outputs.${entry.name} has no name (an output made by pipe cannot be registered).`);
3343
3611
  }
3344
3612
  for (const command of output.commands) {
3345
3613
  if (commands.has(command))
@@ -3369,7 +3637,7 @@ function validateUseCases(source, registry) {
3369
3637
  for (const entry of registry.useCases.values()) {
3370
3638
  const UseCase = entry.value;
3371
3639
  for (const [key, dependency] of Object.entries(UseCase.dependencies)) {
3372
- const found = isUseCaseClass2(dependency) ? useCases.has(dependency) : isEnvironment2(dependency) ? environments.has(dependency) : repositories.has(inspectRepository(dependency).state);
3640
+ const found = isLoggerDeclaration(dependency) ? true : isUseCaseClass2(dependency) ? useCases.has(dependency) : isEnvironment2(dependency) ? environments.has(dependency) : repositories.has(inspectRepository(dependency).state);
3373
3641
  if (!found) {
3374
3642
  throw new UnregisteredUseCaseDependency2({
3375
3643
  source,
@@ -3541,7 +3809,7 @@ function recordDescriptionOf(entry, scope) {
3541
3809
  plugins
3542
3810
  };
3543
3811
  }
3544
- function describeRegistry(name, extended, registry, provider) {
3812
+ function describeRegistry(name, extended, registry, provider, log) {
3545
3813
  const scope = {
3546
3814
  properties: referencesOf(registry, "properties"),
3547
3815
  blueprints: referencesOf(registry, "blueprints"),
@@ -3582,6 +3850,15 @@ function describeRegistry(name, extended, registry, provider) {
3582
3850
  name,
3583
3851
  extends: extended.map((other) => other.name),
3584
3852
  ...provider === undefined ? {} : { provider: providerDescriptionOf2(provider) },
3853
+ ...log === undefined ? {} : log === "opaque" ? { log: { kind: "opaque" } } : {
3854
+ log: {
3855
+ level: log.level,
3856
+ providers: log.providers.map((logProvider) => {
3857
+ const providerName = logProviderNameOf(logProvider);
3858
+ return providerName === undefined ? { kind: "opaque" } : { kind: "log-provider", name: providerName };
3859
+ })
3860
+ }
3861
+ },
3585
3862
  properties: each("properties", (entry) => ({
3586
3863
  from: entry.from,
3587
3864
  ...propertyDescriptionOf(entry.value, scope)
@@ -3632,7 +3909,10 @@ function describeRegistry(name, extended, registry, provider) {
3632
3909
  }),
3633
3910
  dependencies: Object.fromEntries(Object.entries(UseCase.dependencies).map(([key, dependency]) => [
3634
3911
  key,
3635
- isUseCaseClass2(dependency) ? { kind: "use-case", ref: useCaseRefs.get(dependency) } : isEnvironment2(dependency) ? {
3912
+ isLoggerDeclaration(dependency) ? { kind: "logger", ref: "Logger" } : isUseCaseClass2(dependency) ? {
3913
+ kind: "use-case",
3914
+ ref: useCaseRefs.get(dependency)
3915
+ } : isEnvironment2(dependency) ? {
3636
3916
  kind: "environment",
3637
3917
  ref: environmentRefs.get(dependency)
3638
3918
  } : {
@@ -3690,11 +3970,11 @@ function describeRegistry(name, extended, registry, provider) {
3690
3970
  function applicationOf2(settings) {
3691
3971
  const { name } = settings ?? {};
3692
3972
  if (typeof name !== "string" || name === "") {
3693
- invalid5("applicationOf", "Expected a name.");
3973
+ invalid6("applicationOf", "Expected a name.");
3694
3974
  }
3695
3975
  const extended = settings.extends ?? [];
3696
3976
  if (!Array.isArray(extended) || !extended.every(isApplication2)) {
3697
- invalid5(name, "Expected `extends` to be a list of applications.");
3977
+ invalid6(name, "Expected `extends` to be a list of applications.");
3698
3978
  }
3699
3979
  const registry = resolve(settings);
3700
3980
  validate(name, registry);
@@ -3703,7 +3983,7 @@ function applicationOf2(settings) {
3703
3983
  validateOutputs(name, registry);
3704
3984
  const declaredProvider = settings.provider ?? [...extended].reverse().find((other) => other.provider)?.provider;
3705
3985
  if (declaredProvider !== undefined && typeof declaredProvider !== "object") {
3706
- invalid5(name, "Expected `provider` to be a repository provider.");
3986
+ invalid6(name, "Expected `provider` to be a repository provider.");
3707
3987
  }
3708
3988
  const provider = isProviderFactory2(declaredProvider) ? deferredProvider(declaredProvider, name) : declaredProvider;
3709
3989
  {
@@ -3720,6 +4000,13 @@ function applicationOf2(settings) {
3720
4000
  });
3721
4001
  }
3722
4002
  }
4003
+ const declaredLog = settings.log ?? [...extended].reverse().map((other) => logSettings.get(other)).find((log) => log !== undefined);
4004
+ const log = declaredLog === undefined ? undefined : applicationLogger(name);
4005
+ if (declaredLog !== undefined && !isLogFactory2(declaredLog)) {
4006
+ log?.set(checkLogSettings(declaredLog));
4007
+ }
4008
+ const logger = log?.logger;
4009
+ const rebinds = provider !== undefined || logger !== undefined;
3723
4010
  const collection = (key) => Object.freeze(Object.fromEntries([...registry[key].values()].map((entry) => [entry.name, entry.value])));
3724
4011
  const bound = new Map;
3725
4012
  const boundByState = new Map;
@@ -3732,7 +4019,7 @@ function applicationOf2(settings) {
3732
4019
  }
3733
4020
  const boundUseCases = new Map;
3734
4021
  const bindUseCase = (UseCase) => {
3735
- if (provider === undefined)
4022
+ if (!rebinds)
3736
4023
  return UseCase;
3737
4024
  const done = boundUseCases.get(UseCase);
3738
4025
  if (done)
@@ -3745,11 +4032,13 @@ function applicationOf2(settings) {
3745
4032
  boundUseCases.set(UseCase, Bound);
3746
4033
  const dependencies = Object.fromEntries(Object.entries(UseCase.dependencies).map(([key, dependency]) => [
3747
4034
  key,
3748
- isUseCaseClass2(dependency) ? bindUseCase(dependency) : isEnvironment2(dependency) ? dependency : boundByState.get(inspectRepository(dependency).state) ?? dependency
4035
+ isUseCaseClass2(dependency) ? bindUseCase(dependency) : isEnvironment2(dependency) || isLoggerDeclaration(dependency) ? dependency : boundByState.get(inspectRepository(dependency).state) ?? dependency
3749
4036
  ]));
3750
4037
  Object.defineProperty(Bound, "dependencies", {
3751
4038
  value: Object.freeze(dependencies)
3752
4039
  });
4040
+ if (logger)
4041
+ Object.defineProperty(Bound, ApplicationLoggerKey, { value: logger });
3753
4042
  return Bound;
3754
4043
  };
3755
4044
  const useCases = {};
@@ -3763,7 +4052,7 @@ function applicationOf2(settings) {
3763
4052
  const boundCommandOf = new Map;
3764
4053
  for (const entry of registry.commands.values()) {
3765
4054
  const declared = entry.value;
3766
- const rebuilt = provider === undefined ? declared : commandOf2({
4055
+ const rebuilt = !rebinds ? declared : commandOf2({
3767
4056
  name: declared.commandName,
3768
4057
  description: declared.description,
3769
4058
  tags: declared.tags,
@@ -3786,7 +4075,7 @@ function applicationOf2(settings) {
3786
4075
  const boundOutputOf = new Map;
3787
4076
  for (const entry of registry.outputs.values()) {
3788
4077
  const declared = entry.value;
3789
- const rebuilt = provider === undefined ? declared : outputOf2({
4078
+ const rebuilt = !rebinds ? declared : outputOf2({
3790
4079
  name: declared.outputName,
3791
4080
  commands: declared.commands.map((command) => boundCommandOf.get(command)),
3792
4081
  statuses: declared.statuses,
@@ -3797,6 +4086,19 @@ function applicationOf2(settings) {
3797
4086
  }
3798
4087
  const environmentEntries = [...registry.environments.values()];
3799
4088
  const registeredEnvironments = new Set(environmentEntries.map((entry) => entry.value));
4089
+ const context = Object.freeze({
4090
+ name,
4091
+ env(environment) {
4092
+ if (!registeredEnvironments.has(environment)) {
4093
+ throw new UnregisteredApplicationReference2({
4094
+ source: name,
4095
+ details: { holder: "the context", reference: "an environment" }
4096
+ });
4097
+ }
4098
+ return environment.load();
4099
+ },
4100
+ logger: logger ?? silentLogger
4101
+ });
3800
4102
  let starting;
3801
4103
  let started = false;
3802
4104
  const start = async () => {
@@ -3822,8 +4124,11 @@ function applicationOf2(settings) {
3822
4124
  cause
3823
4125
  });
3824
4126
  }
4127
+ if (isLogFactory2(declaredLog)) {
4128
+ log?.set(checkLogSettings(await declaredLog.create(context)));
4129
+ }
3825
4130
  if (provider !== undefined && isDeferredProvider(provider)) {
3826
- const made = await startDeferred(provider);
4131
+ const made = await startDeferred(provider, context);
3827
4132
  checkTransactions(name, made, Object.entries(commands).filter(([, command]) => command.transaction && commandTransactionProvider(command) === provider).map(([key]) => key));
3828
4133
  }
3829
4134
  started = true;
@@ -3833,6 +4138,9 @@ function applicationOf2(settings) {
3833
4138
  name,
3834
4139
  extends: Object.freeze([...extended]),
3835
4140
  provider,
4141
+ logger: logger ?? silentLogger,
4142
+ context,
4143
+ ...logger ? { [ApplicationLoggerKey]: logger } : {},
3836
4144
  properties: collection("properties"),
3837
4145
  blueprints: collection("blueprints"),
3838
4146
  records: collection("records"),
@@ -3845,25 +4153,25 @@ function applicationOf2(settings) {
3845
4153
  exceptions: collection("exceptions"),
3846
4154
  useCase(useCase) {
3847
4155
  if (!boundUseCaseOf.has(useCase)) {
3848
- invalid5(name, "Expected a use case registered in the application.");
4156
+ invalid6(name, "Expected a use case registered in the application.");
3849
4157
  }
3850
4158
  return boundUseCaseOf.get(useCase);
3851
4159
  },
3852
4160
  command(command) {
3853
4161
  if (!boundCommandOf.has(command)) {
3854
- invalid5(name, "Expected a command registered in the application.");
4162
+ invalid6(name, "Expected a command registered in the application.");
3855
4163
  }
3856
4164
  return boundCommandOf.get(command);
3857
4165
  },
3858
4166
  output(output) {
3859
4167
  if (!boundOutputOf.has(output)) {
3860
- invalid5(name, "Expected an output registered in the application.");
4168
+ invalid6(name, "Expected an output registered in the application.");
3861
4169
  }
3862
4170
  return boundOutputOf.get(output);
3863
4171
  },
3864
4172
  repository(repository) {
3865
4173
  if (!bound.has(repository)) {
3866
- invalid5(name, "Expected a repository registered in the application.");
4174
+ invalid6(name, "Expected a repository registered in the application.");
3867
4175
  }
3868
4176
  return bound.get(repository);
3869
4177
  },
@@ -3871,10 +4179,11 @@ function applicationOf2(settings) {
3871
4179
  return applicationOf2({
3872
4180
  name,
3873
4181
  extends: [application, ...others],
3874
- ...provider === undefined ? {} : { provider }
4182
+ ...provider === undefined ? {} : { provider },
4183
+ ...declaredLog === undefined ? {} : { log: declaredLog }
3875
4184
  });
3876
4185
  },
3877
- describe: () => describeRegistry(name, extended, registry, provider),
4186
+ describe: () => describeRegistry(name, extended, registry, provider, isLogFactory2(declaredLog) ? "opaque" : log?.settings),
3878
4187
  get started() {
3879
4188
  return started;
3880
4189
  },
@@ -3901,6 +4210,8 @@ function applicationOf2(settings) {
3901
4210
  if (provider !== undefined && isDeferredProvider(provider)) {
3902
4211
  await stopProvider(provider);
3903
4212
  }
4213
+ if (isLogFactory2(declaredLog))
4214
+ log?.set(undefined);
3904
4215
  throw error;
3905
4216
  });
3906
4217
  return starting;
@@ -3917,11 +4228,14 @@ function applicationOf2(settings) {
3917
4228
  setStartedApplication(undefined);
3918
4229
  if (provider !== undefined)
3919
4230
  await stopProvider(provider);
4231
+ await log?.flush();
4232
+ if (isLogFactory2(declaredLog))
4233
+ log?.set(undefined);
3920
4234
  },
3921
4235
  get(declaration) {
3922
4236
  if (isEnvironment2(declaration)) {
3923
4237
  if (!registeredEnvironments.has(declaration)) {
3924
- invalid5(name, "Expected an environment registered in the application.");
4238
+ invalid6(name, "Expected an environment registered in the application.");
3925
4239
  }
3926
4240
  return declaration.load();
3927
4241
  }
@@ -3934,10 +4248,12 @@ function applicationOf2(settings) {
3934
4248
  if (isRepository2(declaration)) {
3935
4249
  return application.repository(declaration);
3936
4250
  }
3937
- return invalid5(name, "Expected a repository, use case, command, output or environment registered in the application.");
4251
+ return invalid6(name, "Expected a repository, use case, command, output or environment registered in the application.");
3938
4252
  }
3939
4253
  });
3940
4254
  internals.set(application, registry);
4255
+ if (declaredLog !== undefined)
4256
+ logSettings.set(application, declaredLog);
3941
4257
  return application;
3942
4258
  }
3943
4259
  // src/core/blueprint/blueprint-plugin.ts
@@ -4086,7 +4402,7 @@ function validate2(options) {
4086
4402
  }
4087
4403
  return routeOptionsIssue2({ basePath, route }, "openapi");
4088
4404
  }
4089
- function invalid6(reason, source = "openapi") {
4405
+ function invalid7(reason, source = "openapi") {
4090
4406
  throw new InvalidOutputStage2({ source, details: { reason } });
4091
4407
  }
4092
4408
  function kebab(text) {
@@ -4098,7 +4414,7 @@ function operationRoutes2(operations, options, source = "openapi") {
4098
4414
  const ids = new Set(operations.map(({ id }) => id));
4099
4415
  for (const id of Object.keys(route)) {
4100
4416
  if (!ids.has(id)) {
4101
- invalid6(`${source}.route names the unknown operation "${id}".`, source);
4417
+ invalid7(`${source}.route names the unknown operation "${id}".`, source);
4102
4418
  }
4103
4419
  }
4104
4420
  const routes = new Map;
@@ -4109,7 +4425,7 @@ function operationRoutes2(operations, options, source = "openapi") {
4109
4425
  const path = base + (chosen.path ?? `/${kebab(operation.command)}/${kebab(operation.name)}`);
4110
4426
  const key = `${method} ${path}`;
4111
4427
  if (taken.has(key)) {
4112
- invalid6(`Two operations are routed to ${method.toUpperCase()} ${path}.`, source);
4428
+ invalid7(`Two operations are routed to ${method.toUpperCase()} ${path}.`, source);
4113
4429
  }
4114
4430
  taken.add(key);
4115
4431
  routes.set(operation.id, { method, path });
@@ -4215,7 +4531,7 @@ function parametersOf(operation, schema) {
4215
4531
  const field = operation.input.properties[name];
4216
4532
  const type = property.type;
4217
4533
  if (!isProperty2(field) || type === "object" || type === "array" || Array.isArray(type) && type.some((t) => t === "object" || t === "array")) {
4218
- invalid6(`${operation.id} uses a ${"get/delete"} route, whose input becomes query parameters, but "${name}" is not a scalar; route it with method "post".`);
4534
+ invalid7(`${operation.id} uses a ${"get/delete"} route, whose input becomes query parameters, but "${name}" is not a scalar; route it with method "post".`);
4219
4535
  }
4220
4536
  const { description, ...rest } = property;
4221
4537
  return {
@@ -4242,10 +4558,10 @@ var openapi2 = sinkOf2({
4242
4558
  for (const record of records) {
4243
4559
  const name = record.name;
4244
4560
  if (!/^[A-Za-z0-9._-]+$/.test(name) || name === "Problem") {
4245
- invalid6(`The record class "${name}" cannot be a component name; give the class a name that is not "Problem".`);
4561
+ invalid7(`The record class "${name}" cannot be a component name; give the class a name that is not "Problem".`);
4246
4562
  }
4247
4563
  if (classes.has(name)) {
4248
- invalid6(`Two record classes are named "${name}"; rename one.`);
4564
+ invalid7(`Two record classes are named "${name}"; rename one.`);
4249
4565
  }
4250
4566
  classes.set(name, record);
4251
4567
  models[name] = record;
@@ -4265,7 +4581,7 @@ var openapi2 = sinkOf2({
4265
4581
  const { method, path } = routes.get(operation.id);
4266
4582
  const operationId = operation.id.replaceAll(".", "_");
4267
4583
  if (operationIds.has(operationId)) {
4268
- invalid6(`The operationId "${operationId}" is produced twice.`);
4584
+ invalid7(`The operationId "${operationId}" is produced twice.`);
4269
4585
  }
4270
4586
  operationIds.add(operationId);
4271
4587
  const slot = paths[path] ?? {};
@@ -5016,4 +5332,4 @@ var entityOf2 = entityBuilderOf2({
5016
5332
  var recordOf2 = recordBuilderOf2(StdRecordPlugins2);
5017
5333
  // src/std/stages.ts
5018
5334
  var StdStages2 = stageCatalogOf2(select2, openapi2);
5019
- export { InvalidEnvironment2, environmentOf2, isEnvironment2, guard2, ReservedEntityKey2, ImmutableEntityKey2, DeletedEntity2, entityBuilderOf2, isEntityClass2, isEntity2, eventOf2, ENTITY_IDENTITY_KEYS2, RESERVED_ENTITY_KEYS2, EntityUniqueKeys2, AbstractEntity2, InvalidRepositoryQuery2, InvalidRepositoryDeclaration2, InvalidRepositoryEntity2, InvalidRepositoryData2, RepositoryUniqueViolation2, RepositoryEntityNotFound2, providerOf2, providerDescriptionOf2, inMemoryProvider2, AbstractRepository2, repositoryOf2, RepositoryOf2, isRepository2, InvalidUseCaseStep2, InvalidUseCaseDeclaration2, UseCaseAlreadyExecuted2, InvalidUseCaseDependencies2, AbstractUseCase2, useCaseOf2, isUseCaseClass2, isUseCase2, InvalidCommandDeclaration2, UnknownCommandOperation2, InvalidCommandContext2, InvalidCommandEnvironment2, CommandEventFailed2, commandOf2, isCommand2, InvalidApplicationDeclaration2, DuplicateApplicationDeclaration2, ApplicationConflict2, UnregisteredApplicationReference2, UnregisteredRepositoryDependency2, UnregisteredUseCaseDependency2, ApplicationNotStarted2, ApplicationAlreadyStarted2, InvalidApplicationEnvironment2, InvalidOpenAPIModel2, InvalidOutputStage2, DuplicateOperation2, toOpenAPI2, transformOf2, sinkOf2, stageDescriptionOf2, stageKindOf2, stageCatalogOf2, operationOf2, outputOf2, isOutput2, useApplication2, resetApplication2, providerFrom2, isProviderFactory2, isApplication2, applicationOf2, blueprintPluginOf2, statusOf2, PROBLEM_MEDIA_TYPE2, problemOf2, outputValueOf2, routeOptionsIssue2, operationRoutes2, openapi2, select2, recordPluginCatalogOf2, Email2, Phone2, Url2, Ip2, enumOf2, SchemaProperty2, PasswordHasherRequired2, SyncVerifyUnsupported2, configure2, resetRuntime2, Id2, Slug2, PASSWORD_MIN_LENGTH2, PASSWORD_MAX_LENGTH2, PASSWORD_SPECIAL_CHARACTERS2, isPasswordHash2, passwordIssues2, Password2, StringProperty2, Text2, NumberProperty2, Integer2, BooleanProperty2, DateTime2, DateProperty2, CreatedAt2, UpdatedAt2, DeletedAt2, Std2, blueprintOf2, Publishable2, Archivable2, Taggable2, Ownable2, Authenticatable2, StdRecordPlugins2, entityOf2, recordOf2, StdStages2 };
5335
+ export { InvalidEnvironment2, environmentOf2, isEnvironment2, guard2, InvalidApplicationDeclaration2, DuplicateApplicationDeclaration2, ApplicationConflict2, UnregisteredApplicationReference2, UnregisteredRepositoryDependency2, UnregisteredUseCaseDependency2, ApplicationNotStarted2, ApplicationAlreadyStarted2, InvalidApplicationEnvironment2, useApplication2, resetApplication2, InvalidLogDeclaration2, LogLevels2, logProviderOf2, consoleLogProvider2, jsonLogProvider2, memoryLogProvider2, Logger2, ReservedEntityKey2, ImmutableEntityKey2, DeletedEntity2, entityBuilderOf2, isEntityClass2, isEntity2, eventOf2, ENTITY_IDENTITY_KEYS2, RESERVED_ENTITY_KEYS2, EntityUniqueKeys2, AbstractEntity2, InvalidRepositoryQuery2, InvalidRepositoryDeclaration2, InvalidRepositoryEntity2, InvalidRepositoryData2, RepositoryUniqueViolation2, RepositoryEntityNotFound2, providerOf2, providerDescriptionOf2, inMemoryProvider2, AbstractRepository2, repositoryOf2, RepositoryOf2, isRepository2, InvalidUseCaseStep2, InvalidUseCaseDeclaration2, UseCaseAlreadyExecuted2, InvalidUseCaseDependencies2, AbstractUseCase2, useCaseOf2, isUseCaseClass2, isUseCase2, InvalidCommandDeclaration2, UnknownCommandOperation2, InvalidCommandContext2, InvalidCommandEnvironment2, CommandEventFailed2, commandOf2, isCommand2, InvalidOpenAPIModel2, InvalidOutputStage2, DuplicateOperation2, toOpenAPI2, transformOf2, sinkOf2, stageDescriptionOf2, stageKindOf2, stageCatalogOf2, operationOf2, outputOf2, isOutput2, providerFrom2, logFrom2, isLogFactory2, isProviderFactory2, isApplication2, applicationOf2, blueprintPluginOf2, statusOf2, PROBLEM_MEDIA_TYPE2, problemOf2, outputValueOf2, routeOptionsIssue2, operationRoutes2, openapi2, select2, recordPluginCatalogOf2, Email2, Phone2, Url2, Ip2, enumOf2, SchemaProperty2, PasswordHasherRequired2, SyncVerifyUnsupported2, configure2, resetRuntime2, Id2, Slug2, PASSWORD_MIN_LENGTH2, PASSWORD_MAX_LENGTH2, PASSWORD_SPECIAL_CHARACTERS2, isPasswordHash2, passwordIssues2, Password2, StringProperty2, Text2, NumberProperty2, Integer2, BooleanProperty2, DateTime2, DateProperty2, CreatedAt2, UpdatedAt2, DeletedAt2, Std2, blueprintOf2, Publishable2, Archivable2, Taggable2, Ownable2, Authenticatable2, StdRecordPlugins2, entityOf2, recordOf2, StdStages2 };