@palmetto/nestjs-pubsub 1.0.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/README.md ADDED
@@ -0,0 +1,99 @@
1
+ # @palmetto/nestjs-pubsub
2
+
3
+ Provides a NestJS module to provide a PubSub Publisher and automatically discover and manage PubSub subscribers.
4
+
5
+ ## Installation
6
+
7
+ ```sh
8
+ yarn add @palmetto/pubsub @palmetto/nestjs-pubsub zod
9
+ ```
10
+
11
+ Next, add in the PubSub transports you want to use:
12
+
13
+ RabbitMQ:
14
+
15
+ ```sh
16
+ yarn add amqp-connection-manager amqplib
17
+ ```
18
+
19
+ BullMQ:
20
+
21
+ ```sh
22
+ yarn add bullmq
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ ### Add to your `AppModule` imports
28
+
29
+ ```ts
30
+ // MyModel* objects define the model you are publishing or subscribing using RabbitMq
31
+ const MyModelSchema = IdMetaSchema.extend({
32
+ message: z4.string(),
33
+ value: z4.int(),
34
+ });
35
+ type MyModel = z4.infer<typeof MyModelSchema>;
36
+ const MyModelConfig: RabbitQueueExchangeConfiguration = {
37
+ name: "my-model",
38
+ schema: MyModelSchema,
39
+ transport: RABBITMQ_TRANSPORT,
40
+ type: "direct",
41
+ };
42
+
43
+ // MyOtherModel* objects define another model you are publishing or subscribing, this time using BullMq
44
+ const MyOtherModelSchema = IdMetaSchema.extend({
45
+ message: z4.string(),
46
+ values: z4.int().array(),
47
+ });
48
+ type MyOtherModel = z4.infer<typeof MyOtherModelSchema>;
49
+ const MyOtherModelConfig: RabbitQueueExchangeConfiguration = {
50
+ name: "my-other-model",
51
+ schema: MyOtherModelSchema,
52
+ transport: BULLMQ_TRANSPORT,
53
+ };
54
+
55
+ // MyModelHandler demonstrates a subscriber to the MyModel event over RabbitMq
56
+ @Injectable()
57
+ class MyModelHandler {
58
+ constructor(private readonly publisher: Publisher) {}
59
+
60
+ @EventSubscriber(MyModelConfig)
61
+ async handler(message: MyModel) {
62
+ // here, we're publishing a new message to bullmq based on the message we received
63
+ const newMessage: MyOtherModel = {
64
+ message: message.message,
65
+ values: [message.value, message.value + 1, message.value + 2],
66
+ };
67
+
68
+ await publisher.publish(MyOtherModelConfig, newMessage);
69
+ }
70
+ }
71
+ @Module({
72
+ imports: [
73
+ AppConfigModule,
74
+ PubSubModule,
75
+ PubSubRabbitMqModule.registerAsync({
76
+ imports: [AppConfigModule],
77
+ inject: [AppConfig],
78
+ useFactory(appConfig: AppConfig) {
79
+ return {
80
+ host: appConfig.get("rabbit.url"),
81
+ };
82
+ },
83
+ }),
84
+ PubSubBullMqModule.registerAsync({
85
+ imports: [AppConfigModule],
86
+ inject: [AppConfig],
87
+ useFactory(appConfig: AppConfig) {
88
+ return {
89
+ host: appConfig.get("redis.host"),
90
+ username: appConfig.get("bullmq.username"),
91
+ password: appConfig.get("bullmq.password"),
92
+ };
93
+ },
94
+ }),
95
+ ],
96
+ providers: [MyModelHandler],
97
+ })
98
+ export class AppModule {}
99
+ ```
package/dist/main.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export * from "./pubsub-module.js";
2
+ export * from "./pubsub-bullmq-module.js";
3
+ export * from "./pubsub-rabbitmq-module.js";
4
+ export { EventSubcriber } from "./subscriber.js";
package/dist/main.js ADDED
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.EventSubcriber = void 0;
18
+ __exportStar(require("./pubsub-module.js"), exports);
19
+ __exportStar(require("./pubsub-bullmq-module.js"), exports);
20
+ __exportStar(require("./pubsub-rabbitmq-module.js"), exports);
21
+ var subscriber_js_1 = require("./subscriber.js");
22
+ Object.defineProperty(exports, "EventSubcriber", { enumerable: true, get: function () { return subscriber_js_1.EventSubcriber; } });
@@ -0,0 +1,8 @@
1
+ import { ConnectionOptions } from "@palmetto/pubsub";
2
+ declare const ConfigurableModuleClass: import("@nestjs/common").ConfigurableModuleCls<ConnectionOptions, "register", "create", {}>;
3
+ /**
4
+ * Module requires @palmetto/pubsub
5
+ */
6
+ export declare class PubSubBullMqModule extends ConfigurableModuleClass {
7
+ }
8
+ export {};
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.PubSubBullMqModule = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const pubsub_1 = require("@palmetto/pubsub");
15
+ const pubsub_provider_module_1 = require("./pubsub-provider-module");
16
+ const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } = new common_1.ConfigurableModuleBuilder().build();
17
+ let BullMqShutdown = class BullMqShutdown {
18
+ constructor(provider) {
19
+ this.provider = provider;
20
+ }
21
+ onApplicationShutdown() {
22
+ return this.provider.close();
23
+ }
24
+ };
25
+ BullMqShutdown = __decorate([
26
+ (0, common_1.Injectable)(),
27
+ __metadata("design:paramtypes", [pubsub_1.BullMqPubSubProvider])
28
+ ], BullMqShutdown);
29
+ /**
30
+ * Module requires @palmetto/pubsub
31
+ */
32
+ let PubSubBullMqModule = class PubSubBullMqModule extends ConfigurableModuleClass {
33
+ };
34
+ exports.PubSubBullMqModule = PubSubBullMqModule;
35
+ exports.PubSubBullMqModule = PubSubBullMqModule = __decorate([
36
+ (0, common_1.Module)({
37
+ imports: [pubsub_provider_module_1.PubSubProviderFactoryModule],
38
+ providers: [
39
+ {
40
+ provide: pubsub_1.BullMqPubSubProvider,
41
+ useFactory: (providers, config) => {
42
+ const provider = new pubsub_1.BullMqPubSubProvider(config, new common_1.Logger(pubsub_1.BullMqPubSubProvider.name));
43
+ providers.addProvider(provider);
44
+ return provider;
45
+ },
46
+ inject: [pubsub_provider_module_1.PubSubProviderFactory, MODULE_OPTIONS_TOKEN],
47
+ },
48
+ BullMqShutdown,
49
+ ],
50
+ exports: [pubsub_1.BullMqPubSubProvider],
51
+ })
52
+ ], PubSubBullMqModule);
@@ -0,0 +1,2 @@
1
+ export declare class PubSubModule {
2
+ }
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
+ return new (P || (P = Promise))(function (resolve, reject) {
14
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
18
+ });
19
+ };
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.PubSubModule = void 0;
22
+ const pubsub_1 = require("@palmetto/pubsub");
23
+ const common_1 = require("@nestjs/common");
24
+ const nestjs_discovery_1 = require("@golevelup/nestjs-discovery");
25
+ const subscriber_1 = require("./subscriber");
26
+ const pubsub_provider_module_1 = require("./pubsub-provider-module");
27
+ function isPublisherProvider(obj) {
28
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
29
+ return (obj === null || obj === void 0 ? void 0 : obj.publish) !== undefined;
30
+ }
31
+ function isSubscriberProvider(obj) {
32
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
33
+ return (obj === null || obj === void 0 ? void 0 : obj.startSubscribe) !== undefined;
34
+ }
35
+ let PubSubManager = class PubSubManager {
36
+ constructor(discover, publisher, subscriber, pubSubFactory) {
37
+ this.discover = discover;
38
+ this.publisher = publisher;
39
+ this.subscriber = subscriber;
40
+ this.pubSubFactory = pubSubFactory;
41
+ this.logger = new common_1.Logger(PubSubModule.name);
42
+ this.bootstrapped = false;
43
+ }
44
+ beforeApplicationShutdown() {
45
+ return __awaiter(this, void 0, void 0, function* () {
46
+ this.logger.debug(`${PubSubModule.name} Stopping subscribers`);
47
+ yield this.subscriber.unsubscribe();
48
+ this.logger.debug(`${PubSubModule.name} Closing subscriber`);
49
+ yield this.subscriber.close();
50
+ this.logger.debug(`${PubSubModule.name} Closing publisher`);
51
+ yield this.publisher.close();
52
+ this.bootstrapped = false;
53
+ this.logger.debug(`${PubSubModule.name} shutdown`);
54
+ });
55
+ }
56
+ onApplicationBootstrap() {
57
+ return __awaiter(this, void 0, void 0, function* () {
58
+ if (this.bootstrapped) {
59
+ return;
60
+ }
61
+ this.bootstrapped = true;
62
+ {
63
+ for (const provider of this.pubSubFactory.providers) {
64
+ if (isPublisherProvider(provider)) {
65
+ this.publisher.addProvider(provider);
66
+ }
67
+ if (isSubscriberProvider(provider)) {
68
+ this.subscriber.addProvider(provider);
69
+ }
70
+ }
71
+ }
72
+ const handlers = (yield this.discover.providerMethodsWithMetaAtKey(subscriber_1.EVENT_HANDLER)).concat(yield this.discover.controllerMethodsWithMetaAtKey(subscriber_1.EVENT_HANDLER));
73
+ for (const handler of handlers) {
74
+ const method = handler.discoveredMethod;
75
+ yield this.subscriber.subscribe(handler.meta, (msg) => method.handler.call(method.parentClass.instance, msg));
76
+ this.logger.log(`Added subscriber method ${method.parentClass.name}.${method.methodName} for ${handler.meta.transport}:${handler.meta.name}`);
77
+ }
78
+ });
79
+ }
80
+ };
81
+ PubSubManager = __decorate([
82
+ (0, common_1.Injectable)(),
83
+ __metadata("design:paramtypes", [nestjs_discovery_1.DiscoveryService,
84
+ pubsub_1.Publisher,
85
+ pubsub_1.Subscriber,
86
+ pubsub_provider_module_1.PubSubProviderFactory])
87
+ ], PubSubManager);
88
+ let PubSubModule = class PubSubModule {
89
+ };
90
+ exports.PubSubModule = PubSubModule;
91
+ exports.PubSubModule = PubSubModule = __decorate([
92
+ (0, common_1.Module)({
93
+ imports: [nestjs_discovery_1.DiscoveryModule, pubsub_provider_module_1.PubSubProviderFactoryModule],
94
+ providers: [
95
+ {
96
+ provide: pubsub_1.Publisher,
97
+ useFactory: () => {
98
+ return new pubsub_1.Publisher(new common_1.Logger(pubsub_1.Publisher.name));
99
+ },
100
+ },
101
+ {
102
+ provide: pubsub_1.Subscriber,
103
+ useFactory: () => {
104
+ return new pubsub_1.Subscriber(new common_1.Logger(pubsub_1.Subscriber.name));
105
+ },
106
+ },
107
+ PubSubManager,
108
+ ],
109
+ exports: [pubsub_1.Publisher, pubsub_1.Subscriber],
110
+ })
111
+ // eslint-disable-next-line @typescript-eslint/no-extraneous-class
112
+ ], PubSubModule);
@@ -0,0 +1,7 @@
1
+ import { PubOrSubProvider } from "@palmetto/pubsub";
2
+ export declare class PubSubProviderFactory {
3
+ readonly providers: PubOrSubProvider[];
4
+ addProvider(provider: PubOrSubProvider): void;
5
+ }
6
+ export declare class PubSubProviderFactoryModule {
7
+ }
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.PubSubProviderFactoryModule = exports.PubSubProviderFactory = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ let PubSubProviderFactory = class PubSubProviderFactory {
12
+ constructor() {
13
+ this.providers = [];
14
+ }
15
+ addProvider(provider) {
16
+ this.providers.push(provider);
17
+ }
18
+ };
19
+ exports.PubSubProviderFactory = PubSubProviderFactory;
20
+ exports.PubSubProviderFactory = PubSubProviderFactory = __decorate([
21
+ (0, common_1.Injectable)()
22
+ ], PubSubProviderFactory);
23
+ let PubSubProviderFactoryModule = class PubSubProviderFactoryModule {
24
+ };
25
+ exports.PubSubProviderFactoryModule = PubSubProviderFactoryModule;
26
+ exports.PubSubProviderFactoryModule = PubSubProviderFactoryModule = __decorate([
27
+ (0, common_1.Module)({
28
+ providers: [PubSubProviderFactory],
29
+ exports: [PubSubProviderFactory],
30
+ })
31
+ // eslint-disable-next-line @typescript-eslint/no-extraneous-class
32
+ ], PubSubProviderFactoryModule);
@@ -0,0 +1,8 @@
1
+ import { RabbitMqConnectionConfig } from "@palmetto/pubsub";
2
+ declare const ConfigurableModuleClass: import("@nestjs/common").ConfigurableModuleCls<RabbitMqConnectionConfig, "register", "create", {}>;
3
+ /**
4
+ * This module requires @palmetto/pubsub
5
+ */
6
+ export declare class PubSubRabbitMqModule extends ConfigurableModuleClass {
7
+ }
8
+ export {};
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.PubSubRabbitMqModule = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const pubsub_1 = require("@palmetto/pubsub");
15
+ const pubsub_provider_module_1 = require("./pubsub-provider-module");
16
+ const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } = new common_1.ConfigurableModuleBuilder().build();
17
+ let RabbitMqConnectionShutdown = class RabbitMqConnectionShutdown {
18
+ constructor(connection) {
19
+ this.connection = connection;
20
+ }
21
+ onApplicationShutdown() {
22
+ return this.connection.close();
23
+ }
24
+ };
25
+ RabbitMqConnectionShutdown = __decorate([
26
+ (0, common_1.Injectable)(),
27
+ __metadata("design:paramtypes", [pubsub_1.RabbitMqConnection])
28
+ ], RabbitMqConnectionShutdown);
29
+ /**
30
+ * This module requires @palmetto/pubsub
31
+ */
32
+ let PubSubRabbitMqModule = class PubSubRabbitMqModule extends ConfigurableModuleClass {
33
+ };
34
+ exports.PubSubRabbitMqModule = PubSubRabbitMqModule;
35
+ exports.PubSubRabbitMqModule = PubSubRabbitMqModule = __decorate([
36
+ (0, common_1.Module)({
37
+ imports: [pubsub_provider_module_1.PubSubProviderFactoryModule],
38
+ providers: [
39
+ {
40
+ provide: pubsub_1.RabbitMqConnection,
41
+ useFactory: (config) => pubsub_1.RabbitMqConnection.create(config, new common_1.Logger(pubsub_1.RabbitMqConnection.name)),
42
+ inject: [MODULE_OPTIONS_TOKEN],
43
+ },
44
+ {
45
+ provide: pubsub_1.RabbitMqPubSubProvider,
46
+ useFactory: (providers, connection) => {
47
+ const provider = new pubsub_1.RabbitMqPubSubProvider(connection, new common_1.Logger(pubsub_1.RabbitMqPubSubProvider.name));
48
+ providers.addProvider(provider);
49
+ return provider;
50
+ },
51
+ inject: [pubsub_provider_module_1.PubSubProviderFactory, pubsub_1.RabbitMqConnection],
52
+ },
53
+ RabbitMqConnectionShutdown,
54
+ ],
55
+ exports: [pubsub_1.RabbitMqConnection, pubsub_1.RabbitMqPubSubProvider],
56
+ })
57
+ ], PubSubRabbitMqModule);
@@ -0,0 +1,3 @@
1
+ import { PubSubConfiguration } from "@palmetto/pubsub";
2
+ export declare const EVENT_HANDLER: unique symbol;
3
+ export declare const EventSubcriber: (config: PubSubConfiguration) => <TFunction extends Function, Y>(target: TFunction | object, propertyKey?: string | symbol, descriptor?: TypedPropertyDescriptor<Y>) => void;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EventSubcriber = exports.EVENT_HANDLER = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ exports.EVENT_HANDLER = Symbol("EVENT_HANDLER");
6
+ const makePubSubDecorator = () => (config) => (0, common_1.applyDecorators)((0, common_1.SetMetadata)(exports.EVENT_HANDLER, Object.assign({}, config)));
7
+ exports.EventSubcriber = makePubSubDecorator();
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@palmetto/nestjs-pubsub",
3
+ "version": "1.0.0",
4
+ "main": "./dist/main.js",
5
+ "scripts": {
6
+ "lint": "yarn run -T eslint --fix ./src",
7
+ "format": "yarn run -T prettier --write --loglevel warn .",
8
+ "tc": "tsc --noEmit",
9
+ "build": "yarn clean && tsc -p tsconfig.build.json",
10
+ "clean": "rm -rf ./dist/",
11
+ "ci:build": "tsc -p tsconfig.build.json",
12
+ "ci:lint": "yarn run -T eslint . && yarn run -T prettier --check --loglevel warn .",
13
+ "ci:tc": "yarn tc",
14
+ "hook:lint": "eslint --cache --fix",
15
+ "hook:format": "prettier --write --loglevel warn",
16
+ "hook:tc": "yarn tc",
17
+ "prepublishOnly": "yarn build",
18
+ "test": "vitest run"
19
+ },
20
+ "devDependencies": {
21
+ "@nestjs/common": "^11.1.3",
22
+ "@nestjs/core": "^11.1.3",
23
+ "@nestjs/testing": "^11.1.5",
24
+ "@swc/core": "^1.13.3",
25
+ "@types/node": "^24.2.1",
26
+ "@vitest/coverage-v8": "^3.2.4",
27
+ "typescript": "5.7.3",
28
+ "unplugin-swc": "^1.5.6",
29
+ "vitest": "^3.2.4",
30
+ "zod": "^4.0.5"
31
+ },
32
+ "files": [
33
+ "dist/**/*",
34
+ "README.md"
35
+ ],
36
+ "engines": {
37
+ "node": ">=20"
38
+ },
39
+ "publishConfig": {
40
+ "access": "public"
41
+ },
42
+ "dependencies": {
43
+ "@golevelup/nestjs-discovery": "^5.0.0",
44
+ "@palmetto/nestjs-errors": "^2.1.1",
45
+ "@palmetto/pubsub": "^1.0.0",
46
+ "reflect-metadata": "^0.2.2",
47
+ "rxjs": "^7.8.2"
48
+ },
49
+ "peerDependencies": {
50
+ "@nestjs/common": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0",
51
+ "@nestjs/core": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0",
52
+ "zod": "^3.25.0 || ^4.0.0"
53
+ }
54
+ }