@nest-yalc-2/api-strategy 1.3.3

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 (82) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +40 -0
  3. package/package.json +33 -0
  4. package/src/__tests__/call-strategy-wrappers.spec.ts +217 -0
  5. package/src/__tests__/context-call.service.spec.ts +52 -0
  6. package/src/__tests__/context-event.service.spec.ts +52 -0
  7. package/src/__tests__/event-strategy-composition.spec.ts +185 -0
  8. package/src/__tests__/header-whitelist.helper.spec.ts +30 -0
  9. package/src/__tests__/http-abstract-call.strategy.spec.ts +17 -0
  10. package/src/__tests__/nest-http-call.strategy.spec.ts +164 -0
  11. package/src/__tests__/nest-local-call.strategy.spec.ts +263 -0
  12. package/src/__tests__/nest-local-event.strategy.spec.ts +55 -0
  13. package/src/__tests__/rabbitmq-event.strategy.spec.ts +220 -0
  14. package/src/__tests__/strategy-selector.provider.spec.ts +182 -0
  15. package/src/context-call.interface.d.ts +12 -0
  16. package/src/context-call.interface.js +3 -0
  17. package/src/context-call.interface.js.map +1 -0
  18. package/src/context-call.interface.ts +49 -0
  19. package/src/context-call.service.d.ts +7 -0
  20. package/src/context-call.service.js +32 -0
  21. package/src/context-call.service.js.map +1 -0
  22. package/src/context-call.service.ts +31 -0
  23. package/src/context-event.interface.d.ts +4 -0
  24. package/src/context-event.interface.js +3 -0
  25. package/src/context-event.interface.js.map +1 -0
  26. package/src/context-event.interface.ts +4 -0
  27. package/src/context-event.service.d.ts +7 -0
  28. package/src/context-event.service.js +32 -0
  29. package/src/context-event.service.js.map +1 -0
  30. package/src/context-event.service.ts +31 -0
  31. package/src/header-whitelist.helper.d.ts +2 -0
  32. package/src/header-whitelist.helper.js +13 -0
  33. package/src/header-whitelist.helper.js.map +1 -0
  34. package/src/header-whitelist.helper.ts +12 -0
  35. package/src/index.d.ts +15 -0
  36. package/src/index.js +32 -0
  37. package/src/index.js.map +1 -0
  38. package/src/index.ts +17 -0
  39. package/src/strategies/composite-event.strategy.d.ts +14 -0
  40. package/src/strategies/composite-event.strategy.js +52 -0
  41. package/src/strategies/composite-event.strategy.js.map +1 -0
  42. package/src/strategies/composite-event.strategy.ts +76 -0
  43. package/src/strategies/conditional-call.strategy.d.ts +17 -0
  44. package/src/strategies/conditional-call.strategy.js +41 -0
  45. package/src/strategies/conditional-call.strategy.js.map +1 -0
  46. package/src/strategies/conditional-call.strategy.ts +70 -0
  47. package/src/strategies/conditional-event.strategy.d.ts +16 -0
  48. package/src/strategies/conditional-event.strategy.js +38 -0
  49. package/src/strategies/conditional-event.strategy.js.map +1 -0
  50. package/src/strategies/conditional-event.strategy.ts +54 -0
  51. package/src/strategies/fallback-call.strategy.d.ts +14 -0
  52. package/src/strategies/fallback-call.strategy.js +41 -0
  53. package/src/strategies/fallback-call.strategy.js.map +1 -0
  54. package/src/strategies/fallback-call.strategy.ts +67 -0
  55. package/src/strategies/http-abstract-call.strategy.d.ts +44 -0
  56. package/src/strategies/http-abstract-call.strategy.js +19 -0
  57. package/src/strategies/http-abstract-call.strategy.js.map +1 -0
  58. package/src/strategies/http-abstract-call.strategy.ts +238 -0
  59. package/src/strategies/nest-http-call.strategy.d.ts +30 -0
  60. package/src/strategies/nest-http-call.strategy.js +68 -0
  61. package/src/strategies/nest-http-call.strategy.js.map +1 -0
  62. package/src/strategies/nest-http-call.strategy.ts +121 -0
  63. package/src/strategies/nest-local-call.strategy.d.ts +32 -0
  64. package/src/strategies/nest-local-call.strategy.js +84 -0
  65. package/src/strategies/nest-local-call.strategy.js.map +1 -0
  66. package/src/strategies/nest-local-call.strategy.ts +153 -0
  67. package/src/strategies/nest-local-event.strategy.d.ts +17 -0
  68. package/src/strategies/nest-local-event.strategy.js +30 -0
  69. package/src/strategies/nest-local-event.strategy.js.map +1 -0
  70. package/src/strategies/nest-local-event.strategy.ts +42 -0
  71. package/src/strategies/rabbitmq-event.strategy.d.ts +34 -0
  72. package/src/strategies/rabbitmq-event.strategy.js +97 -0
  73. package/src/strategies/rabbitmq-event.strategy.js.map +1 -0
  74. package/src/strategies/rabbitmq-event.strategy.ts +154 -0
  75. package/src/strategies/shadow-call.strategy.d.ts +17 -0
  76. package/src/strategies/shadow-call.strategy.js +42 -0
  77. package/src/strategies/shadow-call.strategy.js.map +1 -0
  78. package/src/strategies/shadow-call.strategy.ts +87 -0
  79. package/src/strategy-selector.provider.d.ts +19 -0
  80. package/src/strategy-selector.provider.js +52 -0
  81. package/src/strategy-selector.provider.js.map +1 -0
  82. package/src/strategy-selector.provider.ts +103 -0
@@ -0,0 +1,182 @@
1
+ import { describe, expect, it } from '@jest/globals';
2
+ import type { IApiCallStrategy } from '../context-call.interface.js';
3
+ import type { IEventStrategy } from '../context-event.interface.js';
4
+ import {
5
+ ApiCallStrategySelectorProvider,
6
+ EventStrategySelectorProvider,
7
+ StrategySelectorProvider,
8
+ } from '../strategy-selector.provider.js';
9
+
10
+ describe('StrategySelectorProvider', () => {
11
+ const localStrategy = { name: 'local' };
12
+ const remoteStrategy = { name: 'remote' };
13
+
14
+ it('should create a provider with strategy tokens before selector tokens', () => {
15
+ const provider = StrategySelectorProvider({
16
+ provide: 'SELECTED_STRATEGY',
17
+ defaultStrategy: 'local',
18
+ strategies: {
19
+ local: 'LOCAL_STRATEGY',
20
+ remote: 'REMOTE_STRATEGY',
21
+ },
22
+ selector: {
23
+ inject: ['CONFIG'],
24
+ useFactory: () => 'remote',
25
+ },
26
+ });
27
+
28
+ expect(provider).toMatchObject({
29
+ provide: 'SELECTED_STRATEGY',
30
+ inject: ['LOCAL_STRATEGY', 'REMOTE_STRATEGY', 'CONFIG'],
31
+ });
32
+ });
33
+
34
+ it('should resolve the default strategy when selector is not configured', async () => {
35
+ const provider = StrategySelectorProvider({
36
+ provide: 'SELECTED_STRATEGY',
37
+ defaultStrategy: 'local',
38
+ strategies: {
39
+ local: 'LOCAL_STRATEGY',
40
+ remote: 'REMOTE_STRATEGY',
41
+ },
42
+ });
43
+
44
+ await expect(
45
+ (provider as any).useFactory(localStrategy, remoteStrategy),
46
+ ).resolves.toBe(localStrategy);
47
+ });
48
+
49
+ it('should resolve the configured strategy from selector args', async () => {
50
+ const provider = StrategySelectorProvider({
51
+ provide: 'SELECTED_STRATEGY',
52
+ defaultStrategy: 'local',
53
+ strategies: {
54
+ local: 'LOCAL_STRATEGY',
55
+ remote: 'REMOTE_STRATEGY',
56
+ },
57
+ selector: {
58
+ inject: ['CONFIG'],
59
+ useFactory: (config: { strategy: string }) => config.strategy,
60
+ },
61
+ });
62
+
63
+ await expect(
64
+ (provider as any).useFactory(localStrategy, remoteStrategy, {
65
+ strategy: 'remote',
66
+ }),
67
+ ).resolves.toBe(remoteStrategy);
68
+ });
69
+
70
+ it('should trim empty selector results and use the default strategy', async () => {
71
+ const provider = StrategySelectorProvider({
72
+ provide: 'SELECTED_STRATEGY',
73
+ defaultStrategy: 'local',
74
+ strategies: {
75
+ local: 'LOCAL_STRATEGY',
76
+ remote: 'REMOTE_STRATEGY',
77
+ },
78
+ selector: {
79
+ useFactory: () => ' ',
80
+ },
81
+ });
82
+
83
+ await expect(
84
+ (provider as any).useFactory(localStrategy, remoteStrategy),
85
+ ).resolves.toBe(localStrategy);
86
+ });
87
+
88
+ it('should throw when selected strategy is unknown by default', async () => {
89
+ const provider = StrategySelectorProvider({
90
+ provide: 'SELECTED_STRATEGY',
91
+ defaultStrategy: 'local',
92
+ strategies: {
93
+ local: 'LOCAL_STRATEGY',
94
+ },
95
+ selector: {
96
+ useFactory: () => 'missing',
97
+ },
98
+ });
99
+
100
+ await expect((provider as any).useFactory(localStrategy)).rejects.toThrow(
101
+ 'Unknown strategy "missing"',
102
+ );
103
+ });
104
+
105
+ it('should fall back to default when configured to fallback on unknown strategies', async () => {
106
+ const provider = StrategySelectorProvider({
107
+ provide: 'SELECTED_STRATEGY',
108
+ defaultStrategy: 'local',
109
+ strategies: {
110
+ local: 'LOCAL_STRATEGY',
111
+ remote: 'REMOTE_STRATEGY',
112
+ },
113
+ selector: {
114
+ useFactory: () => 'missing',
115
+ },
116
+ unknownStrategyBehavior: 'fallback',
117
+ });
118
+
119
+ await expect(
120
+ (provider as any).useFactory(localStrategy, remoteStrategy),
121
+ ).resolves.toBe(localStrategy);
122
+ });
123
+
124
+ it('should throw when no strategies are registered', () => {
125
+ expect(() =>
126
+ StrategySelectorProvider({
127
+ provide: 'SELECTED_STRATEGY',
128
+ defaultStrategy: 'local',
129
+ strategies: {},
130
+ }),
131
+ ).toThrow('at least one strategy');
132
+ });
133
+
134
+ it('should throw when default strategy is not registered', () => {
135
+ expect(() =>
136
+ StrategySelectorProvider({
137
+ provide: 'SELECTED_STRATEGY',
138
+ defaultStrategy: 'local',
139
+ strategies: {
140
+ remote: 'REMOTE_STRATEGY',
141
+ },
142
+ }),
143
+ ).toThrow('Default strategy "local" is not registered');
144
+ });
145
+
146
+ it('should expose a typed api call strategy selector provider', async () => {
147
+ const apiStrategy = {
148
+ call: async () => ({}),
149
+ get: async () => ({}),
150
+ post: async () => ({}),
151
+ } satisfies IApiCallStrategy;
152
+ const provider = ApiCallStrategySelectorProvider({
153
+ provide: 'API_STRATEGY',
154
+ defaultStrategy: 'local',
155
+ strategies: {
156
+ local: 'LOCAL_API_STRATEGY',
157
+ },
158
+ });
159
+
160
+ await expect((provider as any).useFactory(apiStrategy)).resolves.toBe(
161
+ apiStrategy,
162
+ );
163
+ });
164
+
165
+ it('should expose a typed event strategy selector provider', async () => {
166
+ const eventStrategy = {
167
+ emit: () => true,
168
+ emitAsync: async () => true,
169
+ } satisfies IEventStrategy;
170
+ const provider = EventStrategySelectorProvider({
171
+ provide: 'EVENT_STRATEGY',
172
+ defaultStrategy: 'local',
173
+ strategies: {
174
+ local: 'LOCAL_EVENT_STRATEGY',
175
+ },
176
+ });
177
+
178
+ await expect((provider as any).useFactory(eventStrategy)).resolves.toBe(
179
+ eventStrategy,
180
+ );
181
+ });
182
+ });
@@ -0,0 +1,12 @@
1
+ export interface IObjectWithData<TData> {
2
+ data?: TData;
3
+ }
4
+ export interface ICallOptions<TData, TParams extends Record<string, any>> extends IObjectWithData<TData> {
5
+ data?: TData;
6
+ parameters?: TParams;
7
+ }
8
+ export interface IApiCallStrategy {
9
+ call<TOptData, TParams extends Record<string, any>, TResData>(path: string, options?: ICallOptions<TOptData, TParams>): Promise<IObjectWithData<TResData>>;
10
+ get<TOptData, TParams extends Record<string, any>, TResData>(path: string, options?: ICallOptions<TOptData, TParams>): Promise<IObjectWithData<TResData>>;
11
+ post<TOptData, TParams extends Record<string, any>, TResData>(path: string, options?: ICallOptions<TOptData, TParams>): Promise<IObjectWithData<TResData>>;
12
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=context-call.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-call.interface.js","sourceRoot":"","sources":["context-call.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,49 @@
1
+ export interface IObjectWithData<TData> {
2
+ data?: TData;
3
+ }
4
+
5
+ /**
6
+ * @template TData - type of data to be sent to the server (body data in case of http)
7
+ * @template TParams - type of parameters to be sent to the server (query params in case of http)
8
+ */
9
+ export interface ICallOptions<
10
+ TData,
11
+ TParams extends Record<string, any>,
12
+ > extends IObjectWithData<TData> {
13
+ data?: TData;
14
+ parameters?: TParams;
15
+ }
16
+
17
+ export interface IApiCallStrategy {
18
+ /**
19
+ * @template TOptData - type of data to be sent to the server (body data in case of http)
20
+ * @template TParams - type of parameters to be sent to the server (query params in case of http)
21
+ * @template TResData - type of data to be received from the server (response data in case of http)
22
+ */
23
+ call<TOptData, TParams extends Record<string, any>, TResData>(
24
+ path: string,
25
+ options?: ICallOptions<TOptData, TParams>,
26
+ ): Promise<IObjectWithData<TResData>>;
27
+ /**
28
+ * alias for call that retrieves data without side effects (read-only)
29
+ *
30
+ * @template TOptData - type of data to be sent to the server (body data in case of http)
31
+ * @template TParams - type of parameters to be sent to the server (query params in case of http)
32
+ * @template TResData - type of data to be received from the server (response data in case of http)
33
+ */
34
+ get<TOptData, TParams extends Record<string, any>, TResData>(
35
+ path: string,
36
+ options?: ICallOptions<TOptData, TParams>,
37
+ ): Promise<IObjectWithData<TResData>>;
38
+ /**
39
+ * alias for call that retrieves data with side effects (creation of a resource, etc.)
40
+ *
41
+ * @template TOptData - type of data to be sent to the server (body data in case of http)
42
+ * @template TParams - type of parameters to be sent to the server (query params in case of http)
43
+ * @template TResData - type of data to be received from the server (response data in case of http)
44
+ */
45
+ post<TOptData, TParams extends Record<string, any>, TResData>(
46
+ path: string,
47
+ options?: ICallOptions<TOptData, TParams>,
48
+ ): Promise<IObjectWithData<TResData>>;
49
+ }
@@ -0,0 +1,7 @@
1
+ import { ClassType } from '@nest-yalc-2/types/globals.d.js';
2
+ import { IApiCallStrategy } from './context-call.interface.js';
3
+ export interface IApiCallService<Strategy extends IApiCallStrategy> {
4
+ setStrategy(strategy: Strategy): void;
5
+ getStrategy(): Strategy;
6
+ }
7
+ export declare function ContextCallServiceFactory<Strategy extends IApiCallStrategy>(defaultStrategy: Strategy): ClassType<IApiCallService<Strategy>>;
@@ -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
+ 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.ContextCallServiceFactory = ContextCallServiceFactory;
13
+ const common_1 = require("@nestjs/common");
14
+ function ContextCallServiceFactory(defaultStrategy) {
15
+ let ContextCallService = class ContextCallService {
16
+ constructor(strategy = defaultStrategy) {
17
+ this.strategy = strategy;
18
+ }
19
+ setStrategy(strategy) {
20
+ this.strategy = strategy;
21
+ }
22
+ getStrategy() {
23
+ return this.strategy;
24
+ }
25
+ };
26
+ ContextCallService = __decorate([
27
+ (0, common_1.Injectable)(),
28
+ __metadata("design:paramtypes", [Object])
29
+ ], ContextCallService);
30
+ return ContextCallService;
31
+ }
32
+ //# sourceMappingURL=context-call.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-call.service.js","sourceRoot":"","sources":["context-call.service.ts"],"names":[],"mappings":";;;;;;;;;;;AASA,8DAqBC;AA7BD,2CAA4C;AAQ5C,SAAgB,yBAAyB,CACvC,eAAyB;IAEzB,IACM,kBAAkB,GADxB,MACM,kBAAkB;QAKtB,YAAsB,WAAqB,eAAe;YAApC,aAAQ,GAAR,QAAQ,CAA4B;QAAG,CAAC;QAE9D,WAAW,CAAC,QAAkB;YAC5B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAC3B,CAAC;QAED,WAAW;YACT,OAAO,IAAI,CAAC,QAAQ,CAAC;QACvB,CAAC;KACF,CAAA;IAdK,kBAAkB;QADvB,IAAA,mBAAU,GAAE;;OACP,kBAAkB,CAcvB;IAED,OAAO,kBAAkB,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { ClassType } from '@nest-yalc-2/types/globals.d.js';
2
+ import { Injectable } from '@nestjs/common';
3
+ import { IApiCallStrategy } from './context-call.interface.js';
4
+
5
+ export interface IApiCallService<Strategy extends IApiCallStrategy> {
6
+ setStrategy(strategy: Strategy): void;
7
+ getStrategy(): Strategy;
8
+ }
9
+
10
+ export function ContextCallServiceFactory<Strategy extends IApiCallStrategy>(
11
+ defaultStrategy: Strategy,
12
+ ): ClassType<IApiCallService<Strategy>> {
13
+ @Injectable()
14
+ class ContextCallService {
15
+ /**
16
+ *
17
+ * @param strategy - by default, it will use the strategy provided in the factory
18
+ */
19
+ constructor(protected strategy: Strategy = defaultStrategy) {}
20
+
21
+ setStrategy(strategy: Strategy) {
22
+ this.strategy = strategy;
23
+ }
24
+
25
+ getStrategy() {
26
+ return this.strategy;
27
+ }
28
+ }
29
+
30
+ return ContextCallService;
31
+ }
@@ -0,0 +1,4 @@
1
+ export interface IEventStrategy<P = any, R = any, O = any> {
2
+ emit(path: string, payload: P, options?: O): R;
3
+ emitAsync(path: string, payload: P, options?: O): Promise<R>;
4
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=context-event.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-event.interface.js","sourceRoot":"","sources":["context-event.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ export interface IEventStrategy<P = any, R = any, O = any> {
2
+ emit(path: string, payload: P, options?: O): R;
3
+ emitAsync(path: string, payload: P, options?: O): Promise<R>;
4
+ }
@@ -0,0 +1,7 @@
1
+ import { ClassType } from '@nest-yalc-2/types/globals.d.js';
2
+ import { IEventStrategy } from './context-event.interface.js';
3
+ export interface IApiMessageService<Strategy extends IEventStrategy> {
4
+ setStrategy(strategy: Strategy): void;
5
+ getStrategy(): Strategy;
6
+ }
7
+ export declare function ContextEventServiceFactory<Strategy extends IEventStrategy>(defaultStrategy: Strategy): ClassType<IApiMessageService<Strategy>>;
@@ -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
+ 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.ContextEventServiceFactory = ContextEventServiceFactory;
13
+ const common_1 = require("@nestjs/common");
14
+ function ContextEventServiceFactory(defaultStrategy) {
15
+ let ContextEventService = class ContextEventService {
16
+ constructor(strategy = defaultStrategy) {
17
+ this.strategy = strategy;
18
+ }
19
+ setStrategy(strategy) {
20
+ this.strategy = strategy;
21
+ }
22
+ getStrategy() {
23
+ return this.strategy;
24
+ }
25
+ };
26
+ ContextEventService = __decorate([
27
+ (0, common_1.Injectable)(),
28
+ __metadata("design:paramtypes", [Object])
29
+ ], ContextEventService);
30
+ return ContextEventService;
31
+ }
32
+ //# sourceMappingURL=context-event.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-event.service.js","sourceRoot":"","sources":["context-event.service.ts"],"names":[],"mappings":";;;;;;;;;;;AASA,gEAqBC;AA7BD,2CAA4C;AAQ5C,SAAgB,0BAA0B,CACxC,eAAyB;IAEzB,IACM,mBAAmB,GADzB,MACM,mBAAmB;QAKvB,YAAsB,WAAqB,eAAe;YAApC,aAAQ,GAAR,QAAQ,CAA4B;QAAG,CAAC;QAE9D,WAAW,CAAC,QAAkB;YAC5B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAC3B,CAAC;QAED,WAAW;YACT,OAAO,IAAI,CAAC,QAAQ,CAAC;QACvB,CAAC;KACF,CAAA;IAdK,mBAAmB;QADxB,IAAA,mBAAU,GAAE;;OACP,mBAAmB,CAcxB;IAED,OAAO,mBAAmB,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { ClassType } from '@nest-yalc-2/types/globals.d.js';
2
+ import { Injectable } from '@nestjs/common';
3
+ import { IEventStrategy } from './context-event.interface.js';
4
+
5
+ export interface IApiMessageService<Strategy extends IEventStrategy> {
6
+ setStrategy(strategy: Strategy): void;
7
+ getStrategy(): Strategy;
8
+ }
9
+
10
+ export function ContextEventServiceFactory<Strategy extends IEventStrategy>(
11
+ defaultStrategy: Strategy,
12
+ ): ClassType<IApiMessageService<Strategy>> {
13
+ @Injectable()
14
+ class ContextEventService {
15
+ /**
16
+ *
17
+ * @param strategy - by default, it will use the strategy provided in the factory
18
+ */
19
+ constructor(protected strategy: Strategy = defaultStrategy) {}
20
+
21
+ setStrategy(strategy: Strategy) {
22
+ this.strategy = strategy;
23
+ }
24
+
25
+ getStrategy() {
26
+ return this.strategy;
27
+ }
28
+ }
29
+
30
+ return ContextEventService;
31
+ }
@@ -0,0 +1,2 @@
1
+ export declare const headerWhitelist: string[];
2
+ export declare function filterHeaders(headers: Record<string, string> | undefined, whitelist?: string[]): {} | undefined;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.headerWhitelist = void 0;
4
+ exports.filterHeaders = filterHeaders;
5
+ exports.headerWhitelist = ['Authorization'];
6
+ function filterHeaders(headers, whitelist = exports.headerWhitelist) {
7
+ return headers
8
+ ? Object.entries(headers)
9
+ .filter(([key]) => whitelist.includes(key))
10
+ .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {})
11
+ : headers;
12
+ }
13
+ //# sourceMappingURL=header-whitelist.helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"header-whitelist.helper.js","sourceRoot":"","sources":["header-whitelist.helper.ts"],"names":[],"mappings":";;;AAEA,sCASC;AAXY,QAAA,eAAe,GAAG,CAAC,eAAe,CAAC,CAAC;AAEjD,SAAgB,aAAa,CAC3B,OAA2C,EAC3C,SAAS,GAAG,uBAAe;IAE3B,OAAO,OAAO;QACZ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;aACpB,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;aAC1C,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAClE,CAAC,CAAC,OAAO,CAAC;AACd,CAAC"}
@@ -0,0 +1,12 @@
1
+ export const headerWhitelist = ['Authorization'];
2
+
3
+ export function filterHeaders(
4
+ headers: Record<string, string> | undefined,
5
+ whitelist = headerWhitelist,
6
+ ) {
7
+ return headers
8
+ ? Object.entries(headers)
9
+ .filter(([key]) => whitelist.includes(key))
10
+ .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {})
11
+ : headers;
12
+ }
package/src/index.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ export * from './context-event.service.js';
2
+ export * from './context-event.interface.js';
3
+ export * from './context-call.service.js';
4
+ export * from './context-call.interface.js';
5
+ export * from './strategy-selector.provider.js';
6
+ export * from './strategies/composite-event.strategy.js';
7
+ export * from './strategies/conditional-call.strategy.js';
8
+ export * from './strategies/conditional-event.strategy.js';
9
+ export * from './strategies/fallback-call.strategy.js';
10
+ export * from './strategies/http-abstract-call.strategy.js';
11
+ export * from './strategies/nest-http-call.strategy.js';
12
+ export * from './strategies/nest-local-call.strategy.js';
13
+ export * from './strategies/nest-local-event.strategy.js';
14
+ export * from './strategies/rabbitmq-event.strategy.js';
15
+ export * from './strategies/shadow-call.strategy.js';
package/src/index.js ADDED
@@ -0,0 +1,32 @@
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
+ __exportStar(require("./context-event.service.js"), exports);
18
+ __exportStar(require("./context-event.interface.js"), exports);
19
+ __exportStar(require("./context-call.service.js"), exports);
20
+ __exportStar(require("./context-call.interface.js"), exports);
21
+ __exportStar(require("./strategy-selector.provider.js"), exports);
22
+ __exportStar(require("./strategies/composite-event.strategy.js"), exports);
23
+ __exportStar(require("./strategies/conditional-call.strategy.js"), exports);
24
+ __exportStar(require("./strategies/conditional-event.strategy.js"), exports);
25
+ __exportStar(require("./strategies/fallback-call.strategy.js"), exports);
26
+ __exportStar(require("./strategies/http-abstract-call.strategy.js"), exports);
27
+ __exportStar(require("./strategies/nest-http-call.strategy.js"), exports);
28
+ __exportStar(require("./strategies/nest-local-call.strategy.js"), exports);
29
+ __exportStar(require("./strategies/nest-local-event.strategy.js"), exports);
30
+ __exportStar(require("./strategies/rabbitmq-event.strategy.js"), exports);
31
+ __exportStar(require("./strategies/shadow-call.strategy.js"), exports);
32
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAEA,6DAA2C;AAC3C,+DAA6C;AAC7C,4DAA0C;AAC1C,8DAA4C;AAC5C,kEAAgD;AAChD,2EAAyD;AACzD,4EAA0D;AAC1D,6EAA2D;AAC3D,yEAAuD;AACvD,8EAA4D;AAC5D,0EAAwD;AACxD,2EAAyD;AACzD,4EAA0D;AAC1D,0EAAwD;AACxD,uEAAqD"}
package/src/index.ts ADDED
@@ -0,0 +1,17 @@
1
+ /* istanbul ignore file */
2
+
3
+ export * from './context-event.service.js';
4
+ export * from './context-event.interface.js';
5
+ export * from './context-call.service.js';
6
+ export * from './context-call.interface.js';
7
+ export * from './strategy-selector.provider.js';
8
+ export * from './strategies/composite-event.strategy.js';
9
+ export * from './strategies/conditional-call.strategy.js';
10
+ export * from './strategies/conditional-event.strategy.js';
11
+ export * from './strategies/fallback-call.strategy.js';
12
+ export * from './strategies/http-abstract-call.strategy.js';
13
+ export * from './strategies/nest-http-call.strategy.js';
14
+ export * from './strategies/nest-local-call.strategy.js';
15
+ export * from './strategies/nest-local-event.strategy.js';
16
+ export * from './strategies/rabbitmq-event.strategy.js';
17
+ export * from './strategies/shadow-call.strategy.js';
@@ -0,0 +1,14 @@
1
+ import { OnModuleDestroy } from '@nestjs/common';
2
+ import type { IEventStrategy } from '../context-event.interface.js';
3
+ export type CompositeEventStrategyErrorMode = 'throw' | 'ignore';
4
+ export interface CompositeEventStrategyOptions {
5
+ errorMode?: CompositeEventStrategyErrorMode;
6
+ }
7
+ export declare class CompositeEventStrategy<P = any, R = any, O = any> implements IEventStrategy<P, R[], O>, OnModuleDestroy {
8
+ private readonly strategies;
9
+ private readonly errorMode;
10
+ constructor(strategies: IEventStrategy<P, R, O>[], options?: CompositeEventStrategyOptions);
11
+ emit(path: string, payload: P, options?: O): R[];
12
+ emitAsync(path: string, payload: P, options?: O): Promise<R[]>;
13
+ onModuleDestroy(): Promise<void>;
14
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CompositeEventStrategy = void 0;
4
+ class CompositeEventStrategy {
5
+ constructor(strategies, options = {}) {
6
+ this.strategies = strategies;
7
+ if (strategies.length === 0) {
8
+ throw new Error('CompositeEventStrategy requires at least one strategy.');
9
+ }
10
+ this.errorMode = options.errorMode ?? 'throw';
11
+ }
12
+ emit(path, payload, options) {
13
+ const results = [];
14
+ for (const strategy of this.strategies) {
15
+ try {
16
+ results.push(strategy.emit(path, payload, options));
17
+ }
18
+ catch (error) {
19
+ if (this.errorMode === 'throw') {
20
+ throw error;
21
+ }
22
+ }
23
+ }
24
+ return results;
25
+ }
26
+ async emitAsync(path, payload, options) {
27
+ const settled = await Promise.allSettled(this.strategies.map((strategy) => strategy.emitAsync(path, payload, options)));
28
+ const results = [];
29
+ for (const result of settled) {
30
+ if (result.status === 'fulfilled') {
31
+ results.push(result.value);
32
+ }
33
+ else if (this.errorMode === 'throw') {
34
+ throw result.reason;
35
+ }
36
+ }
37
+ return results;
38
+ }
39
+ async onModuleDestroy() {
40
+ await Promise.all(this.strategies.map(async (strategy) => {
41
+ await maybeDestroyStrategy(strategy);
42
+ }));
43
+ }
44
+ }
45
+ exports.CompositeEventStrategy = CompositeEventStrategy;
46
+ async function maybeDestroyStrategy(strategy) {
47
+ const destroyable = strategy;
48
+ if (typeof destroyable.onModuleDestroy === 'function') {
49
+ await destroyable.onModuleDestroy();
50
+ }
51
+ }
52
+ //# sourceMappingURL=composite-event.strategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composite-event.strategy.js","sourceRoot":"","sources":["composite-event.strategy.ts"],"names":[],"mappings":";;;AASA,MAAa,sBAAsB;IAKjC,YACmB,UAAqC,EACtD,UAAyC,EAAE;QAD1B,eAAU,GAAV,UAAU,CAA2B;QAGtD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;QAC5E,CAAC;QAED,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC;IAChD,CAAC;IAED,IAAI,CAAC,IAAY,EAAE,OAAU,EAAE,OAAW;QACxC,MAAM,OAAO,GAAQ,EAAE,CAAC;QAExB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACvC,IAAI,CAAC;gBACH,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;YACtD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,IAAI,CAAC,SAAS,KAAK,OAAO,EAAE,CAAC;oBAC/B,MAAM,KAAK,CAAC;gBACd,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,IAAY,EAAE,OAAU,EAAE,OAAW;QACnD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CACtC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC/B,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAC3C,CACF,CAAC;QACF,MAAM,OAAO,GAAQ,EAAE,CAAC;QAExB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;gBAClC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC7B,CAAC;iBAAM,IAAI,IAAI,CAAC,SAAS,KAAK,OAAO,EAAE,CAAC;gBACtC,MAAM,MAAM,CAAC,MAAM,CAAC;YACtB,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,MAAM,OAAO,CAAC,GAAG,CACf,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;YACrC,MAAM,oBAAoB,CAAC,QAAQ,CAAC,CAAC;QACvC,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;CACF;AA1DD,wDA0DC;AAED,KAAK,UAAU,oBAAoB,CAAC,QAAiB;IACnD,MAAM,WAAW,GAAG,QAAoC,CAAC;IAEzD,IAAI,OAAO,WAAW,CAAC,eAAe,KAAK,UAAU,EAAE,CAAC;QACtD,MAAM,WAAW,CAAC,eAAe,EAAE,CAAC;IACtC,CAAC;AACH,CAAC"}