@vritti/api-sdk 0.2.6 → 0.2.8

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/dist/nats.d.ts ADDED
@@ -0,0 +1,85 @@
1
+ import { ModuleMetadata, InjectionToken, OnModuleDestroy, DynamicModule, ArgumentsHost } from '@nestjs/common';
2
+ import { VrittiSessionInfo, FastifyRequest } from 'fastify';
3
+ import { ClientProxy } from '@nestjs/microservices';
4
+ import { Observable } from 'rxjs';
5
+
6
+ declare const RpcNatsHeaders: (...dataOrPipes: unknown[]) => ParameterDecorator;
7
+ declare const RpcBuId: (...dataOrPipes: unknown[]) => ParameterDecorator;
8
+ declare const RpcBuCurrencyCode: (...dataOrPipes: unknown[]) => ParameterDecorator;
9
+
10
+ interface NatsHeaders {
11
+ orgId: string;
12
+ userId: string;
13
+ buId: string;
14
+ buTimezone: string;
15
+ buCurrencyCode: string;
16
+ buAncestorIds: string[];
17
+ buDescendantIds: string[];
18
+ }
19
+ declare const NATS_HEADER_KEYS: {
20
+ readonly ORG_ID: "x-org-id";
21
+ readonly USER_ID: "x-user-id";
22
+ readonly BU_ID: "x-bu-id";
23
+ readonly BU_TIMEZONE: "x-bu-timezone";
24
+ readonly BU_CURRENCY_CODE: "x-bu-currency-code";
25
+ readonly BU_ANCESTOR_IDS: "x-bu-ancestor-ids";
26
+ readonly BU_DESCENDANT_IDS: "x-bu-descendant-ids";
27
+ };
28
+ declare function parseNatsHeaders(headers: unknown): NatsHeaders | null;
29
+
30
+ type ContextResolverFn = (sessionInfo: VrittiSessionInfo) => Promise<NatsHeaders>;
31
+ interface NatsServiceConfig {
32
+ name: string;
33
+ }
34
+ interface NatsModuleBaseOptions {
35
+ natsUrl?: string;
36
+ services: NatsServiceConfig[];
37
+ }
38
+ interface NatsRootModuleOptions extends NatsModuleBaseOptions {
39
+ contextResolver: ContextResolverFn;
40
+ }
41
+ interface NatsMicroserviceModuleOptions extends NatsModuleBaseOptions {
42
+ }
43
+ interface NatsRootModuleAsyncOptions {
44
+ imports?: ModuleMetadata['imports'];
45
+ inject?: InjectionToken[];
46
+ useFactory: (...args: any[]) => Promise<NatsRootModuleOptions> | NatsRootModuleOptions;
47
+ }
48
+ interface NatsMicroserviceModuleAsyncOptions {
49
+ imports?: ModuleMetadata['imports'];
50
+ inject?: InjectionToken[];
51
+ useFactory: (...args: any[]) => Promise<NatsMicroserviceModuleOptions> | NatsMicroserviceModuleOptions;
52
+ }
53
+
54
+ declare class NatsClientModule implements OnModuleDestroy {
55
+ private static readonly logger;
56
+ private static allClients;
57
+ onModuleDestroy(): Promise<void>;
58
+ private static buildClients;
59
+ static forRoot(asyncOptions: NatsRootModuleAsyncOptions): DynamicModule;
60
+ static forMicroservice(asyncOptions: NatsMicroserviceModuleAsyncOptions): DynamicModule;
61
+ }
62
+
63
+ declare class NatsClientService {
64
+ private readonly request;
65
+ private readonly contextResolver;
66
+ private readonly clients;
67
+ private cachedContext;
68
+ constructor(request: FastifyRequest, contextResolver: ContextResolverFn, clients: Map<string, ClientProxy>);
69
+ send<T>(service: string, cmd: string, data?: object): Promise<T>;
70
+ }
71
+
72
+ declare class NatsMicroserviceClientService {
73
+ private readonly clients;
74
+ constructor(clients: Map<string, ClientProxy>);
75
+ send<T>(service: string, cmd: string, natsHeaders: NatsHeaders, data?: object): Promise<T>;
76
+ }
77
+
78
+ declare class RpcProblemExceptionFilter {
79
+ private readonly logger;
80
+ catch(exception: unknown, _host: ArgumentsHost): Observable<never>;
81
+ private toProblemPayload;
82
+ private isHttpException;
83
+ }
84
+
85
+ export { type ContextResolverFn, NATS_HEADER_KEYS, NatsClientModule, NatsClientService, type NatsHeaders, NatsMicroserviceClientService, type NatsMicroserviceModuleAsyncOptions, type NatsRootModuleAsyncOptions, type NatsServiceConfig, RpcBuCurrencyCode, RpcBuId, RpcNatsHeaders, RpcProblemExceptionFilter, parseNatsHeaders };
package/dist/nats.js ADDED
@@ -0,0 +1,486 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ // src/nats/decorators/nats-headers.decorator.ts
5
+ import { createParamDecorator, InternalServerErrorException } from "@nestjs/common";
6
+
7
+ // src/nats/nats-context.ts
8
+ var NATS_HEADER_KEYS = {
9
+ ORG_ID: "x-org-id",
10
+ USER_ID: "x-user-id",
11
+ BU_ID: "x-bu-id",
12
+ BU_TIMEZONE: "x-bu-timezone",
13
+ BU_CURRENCY_CODE: "x-bu-currency-code",
14
+ BU_ANCESTOR_IDS: "x-bu-ancestor-ids",
15
+ BU_DESCENDANT_IDS: "x-bu-descendant-ids"
16
+ };
17
+ function getHeader(headers, key) {
18
+ if (!headers) return void 0;
19
+ if (typeof headers.get === "function") {
20
+ const val = headers.get(key);
21
+ return Array.isArray(val) ? val[0] : val;
22
+ }
23
+ return headers[key];
24
+ }
25
+ __name(getHeader, "getHeader");
26
+ function parseNatsHeaders(headers) {
27
+ if (!headers) return null;
28
+ const orgId = getHeader(headers, NATS_HEADER_KEYS.ORG_ID);
29
+ const userId = getHeader(headers, NATS_HEADER_KEYS.USER_ID);
30
+ const buId = getHeader(headers, NATS_HEADER_KEYS.BU_ID);
31
+ if (!orgId || !userId || !buId) return null;
32
+ return {
33
+ orgId,
34
+ userId,
35
+ buId,
36
+ buTimezone: getHeader(headers, NATS_HEADER_KEYS.BU_TIMEZONE) || "UTC",
37
+ buCurrencyCode: getHeader(headers, NATS_HEADER_KEYS.BU_CURRENCY_CODE) || "",
38
+ buAncestorIds: JSON.parse(getHeader(headers, NATS_HEADER_KEYS.BU_ANCESTOR_IDS) || "[]"),
39
+ buDescendantIds: JSON.parse(getHeader(headers, NATS_HEADER_KEYS.BU_DESCENDANT_IDS) || "[]")
40
+ };
41
+ }
42
+ __name(parseNatsHeaders, "parseNatsHeaders");
43
+
44
+ // src/nats/decorators/nats-headers.decorator.ts
45
+ var RpcNatsHeaders = createParamDecorator((_data, ctx) => {
46
+ const rpcCtx = ctx.switchToRpc().getContext();
47
+ return parseNatsHeaders(rpcCtx.getHeaders());
48
+ });
49
+ var RpcBuId = createParamDecorator((_data, ctx) => {
50
+ const rpcCtx = ctx.switchToRpc().getContext();
51
+ const headers = parseNatsHeaders(rpcCtx.getHeaders());
52
+ if (!headers?.buId) throw new InternalServerErrorException("Missing buId in NATS headers.");
53
+ return headers.buId;
54
+ });
55
+ var RpcBuCurrencyCode = createParamDecorator((_data, ctx) => {
56
+ const rpcCtx = ctx.switchToRpc().getContext();
57
+ const headers = parseNatsHeaders(rpcCtx.getHeaders());
58
+ if (!headers?.buCurrencyCode) throw new InternalServerErrorException("Missing buCurrencyCode in NATS headers.");
59
+ return headers.buCurrencyCode;
60
+ });
61
+
62
+ // src/nats/nats-client.module.ts
63
+ import { Global, Logger, Module } from "@nestjs/common";
64
+ import { ConfigModule, ConfigService } from "@nestjs/config";
65
+ import { ClientProxyFactory, Transport } from "@nestjs/microservices";
66
+
67
+ // src/nats/constants.ts
68
+ var NATS_MODULE_OPTIONS = Symbol("NATS_MODULE_OPTIONS");
69
+ var NATS_CONTEXT_RESOLVER = Symbol("NATS_CONTEXT_RESOLVER");
70
+
71
+ // src/nats/nats-client.service.ts
72
+ import { Inject, Injectable, Scope } from "@nestjs/common";
73
+ import { REQUEST } from "@nestjs/core";
74
+ import { NatsRecordBuilder } from "@nestjs/microservices";
75
+ import { headers as natsHeaders } from "nats";
76
+ function _ts_decorate(decorators, target, key, desc) {
77
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
78
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
79
+ 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;
80
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
81
+ }
82
+ __name(_ts_decorate, "_ts_decorate");
83
+ function _ts_metadata(k, v) {
84
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
85
+ }
86
+ __name(_ts_metadata, "_ts_metadata");
87
+ function _ts_param(paramIndex, decorator) {
88
+ return function(target, key) {
89
+ decorator(target, key, paramIndex);
90
+ };
91
+ }
92
+ __name(_ts_param, "_ts_param");
93
+ var NATS_CLIENTS = Symbol("NATS_CLIENTS");
94
+ var NatsClientService = class {
95
+ static {
96
+ __name(this, "NatsClientService");
97
+ }
98
+ request;
99
+ contextResolver;
100
+ clients;
101
+ cachedContext = null;
102
+ constructor(request, contextResolver, clients) {
103
+ this.request = request;
104
+ this.contextResolver = contextResolver;
105
+ this.clients = clients;
106
+ }
107
+ // Sends a message to a named microservice with NatsHeaders as NATS headers
108
+ async send(service, cmd, data) {
109
+ const client = this.clients.get(service);
110
+ if (!client) {
111
+ throw new Error(`NATS service "${service}" is not registered. Available: [${[
112
+ ...this.clients.keys()
113
+ ].join(", ")}]`);
114
+ }
115
+ if (!this.cachedContext) {
116
+ const sessionInfo = this.request.sessionInfo;
117
+ if (!sessionInfo) {
118
+ throw new Error("No sessionInfo on request \u2014 is the auth guard active?");
119
+ }
120
+ this.cachedContext = await this.contextResolver(sessionInfo);
121
+ }
122
+ const headers = contextToHeaders(this.cachedContext);
123
+ const record = new NatsRecordBuilder(data ?? {}).setHeaders(headers).build();
124
+ return client.send({
125
+ cmd
126
+ }, record).toPromise();
127
+ }
128
+ };
129
+ NatsClientService = _ts_decorate([
130
+ Injectable({
131
+ scope: Scope.REQUEST
132
+ }),
133
+ _ts_param(0, Inject(REQUEST)),
134
+ _ts_param(1, Inject(NATS_CONTEXT_RESOLVER)),
135
+ _ts_param(2, Inject(NATS_CLIENTS)),
136
+ _ts_metadata("design:type", Function),
137
+ _ts_metadata("design:paramtypes", [
138
+ typeof FastifyRequest === "undefined" ? Object : FastifyRequest,
139
+ typeof ContextResolverFn === "undefined" ? Object : ContextResolverFn,
140
+ typeof Map === "undefined" ? Object : Map
141
+ ])
142
+ ], NatsClientService);
143
+ function contextToHeaders(ctx) {
144
+ const hdrs = natsHeaders();
145
+ hdrs.set(NATS_HEADER_KEYS.ORG_ID, ctx.orgId);
146
+ hdrs.set(NATS_HEADER_KEYS.USER_ID, ctx.userId);
147
+ hdrs.set(NATS_HEADER_KEYS.BU_ID, ctx.buId);
148
+ hdrs.set(NATS_HEADER_KEYS.BU_TIMEZONE, ctx.buTimezone);
149
+ hdrs.set(NATS_HEADER_KEYS.BU_CURRENCY_CODE, ctx.buCurrencyCode);
150
+ hdrs.set(NATS_HEADER_KEYS.BU_ANCESTOR_IDS, JSON.stringify(ctx.buAncestorIds));
151
+ hdrs.set(NATS_HEADER_KEYS.BU_DESCENDANT_IDS, JSON.stringify(ctx.buDescendantIds));
152
+ return hdrs;
153
+ }
154
+ __name(contextToHeaders, "contextToHeaders");
155
+
156
+ // src/nats/nats-microservice-client.service.ts
157
+ import { Inject as Inject2, Injectable as Injectable2 } from "@nestjs/common";
158
+ import { NatsRecordBuilder as NatsRecordBuilder2 } from "@nestjs/microservices";
159
+ function _ts_decorate2(decorators, target, key, desc) {
160
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
161
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
162
+ 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;
163
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
164
+ }
165
+ __name(_ts_decorate2, "_ts_decorate");
166
+ function _ts_metadata2(k, v) {
167
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
168
+ }
169
+ __name(_ts_metadata2, "_ts_metadata");
170
+ function _ts_param2(paramIndex, decorator) {
171
+ return function(target, key) {
172
+ decorator(target, key, paramIndex);
173
+ };
174
+ }
175
+ __name(_ts_param2, "_ts_param");
176
+ var NATS_MS_CLIENTS = Symbol("NATS_MS_CLIENTS");
177
+ var NatsMicroserviceClientService = class {
178
+ static {
179
+ __name(this, "NatsMicroserviceClientService");
180
+ }
181
+ clients;
182
+ constructor(clients) {
183
+ this.clients = clients;
184
+ }
185
+ // Forwards a message to another microservice with NatsHeaders
186
+ async send(service, cmd, natsHeaders2, data) {
187
+ const client = this.clients.get(service);
188
+ if (!client) {
189
+ throw new Error(`NATS service "${service}" is not registered. Available: [${[
190
+ ...this.clients.keys()
191
+ ].join(", ")}]`);
192
+ }
193
+ const headers = {
194
+ [NATS_HEADER_KEYS.ORG_ID]: natsHeaders2.orgId,
195
+ [NATS_HEADER_KEYS.USER_ID]: natsHeaders2.userId,
196
+ [NATS_HEADER_KEYS.BU_ID]: natsHeaders2.buId,
197
+ [NATS_HEADER_KEYS.BU_TIMEZONE]: natsHeaders2.buTimezone,
198
+ [NATS_HEADER_KEYS.BU_ANCESTOR_IDS]: JSON.stringify(natsHeaders2.buAncestorIds),
199
+ [NATS_HEADER_KEYS.BU_DESCENDANT_IDS]: JSON.stringify(natsHeaders2.buDescendantIds)
200
+ };
201
+ const record = new NatsRecordBuilder2(data ?? {}).setHeaders(headers).build();
202
+ return client.send({
203
+ cmd
204
+ }, record).toPromise();
205
+ }
206
+ };
207
+ NatsMicroserviceClientService = _ts_decorate2([
208
+ Injectable2(),
209
+ _ts_param2(0, Inject2(NATS_MS_CLIENTS)),
210
+ _ts_metadata2("design:type", Function),
211
+ _ts_metadata2("design:paramtypes", [
212
+ typeof Map === "undefined" ? Object : Map
213
+ ])
214
+ ], NatsMicroserviceClientService);
215
+
216
+ // src/nats/nats-client.module.ts
217
+ function _ts_decorate3(decorators, target, key, desc) {
218
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
219
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
220
+ 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;
221
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
222
+ }
223
+ __name(_ts_decorate3, "_ts_decorate");
224
+ var NATS_MS_OPTIONS = Symbol("NATS_MS_OPTIONS");
225
+ var NatsClientModule = class _NatsClientModule {
226
+ static {
227
+ __name(this, "NatsClientModule");
228
+ }
229
+ static logger = new Logger(_NatsClientModule.name);
230
+ static allClients = [];
231
+ async onModuleDestroy() {
232
+ await Promise.all(_NatsClientModule.allClients.map((c) => c.close()));
233
+ _NatsClientModule.allClients = [];
234
+ }
235
+ // Builds a Map of named NATS ClientProxy instances
236
+ static buildClients(options, natsUrl) {
237
+ const clients = /* @__PURE__ */ new Map();
238
+ for (const svc of options.services) {
239
+ const proxy = ClientProxyFactory.create({
240
+ transport: Transport.NATS,
241
+ options: {
242
+ servers: [
243
+ natsUrl
244
+ ]
245
+ }
246
+ });
247
+ clients.set(svc.name, proxy);
248
+ _NatsClientModule.allClients.push(proxy);
249
+ _NatsClientModule.logger.log(`Registered NATS client: ${svc.name} \u2192 ${natsUrl}`);
250
+ }
251
+ return clients;
252
+ }
253
+ // Gateway mode — request-scoped, resolves context from sessionInfo via callback
254
+ static forRoot(asyncOptions) {
255
+ const optionsProvider = {
256
+ provide: NATS_MODULE_OPTIONS,
257
+ useFactory: asyncOptions.useFactory,
258
+ inject: asyncOptions.inject || []
259
+ };
260
+ const resolverProvider = {
261
+ provide: NATS_CONTEXT_RESOLVER,
262
+ useFactory: /* @__PURE__ */ __name((options) => options.contextResolver, "useFactory"),
263
+ inject: [
264
+ NATS_MODULE_OPTIONS
265
+ ]
266
+ };
267
+ const clientsProvider = {
268
+ provide: NATS_CLIENTS,
269
+ useFactory: /* @__PURE__ */ __name((options, config) => {
270
+ const natsUrl = options.natsUrl ?? config.get("NATS_URL", "nats://localhost:4222");
271
+ return _NatsClientModule.buildClients(options, natsUrl);
272
+ }, "useFactory"),
273
+ inject: [
274
+ NATS_MODULE_OPTIONS,
275
+ ConfigService
276
+ ]
277
+ };
278
+ return {
279
+ module: _NatsClientModule,
280
+ imports: [
281
+ ConfigModule,
282
+ ...asyncOptions.imports ?? []
283
+ ],
284
+ providers: [
285
+ optionsProvider,
286
+ resolverProvider,
287
+ clientsProvider,
288
+ NatsClientService
289
+ ],
290
+ exports: [
291
+ NatsClientService
292
+ ]
293
+ };
294
+ }
295
+ // Microservice mode — singleton, forwards context from incoming NATS payload
296
+ static forMicroservice(asyncOptions) {
297
+ const optionsProvider = {
298
+ provide: NATS_MS_OPTIONS,
299
+ useFactory: asyncOptions.useFactory,
300
+ inject: asyncOptions.inject || []
301
+ };
302
+ const clientsProvider = {
303
+ provide: NATS_MS_CLIENTS,
304
+ useFactory: /* @__PURE__ */ __name((options, config) => {
305
+ const natsUrl = options.natsUrl ?? config.get("NATS_URL", "nats://localhost:4222");
306
+ return _NatsClientModule.buildClients(options, natsUrl);
307
+ }, "useFactory"),
308
+ inject: [
309
+ NATS_MS_OPTIONS,
310
+ ConfigService
311
+ ]
312
+ };
313
+ return {
314
+ module: _NatsClientModule,
315
+ imports: [
316
+ ConfigModule,
317
+ ...asyncOptions.imports ?? []
318
+ ],
319
+ providers: [
320
+ optionsProvider,
321
+ clientsProvider,
322
+ NatsMicroserviceClientService
323
+ ],
324
+ exports: [
325
+ NatsMicroserviceClientService
326
+ ]
327
+ };
328
+ }
329
+ };
330
+ NatsClientModule = _ts_decorate3([
331
+ Global(),
332
+ Module({})
333
+ ], NatsClientModule);
334
+
335
+ // src/filters/rpc-problem-exception.filter.ts
336
+ import { Catch, HttpStatus as HttpStatus2, Logger as Logger2 } from "@nestjs/common";
337
+ import { RpcException } from "@nestjs/microservices";
338
+ import { throwError } from "rxjs";
339
+
340
+ // src/exceptions/conflict.exception.ts
341
+ import { HttpStatus } from "@nestjs/common";
342
+
343
+ // src/exceptions/base-field.exception.ts
344
+ import { HttpException } from "@nestjs/common";
345
+ var HttpProblemException = class extends HttpException {
346
+ static {
347
+ __name(this, "HttpProblemException");
348
+ }
349
+ constructor(detailOrOptions, httpStatus) {
350
+ const options = typeof detailOrOptions === "string" ? {
351
+ detail: detailOrOptions
352
+ } : detailOrOptions;
353
+ super({
354
+ type: options.type ?? "about:blank",
355
+ label: options.label,
356
+ detail: options.detail,
357
+ errors: options.errors ?? []
358
+ }, httpStatus);
359
+ }
360
+ };
361
+
362
+ // src/exceptions/conflict.exception.ts
363
+ var ConflictException = class extends HttpProblemException {
364
+ static {
365
+ __name(this, "ConflictException");
366
+ }
367
+ constructor(detailOrOptions) {
368
+ super(detailOrOptions ?? "Conflict", HttpStatus.CONFLICT);
369
+ }
370
+ };
371
+
372
+ // src/filters/pg-error.translator.ts
373
+ var PG_UNIQUE_VIOLATION = "23505";
374
+ function tryTranslatePgError(error) {
375
+ const pgError = findPgError(error);
376
+ if (!pgError) return void 0;
377
+ const { code, constraint, table, detail } = pgError;
378
+ if (code !== PG_UNIQUE_VIOLATION) return void 0;
379
+ return new ConflictException({
380
+ label: "Duplicate Entry",
381
+ detail: detail?.trim() || "A record with these values already exists.",
382
+ errors: [],
383
+ ...constraint || table ? {
384
+ meta: {
385
+ constraint,
386
+ table
387
+ }
388
+ } : {}
389
+ });
390
+ }
391
+ __name(tryTranslatePgError, "tryTranslatePgError");
392
+ function findPgError(error, depth = 0) {
393
+ if (!error || typeof error !== "object" || depth > 5) return void 0;
394
+ const candidate = error;
395
+ if (typeof candidate.code === "string") return candidate;
396
+ return findPgError(candidate.cause, depth + 1);
397
+ }
398
+ __name(findPgError, "findPgError");
399
+
400
+ // src/filters/rpc-problem-exception.filter.ts
401
+ function _ts_decorate4(decorators, target, key, desc) {
402
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
403
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
404
+ 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;
405
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
406
+ }
407
+ __name(_ts_decorate4, "_ts_decorate");
408
+ var RpcProblemExceptionFilter = class _RpcProblemExceptionFilter {
409
+ static {
410
+ __name(this, "RpcProblemExceptionFilter");
411
+ }
412
+ logger = new Logger2(_RpcProblemExceptionFilter.name);
413
+ catch(exception, _host) {
414
+ const translatedPgError = tryTranslatePgError(exception);
415
+ if (translatedPgError) exception = translatedPgError;
416
+ if (exception instanceof RpcException) {
417
+ return throwError(() => exception.getError());
418
+ }
419
+ if (this.isHttpException(exception)) {
420
+ const status = exception.getStatus();
421
+ const response = exception.getResponse();
422
+ return throwError(() => this.toProblemPayload(response, status));
423
+ }
424
+ if (exception instanceof Error) {
425
+ const cause = exception.cause;
426
+ const causeMessage = cause instanceof Error ? cause.message : void 0;
427
+ const causeStack = cause instanceof Error ? cause.stack : void 0;
428
+ this.logger.error(causeMessage ?? exception.message, causeStack ?? exception.stack);
429
+ if (cause && cause !== exception) {
430
+ this.logger.error(`Wrapped by: ${exception.message}`);
431
+ }
432
+ return throwError(() => this.toProblemPayload({
433
+ type: "about:blank",
434
+ detail: causeMessage ?? exception.message,
435
+ errors: []
436
+ }, HttpStatus2.INTERNAL_SERVER_ERROR));
437
+ }
438
+ this.logger.error(`Unhandled non-error exception: ${JSON.stringify(exception)}`);
439
+ return throwError(() => this.toProblemPayload({
440
+ type: "about:blank",
441
+ detail: "An unexpected error occurred",
442
+ errors: []
443
+ }, HttpStatus2.INTERNAL_SERVER_ERROR));
444
+ }
445
+ toProblemPayload(response, status) {
446
+ if (typeof response === "string") {
447
+ return {
448
+ type: "about:blank",
449
+ detail: response,
450
+ message: response,
451
+ errors: [],
452
+ status,
453
+ statusCode: status
454
+ };
455
+ }
456
+ const obj = response ?? {};
457
+ const detail = typeof obj.detail === "string" ? obj.detail : "Request failed";
458
+ return {
459
+ type: typeof obj.type === "string" ? obj.type : "about:blank",
460
+ label: typeof obj.label === "string" ? obj.label : void 0,
461
+ detail,
462
+ message: detail,
463
+ errors: Array.isArray(obj.errors) ? obj.errors : [],
464
+ status,
465
+ statusCode: status
466
+ };
467
+ }
468
+ isHttpException(error) {
469
+ return error instanceof Error && typeof error.getStatus === "function" && typeof error.getResponse === "function";
470
+ }
471
+ };
472
+ RpcProblemExceptionFilter = _ts_decorate4([
473
+ Catch()
474
+ ], RpcProblemExceptionFilter);
475
+ export {
476
+ NATS_HEADER_KEYS,
477
+ NatsClientModule,
478
+ NatsClientService,
479
+ NatsMicroserviceClientService,
480
+ RpcBuCurrencyCode,
481
+ RpcBuId,
482
+ RpcNatsHeaders,
483
+ RpcProblemExceptionFilter,
484
+ parseNatsHeaders
485
+ };
486
+ //# sourceMappingURL=nats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/nats/decorators/nats-headers.decorator.ts","../src/nats/nats-context.ts","../src/nats/nats-client.module.ts","../src/nats/constants.ts","../src/nats/nats-client.service.ts","../src/nats/nats-microservice-client.service.ts","../src/filters/rpc-problem-exception.filter.ts","../src/exceptions/conflict.exception.ts","../src/exceptions/base-field.exception.ts","../src/filters/pg-error.translator.ts"],"sourcesContent":["import { createParamDecorator, type ExecutionContext, InternalServerErrorException } from '@nestjs/common';\nimport { NatsContext } from '@nestjs/microservices';\nimport { parseNatsHeaders } from '../nats-context';\n\n// Extracts parsed NatsContext from NATS message headers\nexport const RpcNatsHeaders = createParamDecorator((_data: unknown, ctx: ExecutionContext) => {\n const rpcCtx = ctx.switchToRpc().getContext<NatsContext>();\n return parseNatsHeaders(rpcCtx.getHeaders());\n});\n\n// Extracts buId from NATS headers — throws if missing or empty\nexport const RpcBuId = createParamDecorator((_data: unknown, ctx: ExecutionContext): string => {\n const rpcCtx = ctx.switchToRpc().getContext<NatsContext>();\n const headers = parseNatsHeaders(rpcCtx.getHeaders());\n if (!headers?.buId) throw new InternalServerErrorException('Missing buId in NATS headers.');\n return headers.buId;\n});\n\n// Extracts buCurrencyCode from NATS headers — throws if missing or empty\nexport const RpcBuCurrencyCode = createParamDecorator((_data: unknown, ctx: ExecutionContext): string => {\n const rpcCtx = ctx.switchToRpc().getContext<NatsContext>();\n const headers = parseNatsHeaders(rpcCtx.getHeaders());\n if (!headers?.buCurrencyCode) throw new InternalServerErrorException('Missing buCurrencyCode in NATS headers.');\n return headers.buCurrencyCode;\n});\n","export interface NatsHeaders {\n orgId: string;\n userId: string;\n buId: string;\n buTimezone: string;\n buCurrencyCode: string;\n buAncestorIds: string[];\n buDescendantIds: string[];\n}\n\n// Header keys for NATS context transport\nexport const NATS_HEADER_KEYS = {\n ORG_ID: 'x-org-id',\n USER_ID: 'x-user-id',\n BU_ID: 'x-bu-id',\n BU_TIMEZONE: 'x-bu-timezone',\n BU_CURRENCY_CODE: 'x-bu-currency-code',\n BU_ANCESTOR_IDS: 'x-bu-ancestor-ids',\n BU_DESCENDANT_IDS: 'x-bu-descendant-ids',\n} as const;\n\n// Reads a header value from either a plain object or a NATS MsgHdrsImpl\nfunction getHeader(headers: unknown, key: string): string | undefined {\n if (!headers) return undefined;\n // MsgHdrsImpl uses .get(), plain objects use bracket access\n if (typeof (headers as { get?: unknown }).get === 'function') {\n const val = (headers as { get(key: string): string[] }).get(key);\n return Array.isArray(val) ? val[0] : (val as string | undefined);\n }\n return (headers as Record<string, string>)[key];\n}\n\n// Parses NATS message headers into a NatsHeaders object\nexport function parseNatsHeaders(headers: unknown): NatsHeaders | null {\n if (!headers) return null;\n\n const orgId = getHeader(headers, NATS_HEADER_KEYS.ORG_ID);\n const userId = getHeader(headers, NATS_HEADER_KEYS.USER_ID);\n const buId = getHeader(headers, NATS_HEADER_KEYS.BU_ID);\n\n if (!orgId || !userId || !buId) return null;\n\n return {\n orgId,\n userId,\n buId,\n buTimezone: getHeader(headers, NATS_HEADER_KEYS.BU_TIMEZONE) || 'UTC',\n buCurrencyCode: getHeader(headers, NATS_HEADER_KEYS.BU_CURRENCY_CODE) || '',\n buAncestorIds: JSON.parse(getHeader(headers, NATS_HEADER_KEYS.BU_ANCESTOR_IDS) || '[]'),\n buDescendantIds: JSON.parse(getHeader(headers, NATS_HEADER_KEYS.BU_DESCENDANT_IDS) || '[]'),\n };\n}\n","import { type DynamicModule, Global, Logger, Module, type OnModuleDestroy, type Provider } from '@nestjs/common';\nimport { ConfigModule, ConfigService } from '@nestjs/config';\nimport type { ClientProxy } from '@nestjs/microservices';\nimport { ClientProxyFactory, Transport } from '@nestjs/microservices';\nimport { NATS_CONTEXT_RESOLVER, NATS_MODULE_OPTIONS } from './constants';\nimport type {\n NatsMicroserviceModuleAsyncOptions,\n NatsModuleBaseOptions,\n NatsRootModuleAsyncOptions,\n NatsRootModuleOptions,\n} from './nats-client.interfaces';\nimport { NATS_CLIENTS, NatsClientService } from './nats-client.service';\nimport { NATS_MS_CLIENTS, NatsMicroserviceClientService } from './nats-microservice-client.service';\n\nconst NATS_MS_OPTIONS = Symbol('NATS_MS_OPTIONS');\n\n@Global()\n@Module({})\nexport class NatsClientModule implements OnModuleDestroy {\n private static readonly logger = new Logger(NatsClientModule.name);\n private static allClients: ClientProxy[] = [];\n\n async onModuleDestroy() {\n await Promise.all(NatsClientModule.allClients.map((c) => c.close()));\n NatsClientModule.allClients = [];\n }\n\n // Builds a Map of named NATS ClientProxy instances\n private static buildClients(options: NatsModuleBaseOptions, natsUrl: string): Map<string, ClientProxy> {\n const clients = new Map<string, ClientProxy>();\n\n for (const svc of options.services) {\n const proxy = ClientProxyFactory.create({\n transport: Transport.NATS,\n options: { servers: [natsUrl] },\n });\n clients.set(svc.name, proxy);\n NatsClientModule.allClients.push(proxy);\n NatsClientModule.logger.log(`Registered NATS client: ${svc.name} → ${natsUrl}`);\n }\n\n return clients;\n }\n\n // Gateway mode — request-scoped, resolves context from sessionInfo via callback\n static forRoot(asyncOptions: NatsRootModuleAsyncOptions): DynamicModule {\n const optionsProvider: Provider = {\n provide: NATS_MODULE_OPTIONS,\n useFactory: asyncOptions.useFactory,\n inject: asyncOptions.inject || [],\n };\n\n const resolverProvider: Provider = {\n provide: NATS_CONTEXT_RESOLVER,\n useFactory: (options: NatsRootModuleOptions) => options.contextResolver,\n inject: [NATS_MODULE_OPTIONS],\n };\n\n const clientsProvider: Provider = {\n provide: NATS_CLIENTS,\n useFactory: (options: NatsRootModuleOptions, config: ConfigService): Map<string, ClientProxy> => {\n const natsUrl = options.natsUrl ?? config.get<string>('NATS_URL', 'nats://localhost:4222');\n return NatsClientModule.buildClients(options, natsUrl);\n },\n inject: [NATS_MODULE_OPTIONS, ConfigService],\n };\n\n return {\n module: NatsClientModule,\n imports: [ConfigModule, ...(asyncOptions.imports ?? [])],\n providers: [optionsProvider, resolverProvider, clientsProvider, NatsClientService],\n exports: [NatsClientService],\n };\n }\n\n // Microservice mode — singleton, forwards context from incoming NATS payload\n static forMicroservice(asyncOptions: NatsMicroserviceModuleAsyncOptions): DynamicModule {\n const optionsProvider: Provider = {\n provide: NATS_MS_OPTIONS,\n useFactory: asyncOptions.useFactory,\n inject: asyncOptions.inject || [],\n };\n\n const clientsProvider: Provider = {\n provide: NATS_MS_CLIENTS,\n useFactory: (options: NatsModuleBaseOptions, config: ConfigService): Map<string, ClientProxy> => {\n const natsUrl = options.natsUrl ?? config.get<string>('NATS_URL', 'nats://localhost:4222');\n return NatsClientModule.buildClients(options, natsUrl);\n },\n inject: [NATS_MS_OPTIONS, ConfigService],\n };\n\n return {\n module: NatsClientModule,\n imports: [ConfigModule, ...(asyncOptions.imports ?? [])],\n providers: [optionsProvider, clientsProvider, NatsMicroserviceClientService],\n exports: [NatsMicroserviceClientService],\n };\n }\n}\n","export const NATS_MODULE_OPTIONS = Symbol('NATS_MODULE_OPTIONS');\nexport const NATS_CONTEXT_RESOLVER = Symbol('NATS_CONTEXT_RESOLVER');\n","import { Inject, Injectable, Scope } from '@nestjs/common';\nimport { REQUEST } from '@nestjs/core';\nimport type { ClientProxy } from '@nestjs/microservices';\nimport { NatsRecordBuilder } from '@nestjs/microservices';\nimport type { FastifyRequest } from 'fastify';\nimport { headers as natsHeaders } from 'nats';\nimport { NATS_CONTEXT_RESOLVER } from './constants';\nimport type { ContextResolverFn } from './nats-client.interfaces';\nimport { NATS_HEADER_KEYS, type NatsHeaders } from './nats-context';\n\nexport const NATS_CLIENTS = Symbol('NATS_CLIENTS');\n\n@Injectable({ scope: Scope.REQUEST })\nexport class NatsClientService {\n private cachedContext: NatsHeaders | null = null;\n\n constructor(\n @Inject(REQUEST) private readonly request: FastifyRequest,\n @Inject(NATS_CONTEXT_RESOLVER) private readonly contextResolver: ContextResolverFn,\n @Inject(NATS_CLIENTS) private readonly clients: Map<string, ClientProxy>,\n ) {}\n\n // Sends a message to a named microservice with NatsHeaders as NATS headers\n async send<T>(service: string, cmd: string, data?: object): Promise<T> {\n const client = this.clients.get(service);\n if (!client) {\n throw new Error(\n `NATS service \"${service}\" is not registered. Available: [${[...this.clients.keys()].join(', ')}]`,\n );\n }\n\n if (!this.cachedContext) {\n const sessionInfo = this.request.sessionInfo;\n if (!sessionInfo) {\n throw new Error('No sessionInfo on request — is the auth guard active?');\n }\n this.cachedContext = await this.contextResolver(sessionInfo);\n }\n\n const headers = contextToHeaders(this.cachedContext);\n const record = new NatsRecordBuilder(data ?? {}).setHeaders(headers).build();\n\n return client.send<T>({ cmd }, record).toPromise() as Promise<T>;\n }\n}\n\n// Converts NatsHeaders to a NATS MsgHdrs object for NATS transport\nfunction contextToHeaders(ctx: NatsHeaders): import('nats').MsgHdrs {\n const hdrs = natsHeaders();\n hdrs.set(NATS_HEADER_KEYS.ORG_ID, ctx.orgId);\n hdrs.set(NATS_HEADER_KEYS.USER_ID, ctx.userId);\n hdrs.set(NATS_HEADER_KEYS.BU_ID, ctx.buId);\n hdrs.set(NATS_HEADER_KEYS.BU_TIMEZONE, ctx.buTimezone);\n hdrs.set(NATS_HEADER_KEYS.BU_CURRENCY_CODE, ctx.buCurrencyCode);\n hdrs.set(NATS_HEADER_KEYS.BU_ANCESTOR_IDS, JSON.stringify(ctx.buAncestorIds));\n hdrs.set(NATS_HEADER_KEYS.BU_DESCENDANT_IDS, JSON.stringify(ctx.buDescendantIds));\n return hdrs;\n}\n","import { Inject, Injectable } from '@nestjs/common';\nimport type { ClientProxy } from '@nestjs/microservices';\nimport { NatsRecordBuilder } from '@nestjs/microservices';\nimport { NATS_HEADER_KEYS, type NatsHeaders } from './nats-context';\n\nexport const NATS_MS_CLIENTS = Symbol('NATS_MS_CLIENTS');\n\n@Injectable()\nexport class NatsMicroserviceClientService {\n constructor(@Inject(NATS_MS_CLIENTS) private readonly clients: Map<string, ClientProxy>) {}\n\n // Forwards a message to another microservice with NatsHeaders\n async send<T>(service: string, cmd: string, natsHeaders: NatsHeaders, data?: object): Promise<T> {\n const client = this.clients.get(service);\n if (!client) {\n throw new Error(\n `NATS service \"${service}\" is not registered. Available: [${[...this.clients.keys()].join(', ')}]`,\n );\n }\n\n const headers: Record<string, string> = {\n [NATS_HEADER_KEYS.ORG_ID]: natsHeaders.orgId,\n [NATS_HEADER_KEYS.USER_ID]: natsHeaders.userId,\n [NATS_HEADER_KEYS.BU_ID]: natsHeaders.buId,\n [NATS_HEADER_KEYS.BU_TIMEZONE]: natsHeaders.buTimezone,\n [NATS_HEADER_KEYS.BU_ANCESTOR_IDS]: JSON.stringify(natsHeaders.buAncestorIds),\n [NATS_HEADER_KEYS.BU_DESCENDANT_IDS]: JSON.stringify(natsHeaders.buDescendantIds),\n };\n\n const record = new NatsRecordBuilder(data ?? {}).setHeaders(headers).build();\n return client.send<T>({ cmd }, record).toPromise() as Promise<T>;\n }\n}\n","import { type ArgumentsHost, Catch, type HttpException, HttpStatus, Logger } from '@nestjs/common';\nimport { RpcException } from '@nestjs/microservices';\nimport { type Observable, throwError } from 'rxjs';\nimport { tryTranslatePgError } from './pg-error.translator';\n\ninterface FieldError {\n field: string;\n message: string;\n}\n\ninterface ProblemPayload {\n type: string;\n label?: string;\n detail: string;\n message: string;\n errors: FieldError[];\n status: number;\n statusCode: number;\n}\n\n@Catch()\nexport class RpcProblemExceptionFilter {\n private readonly logger = new Logger(RpcProblemExceptionFilter.name);\n\n catch(exception: unknown, _host: ArgumentsHost): Observable<never> {\n // Translate raw Postgres errors (e.g. 23505 unique_violation from an unguarded INSERT in\n // a NATS handler) into a ConflictException before the rest of the filter handles them.\n const translatedPgError = tryTranslatePgError(exception);\n if (translatedPgError) exception = translatedPgError;\n\n if (exception instanceof RpcException) {\n return throwError(() => exception.getError());\n }\n\n if (this.isHttpException(exception)) {\n const status = exception.getStatus();\n const response = exception.getResponse();\n return throwError(() => this.toProblemPayload(response, status));\n }\n\n if (exception instanceof Error) {\n const cause = (exception as { cause?: unknown }).cause;\n const causeMessage = cause instanceof Error ? cause.message : undefined;\n const causeStack = cause instanceof Error ? cause.stack : undefined;\n this.logger.error(causeMessage ?? exception.message, causeStack ?? exception.stack);\n if (cause && cause !== exception) {\n this.logger.error(`Wrapped by: ${exception.message}`);\n }\n return throwError(() =>\n this.toProblemPayload(\n {\n type: 'about:blank',\n detail: causeMessage ?? exception.message,\n errors: [],\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n ),\n );\n }\n\n this.logger.error(`Unhandled non-error exception: ${JSON.stringify(exception)}`);\n return throwError(() =>\n this.toProblemPayload(\n {\n type: 'about:blank',\n detail: 'An unexpected error occurred',\n errors: [],\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n ),\n );\n }\n\n private toProblemPayload(response: unknown, status: number): ProblemPayload {\n if (typeof response === 'string') {\n return {\n type: 'about:blank',\n detail: response,\n message: response,\n errors: [],\n status,\n statusCode: status,\n };\n }\n\n const obj = (response ?? {}) as Record<string, unknown>;\n const detail = typeof obj.detail === 'string' ? obj.detail : 'Request failed';\n return {\n type: typeof obj.type === 'string' ? obj.type : 'about:blank',\n label: typeof obj.label === 'string' ? obj.label : undefined,\n detail,\n message: detail,\n errors: Array.isArray(obj.errors) ? (obj.errors as FieldError[]) : [],\n status,\n statusCode: status,\n };\n }\n\n private isHttpException(error: unknown): error is HttpException {\n return (\n error instanceof Error &&\n typeof (error as { getStatus?: unknown }).getStatus === 'function' &&\n typeof (error as { getResponse?: unknown }).getResponse === 'function'\n );\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class ConflictException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Conflict', HttpStatus.CONFLICT);\n }\n}\n","import { HttpException, HttpStatus } from '@nestjs/common';\nimport type { FieldError } from '../types/error-response.types';\n\n// Re-export FieldError for backwards compatibility\nexport type { FieldError } from '../types/error-response.types';\n\nexport interface ProblemOptions {\n type?: string;\n label?: string;\n detail?: string;\n errors?: FieldError[];\n}\n\nexport abstract class HttpProblemException extends HttpException {\n constructor(detailOrOptions: string | ProblemOptions, httpStatus: HttpStatus) {\n const options = typeof detailOrOptions === 'string' ? { detail: detailOrOptions } : detailOrOptions;\n\n super(\n {\n type: options.type ?? 'about:blank',\n label: options.label,\n detail: options.detail,\n errors: options.errors ?? [],\n },\n httpStatus,\n );\n }\n}\n","import { ConflictException } from '../exceptions/conflict.exception';\n\n// Postgres SQLSTATE codes we translate before the global filters render the response.\n// Reference: https://www.postgresql.org/docs/current/errcodes-appendix.html\n//\n// Today we only handle 23505 (unique_violation) — services already pre-check the common\n// duplicate cases for friendly messages; this is the race-condition / unguarded-write backstop\n// so a raw `error: duplicate key value violates unique constraint \"...\"` never reaches the\n// client as a 500. Extend the switch below as we identify other SQLSTATEs worth surfacing\n// (e.g. 23503 foreign_key_violation → 409 with FK info).\nconst PG_UNIQUE_VIOLATION = '23505';\n\ntype PgErrorShape = {\n code?: string;\n constraint?: string;\n table?: string;\n detail?: string;\n};\n\n// Returns a ConflictException for a Postgres unique-violation error, otherwise undefined.\n// Both global filters call this at the top of their catch method so any 23505 escaping a\n// service produces the same RFC 9457 payload regardless of where it was thrown.\n//\n// Drizzle 1.0+ wraps pg driver errors in `DrizzleQueryError` with the original pg error on\n// `.cause`, so we walk a short cause chain to find the SQLSTATE.\nexport function tryTranslatePgError(error: unknown): ConflictException | undefined {\n const pgError = findPgError(error);\n if (!pgError) return undefined;\n const { code, constraint, table, detail } = pgError;\n if (code !== PG_UNIQUE_VIOLATION) return undefined;\n return new ConflictException({\n label: 'Duplicate Entry',\n detail: detail?.trim() || 'A record with these values already exists.',\n errors: [],\n ...(constraint || table ? { meta: { constraint, table } } : {}),\n });\n}\n\n// Walks up to N levels of `.cause` looking for a pg-shaped error (has SQLSTATE `code`).\n// Caps depth so a circular `cause` graph can't trap us.\nfunction findPgError(error: unknown, depth = 0): PgErrorShape | undefined {\n if (!error || typeof error !== 'object' || depth > 5) return undefined;\n const candidate = error as PgErrorShape & { cause?: unknown };\n if (typeof candidate.code === 'string') return candidate;\n return findPgError(candidate.cause, depth + 1);\n}\n"],"mappings":"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","names":["createParamDecorator","InternalServerErrorException","NATS_HEADER_KEYS","ORG_ID","USER_ID","BU_ID","BU_TIMEZONE","BU_CURRENCY_CODE","BU_ANCESTOR_IDS","BU_DESCENDANT_IDS","getHeader","headers","key","undefined","get","val","Array","isArray","parseNatsHeaders","orgId","userId","buId","buTimezone","buCurrencyCode","buAncestorIds","JSON","parse","buDescendantIds","RpcNatsHeaders","createParamDecorator","_data","ctx","rpcCtx","switchToRpc","getContext","parseNatsHeaders","getHeaders","RpcBuId","headers","buId","InternalServerErrorException","RpcBuCurrencyCode","buCurrencyCode","Global","Logger","Module","ConfigModule","ConfigService","ClientProxyFactory","Transport","NATS_MODULE_OPTIONS","Symbol","NATS_CONTEXT_RESOLVER","Inject","Injectable","Scope","REQUEST","NatsRecordBuilder","headers","natsHeaders","NATS_CLIENTS","Symbol","NatsClientService","cachedContext","request","contextResolver","clients","send","service","cmd","data","client","get","Error","keys","join","sessionInfo","headers","contextToHeaders","record","NatsRecordBuilder","setHeaders","build","toPromise","scope","Scope","REQUEST","ctx","hdrs","natsHeaders","set","NATS_HEADER_KEYS","ORG_ID","orgId","USER_ID","userId","BU_ID","buId","BU_TIMEZONE","buTimezone","BU_CURRENCY_CODE","buCurrencyCode","BU_ANCESTOR_IDS","JSON","stringify","buAncestorIds","BU_DESCENDANT_IDS","buDescendantIds","Inject","Injectable","NatsRecordBuilder","NATS_MS_CLIENTS","Symbol","NatsMicroserviceClientService","clients","send","service","cmd","natsHeaders","data","client","get","Error","keys","join","headers","NATS_HEADER_KEYS","ORG_ID","orgId","USER_ID","userId","BU_ID","buId","BU_TIMEZONE","buTimezone","BU_ANCESTOR_IDS","JSON","stringify","buAncestorIds","BU_DESCENDANT_IDS","buDescendantIds","record","NatsRecordBuilder","setHeaders","build","toPromise","NATS_MS_OPTIONS","Symbol","NatsClientModule","logger","Logger","name","allClients","onModuleDestroy","Promise","all","map","c","close","buildClients","options","natsUrl","clients","Map","svc","services","proxy","ClientProxyFactory","create","transport","Transport","NATS","servers","set","push","log","forRoot","asyncOptions","optionsProvider","provide","NATS_MODULE_OPTIONS","useFactory","inject","resolverProvider","NATS_CONTEXT_RESOLVER","contextResolver","clientsProvider","NATS_CLIENTS","config","get","ConfigService","module","imports","ConfigModule","providers","NatsClientService","exports","forMicroservice","NATS_MS_CLIENTS","NatsMicroserviceClientService","Catch","HttpStatus","Logger","RpcException","throwError","HttpStatus","HttpException","HttpProblemException","HttpException","detailOrOptions","httpStatus","options","detail","type","label","errors","ConflictException","HttpProblemException","detailOrOptions","HttpStatus","CONFLICT","PG_UNIQUE_VIOLATION","tryTranslatePgError","error","pgError","findPgError","undefined","code","constraint","table","detail","ConflictException","label","trim","errors","meta","depth","candidate","cause","RpcProblemExceptionFilter","logger","Logger","name","catch","exception","_host","translatedPgError","tryTranslatePgError","RpcException","throwError","getError","isHttpException","status","getStatus","response","getResponse","toProblemPayload","Error","cause","causeMessage","message","undefined","causeStack","stack","error","type","detail","errors","HttpStatus","INTERNAL_SERVER_ERROR","JSON","stringify","statusCode","obj","label","Array","isArray"]}