@venizia/ignis-kernel 0.4.6 → 0.4.7-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/LICENSE.md +1 -4
  2. package/dist/esm/base/applications/artifact-group.d.ts.map +1 -1
  3. package/dist/esm/base/applications/artifact-group.js +4 -1
  4. package/dist/esm/base/applications/artifact-group.js.map +1 -1
  5. package/dist/esm/base/applications/artifact-index.d.ts.map +1 -1
  6. package/dist/esm/base/applications/artifact-index.js +2 -1
  7. package/dist/esm/base/applications/artifact-index.js.map +1 -1
  8. package/dist/esm/base/applications/cors.d.ts +12 -10
  9. package/dist/esm/base/applications/cors.d.ts.map +1 -1
  10. package/dist/esm/base/applications/cors.js +37 -35
  11. package/dist/esm/base/applications/cors.js.map +1 -1
  12. package/dist/esm/base/applications/rest.js +11 -11
  13. package/dist/esm/base/applications/rest.js.map +1 -1
  14. package/dist/esm/base/auth/authenticate/common/codecs.js +2 -2
  15. package/dist/esm/base/auth/authenticate/common/codecs.js.map +1 -1
  16. package/dist/esm/base/auth/authenticate/strategies/strategy-registry.d.ts +1 -1
  17. package/dist/esm/base/auth/authenticate/strategies/strategy-registry.js +1 -1
  18. package/dist/esm/base/auth/authenticate/strategies/strategy-registry.js.map +1 -1
  19. package/dist/esm/base/auth/authorize/providers/authorization.provider.d.ts.map +1 -1
  20. package/dist/esm/base/auth/authorize/providers/authorization.provider.js +14 -11
  21. package/dist/esm/base/auth/authorize/providers/authorization.provider.js.map +1 -1
  22. package/dist/esm/base/auth/authorize/providers/request-domain.d.ts +14 -11
  23. package/dist/esm/base/auth/authorize/providers/request-domain.d.ts.map +1 -1
  24. package/dist/esm/base/auth/authorize/providers/request-domain.js +42 -39
  25. package/dist/esm/base/auth/authorize/providers/request-domain.js.map +1 -1
  26. package/dist/esm/base/auth/base/abstract-auth-registry.js +2 -2
  27. package/dist/esm/base/auth/base/abstract-auth-registry.js.map +1 -1
  28. package/dist/esm/base/auth/models/requests/change-password.schema.js +3 -3
  29. package/dist/esm/base/auth/models/requests/change-password.schema.js.map +1 -1
  30. package/dist/esm/base/auth/models/requests/sign-in.schema.js +5 -5
  31. package/dist/esm/base/auth/models/requests/sign-in.schema.js.map +1 -1
  32. package/dist/esm/base/components/controller/rest/rest.component.js +2 -2
  33. package/dist/esm/base/components/controller/rest/rest.component.js.map +1 -1
  34. package/dist/esm/base/controllers/common/index.d.ts +0 -1
  35. package/dist/esm/base/controllers/common/index.d.ts.map +1 -1
  36. package/dist/esm/base/controllers/common/index.js +0 -1
  37. package/dist/esm/base/controllers/common/index.js.map +1 -1
  38. package/dist/esm/base/controllers/common/schema-builders.d.ts +0 -5
  39. package/dist/esm/base/controllers/common/schema-builders.d.ts.map +1 -1
  40. package/dist/esm/base/controllers/common/schema-builders.js +0 -14
  41. package/dist/esm/base/controllers/common/schema-builders.js.map +1 -1
  42. package/dist/esm/base/controllers/context.d.ts +7 -2
  43. package/dist/esm/base/controllers/context.d.ts.map +1 -1
  44. package/dist/esm/base/controllers/context.js +7 -4
  45. package/dist/esm/base/controllers/context.js.map +1 -1
  46. package/dist/esm/base/controllers/factory/controller.d.ts +33 -1
  47. package/dist/esm/base/controllers/factory/controller.d.ts.map +1 -1
  48. package/dist/esm/base/controllers/factory/controller.js +90 -6
  49. package/dist/esm/base/controllers/factory/controller.js.map +1 -1
  50. package/dist/esm/base/controllers/factory/crud/persistable.d.ts.map +1 -1
  51. package/dist/esm/base/controllers/factory/crud/persistable.js +40 -25
  52. package/dist/esm/base/controllers/factory/crud/persistable.js.map +1 -1
  53. package/dist/esm/base/controllers/factory/crud/readable.d.ts.map +1 -1
  54. package/dist/esm/base/controllers/factory/crud/readable.js +4 -3
  55. package/dist/esm/base/controllers/factory/crud/readable.js.map +1 -1
  56. package/dist/esm/base/controllers/factory/definition.d.ts +1 -8
  57. package/dist/esm/base/controllers/factory/definition.d.ts.map +1 -1
  58. package/dist/esm/base/controllers/factory/definition.js +17 -24
  59. package/dist/esm/base/controllers/factory/definition.js.map +1 -1
  60. package/dist/esm/base/controllers/factory/index.d.ts +0 -1
  61. package/dist/esm/base/controllers/factory/index.d.ts.map +1 -1
  62. package/dist/esm/base/controllers/factory/index.js +0 -1
  63. package/dist/esm/base/controllers/factory/index.js.map +1 -1
  64. package/dist/esm/base/controllers/rest/abstract.d.ts.map +1 -1
  65. package/dist/esm/base/controllers/rest/abstract.js +6 -6
  66. package/dist/esm/base/controllers/rest/abstract.js.map +1 -1
  67. package/dist/esm/base/controllers/rest/base.d.ts +0 -5
  68. package/dist/esm/base/controllers/rest/base.d.ts.map +1 -1
  69. package/dist/esm/base/controllers/rest/base.js +14 -14
  70. package/dist/esm/base/controllers/rest/base.js.map +1 -1
  71. package/dist/esm/base/datasources/abstract.js +2 -2
  72. package/dist/esm/base/datasources/abstract.js.map +1 -1
  73. package/dist/esm/base/events/event-bus.js +4 -4
  74. package/dist/esm/base/events/event-bus.js.map +1 -1
  75. package/dist/esm/base/metadata/injectable.d.ts +7 -4
  76. package/dist/esm/base/metadata/injectable.d.ts.map +1 -1
  77. package/dist/esm/base/metadata/injectable.js +26 -23
  78. package/dist/esm/base/metadata/injectable.js.map +1 -1
  79. package/dist/esm/base/metadata/model-metadata.d.ts +27 -13
  80. package/dist/esm/base/metadata/model-metadata.d.ts.map +1 -1
  81. package/dist/esm/base/metadata/model-metadata.js +56 -26
  82. package/dist/esm/base/metadata/model-metadata.js.map +1 -1
  83. package/dist/esm/base/metadata/persistents.d.ts.map +1 -1
  84. package/dist/esm/base/metadata/persistents.js +21 -13
  85. package/dist/esm/base/metadata/persistents.js.map +1 -1
  86. package/dist/esm/base/metadata/routes/controller.d.ts.map +1 -1
  87. package/dist/esm/base/metadata/routes/controller.js +5 -2
  88. package/dist/esm/base/metadata/routes/controller.js.map +1 -1
  89. package/dist/esm/base/middlewares/app-error/app-error.middleware.js +7 -7
  90. package/dist/esm/base/middlewares/app-error/app-error.middleware.js.map +1 -1
  91. package/dist/esm/base/middlewares/app-error/database.handler.d.ts +14 -12
  92. package/dist/esm/base/middlewares/app-error/database.handler.d.ts.map +1 -1
  93. package/dist/esm/base/middlewares/app-error/database.handler.js +37 -35
  94. package/dist/esm/base/middlewares/app-error/database.handler.js.map +1 -1
  95. package/dist/esm/base/middlewares/app-error/zod.handler.d.ts +28 -23
  96. package/dist/esm/base/middlewares/app-error/zod.handler.d.ts.map +1 -1
  97. package/dist/esm/base/middlewares/app-error/zod.handler.js +56 -53
  98. package/dist/esm/base/middlewares/app-error/zod.handler.js.map +1 -1
  99. package/dist/esm/base/middlewares/emoji-favicon/emoji-favicon.middleware.d.ts +6 -4
  100. package/dist/esm/base/middlewares/emoji-favicon/emoji-favicon.middleware.d.ts.map +1 -1
  101. package/dist/esm/base/middlewares/emoji-favicon/emoji-favicon.middleware.js +14 -12
  102. package/dist/esm/base/middlewares/emoji-favicon/emoji-favicon.middleware.js.map +1 -1
  103. package/dist/esm/base/middlewares/form-body/form-body.middleware.d.ts +15 -11
  104. package/dist/esm/base/middlewares/form-body/form-body.middleware.d.ts.map +1 -1
  105. package/dist/esm/base/middlewares/form-body/form-body.middleware.js +25 -21
  106. package/dist/esm/base/middlewares/form-body/form-body.middleware.js.map +1 -1
  107. package/dist/esm/base/models/common/schemas.d.ts +184 -105
  108. package/dist/esm/base/models/common/schemas.d.ts.map +1 -1
  109. package/dist/esm/base/models/common/schemas.js +105 -54
  110. package/dist/esm/base/models/common/schemas.js.map +1 -1
  111. package/dist/esm/base/models/common/utilities.d.ts +10 -5
  112. package/dist/esm/base/models/common/utilities.d.ts.map +1 -1
  113. package/dist/esm/base/models/common/utilities.js +22 -16
  114. package/dist/esm/base/models/common/utilities.js.map +1 -1
  115. package/dist/esm/base/repositories/common/types/results.d.ts +15 -7
  116. package/dist/esm/base/repositories/common/types/results.d.ts.map +1 -1
  117. package/dist/esm/base/repositories/common/types/results.js +16 -7
  118. package/dist/esm/base/repositories/common/types/results.js.map +1 -1
  119. package/dist/esm/base/repositories/core/abstract.d.ts.map +1 -1
  120. package/dist/esm/base/repositories/core/abstract.js +5 -3
  121. package/dist/esm/base/repositories/core/abstract.js.map +1 -1
  122. package/dist/esm/base/repositories/query-schemas/index.d.ts +1 -1
  123. package/dist/esm/base/repositories/query-schemas/index.d.ts.map +1 -1
  124. package/dist/esm/base/repositories/query-schemas/index.js +3 -3
  125. package/dist/esm/base/repositories/query-schemas/index.js.map +1 -1
  126. package/dist/esm/helpers/inversion/common/relation-builder.js.map +1 -1
  127. package/dist/esm/helpers/inversion/index.d.ts +1 -1
  128. package/dist/esm/helpers/inversion/index.d.ts.map +1 -1
  129. package/dist/esm/helpers/inversion/index.js +1 -1
  130. package/dist/esm/helpers/inversion/index.js.map +1 -1
  131. package/dist/esm/helpers/inversion/mixins/repository.mixin.d.ts.map +1 -1
  132. package/dist/esm/helpers/inversion/mixins/repository.mixin.js +5 -5
  133. package/dist/esm/helpers/inversion/mixins/repository.mixin.js.map +1 -1
  134. package/dist/esm/metadata.d.ts +1 -1
  135. package/dist/esm/metadata.d.ts.map +1 -1
  136. package/dist/esm/metadata.js +1 -1
  137. package/dist/esm/metadata.js.map +1 -1
  138. package/dist/esm/repository.d.ts +2 -2
  139. package/dist/esm/repository.d.ts.map +1 -1
  140. package/dist/esm/repository.js +2 -2
  141. package/dist/esm/repository.js.map +1 -1
  142. package/dist/esm/utilities/index.d.ts +1 -1
  143. package/dist/esm/utilities/index.d.ts.map +1 -1
  144. package/dist/esm/utilities/index.js +1 -1
  145. package/dist/esm/utilities/index.js.map +1 -1
  146. package/dist/esm/utilities/not-supported.utility.d.ts +11 -0
  147. package/dist/esm/utilities/not-supported.utility.d.ts.map +1 -0
  148. package/dist/esm/utilities/not-supported.utility.js +19 -0
  149. package/dist/esm/utilities/not-supported.utility.js.map +1 -0
  150. package/package.json +6 -7
  151. package/dist/esm/base/controllers/common/html-response.d.ts +0 -70
  152. package/dist/esm/base/controllers/common/html-response.d.ts.map +0 -1
  153. package/dist/esm/base/controllers/common/html-response.js +0 -30
  154. package/dist/esm/base/controllers/common/html-response.js.map +0 -1
  155. package/dist/esm/base/controllers/factory/authorize-guard.d.ts +0 -19
  156. package/dist/esm/base/controllers/factory/authorize-guard.d.ts.map +0 -1
  157. package/dist/esm/base/controllers/factory/authorize-guard.js +0 -56
  158. package/dist/esm/base/controllers/factory/authorize-guard.js.map +0 -1
  159. package/dist/esm/base/controllers/factory/helper.d.ts +0 -2
  160. package/dist/esm/base/controllers/factory/helper.d.ts.map +0 -1
  161. package/dist/esm/base/controllers/factory/helper.js +0 -2
  162. package/dist/esm/base/controllers/factory/helper.js.map +0 -1
  163. package/dist/esm/base/controllers/factory/repository-injection.d.ts +0 -14
  164. package/dist/esm/base/controllers/factory/repository-injection.d.ts.map +0 -1
  165. package/dist/esm/base/controllers/factory/repository-injection.js +0 -27
  166. package/dist/esm/base/controllers/factory/repository-injection.js.map +0 -1
  167. package/dist/esm/base/metadata/model-settings.d.ts +0 -11
  168. package/dist/esm/base/metadata/model-settings.d.ts.map +0 -1
  169. package/dist/esm/base/metadata/model-settings.js +0 -30
  170. package/dist/esm/base/metadata/model-settings.js.map +0 -1
  171. package/dist/esm/utilities/error.utility.d.ts +0 -8
  172. package/dist/esm/utilities/error.utility.d.ts.map +0 -1
  173. package/dist/esm/utilities/error.utility.js +0 -14
  174. package/dist/esm/utilities/error.utility.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { isEmpty } from '@venizia/ignis-helpers/common';
1
+ import { ObjectUtility } from '@venizia/ignis-helpers/common';
2
2
  import { BaseHelper, getError, RetryBackoffStrategies, RetryHelper, RetryJitterModes, } from '@venizia/ignis-helpers/core';
3
3
  import { EventDispatchRetry, EventHandlerTypes } from './common/constants.js';
4
4
  /** In-process, fire-and-forget domain event bus. `TPayloadMap` keys the event names, so a wrong name
@@ -67,7 +67,7 @@ export class EventBus extends BaseHelper {
67
67
  */
68
68
  static buildHandlerInvoker(opts) {
69
69
  const { container, handler, name } = opts;
70
- if (isEmpty({ value: handler })) {
70
+ if (ObjectUtility.isEmpty({ value: handler })) {
71
71
  throw getError({
72
72
  message: `[EventBus][register] Invalid handler | name: ${name} | Got: ${handler}`,
73
73
  });
@@ -75,7 +75,7 @@ export class EventBus extends BaseHelper {
75
75
  switch (handler.type) {
76
76
  case EventHandlerTypes.BINDING_KEY: {
77
77
  const { key } = handler;
78
- if (isEmpty({ value: key })) {
78
+ if (ObjectUtility.isEmpty({ value: key })) {
79
79
  throw getError({
80
80
  message: `[EventBus][register] Invalid handler.key | name: ${name} | Got: ${key}`,
81
81
  });
@@ -113,7 +113,7 @@ export class EventBus extends BaseHelper {
113
113
  */
114
114
  register(opts) {
115
115
  const { name, handler, retry } = opts;
116
- if (isEmpty({ value: name })) {
116
+ if (ObjectUtility.isEmpty({ value: name })) {
117
117
  throw getError({
118
118
  message: `[EventBus][register] Invalid registration | name: ${String(name)}`,
119
119
  });
@@ -1 +1 @@
1
- {"version":3,"file":"event-bus.js","sourceRoot":"","sources":["../../../../src/base/events/event-bus.ts"],"names":[],"mappings":"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","sourcesContent":["import { isEmpty } from '@venizia/ignis-helpers/common';\nimport type { Container } from '@/helpers/inversion/container';\nimport type { AnyType, ValueOrPromise } from '@venizia/ignis-helpers/common';\nimport {\n BaseHelper,\n getError,\n RetryBackoffStrategies,\n RetryHelper,\n RetryJitterModes,\n} from '@venizia/ignis-helpers/core';\nimport { EventDispatchRetry, EventHandlerTypes } from './common/constants';\nimport type {\n IDomainEvent,\n IEventHandler,\n IEventHandlerRetryOptions,\n TEventHandlerReference,\n} from './common/types';\n\ntype TEventHandlerInvoker = (opts: { event: IDomainEvent<unknown> }) => ValueOrPromise<void>;\n\n/** One `register`ed handler, resolved to concrete retry numbers and a ready-to-call invoker -\n * `EventDispatchRetry`'s defaults already applied and `handler`'s shape already resolved, so\n * `dispatch` never has to branch on either. */\ninterface IResolvedEventRegistration {\n invokeHandler: TEventHandlerInvoker;\n /** For the exhaustion log line only - a binding key or `<function fn.name>`. */\n description: string;\n maxAttempts: number;\n baseDelayMs: number;\n}\n\n/** In-process, fire-and-forget domain event bus. `TPayloadMap` keys the event names, so a wrong name\n * or payload shape is a compile error. Delivery is always async. Retry timing is a property of the\n * handler's own failure mode, not of the event, so `register` may tune it per registration. But\n * nobody awaits a fire-and-forget dispatch, so an unbounded window would let one event hold a\n * handler - and whatever it holds open, e.g. a database connection - for an unbounded time with no\n * one to report it. What the bus guarantees instead: a bounded MAXIMUM time a single dispatch can\n * occupy, enforced as a hard ceiling at `register()` - see `EventDispatchRetry`. Retry makes\n * delivery at-least-once: handlers must be idempotent, see `IEventHandler`. */\nexport class EventBus<TPayloadMap extends object> extends BaseHelper {\n private readonly container: Container;\n\n /** `register` appends, never replaces - two handlers may share an event name, and replacing would\n * drop the first with no way for the caller to notice. */\n private readonly registrationsByName: Map<string, IResolvedEventRegistration[]>;\n\n constructor(opts: { scope?: string; container: Container }) {\n super({ scope: opts.scope ?? EventBus.name });\n this.container = opts.container;\n this.registrationsByName = new Map();\n }\n\n /** The pre-jitter total of every inter-attempt delay `maxAttempts`/`baseDelayMs` would produce -\n * jitter (always on, see `dispatch`) only ever shrinks a delay, so this is a true upper bound. */\n private static computeTotalWindowMs(opts: { maxAttempts: number; baseDelayMs: number }): number {\n const { maxAttempts, baseDelayMs } = opts;\n let totalWindowMs = 0;\n\n for (let attempt = 1; attempt < maxAttempts; attempt++) {\n totalWindowMs += RetryHelper.computeBackoffDelayMs({\n attempt,\n backoff: {\n strategy: RetryBackoffStrategies.EXPONENTIAL,\n initialDelayMs: baseDelayMs,\n jitter: RetryJitterModes.NONE,\n },\n });\n }\n\n return totalWindowMs;\n }\n\n /** Loud rejection, never a silent clamp: a caller who believes a number the bus does not honour is\n * worse off than one who sees the ceiling at boot. */\n private static assertValidRetry(opts: {\n name: string;\n maxAttempts: number;\n baseDelayMs: number;\n }): void {\n const { name, maxAttempts, baseDelayMs } = opts;\n\n if (!Number.isInteger(maxAttempts) || maxAttempts < 1) {\n throw getError({\n message: `[EventBus][register] retry.maxAttempts must be a positive integer | name: ${name} | Got: ${maxAttempts}`,\n });\n }\n\n if (!Number.isInteger(baseDelayMs) || baseDelayMs < 1) {\n throw getError({\n message: `[EventBus][register] retry.baseDelayMs must be a positive integer | name: ${name} | Got: ${baseDelayMs}`,\n });\n }\n\n if (maxAttempts > EventDispatchRetry.MAX_ATTEMPTS_CEILING) {\n throw getError({\n message: `[EventBus][register] retry.maxAttempts exceeds the ceiling | name: ${name} | Got: ${maxAttempts} | Ceiling: ${EventDispatchRetry.MAX_ATTEMPTS_CEILING} | Lower retry.maxAttempts`,\n });\n }\n\n const totalWindowMs = EventBus.computeTotalWindowMs({ maxAttempts, baseDelayMs });\n if (totalWindowMs > EventDispatchRetry.MAX_TOTAL_WINDOW_MS) {\n throw getError({\n message: `[EventBus][register] retry window exceeds the ceiling | name: ${name} | Got: ${totalWindowMs}ms | Ceiling: ${EventDispatchRetry.MAX_TOTAL_WINDOW_MS}ms | Lower retry.maxAttempts or retry.baseDelayMs`,\n });\n }\n }\n\n /**\n * Turns `handler` into a uniform invoker plus a description for the exhaustion log line.\n * `BINDING_KEY` resolves through the container INSIDE the returned closure, so every call re-reads\n * the current binding; `FUNCTION` calls `fn` directly, so the closure IS the resolution - there is\n * nothing left to re-read on a later attempt. The tag (`handler.type`) is what this switches on,\n * not which field happens to be present - see `EventHandlerTypes`' doc.\n */\n private static buildHandlerInvoker(opts: {\n container: Container;\n handler: TEventHandlerReference<AnyType>;\n name: string;\n }): { invokeHandler: TEventHandlerInvoker; description: string } {\n const { container, handler, name } = opts;\n\n if (isEmpty({ value: handler })) {\n throw getError({\n message: `[EventBus][register] Invalid handler | name: ${name} | Got: ${handler}`,\n });\n }\n\n switch (handler.type) {\n case EventHandlerTypes.BINDING_KEY: {\n const { key } = handler;\n if (isEmpty({ value: key })) {\n throw getError({\n message: `[EventBus][register] Invalid handler.key | name: ${name} | Got: ${key}`,\n });\n }\n\n return {\n invokeHandler: ({ event }) => container.get<IEventHandler>({ key }).handle({ event }),\n description: `binding-key:${key}`,\n };\n }\n\n case EventHandlerTypes.FUNCTION: {\n const { fn } = handler;\n if (typeof fn !== 'function') {\n throw getError({\n message: `[EventBus][register] Invalid handler.fn | name: ${name} | Expected a function | Got: ${typeof fn}`,\n });\n }\n\n return {\n invokeHandler: ({ event }) => fn({ event }),\n description: `function:${fn.name || 'anonymous'}`,\n };\n }\n\n default: {\n throw getError({\n message: `[EventBus][register] Unknown handler.type | name: ${name} | Expected one of: ${[...EventHandlerTypes.SCHEME_SET].join(', ')} | Got: ${(handler as { type?: unknown }).type}`,\n });\n }\n }\n }\n\n /**\n * `retry` is optional and per REGISTRATION, not per publish: the right window belongs to the\n * handler's own failure mode, and two handlers on the same event name may each pick their own.\n * Omitting it reproduces today's `EventDispatchRetry` defaults exactly. Both `maxAttempts` and the\n * total backoff window it implies are bounded - see `EventDispatchRetry` - and exceeding either\n * throws here, at boot where a human sees it, rather than being silently clamped at dispatch time.\n */\n register<K extends keyof TPayloadMap & string>(opts: {\n name: K;\n /** A `BINDING_KEY` reference re-resolves through the container on every retry attempt, so a\n * rebind reaches a dispatch already in flight. A `FUNCTION` reference is captured as-is: a\n * rebind has nothing to reach, and every attempt in a long retry window calls the exact `fn`\n * registered here. */\n handler: TEventHandlerReference<TPayloadMap[K]>;\n retry?: IEventHandlerRetryOptions;\n }): void {\n const { name, handler, retry } = opts;\n\n if (isEmpty({ value: name })) {\n throw getError({\n message: `[EventBus][register] Invalid registration | name: ${String(name)}`,\n });\n }\n\n const maxAttempts = retry?.maxAttempts ?? EventDispatchRetry.MAX_ATTEMPTS;\n const baseDelayMs = retry?.baseDelayMs ?? EventDispatchRetry.BASE_DELAY_MS;\n EventBus.assertValidRetry({ name, maxAttempts, baseDelayMs });\n\n const { invokeHandler, description } = EventBus.buildHandlerInvoker({\n container: this.container,\n handler,\n name,\n });\n\n const registration: IResolvedEventRegistration = {\n invokeHandler,\n description,\n maxAttempts,\n baseDelayMs,\n };\n\n const existing = this.registrationsByName.get(name);\n if (existing) {\n existing.push(registration);\n return;\n }\n\n this.registrationsByName.set(name, [registration]);\n }\n\n /**\n * Never blocks and never throws back to the caller: dispatch runs outside this call's flow via\n * `queueMicrotask`, and a handler failure is caught and logged where it happens (`dispatch`),\n * never here.\n */\n publish<K extends keyof TPayloadMap & string>(opts: {\n name: K;\n payload: TPayloadMap[K];\n traceId?: string;\n }): void {\n const { name, payload, traceId } = opts;\n\n const event: IDomainEvent<TPayloadMap[K]> = {\n name,\n payload,\n occurredAt: new Date().toISOString(),\n traceId,\n };\n\n const registrations = this.registrationsByName.get(name);\n if (!registrations?.length) {\n // A typo is already a compile error, so at runtime this only means nobody is listening yet -\n // a legitimate state on a fire-and-forget bus, not an incident.\n this.logger.debug('[publish] No handler registered | name: %s | traceId: %s', name, traceId);\n return;\n }\n\n for (const registration of registrations) {\n queueMicrotask(() => {\n // `dispatch` catches every failure path itself and never rejects - this `.catch` is an\n // unreachable backstop, kept (and logged) rather than left floating, for the day it isn't.\n this.dispatch({ event, registration }).catch((error: unknown) => {\n this.logger.error(\n '[publish] Unexpected dispatch failure | name: %s | Error: %s',\n event.name,\n error,\n );\n });\n });\n }\n }\n\n /**\n * Attempts/backoff come from the registration (`EventDispatchRetry`'s defaults when omitted),\n * always with full jitter - `RetryJitterModes.FULL` decorrelates a shared-resource pile-up hardest,\n * so many handlers retrying the same lock do not collide on the same instant a second and third\n * time. `invokeHandler` already encodes whether that re-resolves (`BINDING_KEY`) or was captured\n * once (`FUNCTION`) - see `buildHandlerInvoker` - so this method calls it uniformly. A handler that\n * throws synchronously is caught exactly like one that returns a rejected promise: `execution`\n * here is itself `async`, and JS converts a synchronous throw inside an async function body into a\n * rejection of that function's own promise - `RetryHelper.executeWithRetry`'s attempt loop never\n * sees the difference.\n *\n * `RetryHelper.executeWithRetry` is used without its own `logger` - its internal per-attempt/exhaustion\n * logging knows nothing about the event name or `traceId`, so it cannot be the trace anyone\n * relies on. The one line below, logged only on final failure, is.\n */\n private async dispatch(opts: {\n event: IDomainEvent<unknown>;\n registration: IResolvedEventRegistration;\n }): Promise<void> {\n const { event, registration } = opts;\n const { invokeHandler, description, maxAttempts, baseDelayMs } = registration;\n let lastAttempt = 0;\n\n try {\n await RetryHelper.executeWithRetry({\n operation: `EventBus.dispatch:${event.name}`,\n maxAttempts,\n backoff: {\n strategy: RetryBackoffStrategies.EXPONENTIAL,\n initialDelayMs: baseDelayMs,\n jitter: RetryJitterModes.FULL,\n },\n execution: async ({ attempt }) => {\n lastAttempt = attempt;\n await invokeHandler({ event });\n },\n });\n } catch (error) {\n // The only trace this failure leaves: it is caught here and never reaches the publisher, so\n // the event name, traceId and attempt count all have to be on this one line.\n this.logger.error(\n '[dispatch] Handler exhausted retries | name: %s | traceId: %s | attempts: %d | handler: %s | Error: %s',\n event.name,\n event.traceId,\n lastAttempt,\n description,\n error,\n );\n }\n }\n}\n"]}
1
+ {"version":3,"file":"event-bus.js","sourceRoot":"","sources":["../../../../src/base/events/event-bus.ts"],"names":[],"mappings":"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","sourcesContent":["import { ObjectUtility } from '@venizia/ignis-helpers/common';\nimport type { Container } from '@/helpers/inversion/container';\nimport type { AnyType, ValueOrPromise } from '@venizia/ignis-helpers/common';\nimport {\n BaseHelper,\n getError,\n RetryBackoffStrategies,\n RetryHelper,\n RetryJitterModes,\n} from '@venizia/ignis-helpers/core';\nimport { EventDispatchRetry, EventHandlerTypes } from './common/constants';\nimport type {\n IDomainEvent,\n IEventHandler,\n IEventHandlerRetryOptions,\n TEventHandlerReference,\n} from './common/types';\n\ntype TEventHandlerInvoker = (opts: { event: IDomainEvent<unknown> }) => ValueOrPromise<void>;\n\n/** One `register`ed handler, resolved to concrete retry numbers and a ready-to-call invoker -\n * `EventDispatchRetry`'s defaults already applied and `handler`'s shape already resolved, so\n * `dispatch` never has to branch on either. */\ninterface IResolvedEventRegistration {\n invokeHandler: TEventHandlerInvoker;\n /** For the exhaustion log line only - a binding key or `<function fn.name>`. */\n description: string;\n maxAttempts: number;\n baseDelayMs: number;\n}\n\n/** In-process, fire-and-forget domain event bus. `TPayloadMap` keys the event names, so a wrong name\n * or payload shape is a compile error. Delivery is always async. Retry timing is a property of the\n * handler's own failure mode, not of the event, so `register` may tune it per registration. But\n * nobody awaits a fire-and-forget dispatch, so an unbounded window would let one event hold a\n * handler - and whatever it holds open, e.g. a database connection - for an unbounded time with no\n * one to report it. What the bus guarantees instead: a bounded MAXIMUM time a single dispatch can\n * occupy, enforced as a hard ceiling at `register()` - see `EventDispatchRetry`. Retry makes\n * delivery at-least-once: handlers must be idempotent, see `IEventHandler`. */\nexport class EventBus<TPayloadMap extends object> extends BaseHelper {\n private readonly container: Container;\n\n /** `register` appends, never replaces - two handlers may share an event name, and replacing would\n * drop the first with no way for the caller to notice. */\n private readonly registrationsByName: Map<string, IResolvedEventRegistration[]>;\n\n constructor(opts: { scope?: string; container: Container }) {\n super({ scope: opts.scope ?? EventBus.name });\n this.container = opts.container;\n this.registrationsByName = new Map();\n }\n\n /** The pre-jitter total of every inter-attempt delay `maxAttempts`/`baseDelayMs` would produce -\n * jitter (always on, see `dispatch`) only ever shrinks a delay, so this is a true upper bound. */\n private static computeTotalWindowMs(opts: { maxAttempts: number; baseDelayMs: number }): number {\n const { maxAttempts, baseDelayMs } = opts;\n let totalWindowMs = 0;\n\n for (let attempt = 1; attempt < maxAttempts; attempt++) {\n totalWindowMs += RetryHelper.computeBackoffDelayMs({\n attempt,\n backoff: {\n strategy: RetryBackoffStrategies.EXPONENTIAL,\n initialDelayMs: baseDelayMs,\n jitter: RetryJitterModes.NONE,\n },\n });\n }\n\n return totalWindowMs;\n }\n\n /** Loud rejection, never a silent clamp: a caller who believes a number the bus does not honour is\n * worse off than one who sees the ceiling at boot. */\n private static assertValidRetry(opts: {\n name: string;\n maxAttempts: number;\n baseDelayMs: number;\n }): void {\n const { name, maxAttempts, baseDelayMs } = opts;\n\n if (!Number.isInteger(maxAttempts) || maxAttempts < 1) {\n throw getError({\n message: `[EventBus][register] retry.maxAttempts must be a positive integer | name: ${name} | Got: ${maxAttempts}`,\n });\n }\n\n if (!Number.isInteger(baseDelayMs) || baseDelayMs < 1) {\n throw getError({\n message: `[EventBus][register] retry.baseDelayMs must be a positive integer | name: ${name} | Got: ${baseDelayMs}`,\n });\n }\n\n if (maxAttempts > EventDispatchRetry.MAX_ATTEMPTS_CEILING) {\n throw getError({\n message: `[EventBus][register] retry.maxAttempts exceeds the ceiling | name: ${name} | Got: ${maxAttempts} | Ceiling: ${EventDispatchRetry.MAX_ATTEMPTS_CEILING} | Lower retry.maxAttempts`,\n });\n }\n\n const totalWindowMs = EventBus.computeTotalWindowMs({ maxAttempts, baseDelayMs });\n if (totalWindowMs > EventDispatchRetry.MAX_TOTAL_WINDOW_MS) {\n throw getError({\n message: `[EventBus][register] retry window exceeds the ceiling | name: ${name} | Got: ${totalWindowMs}ms | Ceiling: ${EventDispatchRetry.MAX_TOTAL_WINDOW_MS}ms | Lower retry.maxAttempts or retry.baseDelayMs`,\n });\n }\n }\n\n /**\n * Turns `handler` into a uniform invoker plus a description for the exhaustion log line.\n * `BINDING_KEY` resolves through the container INSIDE the returned closure, so every call re-reads\n * the current binding; `FUNCTION` calls `fn` directly, so the closure IS the resolution - there is\n * nothing left to re-read on a later attempt. The tag (`handler.type`) is what this switches on,\n * not which field happens to be present - see `EventHandlerTypes`' doc.\n */\n private static buildHandlerInvoker(opts: {\n container: Container;\n handler: TEventHandlerReference<AnyType>;\n name: string;\n }): { invokeHandler: TEventHandlerInvoker; description: string } {\n const { container, handler, name } = opts;\n\n if (ObjectUtility.isEmpty({ value: handler })) {\n throw getError({\n message: `[EventBus][register] Invalid handler | name: ${name} | Got: ${handler}`,\n });\n }\n\n switch (handler.type) {\n case EventHandlerTypes.BINDING_KEY: {\n const { key } = handler;\n if (ObjectUtility.isEmpty({ value: key })) {\n throw getError({\n message: `[EventBus][register] Invalid handler.key | name: ${name} | Got: ${key}`,\n });\n }\n\n return {\n invokeHandler: ({ event }) => container.get<IEventHandler>({ key }).handle({ event }),\n description: `binding-key:${key}`,\n };\n }\n\n case EventHandlerTypes.FUNCTION: {\n const { fn } = handler;\n if (typeof fn !== 'function') {\n throw getError({\n message: `[EventBus][register] Invalid handler.fn | name: ${name} | Expected a function | Got: ${typeof fn}`,\n });\n }\n\n return {\n invokeHandler: ({ event }) => fn({ event }),\n description: `function:${fn.name || 'anonymous'}`,\n };\n }\n\n default: {\n throw getError({\n message: `[EventBus][register] Unknown handler.type | name: ${name} | Expected one of: ${[...EventHandlerTypes.SCHEME_SET].join(', ')} | Got: ${(handler as { type?: unknown }).type}`,\n });\n }\n }\n }\n\n /**\n * `retry` is optional and per REGISTRATION, not per publish: the right window belongs to the\n * handler's own failure mode, and two handlers on the same event name may each pick their own.\n * Omitting it reproduces today's `EventDispatchRetry` defaults exactly. Both `maxAttempts` and the\n * total backoff window it implies are bounded - see `EventDispatchRetry` - and exceeding either\n * throws here, at boot where a human sees it, rather than being silently clamped at dispatch time.\n */\n register<K extends keyof TPayloadMap & string>(opts: {\n name: K;\n /** A `BINDING_KEY` reference re-resolves through the container on every retry attempt, so a\n * rebind reaches a dispatch already in flight. A `FUNCTION` reference is captured as-is: a\n * rebind has nothing to reach, and every attempt in a long retry window calls the exact `fn`\n * registered here. */\n handler: TEventHandlerReference<TPayloadMap[K]>;\n retry?: IEventHandlerRetryOptions;\n }): void {\n const { name, handler, retry } = opts;\n\n if (ObjectUtility.isEmpty({ value: name })) {\n throw getError({\n message: `[EventBus][register] Invalid registration | name: ${String(name)}`,\n });\n }\n\n const maxAttempts = retry?.maxAttempts ?? EventDispatchRetry.MAX_ATTEMPTS;\n const baseDelayMs = retry?.baseDelayMs ?? EventDispatchRetry.BASE_DELAY_MS;\n EventBus.assertValidRetry({ name, maxAttempts, baseDelayMs });\n\n const { invokeHandler, description } = EventBus.buildHandlerInvoker({\n container: this.container,\n handler,\n name,\n });\n\n const registration: IResolvedEventRegistration = {\n invokeHandler,\n description,\n maxAttempts,\n baseDelayMs,\n };\n\n const existing = this.registrationsByName.get(name);\n if (existing) {\n existing.push(registration);\n return;\n }\n\n this.registrationsByName.set(name, [registration]);\n }\n\n /**\n * Never blocks and never throws back to the caller: dispatch runs outside this call's flow via\n * `queueMicrotask`, and a handler failure is caught and logged where it happens (`dispatch`),\n * never here.\n */\n publish<K extends keyof TPayloadMap & string>(opts: {\n name: K;\n payload: TPayloadMap[K];\n traceId?: string;\n }): void {\n const { name, payload, traceId } = opts;\n\n const event: IDomainEvent<TPayloadMap[K]> = {\n name,\n payload,\n occurredAt: new Date().toISOString(),\n traceId,\n };\n\n const registrations = this.registrationsByName.get(name);\n if (!registrations?.length) {\n // A typo is already a compile error, so at runtime this only means nobody is listening yet -\n // a legitimate state on a fire-and-forget bus, not an incident.\n this.logger.debug('[publish] No handler registered | name: %s | traceId: %s', name, traceId);\n return;\n }\n\n for (const registration of registrations) {\n queueMicrotask(() => {\n // `dispatch` catches every failure path itself and never rejects - this `.catch` is an\n // unreachable backstop, kept (and logged) rather than left floating, for the day it isn't.\n this.dispatch({ event, registration }).catch((error: unknown) => {\n this.logger.error(\n '[publish] Unexpected dispatch failure | name: %s | Error: %s',\n event.name,\n error,\n );\n });\n });\n }\n }\n\n /**\n * Attempts/backoff come from the registration (`EventDispatchRetry`'s defaults when omitted),\n * always with full jitter - `RetryJitterModes.FULL` decorrelates a shared-resource pile-up hardest,\n * so many handlers retrying the same lock do not collide on the same instant a second and third\n * time. `invokeHandler` already encodes whether that re-resolves (`BINDING_KEY`) or was captured\n * once (`FUNCTION`) - see `buildHandlerInvoker` - so this method calls it uniformly. A handler that\n * throws synchronously is caught exactly like one that returns a rejected promise: `execution`\n * here is itself `async`, and JS converts a synchronous throw inside an async function body into a\n * rejection of that function's own promise - `RetryHelper.executeWithRetry`'s attempt loop never\n * sees the difference.\n *\n * `RetryHelper.executeWithRetry` is used without its own `logger` - its internal per-attempt/exhaustion\n * logging knows nothing about the event name or `traceId`, so it cannot be the trace anyone\n * relies on. The one line below, logged only on final failure, is.\n */\n private async dispatch(opts: {\n event: IDomainEvent<unknown>;\n registration: IResolvedEventRegistration;\n }): Promise<void> {\n const { event, registration } = opts;\n const { invokeHandler, description, maxAttempts, baseDelayMs } = registration;\n let lastAttempt = 0;\n\n try {\n await RetryHelper.executeWithRetry({\n operation: `EventBus.dispatch:${event.name}`,\n maxAttempts,\n backoff: {\n strategy: RetryBackoffStrategies.EXPONENTIAL,\n initialDelayMs: baseDelayMs,\n jitter: RetryJitterModes.FULL,\n },\n execution: async ({ attempt }) => {\n lastAttempt = attempt;\n await invokeHandler({ event });\n },\n });\n } catch (error) {\n // The only trace this failure leaves: it is caught here and never reaches the publisher, so\n // the event name, traceId and attempt count all have to be on this one line.\n this.logger.error(\n '[dispatch] Handler exhausted retries | name: %s | traceId: %s | attempts: %d | handler: %s | Error: %s',\n event.name,\n event.traceId,\n lastAttempt,\n description,\n error,\n );\n }\n }\n}\n"]}
@@ -9,8 +9,11 @@ export declare const provide: (opts: {
9
9
  key: string;
10
10
  scope?: TBindingScope;
11
11
  }) => MethodDecorator;
12
- /** The registration defaults a stereotype forwards to `@injectable`, copied field by field so an absent option stays absent. */
13
- export declare const pickRegistrationOptions: <ApplicationType = unknown>(opts: {
14
- metadata: IArtifactRegistrationOptions<ApplicationType>;
15
- }) => IArtifactRegistrationOptions<ApplicationType>;
12
+ /** Helpers of the stereotype decorators; the decorators themselves stay functions. */
13
+ export declare class InjectableUtility {
14
+ /** The registration defaults a stereotype forwards to `@injectable`, copied field by field so an absent option stays absent. */
15
+ static pickRegistrationOptions<ApplicationType = unknown>(opts: {
16
+ metadata: IArtifactRegistrationOptions<ApplicationType>;
17
+ }): IArtifactRegistrationOptions<ApplicationType>;
18
+ }
16
19
  //# sourceMappingURL=injectable.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"injectable.d.ts","sourceRoot":"","sources":["../../../../src/base/metadata/injectable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,4BAA4B,EAC5B,aAAa,EACd,MAAM,qBAAqB,CAAC;AAM7B,oJAAoJ;AACpJ,eAAO,MAAM,UAAU,GAAI,eAAe,GAAG,OAAO,EAClD,MAAM,iBAAiB,CAAC,eAAe,CAAC,KACvC,cAmCF,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,eAAe,GAAG,OAAO,EAC/C,OAAO,4BAA4B,CAAC,eAAe,CAAC,KACnD,cAEF,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,eAAe,GAAG,OAAO,EACjD,OAAO,4BAA4B,CAAC,eAAe,CAAC,KACnD,cAEF,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,eAAe,GAAG,OAAO,EACrD,OAAO,4BAA4B,CAAC,eAAe,CAAC,KACnD,cAEF,CAAC;AACF,yMAAyM;AACzM,eAAO,MAAM,OAAO,GAAI,MAAM;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,aAAa,CAAA;CAAE,KAAG,eAWtE,CAAC;AAEF,gIAAgI;AAChI,eAAO,MAAM,uBAAuB,GAAI,eAAe,GAAG,OAAO,EAAE,MAAM;IACvE,QAAQ,EAAE,4BAA4B,CAAC,eAAe,CAAC,CAAC;CACzD,KAAG,4BAA4B,CAAC,eAAe,CA6B/C,CAAC"}
1
+ {"version":3,"file":"injectable.d.ts","sourceRoot":"","sources":["../../../../src/base/metadata/injectable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,4BAA4B,EAC5B,aAAa,EACd,MAAM,qBAAqB,CAAC;AAM7B,oJAAoJ;AACpJ,eAAO,MAAM,UAAU,GAAI,eAAe,GAAG,OAAO,EAClD,MAAM,iBAAiB,CAAC,eAAe,CAAC,KACvC,cAmCF,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,eAAe,GAAG,OAAO,EAC/C,OAAO,4BAA4B,CAAC,eAAe,CAAC,KACnD,cAEF,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,eAAe,GAAG,OAAO,EACjD,OAAO,4BAA4B,CAAC,eAAe,CAAC,KACnD,cAEF,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,eAAe,GAAG,OAAO,EACrD,OAAO,4BAA4B,CAAC,eAAe,CAAC,KACnD,cAEF,CAAC;AACF,yMAAyM;AACzM,eAAO,MAAM,OAAO,GAAI,MAAM;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,aAAa,CAAA;CAAE,KAAG,eAWtE,CAAC;AAEF,sFAAsF;AACtF,qBAAa,iBAAiB;IAC5B,gIAAgI;IAChI,MAAM,CAAC,uBAAuB,CAAC,eAAe,GAAG,OAAO,EAAE,IAAI,EAAE;QAC9D,QAAQ,EAAE,4BAA4B,CAAC,eAAe,CAAC,CAAC;KACzD,GAAG,4BAA4B,CAAC,eAAe,CAAC;CA8BlD"}
@@ -57,28 +57,31 @@ export const provide = (opts) => {
57
57
  });
58
58
  };
59
59
  };
60
- /** The registration defaults a stereotype forwards to `@injectable`, copied field by field so an absent option stays absent. */
61
- export const pickRegistrationOptions = (opts) => {
62
- const { binding, allowOverride, scope, order, when, after } = opts.metadata;
63
- const registration = {};
64
- if (binding !== undefined) {
65
- registration.binding = binding;
66
- }
67
- if (allowOverride !== undefined) {
68
- registration.allowOverride = allowOverride;
69
- }
70
- if (scope !== undefined) {
71
- registration.scope = scope;
72
- }
73
- if (order !== undefined) {
74
- registration.order = order;
75
- }
76
- if (when !== undefined) {
77
- registration.when = when;
78
- }
79
- if (after !== undefined) {
80
- registration.after = after;
60
+ /** Helpers of the stereotype decorators; the decorators themselves stay functions. */
61
+ export class InjectableUtility {
62
+ /** The registration defaults a stereotype forwards to `@injectable`, copied field by field so an absent option stays absent. */
63
+ static pickRegistrationOptions(opts) {
64
+ const { binding, allowOverride, scope, order, when, after } = opts.metadata;
65
+ const registration = {};
66
+ if (binding !== undefined) {
67
+ registration.binding = binding;
68
+ }
69
+ if (allowOverride !== undefined) {
70
+ registration.allowOverride = allowOverride;
71
+ }
72
+ if (scope !== undefined) {
73
+ registration.scope = scope;
74
+ }
75
+ if (order !== undefined) {
76
+ registration.order = order;
77
+ }
78
+ if (when !== undefined) {
79
+ registration.when = when;
80
+ }
81
+ if (after !== undefined) {
82
+ registration.after = after;
83
+ }
84
+ return registration;
81
85
  }
82
- return registration;
83
- };
86
+ }
84
87
  //# sourceMappingURL=injectable.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"injectable.js","sourceRoot":"","sources":["../../../../src/base/metadata/injectable.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n IArtifactMetadata,\n IArtifactRegistrationOptions,\n TBindingScope,\n} from '@/helpers/inversion';\nimport { ArtifactNamespaces, BindingNamespaces } from '@/common/bindings';\nimport { ArtifactTypes, MetadataRegistry } from '@/helpers/inversion';\nimport { ArtifactBindingKeys } from './artifact-keys';\nimport { getError } from '@venizia/ignis-helpers/core';\n\n/** The root stereotype: marks a class as an artifact the application registers, with its registration defaults. Every other stereotype calls it. */\nexport const injectable = <ApplicationType = unknown>(\n opts: IArtifactMetadata<ApplicationType>,\n): ClassDecorator => {\n return (target) => {\n if (!ArtifactTypes.isValid(opts.type)) {\n throw getError({\n message: `[injectable][${target.name}] Invalid artifact type: '${opts.type}' | Expected one of: ${[...ArtifactTypes.SCHEME_SET].join(', ')}`,\n });\n }\n\n // At import time, so the failure lands where the binding is written, not at boot.\n if (opts.binding) {\n BindingNamespaces.assertArtifactNamespace({\n namespace: opts.binding.namespace,\n artifact: target.name,\n caller: 'injectable',\n });\n }\n\n const registry = MetadataRegistry.getInstance();\n registry.setArtifactMetadata({ target, metadata: opts });\n\n // Discovery happens HERE, at import time. A boot-time filesystem scan cannot see a compiled\n // single-file binary, and a class exists at run time only because something imported it.\n registry.addDiscoveredArtifact({ target });\n\n // The key this class WOULD get; `registerArtifact` overwrites it with the one actually bound.\n registry.setBindingKey({\n target,\n key: ArtifactBindingKeys.resolve({\n target,\n namespace: ArtifactNamespaces.resolve({ type: opts.type }),\n binding: opts.binding,\n }).key,\n isProvisional: true,\n });\n };\n};\n\nexport const service = <ApplicationType = unknown>(\n opts?: IArtifactRegistrationOptions<ApplicationType>,\n): ClassDecorator => {\n return injectable<ApplicationType>({ type: ArtifactTypes.SERVICE, ...opts });\n};\n\nexport const component = <ApplicationType = unknown>(\n opts?: IArtifactRegistrationOptions<ApplicationType>,\n): ClassDecorator => {\n return injectable<ApplicationType>({ type: ArtifactTypes.COMPONENT, ...opts });\n};\n\nexport const configuration = <ApplicationType = unknown>(\n opts?: IArtifactRegistrationOptions<ApplicationType>,\n): ClassDecorator => {\n return injectable<ApplicationType>({ type: ArtifactTypes.CONFIGURATION, ...opts });\n};\n/** Marks a component method as the provider of `key`. `registerArtifacts` binds the key to a lazy provider that resolves the component and calls the method; SINGLETON unless `scope` says otherwise. */\nexport const provide = (opts: { key: string; scope?: TBindingScope }): MethodDecorator => {\n return (target, propertyKey) => {\n MetadataRegistry.getInstance().addProvideMetadata({\n target: target.constructor,\n metadata: {\n methodName: propertyKey,\n key: opts.key,\n ...(opts.scope ? { scope: opts.scope } : {}),\n },\n });\n };\n};\n\n/** The registration defaults a stereotype forwards to `@injectable`, copied field by field so an absent option stays absent. */\nexport const pickRegistrationOptions = <ApplicationType = unknown>(opts: {\n metadata: IArtifactRegistrationOptions<ApplicationType>;\n}): IArtifactRegistrationOptions<ApplicationType> => {\n const { binding, allowOverride, scope, order, when, after } = opts.metadata;\n const registration: IArtifactRegistrationOptions<ApplicationType> = {};\n\n if (binding !== undefined) {\n registration.binding = binding;\n }\n\n if (allowOverride !== undefined) {\n registration.allowOverride = allowOverride;\n }\n\n if (scope !== undefined) {\n registration.scope = scope;\n }\n\n if (order !== undefined) {\n registration.order = order;\n }\n\n if (when !== undefined) {\n registration.when = when;\n }\n\n if (after !== undefined) {\n registration.after = after;\n }\n\n return registration;\n};\n"]}
1
+ {"version":3,"file":"injectable.js","sourceRoot":"","sources":["../../../../src/base/metadata/injectable.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n IArtifactMetadata,\n IArtifactRegistrationOptions,\n TBindingScope,\n} from '@/helpers/inversion';\nimport { ArtifactNamespaces, BindingNamespaces } from '@/common/bindings';\nimport { ArtifactTypes, MetadataRegistry } from '@/helpers/inversion';\nimport { ArtifactBindingKeys } from './artifact-keys';\nimport { getError } from '@venizia/ignis-helpers/core';\n\n/** The root stereotype: marks a class as an artifact the application registers, with its registration defaults. Every other stereotype calls it. */\nexport const injectable = <ApplicationType = unknown>(\n opts: IArtifactMetadata<ApplicationType>,\n): ClassDecorator => {\n return (target) => {\n if (!ArtifactTypes.isValid(opts.type)) {\n throw getError({\n message: `[injectable][${target.name}] Invalid artifact type: '${opts.type}' | Expected one of: ${[...ArtifactTypes.SCHEME_SET].join(', ')}`,\n });\n }\n\n // At import time, so the failure lands where the binding is written, not at boot.\n if (opts.binding) {\n BindingNamespaces.assertArtifactNamespace({\n namespace: opts.binding.namespace,\n artifact: target.name,\n caller: 'injectable',\n });\n }\n\n const registry = MetadataRegistry.getInstance();\n registry.setArtifactMetadata({ target, metadata: opts });\n\n // Discovery happens HERE, at import time. A boot-time filesystem scan cannot see a compiled\n // single-file binary, and a class exists at run time only because something imported it.\n registry.addDiscoveredArtifact({ target });\n\n // The key this class WOULD get; `registerArtifact` overwrites it with the one actually bound.\n registry.setBindingKey({\n target,\n key: ArtifactBindingKeys.resolve({\n target,\n namespace: ArtifactNamespaces.resolve({ type: opts.type }),\n binding: opts.binding,\n }).key,\n isProvisional: true,\n });\n };\n};\n\nexport const service = <ApplicationType = unknown>(\n opts?: IArtifactRegistrationOptions<ApplicationType>,\n): ClassDecorator => {\n return injectable<ApplicationType>({ type: ArtifactTypes.SERVICE, ...opts });\n};\n\nexport const component = <ApplicationType = unknown>(\n opts?: IArtifactRegistrationOptions<ApplicationType>,\n): ClassDecorator => {\n return injectable<ApplicationType>({ type: ArtifactTypes.COMPONENT, ...opts });\n};\n\nexport const configuration = <ApplicationType = unknown>(\n opts?: IArtifactRegistrationOptions<ApplicationType>,\n): ClassDecorator => {\n return injectable<ApplicationType>({ type: ArtifactTypes.CONFIGURATION, ...opts });\n};\n/** Marks a component method as the provider of `key`. `registerArtifacts` binds the key to a lazy provider that resolves the component and calls the method; SINGLETON unless `scope` says otherwise. */\nexport const provide = (opts: { key: string; scope?: TBindingScope }): MethodDecorator => {\n return (target, propertyKey) => {\n MetadataRegistry.getInstance().addProvideMetadata({\n target: target.constructor,\n metadata: {\n methodName: propertyKey,\n key: opts.key,\n ...(opts.scope ? { scope: opts.scope } : {}),\n },\n });\n };\n};\n\n/** Helpers of the stereotype decorators; the decorators themselves stay functions. */\nexport class InjectableUtility {\n /** The registration defaults a stereotype forwards to `@injectable`, copied field by field so an absent option stays absent. */\n static pickRegistrationOptions<ApplicationType = unknown>(opts: {\n metadata: IArtifactRegistrationOptions<ApplicationType>;\n }): IArtifactRegistrationOptions<ApplicationType> {\n const { binding, allowOverride, scope, order, when, after } = opts.metadata;\n const registration: IArtifactRegistrationOptions<ApplicationType> = {};\n\n if (binding !== undefined) {\n registration.binding = binding;\n }\n\n if (allowOverride !== undefined) {\n registration.allowOverride = allowOverride;\n }\n\n if (scope !== undefined) {\n registration.scope = scope;\n }\n\n if (order !== undefined) {\n registration.order = order;\n }\n\n if (when !== undefined) {\n registration.when = when;\n }\n\n if (after !== undefined) {\n registration.after = after;\n }\n\n return registration;\n }\n}\n"]}
@@ -1,15 +1,29 @@
1
1
  import type { IModelMetadata } from '../../helpers/inversion/index.js';
2
- /**
3
- * The one place the `@model` metadata outside `settings` is checked and normalised.
4
- *
5
- * - `type` is optional; a value must be one of {@link ModelTypes}.
6
- * - `skipMigrate` is gone (0.4.4): the decorator throws on it and names the replacement, the way it
7
- * does for the flat settings keys removed in 0.4.3. The check reads the key by name because an
8
- * untyped caller, or a model written before the removal, never meets the type error.
9
- * - When the model declares `migration`, the registry entry carries it with `use` filled in.
10
- */
11
- export declare const normalizeModelMetadata: (opts: {
12
- model: string;
13
- metadata: IModelMetadata;
14
- }) => IModelMetadata;
2
+ export declare class ModelMetadataUtility {
3
+ /** The keys 0.4.2 deprecated and 0.4.3 removed, and the key that replaces each. */
4
+ private static readonly REMOVED_MODEL_SETTINGS;
5
+ /**
6
+ * The one place the `@model` metadata outside `settings` is checked and normalised.
7
+ *
8
+ * - `type` is optional; a value must be one of {@link ModelTypes}.
9
+ * - `skipMigrate` is gone (0.4.4): the decorator throws on it and names the replacement, the way it
10
+ * does for the flat settings keys removed in 0.4.3. The check reads the key by name because an
11
+ * untyped caller, or a model written before the removal, never meets the type error.
12
+ * - When the model declares `migration`, the registry entry carries it with `use` filled in.
13
+ */
14
+ static normalizeModelMetadata(opts: {
15
+ model: string;
16
+ metadata: IModelMetadata;
17
+ }): IModelMetadata;
18
+ /**
19
+ * Refuses a removed `@model` settings key. A model that still says `scopeFilter` would otherwise
20
+ * lose its row scope without a sound (a plain-JavaScript or `any`-typed model gets no type error),
21
+ * so the decorator throws instead, naming the key to use. `devz codemod model-settings --write` rewrites
22
+ * the keys.
23
+ */
24
+ static assertNoRemovedModelSettings(opts: {
25
+ model: string;
26
+ settings: object | undefined;
27
+ }): void;
28
+ }
15
29
  //# sourceMappingURL=model-metadata.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"model-metadata.d.ts","sourceRoot":"","sources":["../../../../src/base/metadata/model-metadata.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAG1D;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,GAAI,MAAM;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,cAAc,CAAC;CAC1B,KAAG,cA0BH,CAAC"}
1
+ {"version":3,"file":"model-metadata.d.ts","sourceRoot":"","sources":["../../../../src/base/metadata/model-metadata.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAG1D,qBAAa,oBAAoB;IAC/B,mFAAmF;IACnF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAK5C;IAEF;;;;;;;;OAQG;IACH,MAAM,CAAC,sBAAsB,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,cAAc,CAAA;KAAE,GAAG,cAAc;IA4BhG;;;;;OAKG;IACH,MAAM,CAAC,4BAA4B,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,GAAG,IAAI;CAyBjG"}
@@ -1,33 +1,63 @@
1
1
  import { getError } from '@venizia/ignis-helpers/core';
2
2
  import { ModelTypes } from '../models/common/constants.js';
3
- /**
4
- * The one place the `@model` metadata outside `settings` is checked and normalised.
5
- *
6
- * - `type` is optional; a value must be one of {@link ModelTypes}.
7
- * - `skipMigrate` is gone (0.4.4): the decorator throws on it and names the replacement, the way it
8
- * does for the flat settings keys removed in 0.4.3. The check reads the key by name because an
9
- * untyped caller, or a model written before the removal, never meets the type error.
10
- * - When the model declares `migration`, the registry entry carries it with `use` filled in.
11
- */
12
- export const normalizeModelMetadata = (opts) => {
13
- const { model, metadata } = opts;
14
- const { type, migration } = metadata;
15
- if (type !== undefined && !ModelTypes.isValid(type)) {
16
- throw getError({
17
- message: `[model][${model}] Invalid 'type' | Expected one of: ${[...ModelTypes.SCHEME_SET].join(', ')} (or leave it out) | Got: ${String(type)}`,
18
- });
3
+ export class ModelMetadataUtility {
4
+ /** The keys 0.4.2 deprecated and 0.4.3 removed, and the key that replaces each. */
5
+ static { this.REMOVED_MODEL_SETTINGS = {
6
+ defaultFilter: 'query.filter',
7
+ defaultLimit: 'query.limit.default',
8
+ maxLimit: 'query.limit.max',
9
+ scopeFilter: 'access',
10
+ }; }
11
+ /**
12
+ * The one place the `@model` metadata outside `settings` is checked and normalised.
13
+ *
14
+ * - `type` is optional; a value must be one of {@link ModelTypes}.
15
+ * - `skipMigrate` is gone (0.4.4): the decorator throws on it and names the replacement, the way it
16
+ * does for the flat settings keys removed in 0.4.3. The check reads the key by name because an
17
+ * untyped caller, or a model written before the removal, never meets the type error.
18
+ * - When the model declares `migration`, the registry entry carries it with `use` filled in.
19
+ */
20
+ static normalizeModelMetadata(opts) {
21
+ const { model, metadata } = opts;
22
+ const { type, migration } = metadata;
23
+ if (type !== undefined && !ModelTypes.isValid(type)) {
24
+ throw getError({
25
+ message: `[model][${model}] Invalid 'type' | Expected one of: ${[...ModelTypes.SCHEME_SET].join(', ')} (or leave it out) | Got: ${String(type)}`,
26
+ });
27
+ }
28
+ if ('skipMigrate' in metadata) {
29
+ const replacement = metadata.skipMigrate === false
30
+ ? 'remove the key (migration.use is true by default)'
31
+ : 'write migration: { use: false }';
32
+ throw getError({
33
+ message: `[model][${model}] skipMigrate was removed in 0.4.4 | ${replacement} | run \`bunx devz codemod model-settings --write\` to rewrite every model`,
34
+ });
35
+ }
36
+ if (migration === undefined) {
37
+ return metadata;
38
+ }
39
+ return { ...metadata, migration: { ...migration, use: migration.use !== false } };
19
40
  }
20
- if ('skipMigrate' in metadata) {
21
- const replacement = metadata.skipMigrate === false
22
- ? 'remove the key (migration.use is true by default)'
23
- : 'write migration: { use: false }';
41
+ /**
42
+ * Refuses a removed `@model` settings key. A model that still says `scopeFilter` would otherwise
43
+ * lose its row scope without a sound (a plain-JavaScript or `any`-typed model gets no type error),
44
+ * so the decorator throws instead, naming the key to use. `devz codemod model-settings --write` rewrites
45
+ * the keys.
46
+ */
47
+ static assertNoRemovedModelSettings(opts) {
48
+ const { model, settings } = opts;
49
+ if (!settings) {
50
+ return;
51
+ }
52
+ const removed = Object.keys(ModelMetadataUtility.REMOVED_MODEL_SETTINGS).filter((key) => Object.hasOwn(settings, key));
53
+ if (removed.length === 0) {
54
+ return;
55
+ }
24
56
  throw getError({
25
- message: `[model][${model}] skipMigrate was removed in 0.4.4 | ${replacement} | run \`bunx devz codemod model-settings --write\` to rewrite every model`,
57
+ message: `[model][${model}] Removed settings key(s): ${removed
58
+ .map((key) => `settings.${key} (use settings.${ModelMetadataUtility.REMOVED_MODEL_SETTINGS[key]})`)
59
+ .join(', ')} | removed in 0.4.3 | run 'devz codemod model-settings --write' to rewrite them`,
26
60
  });
27
61
  }
28
- if (migration === undefined) {
29
- return metadata;
30
- }
31
- return { ...metadata, migration: { ...migration, use: migration.use !== false } };
32
- };
62
+ }
33
63
  //# sourceMappingURL=model-metadata.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"model-metadata.js","sourceRoot":"","sources":["../../../../src/base/metadata/model-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAExD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,IAGtC,EAAkB,EAAE;IACnB,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IACjC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC;IAErC,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACpD,MAAM,QAAQ,CAAC;YACb,OAAO,EAAE,WAAW,KAAK,uCAAuC,CAAC,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,6BAA6B,MAAM,CAAC,IAAI,CAAC,EAAE;SACjJ,CAAC,CAAC;IACL,CAAC;IAED,IAAI,aAAa,IAAI,QAAQ,EAAE,CAAC;QAC9B,MAAM,WAAW,GACf,QAAQ,CAAC,WAAW,KAAK,KAAK;YAC5B,CAAC,CAAC,mDAAmD;YACrD,CAAC,CAAC,iCAAiC,CAAC;QAExC,MAAM,QAAQ,CAAC;YACb,OAAO,EAAE,WAAW,KAAK,wCAAwC,WAAW,4EAA4E;SACzJ,CAAC,CAAC;IACL,CAAC;IAED,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,OAAO,EAAE,GAAG,QAAQ,EAAE,SAAS,EAAE,EAAE,GAAG,SAAS,EAAE,GAAG,EAAE,SAAS,CAAC,GAAG,KAAK,KAAK,EAAE,EAAE,CAAC;AACpF,CAAC,CAAC","sourcesContent":["import { getError } from '@venizia/ignis-helpers/core';\nimport type { IModelMetadata } from '@/helpers/inversion';\nimport { ModelTypes } from '../models/common/constants';\n\n/**\n * The one place the `@model` metadata outside `settings` is checked and normalised.\n *\n * - `type` is optional; a value must be one of {@link ModelTypes}.\n * - `skipMigrate` is gone (0.4.4): the decorator throws on it and names the replacement, the way it\n * does for the flat settings keys removed in 0.4.3. The check reads the key by name because an\n * untyped caller, or a model written before the removal, never meets the type error.\n * - When the model declares `migration`, the registry entry carries it with `use` filled in.\n */\nexport const normalizeModelMetadata = (opts: {\n model: string;\n metadata: IModelMetadata;\n}): IModelMetadata => {\n const { model, metadata } = opts;\n const { type, migration } = metadata;\n\n if (type !== undefined && !ModelTypes.isValid(type)) {\n throw getError({\n message: `[model][${model}] Invalid 'type' | Expected one of: ${[...ModelTypes.SCHEME_SET].join(', ')} (or leave it out) | Got: ${String(type)}`,\n });\n }\n\n if ('skipMigrate' in metadata) {\n const replacement =\n metadata.skipMigrate === false\n ? 'remove the key (migration.use is true by default)'\n : 'write migration: { use: false }';\n\n throw getError({\n message: `[model][${model}] skipMigrate was removed in 0.4.4 | ${replacement} | run \\`bunx devz codemod model-settings --write\\` to rewrite every model`,\n });\n }\n\n if (migration === undefined) {\n return metadata;\n }\n\n return { ...metadata, migration: { ...migration, use: migration.use !== false } };\n};\n"]}
1
+ {"version":3,"file":"model-metadata.js","sourceRoot":"","sources":["../../../../src/base/metadata/model-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAExD,MAAM,OAAO,oBAAoB;IAC/B,mFAAmF;aAC3D,2BAAsB,GAA2B;QACvE,aAAa,EAAE,cAAc;QAC7B,YAAY,EAAE,qBAAqB;QACnC,QAAQ,EAAE,iBAAiB;QAC3B,WAAW,EAAE,QAAQ;KACtB,CAAC;IAEF;;;;;;;;OAQG;IACH,MAAM,CAAC,sBAAsB,CAAC,IAAiD;QAC7E,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;QACjC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC;QAErC,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACpD,MAAM,QAAQ,CAAC;gBACb,OAAO,EAAE,WAAW,KAAK,uCAAuC,CAAC,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,6BAA6B,MAAM,CAAC,IAAI,CAAC,EAAE;aACjJ,CAAC,CAAC;QACL,CAAC;QAED,IAAI,aAAa,IAAI,QAAQ,EAAE,CAAC;YAC9B,MAAM,WAAW,GACf,QAAQ,CAAC,WAAW,KAAK,KAAK;gBAC5B,CAAC,CAAC,mDAAmD;gBACrD,CAAC,CAAC,iCAAiC,CAAC;YAExC,MAAM,QAAQ,CAAC;gBACb,OAAO,EAAE,WAAW,KAAK,wCAAwC,WAAW,4EAA4E;aACzJ,CAAC,CAAC;QACL,CAAC;QAED,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,OAAO,EAAE,GAAG,QAAQ,EAAE,SAAS,EAAE,EAAE,GAAG,SAAS,EAAE,GAAG,EAAE,SAAS,CAAC,GAAG,KAAK,KAAK,EAAE,EAAE,CAAC;IACpF,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,4BAA4B,CAAC,IAAqD;QACvF,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;QAEjC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CACtF,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,CAC7B,CAAC;QACF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,CAAC;YACb,OAAO,EAAE,WAAW,KAAK,8BAA8B,OAAO;iBAC3D,GAAG,CACF,CAAC,GAAG,EAAE,EAAE,CACN,YAAY,GAAG,kBAAkB,oBAAoB,CAAC,sBAAsB,CAAC,GAAG,CAAC,GAAG,CACvF;iBACA,IAAI,CACH,IAAI,CACL,iFAAiF;SACrF,CAAC,CAAC;IACL,CAAC","sourcesContent":["import { getError } from '@venizia/ignis-helpers/core';\nimport type { IModelMetadata } from '@/helpers/inversion';\nimport { ModelTypes } from '../models/common/constants';\n\nexport class ModelMetadataUtility {\n /** The keys 0.4.2 deprecated and 0.4.3 removed, and the key that replaces each. */\n private static readonly REMOVED_MODEL_SETTINGS: Record<string, string> = {\n defaultFilter: 'query.filter',\n defaultLimit: 'query.limit.default',\n maxLimit: 'query.limit.max',\n scopeFilter: 'access',\n };\n\n /**\n * The one place the `@model` metadata outside `settings` is checked and normalised.\n *\n * - `type` is optional; a value must be one of {@link ModelTypes}.\n * - `skipMigrate` is gone (0.4.4): the decorator throws on it and names the replacement, the way it\n * does for the flat settings keys removed in 0.4.3. The check reads the key by name because an\n * untyped caller, or a model written before the removal, never meets the type error.\n * - When the model declares `migration`, the registry entry carries it with `use` filled in.\n */\n static normalizeModelMetadata(opts: { model: string; metadata: IModelMetadata }): IModelMetadata {\n const { model, metadata } = opts;\n const { type, migration } = metadata;\n\n if (type !== undefined && !ModelTypes.isValid(type)) {\n throw getError({\n message: `[model][${model}] Invalid 'type' | Expected one of: ${[...ModelTypes.SCHEME_SET].join(', ')} (or leave it out) | Got: ${String(type)}`,\n });\n }\n\n if ('skipMigrate' in metadata) {\n const replacement =\n metadata.skipMigrate === false\n ? 'remove the key (migration.use is true by default)'\n : 'write migration: { use: false }';\n\n throw getError({\n message: `[model][${model}] skipMigrate was removed in 0.4.4 | ${replacement} | run \\`bunx devz codemod model-settings --write\\` to rewrite every model`,\n });\n }\n\n if (migration === undefined) {\n return metadata;\n }\n\n return { ...metadata, migration: { ...migration, use: migration.use !== false } };\n }\n\n /**\n * Refuses a removed `@model` settings key. A model that still says `scopeFilter` would otherwise\n * lose its row scope without a sound (a plain-JavaScript or `any`-typed model gets no type error),\n * so the decorator throws instead, naming the key to use. `devz codemod model-settings --write` rewrites\n * the keys.\n */\n static assertNoRemovedModelSettings(opts: { model: string; settings: object | undefined }): void {\n const { model, settings } = opts;\n\n if (!settings) {\n return;\n }\n\n const removed = Object.keys(ModelMetadataUtility.REMOVED_MODEL_SETTINGS).filter((key) =>\n Object.hasOwn(settings, key),\n );\n if (removed.length === 0) {\n return;\n }\n\n throw getError({\n message: `[model][${model}] Removed settings key(s): ${removed\n .map(\n (key) =>\n `settings.${key} (use settings.${ModelMetadataUtility.REMOVED_MODEL_SETTINGS[key]})`,\n )\n .join(\n ', ',\n )} | removed in 0.4.3 | run 'devz codemod model-settings --write' to rewrite them`,\n });\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"persistents.d.ts","sourceRoot":"","sources":["../../../../src/base/metadata/persistents.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,mBAAmB,EAEnB,cAAc,EAEd,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAU7B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAMhD,oEAAoE;AACpE,eAAO,MAAM,KAAK,GAAI,QAAO,cAAmB,KAAG,cAmClD,CAAC;AAEF,sEAAsE;AACtE,eAAO,MAAM,UAAU,GAAI,WAAW,mBAAmB,KAAG,cAQ3D,CAAC;AA0PF,eAAO,MAAM,UAAU,GACrB,KAAK,SAAS,cAAc,GAAG,cAAc,EAC7C,UAAU,SAAS,WAAW,GAAG,WAAW,EAE5C,WAAW,mBAAmB,CAAC,KAAK,EAAE,UAAU,CAAC,KAChD,cAeF,CAAC"}
1
+ {"version":3,"file":"persistents.d.ts","sourceRoot":"","sources":["../../../../src/base/metadata/persistents.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,mBAAmB,EAEnB,cAAc,EAEd,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAI7B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAKhD,oEAAoE;AACpE,eAAO,MAAM,KAAK,GAAI,QAAO,cAAmB,KAAG,cA0ClD,CAAC;AAEF,sEAAsE;AACtE,eAAO,MAAM,UAAU,GAAI,WAAW,mBAAmB,KAAG,cAQ3D,CAAC;AA0PF,eAAO,MAAM,UAAU,GACrB,KAAK,SAAS,cAAc,GAAG,cAAc,EAC7C,UAAU,SAAS,WAAW,GAAG,WAAW,EAE5C,WAAW,mBAAmB,CAAC,KAAK,EAAE,UAAU,CAAC,KAChD,cAeF,CAAC"}
@@ -1,18 +1,26 @@
1
1
  import { BindingNamespaces } from '../../common/bindings.js';
2
- import { ArtifactTypes, BindingKeys, MetadataKeys, MetadataRegistry, resolveInjectTarget, } from '../../helpers/inversion/index.js';
3
- import { resolveClass, resolveValue } from '@venizia/ignis-helpers/common';
2
+ import { ArtifactTypes, BindingKeys, MetadataKeys, MetadataRegistry } from '../../helpers/inversion/index.js';
3
+ import { ClassResolver, ResolverUtility } from '@venizia/ignis-helpers/common';
4
4
  import { getError } from '@venizia/ignis-helpers/core';
5
5
  import { isDataSourceClass } from '../datasources/index.js';
6
6
  import { RepositoryTypes } from '../repositories/common/constants.js';
7
- import { injectable, pickRegistrationOptions } from './injectable.js';
8
- import { normalizeModelMetadata } from './model-metadata.js';
9
- import { assertNoRemovedModelSettings } from './model-settings.js';
7
+ import { injectable, InjectableUtility } from './injectable.js';
8
+ import { ModelMetadataUtility } from './model-metadata.js';
10
9
  /** Registers a model class with its static schema and relations. */
11
10
  export const model = (input = {}) => {
12
11
  return (target) => {
13
- injectable({ type: ArtifactTypes.MODEL, ...pickRegistrationOptions({ metadata: input }) })(target);
14
- const metadata = normalizeModelMetadata({ model: target.name, metadata: input });
15
- assertNoRemovedModelSettings({ model: target.name, settings: metadata.settings });
12
+ injectable({
13
+ type: ArtifactTypes.MODEL,
14
+ ...InjectableUtility.pickRegistrationOptions({ metadata: input }),
15
+ })(target);
16
+ const metadata = ModelMetadataUtility.normalizeModelMetadata({
17
+ model: target.name,
18
+ metadata: input,
19
+ });
20
+ ModelMetadataUtility.assertNoRemovedModelSettings({
21
+ model: target.name,
22
+ settings: metadata.settings,
23
+ });
16
24
  const { settings } = metadata;
17
25
  const defaultLimit = settings?.query?.limit?.default;
18
26
  if (defaultLimit !== undefined && (!Number.isInteger(defaultLimit) || defaultLimit <= 0)) {
@@ -41,7 +49,7 @@ export const datasource = (metadata) => {
41
49
  return (target) => {
42
50
  injectable({
43
51
  type: ArtifactTypes.DATASOURCE,
44
- ...pickRegistrationOptions({ metadata: metadata ?? {} }),
52
+ ...InjectableUtility.pickRegistrationOptions({ metadata: metadata ?? {} }),
45
53
  })(target);
46
54
  MetadataRegistry.getInstance().setDataSourceMetadata({ target, metadata });
47
55
  };
@@ -106,7 +114,7 @@ const registerDataSourceInjection = (opts) => {
106
114
  // `@inject({ target })` carries no key; read the one recorded on the class. The function form
107
115
  // resolves through the same helper the container uses, so both paths read one class.
108
116
  const injectedTarget = injectAtIndex0.target
109
- ? resolveInjectTarget({ target: injectAtIndex0.target })
117
+ ? ResolverUtility.resolveInjectTarget({ target: injectAtIndex0.target })
110
118
  : undefined;
111
119
  const injectKey = injectAtIndex0.key ??
112
120
  (injectedTarget ? registry.getBindingKey({ target: injectedTarget }) : undefined);
@@ -152,7 +160,7 @@ const registerDataSourceInjection = (opts) => {
152
160
  const resolveRepositoryMetadata = (opts) => {
153
161
  const { metadata, target, registry } = opts;
154
162
  validateRepositoryMetadata({ metadata, target });
155
- const resolvedDataSource = resolveClass({ ref: metadata.dataSource });
163
+ const resolvedDataSource = ClassResolver.resolveClass({ ref: metadata.dataSource });
156
164
  if (!resolvedDataSource) {
157
165
  throw getError({
158
166
  message: `[@repository][${target.name}] The dataSource resolver returned nothing at decoration time | An import cycle leaves the datasource class undefined here; import it without the cycle, or name it as a string`,
@@ -172,7 +180,7 @@ const resolveRepositoryMetadata = (opts) => {
172
180
  operationScope: metadata.operationScope,
173
181
  };
174
182
  }
175
- const resolvedModel = resolveValue({ value: metadata.model });
183
+ const resolvedModel = ResolverUtility.resolveValue({ value: metadata.model });
176
184
  registry.registerRepositoryBinding({
177
185
  repository: target,
178
186
  model: resolvedModel,
@@ -211,7 +219,7 @@ const applyRepositoryMetadata = (opts) => {
211
219
  const { metadata, registration, target, registry } = opts;
212
220
  injectable({
213
221
  type: ArtifactTypes.REPOSITORY,
214
- ...pickRegistrationOptions({ metadata: registration }),
222
+ ...InjectableUtility.pickRegistrationOptions({ metadata: registration }),
215
223
  })(target);
216
224
  const resolved = resolveRepositoryMetadata({ metadata, target, registry });
217
225
  registry.setRepositoryMetadata({ target, metadata: { ...metadata, _resolved: resolved } });