@pattern-stack/codegen 0.14.2 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pattern-stack/codegen",
3
- "version": "0.14.2",
3
+ "version": "0.15.0",
4
4
  "description": "Entity-driven code generation for full-stack TypeScript applications",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -44,7 +44,7 @@
44
44
  * `new Class()` which silently left `db` / `redisUrl` undefined
45
45
  * (issue #108).
46
46
  */
47
- import { Module, type DynamicModule, type Provider } from '@nestjs/common';
47
+ import { Module, type DynamicModule, type Provider, type Type } from '@nestjs/common';
48
48
  import {
49
49
  EVENT_BUS,
50
50
  EVENT_READ_PORT,
@@ -112,6 +112,31 @@ export interface EventsModuleOptions {
112
112
  * Defaults to `false`.
113
113
  */
114
114
  multiTenant?: boolean;
115
+ /**
116
+ * The generated `TypedEventBus` class to bind to `TYPED_EVENT_BUS`.
117
+ *
118
+ * **Package mode (ADR-037).** When the runtime is imported from
119
+ * `@pattern-stack/codegen` (not vendored), the bundled `./generated/bus`
120
+ * `TypedEventBus` is typed to an EMPTY event union and reads the bundled
121
+ * empty `eventRegistry` — a consumer's `events/*.yaml` are scanned into
122
+ * `src/generated/events/bus.ts` (typed to THEIR union, reading THEIR
123
+ * registry), which the package can't import. The generated subsystem barrel
124
+ * therefore threads that class in here:
125
+ * `EventsModule.forRoot({ ..., typedBus: TypedEventBus })`. Nest constructs
126
+ * it with this module's `EVENT_BUS` + `EVENTS_MULTI_TENANT` providers (the
127
+ * generated class injects the same string-valued tokens, which match across
128
+ * the package boundary).
129
+ *
130
+ * Omitted (vendored mode / tests) ⇒ falls back to the bundled
131
+ * `./generated/bus`, which in a vendored tree IS the consumer's generated
132
+ * file. Without this, a package-mode consumer's typed `publish<'…'>()` calls
133
+ * resolve against the empty union and their events never get the right
134
+ * `pool` / `direction` stamped.
135
+ *
136
+ * Only consulted by `forRoot` (the path the barrel emits); `forRootAsync`
137
+ * keeps the bundled bus.
138
+ */
139
+ typedBus?: Type<unknown>;
115
140
  }
116
141
 
117
142
  export interface EventsModuleAsyncOptions {
@@ -125,10 +150,18 @@ export interface EventsModuleAsyncOptions {
125
150
  * binding, and the resolved `EVENTS_MULTI_TENANT` flag. Returned from one
126
151
  * place so every `forRoot` branch and `forRootAsync` agree.
127
152
  */
128
- function buildTypedBusProviders(multiTenant: boolean): Provider[] {
153
+ function buildTypedBusProviders(
154
+ multiTenant: boolean,
155
+ typedBus?: Type<unknown>,
156
+ ): Provider[] {
157
+ // Package mode threads the consumer's generated `TypedEventBus` (typed to
158
+ // their event union, reading their registry) via `typedBus`; vendored mode
159
+ // omits it and we fall back to the bundled `./generated/bus` (which IS the
160
+ // consumer's generated file in a vendored tree). See `EventsModuleOptions.typedBus`.
161
+ const BusClass = typedBus ?? TypedEventBus;
129
162
  return [
130
- TypedEventBus,
131
- { provide: TYPED_EVENT_BUS, useExisting: TypedEventBus },
163
+ BusClass,
164
+ { provide: TYPED_EVENT_BUS, useExisting: BusClass },
132
165
  { provide: EVENTS_MULTI_TENANT, useValue: multiTenant },
133
166
  ];
134
167
  }
@@ -249,7 +282,7 @@ export class EventsModule {
249
282
  },
250
283
  inject: [REDIS_URL],
251
284
  },
252
- ...buildTypedBusProviders(multiTenant),
285
+ ...buildTypedBusProviders(multiTenant, options.typedBus),
253
286
  ],
254
287
  exports: [EVENT_BUS, TYPED_EVENT_BUS, EVENTS_MULTI_TENANT],
255
288
  };
@@ -270,7 +303,7 @@ export class EventsModule {
270
303
  // IEventReadPort on the same instance as EVENT_BUS. The redis
271
304
  // backend retains no history and does not provide this token.
272
305
  { provide: EVENT_READ_PORT, useExisting: EVENT_BUS },
273
- ...buildTypedBusProviders(multiTenant),
306
+ ...buildTypedBusProviders(multiTenant, options.typedBus),
274
307
  ],
275
308
  exports: [EVENT_BUS, EVENT_READ_PORT, TYPED_EVENT_BUS, EVENTS_MULTI_TENANT],
276
309
  };