@vritti/api-sdk 0.2.2 → 0.2.4

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/index.js CHANGED
@@ -1,5 +1,17 @@
1
1
  var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
2
5
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
6
+ var __copyProps = (to, from, except, desc2) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc2 = __getOwnPropDesc(from, key)) || desc2.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
3
15
 
4
16
  // src/auth/auth-config.module.ts
5
17
  import { Global as Global2, Module as Module2 } from "@nestjs/common";
@@ -14,6 +26,225 @@ import { Global, Module } from "@nestjs/common";
14
26
  import { Inject, Injectable, Scope } from "@nestjs/common";
15
27
  import { REQUEST } from "@nestjs/core";
16
28
 
29
+ // src/exceptions/bad-gateway.exception.ts
30
+ import { HttpStatus } from "@nestjs/common";
31
+
32
+ // src/exceptions/base-field.exception.ts
33
+ import { HttpException } from "@nestjs/common";
34
+ var HttpProblemException = class extends HttpException {
35
+ static {
36
+ __name(this, "HttpProblemException");
37
+ }
38
+ constructor(detailOrOptions, httpStatus) {
39
+ const options = typeof detailOrOptions === "string" ? {
40
+ detail: detailOrOptions
41
+ } : detailOrOptions;
42
+ super({
43
+ type: options.type ?? "about:blank",
44
+ label: options.label,
45
+ detail: options.detail,
46
+ errors: options.errors ?? []
47
+ }, httpStatus);
48
+ }
49
+ };
50
+
51
+ // src/exceptions/bad-gateway.exception.ts
52
+ var BadGatewayException = class extends HttpProblemException {
53
+ static {
54
+ __name(this, "BadGatewayException");
55
+ }
56
+ constructor(detailOrOptions) {
57
+ super(detailOrOptions ?? "Bad Gateway", HttpStatus.BAD_GATEWAY);
58
+ }
59
+ };
60
+
61
+ // src/exceptions/bad-request.exception.ts
62
+ import { HttpStatus as HttpStatus2 } from "@nestjs/common";
63
+ var BadRequestException = class extends HttpProblemException {
64
+ static {
65
+ __name(this, "BadRequestException");
66
+ }
67
+ constructor(detailOrOptions) {
68
+ super(detailOrOptions ?? "Bad Request", HttpStatus2.BAD_REQUEST);
69
+ }
70
+ };
71
+
72
+ // src/exceptions/conflict.exception.ts
73
+ import { HttpStatus as HttpStatus3 } from "@nestjs/common";
74
+ var ConflictException = class extends HttpProblemException {
75
+ static {
76
+ __name(this, "ConflictException");
77
+ }
78
+ constructor(detailOrOptions) {
79
+ super(detailOrOptions ?? "Conflict", HttpStatus3.CONFLICT);
80
+ }
81
+ };
82
+
83
+ // src/exceptions/forbidden.exception.ts
84
+ import { HttpStatus as HttpStatus4 } from "@nestjs/common";
85
+ var ForbiddenException = class extends HttpProblemException {
86
+ static {
87
+ __name(this, "ForbiddenException");
88
+ }
89
+ constructor(detailOrOptions) {
90
+ super(detailOrOptions ?? "Forbidden", HttpStatus4.FORBIDDEN);
91
+ }
92
+ };
93
+
94
+ // src/exceptions/gone.exception.ts
95
+ import { HttpStatus as HttpStatus5 } from "@nestjs/common";
96
+ var GoneException = class extends HttpProblemException {
97
+ static {
98
+ __name(this, "GoneException");
99
+ }
100
+ constructor(detailOrOptions) {
101
+ super(detailOrOptions ?? "Gone", HttpStatus5.GONE);
102
+ }
103
+ };
104
+
105
+ // src/exceptions/internal-server-error.exception.ts
106
+ import { HttpStatus as HttpStatus6 } from "@nestjs/common";
107
+ var InternalServerErrorException = class extends HttpProblemException {
108
+ static {
109
+ __name(this, "InternalServerErrorException");
110
+ }
111
+ constructor(detailOrOptions) {
112
+ super(detailOrOptions ?? "Internal Server Error", HttpStatus6.INTERNAL_SERVER_ERROR);
113
+ }
114
+ };
115
+
116
+ // src/exceptions/method-not-allowed.exception.ts
117
+ import { HttpStatus as HttpStatus7 } from "@nestjs/common";
118
+ var MethodNotAllowedException = class extends HttpProblemException {
119
+ static {
120
+ __name(this, "MethodNotAllowedException");
121
+ }
122
+ constructor(detailOrOptions) {
123
+ super(detailOrOptions ?? "Method Not Allowed", HttpStatus7.METHOD_NOT_ALLOWED);
124
+ }
125
+ };
126
+
127
+ // src/exceptions/not-acceptable.exception.ts
128
+ import { HttpStatus as HttpStatus8 } from "@nestjs/common";
129
+ var NotAcceptableException = class extends HttpProblemException {
130
+ static {
131
+ __name(this, "NotAcceptableException");
132
+ }
133
+ constructor(detailOrOptions) {
134
+ super(detailOrOptions ?? "Not Acceptable", HttpStatus8.NOT_ACCEPTABLE);
135
+ }
136
+ };
137
+
138
+ // src/exceptions/not-found.exception.ts
139
+ import { HttpStatus as HttpStatus9 } from "@nestjs/common";
140
+ var NotFoundException = class extends HttpProblemException {
141
+ static {
142
+ __name(this, "NotFoundException");
143
+ }
144
+ constructor(detailOrOptions) {
145
+ super(detailOrOptions ?? "Not Found", HttpStatus9.NOT_FOUND);
146
+ }
147
+ };
148
+
149
+ // src/exceptions/not-implemented.exception.ts
150
+ import { HttpStatus as HttpStatus10 } from "@nestjs/common";
151
+ var NotImplementedException = class extends HttpProblemException {
152
+ static {
153
+ __name(this, "NotImplementedException");
154
+ }
155
+ constructor(detailOrOptions) {
156
+ super(detailOrOptions ?? "Not Implemented", HttpStatus10.NOT_IMPLEMENTED);
157
+ }
158
+ };
159
+
160
+ // src/exceptions/payload-too-large.exception.ts
161
+ import { HttpStatus as HttpStatus11 } from "@nestjs/common";
162
+ var PayloadTooLargeException = class extends HttpProblemException {
163
+ static {
164
+ __name(this, "PayloadTooLargeException");
165
+ }
166
+ constructor(detailOrOptions) {
167
+ super(detailOrOptions ?? "Payload Too Large", HttpStatus11.PAYLOAD_TOO_LARGE);
168
+ }
169
+ };
170
+
171
+ // src/exceptions/request-timeout.exception.ts
172
+ import { HttpStatus as HttpStatus12 } from "@nestjs/common";
173
+ var RequestTimeoutException = class extends HttpProblemException {
174
+ static {
175
+ __name(this, "RequestTimeoutException");
176
+ }
177
+ constructor(detailOrOptions) {
178
+ super(detailOrOptions ?? "Request Timeout", HttpStatus12.REQUEST_TIMEOUT);
179
+ }
180
+ };
181
+
182
+ // src/exceptions/service-unavailable.exception.ts
183
+ import { HttpStatus as HttpStatus13 } from "@nestjs/common";
184
+ var ServiceUnavailableException = class extends HttpProblemException {
185
+ static {
186
+ __name(this, "ServiceUnavailableException");
187
+ }
188
+ constructor(detailOrOptions) {
189
+ super(detailOrOptions ?? "Service Unavailable", HttpStatus13.SERVICE_UNAVAILABLE);
190
+ }
191
+ };
192
+
193
+ // src/exceptions/too-many-requests.exception.ts
194
+ import { HttpStatus as HttpStatus14 } from "@nestjs/common";
195
+ var TooManyRequestsException = class extends HttpProblemException {
196
+ static {
197
+ __name(this, "TooManyRequestsException");
198
+ }
199
+ constructor(detailOrOptions) {
200
+ super(detailOrOptions ?? "Too Many Requests", HttpStatus14.TOO_MANY_REQUESTS);
201
+ }
202
+ };
203
+
204
+ // src/exceptions/unauthorized.exception.ts
205
+ import { HttpStatus as HttpStatus15 } from "@nestjs/common";
206
+ var UnauthorizedException = class extends HttpProblemException {
207
+ static {
208
+ __name(this, "UnauthorizedException");
209
+ }
210
+ constructor(detailOrOptions) {
211
+ super(detailOrOptions ?? "Unauthorized", HttpStatus15.UNAUTHORIZED);
212
+ }
213
+ };
214
+
215
+ // src/exceptions/unprocessable-entity.exception.ts
216
+ import { HttpStatus as HttpStatus16 } from "@nestjs/common";
217
+ var UnprocessableEntityException = class extends HttpProblemException {
218
+ static {
219
+ __name(this, "UnprocessableEntityException");
220
+ }
221
+ constructor(detailOrOptions) {
222
+ super(detailOrOptions ?? "Unprocessable Entity", HttpStatus16.UNPROCESSABLE_ENTITY);
223
+ }
224
+ };
225
+
226
+ // src/exceptions/unsupported-media-type.exception.ts
227
+ import { HttpStatus as HttpStatus17 } from "@nestjs/common";
228
+ var UnsupportedMediaTypeException = class extends HttpProblemException {
229
+ static {
230
+ __name(this, "UnsupportedMediaTypeException");
231
+ }
232
+ constructor(detailOrOptions) {
233
+ super(detailOrOptions ?? "Unsupported Media Type", HttpStatus17.UNSUPPORTED_MEDIA_TYPE);
234
+ }
235
+ };
236
+
237
+ // src/exceptions/validation.exception.ts
238
+ import { HttpStatus as HttpStatus18 } from "@nestjs/common";
239
+ var ValidationException = class extends HttpProblemException {
240
+ static {
241
+ __name(this, "ValidationException");
242
+ }
243
+ constructor(detailOrOptions) {
244
+ super(detailOrOptions ?? "Validation Failed", HttpStatus18.BAD_REQUEST);
245
+ }
246
+ };
247
+
17
248
  // src/config/index.ts
18
249
  var defaultConfig = {
19
250
  cookie: {
@@ -70,19 +301,36 @@ function resetConfig() {
70
301
  }
71
302
  __name(resetConfig, "resetConfig");
72
303
  function getRefreshCookieOptions() {
73
- const options = {
304
+ return {
74
305
  httpOnly: true,
75
306
  secure: currentConfig.cookie.refreshCookieSecure,
76
307
  sameSite: currentConfig.cookie.refreshCookieSameSite,
77
308
  path: currentConfig.cookie.refreshCookiePath,
78
- maxAge: currentConfig.cookie.refreshCookieMaxAge
309
+ maxAge: currentConfig.cookie.refreshCookieMaxAge,
310
+ ...currentConfig.cookie.refreshCookieDomain && {
311
+ domain: currentConfig.cookie.refreshCookieDomain
312
+ }
79
313
  };
80
- if (currentConfig.cookie.refreshCookieDomain) {
81
- options.domain = currentConfig.cookie.refreshCookieDomain;
82
- }
83
- return options;
84
314
  }
85
315
  __name(getRefreshCookieOptions, "getRefreshCookieOptions");
316
+ function getRefreshCookieOptionsForHost(hostname) {
317
+ const baseDomain = currentConfig.cookie.refreshCookieDomain;
318
+ if (!baseDomain) {
319
+ throw new Error("refreshCookieDomain must be configured before using getRefreshCookieOptionsForHost");
320
+ }
321
+ if (!hostname.endsWith(`.${baseDomain}`)) {
322
+ throw new UnauthorizedException("Invalid request host.");
323
+ }
324
+ return {
325
+ httpOnly: true,
326
+ secure: currentConfig.cookie.refreshCookieSecure,
327
+ sameSite: currentConfig.cookie.refreshCookieSameSite,
328
+ path: currentConfig.cookie.refreshCookiePath,
329
+ maxAge: currentConfig.cookie.refreshCookieMaxAge,
330
+ domain: hostname
331
+ };
332
+ }
333
+ __name(getRefreshCookieOptionsForHost, "getRefreshCookieOptionsForHost");
86
334
  function getJwtExpiry() {
87
335
  return {
88
336
  access: currentConfig.jwt.accessTokenExpiry,
@@ -93,9 +341,9 @@ function getJwtExpiry() {
93
341
  __name(getJwtExpiry, "getJwtExpiry");
94
342
 
95
343
  // src/request/services/request.service.ts
96
- function _ts_decorate(decorators, target, key, desc) {
97
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
98
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
344
+ function _ts_decorate(decorators, target, key, desc2) {
345
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
346
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
99
347
  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;
100
348
  return c > 3 && r && Object.defineProperty(target, key, r), r;
101
349
  }
@@ -172,9 +420,9 @@ RequestService = _ts_decorate([
172
420
  ], RequestService);
173
421
 
174
422
  // src/request/request.module.ts
175
- function _ts_decorate2(decorators, target, key, desc) {
176
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
177
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
423
+ function _ts_decorate2(decorators, target, key, desc2) {
424
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
425
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
178
426
  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;
179
427
  return c > 3 && r && Object.defineProperty(target, key, r), r;
180
428
  }
@@ -197,7 +445,7 @@ RequestModule = _ts_decorate2([
197
445
  ], RequestModule);
198
446
 
199
447
  // src/auth/guards/vritti-auth.guard.ts
200
- import { ForbiddenException, Injectable as Injectable2, Logger as Logger2, Scope as Scope2, UnauthorizedException } from "@nestjs/common";
448
+ import { ForbiddenException as ForbiddenException2, Injectable as Injectable2, Logger as Logger2, Scope as Scope2, UnauthorizedException as UnauthorizedException2 } from "@nestjs/common";
201
449
  import { SSE_METADATA } from "@nestjs/common/constants";
202
450
  import { ConfigService } from "@nestjs/config";
203
451
  import { Reflector } from "@nestjs/core";
@@ -227,9 +475,9 @@ function verifyTokenHash(token, expectedHash) {
227
475
  __name(verifyTokenHash, "verifyTokenHash");
228
476
 
229
477
  // src/auth/guards/vritti-auth.guard.ts
230
- function _ts_decorate3(decorators, target, key, desc) {
231
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
232
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
478
+ function _ts_decorate3(decorators, target, key, desc2) {
479
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
480
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
233
481
  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;
234
482
  return c > 3 && r && Object.defineProperty(target, key, r), r;
235
483
  }
@@ -285,21 +533,21 @@ var VrittiAuthGuard = class _VrittiAuthGuard {
285
533
  try {
286
534
  const accessToken = this.requestService.getAccessToken();
287
535
  if (!accessToken) {
288
- throw new UnauthorizedException("Access token not found");
536
+ throw new UnauthorizedException2("Access token not found");
289
537
  }
290
538
  const decodedAccessToken = this.validateAccessToken(accessToken);
291
539
  if (decodedAccessToken.tokenType !== "access") {
292
- throw new UnauthorizedException("Invalid token type");
540
+ throw new UnauthorizedException2("Invalid token type");
293
541
  }
294
542
  this.validateRefreshTokenBinding(decodedAccessToken);
295
543
  if (isOnboarding && decodedAccessToken.sessionType !== "ONBOARDING") {
296
- throw new UnauthorizedException("This endpoint requires an onboarding session");
544
+ throw new UnauthorizedException2("This endpoint requires an onboarding session");
297
545
  }
298
546
  if (isReset && decodedAccessToken.sessionType !== "RESET") {
299
- throw new UnauthorizedException("This endpoint requires a reset session");
547
+ throw new UnauthorizedException2("This endpoint requires a reset session");
300
548
  }
301
549
  if (!isOnboarding && !isReset && (decodedAccessToken.sessionType === "ONBOARDING" || decodedAccessToken.sessionType === "RESET")) {
302
- throw new UnauthorizedException(`${decodedAccessToken.sessionType} sessions cannot access this endpoint`);
550
+ throw new UnauthorizedException2(`${decodedAccessToken.sessionType} sessions cannot access this endpoint`);
303
551
  }
304
552
  request.sessionInfo = {
305
553
  userId: decodedAccessToken.userId,
@@ -308,11 +556,11 @@ var VrittiAuthGuard = class _VrittiAuthGuard {
308
556
  };
309
557
  return true;
310
558
  } catch (error) {
311
- if (error instanceof UnauthorizedException) {
559
+ if (error instanceof UnauthorizedException2) {
312
560
  throw error;
313
561
  }
314
562
  this.logger.error("Unexpected error in auth guard", error);
315
- throw new UnauthorizedException("Authentication failed");
563
+ throw new UnauthorizedException2("Authentication failed");
316
564
  }
317
565
  }
318
566
  // Validates JWT signature, expiry, and not-before claims
@@ -320,50 +568,50 @@ var VrittiAuthGuard = class _VrittiAuthGuard {
320
568
  try {
321
569
  return this.jwtService.verify(token);
322
570
  } catch (error) {
323
- if (error instanceof UnauthorizedException) throw error;
571
+ if (error instanceof UnauthorizedException2) throw error;
324
572
  const jwtError = error;
325
573
  if (jwtError?.name === "TokenExpiredError") {
326
- throw new UnauthorizedException("Access token has expired");
574
+ throw new UnauthorizedException2("Access token has expired");
327
575
  }
328
576
  if (jwtError?.name === "JsonWebTokenError") {
329
- throw new UnauthorizedException("Invalid access token");
577
+ throw new UnauthorizedException2("Invalid access token");
330
578
  }
331
579
  if (jwtError?.name === "NotBeforeError") {
332
- throw new UnauthorizedException("Access token not yet valid");
580
+ throw new UnauthorizedException2("Access token not yet valid");
333
581
  }
334
- throw new UnauthorizedException("Access token validation failed");
582
+ throw new UnauthorizedException2("Access token validation failed");
335
583
  }
336
584
  }
337
585
  // Validates that the access token is bound to the refresh token in the cookie
338
586
  validateRefreshTokenBinding(decodedAccessToken) {
339
587
  if (!decodedAccessToken.refreshTokenHash) {
340
- throw new UnauthorizedException("Token missing refresh token binding");
588
+ throw new UnauthorizedException2("Token missing refresh token binding");
341
589
  }
342
590
  const refreshToken = this.requestService.getRefreshToken();
343
591
  if (!refreshToken) {
344
- throw new UnauthorizedException("Session validation failed");
592
+ throw new UnauthorizedException2("Session validation failed");
345
593
  }
346
594
  if (!verifyTokenHash(refreshToken, decodedAccessToken.refreshTokenHash)) {
347
- throw new UnauthorizedException("Session validation failed");
595
+ throw new UnauthorizedException2("Session validation failed");
348
596
  }
349
597
  }
350
598
  // Authenticates SSE connections using the refresh token httpOnly cookie
351
599
  handleSseAuth(request, isOnboarding) {
352
600
  const refreshToken = this.requestService.getRefreshToken();
353
601
  if (!refreshToken) {
354
- throw new UnauthorizedException("Authentication required");
602
+ throw new UnauthorizedException2("Authentication required");
355
603
  }
356
604
  let decoded;
357
605
  try {
358
606
  decoded = this.jwtService.verify(refreshToken);
359
607
  } catch {
360
- throw new UnauthorizedException("Invalid or expired session");
608
+ throw new UnauthorizedException2("Invalid or expired session");
361
609
  }
362
610
  if (decoded.tokenType !== "refresh") {
363
- throw new UnauthorizedException("Invalid token type");
611
+ throw new UnauthorizedException2("Invalid token type");
364
612
  }
365
613
  if (isOnboarding && decoded.sessionType !== "ONBOARDING") {
366
- throw new UnauthorizedException("This endpoint requires an onboarding session");
614
+ throw new UnauthorizedException2("This endpoint requires an onboarding session");
367
615
  }
368
616
  request.sessionInfo = {
369
617
  userId: decoded.userId,
@@ -384,7 +632,7 @@ var VrittiAuthGuard = class _VrittiAuthGuard {
384
632
  const fastifyInstance = request.server;
385
633
  const csrfProtection = fastifyInstance.csrfProtection;
386
634
  if (!csrfProtection) {
387
- throw new ForbiddenException("CSRF protection not configured");
635
+ throw new ForbiddenException2("CSRF protection not configured");
388
636
  }
389
637
  await new Promise((resolve, reject) => {
390
638
  const originalSend = reply.send.bind(reply);
@@ -400,7 +648,7 @@ var VrittiAuthGuard = class _VrittiAuthGuard {
400
648
  });
401
649
  });
402
650
  } catch (error) {
403
- throw new ForbiddenException({
651
+ throw new ForbiddenException2({
404
652
  errors: [
405
653
  {
406
654
  field: "csrf",
@@ -465,9 +713,9 @@ var TokenType = /* @__PURE__ */ (function(TokenType2) {
465
713
  })({});
466
714
 
467
715
  // src/auth/services/jwt-auth.service.ts
468
- function _ts_decorate4(decorators, target, key, desc) {
469
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
470
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
716
+ function _ts_decorate4(decorators, target, key, desc2) {
717
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
718
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
471
719
  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;
472
720
  return c > 3 && r && Object.defineProperty(target, key, r), r;
473
721
  }
@@ -548,9 +796,9 @@ JwtAuthService = _ts_decorate4([
548
796
  ], JwtAuthService);
549
797
 
550
798
  // src/auth/auth-config.module.ts
551
- function _ts_decorate5(decorators, target, key, desc) {
552
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
553
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
799
+ function _ts_decorate5(decorators, target, key, desc2) {
800
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
801
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
554
802
  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;
555
803
  return c > 3 && r && Object.defineProperty(target, key, r), r;
556
804
  }
@@ -613,6 +861,18 @@ var AccessToken = createParamDecorator((_data, ctx) => {
613
861
  return authHeader?.replace("Bearer ", "") || "";
614
862
  });
615
863
 
864
+ // src/auth/decorators/cookie-domain.decorator.ts
865
+ import { createParamDecorator as createParamDecorator2 } from "@nestjs/common";
866
+ var CookieDomain = createParamDecorator2((_data, ctx) => {
867
+ const request = ctx.switchToHttp().getRequest();
868
+ const forwarded = request.headers["x-forwarded-host"];
869
+ const raw = Array.isArray(forwarded) ? forwarded[0] : forwarded;
870
+ const hostStr = raw ?? request.hostname;
871
+ const domain = hostStr.split(":")[0] ?? hostStr;
872
+ const baseDomain = getConfig().cookie.refreshCookieDomain ?? "";
873
+ return domain.endsWith(`.${baseDomain}`) ? domain : baseDomain;
874
+ });
875
+
616
876
  // src/auth/decorators/onboarding.decorator.ts
617
877
  import { SetMetadata as SetMetadata3 } from "@nestjs/common";
618
878
  var Onboarding = /* @__PURE__ */ __name(() => SetMetadata3("isOnboarding", true), "Onboarding");
@@ -621,9 +881,20 @@ var Onboarding = /* @__PURE__ */ __name(() => SetMetadata3("isOnboarding", true)
621
881
  import { SetMetadata as SetMetadata4 } from "@nestjs/common";
622
882
  var Public = /* @__PURE__ */ __name(() => SetMetadata4("isPublic", true), "Public");
623
883
 
884
+ // src/auth/decorators/refresh-cookie-options.decorator.ts
885
+ import { createParamDecorator as createParamDecorator3 } from "@nestjs/common";
886
+ var RefreshCookieOptions = createParamDecorator3((_data, ctx) => {
887
+ const request = ctx.switchToHttp().getRequest();
888
+ const forwarded = request.headers["x-forwarded-host"];
889
+ const raw = Array.isArray(forwarded) ? forwarded[0] : forwarded;
890
+ const hostStr = raw ?? request.hostname;
891
+ const domain = hostStr.split(":")[0] ?? hostStr;
892
+ return getRefreshCookieOptionsForHost(domain);
893
+ });
894
+
624
895
  // src/auth/decorators/refresh-token-cookie.decorator.ts
625
- import { createParamDecorator as createParamDecorator2 } from "@nestjs/common";
626
- var RefreshTokenCookie = createParamDecorator2((_data, ctx) => {
896
+ import { createParamDecorator as createParamDecorator4 } from "@nestjs/common";
897
+ var RefreshTokenCookie = createParamDecorator4((_data, ctx) => {
627
898
  const request = ctx.switchToHttp().getRequest();
628
899
  const cookies = request.cookies ?? {};
629
900
  const config = getConfig();
@@ -631,8 +902,8 @@ var RefreshTokenCookie = createParamDecorator2((_data, ctx) => {
631
902
  });
632
903
 
633
904
  // src/auth/decorators/session-data.decorator.ts
634
- import { createParamDecorator as createParamDecorator3 } from "@nestjs/common";
635
- var SessionData = createParamDecorator3((_data, ctx) => {
905
+ import { createParamDecorator as createParamDecorator5 } from "@nestjs/common";
906
+ var SessionData = createParamDecorator5((_data, ctx) => {
636
907
  const request = ctx.switchToHttp().getRequest();
637
908
  const sessionInfo = request.sessionInfo;
638
909
  if (!sessionInfo?.sessionId) {
@@ -646,8 +917,8 @@ var SessionData = createParamDecorator3((_data, ctx) => {
646
917
  });
647
918
 
648
919
  // src/auth/decorators/user-id.decorator.ts
649
- import { createParamDecorator as createParamDecorator4 } from "@nestjs/common";
650
- var UserId = createParamDecorator4((_data, ctx) => {
920
+ import { createParamDecorator as createParamDecorator6 } from "@nestjs/common";
921
+ var UserId = createParamDecorator6((_data, ctx) => {
651
922
  const request = ctx.switchToHttp().getRequest();
652
923
  const sessionInfo = request.sessionInfo;
653
924
  if (!sessionInfo?.userId) {
@@ -656,21 +927,20 @@ var UserId = createParamDecorator4((_data, ctx) => {
656
927
  return sessionInfo.userId;
657
928
  });
658
929
 
659
- // src/database/database.module.ts
660
- import { Global as Global3, Module as Module3 } from "@nestjs/common";
661
- import { Reflector as Reflector3 } from "@nestjs/core";
930
+ // src/cache/cache.module.ts
931
+ import { Module as Module3 } from "@nestjs/common";
932
+ import { ConfigModule as ConfigModule2 } from "@nestjs/config";
662
933
 
663
- // src/database/constants.ts
664
- var DATABASE_MODULE_OPTIONS = Symbol("DATABASE_MODULE_OPTIONS");
934
+ // src/cache/cache.service.ts
935
+ import { Inject as Inject2, Injectable as Injectable4, Logger as Logger4 } from "@nestjs/common";
665
936
 
666
- // src/database/services/primary-database.service.ts
667
- import { Inject as Inject2, Injectable as Injectable4, InternalServerErrorException, Logger as Logger4 } from "@nestjs/common";
668
- import { eq, or } from "drizzle-orm";
669
- import { drizzle } from "drizzle-orm/node-postgres";
670
- import { Pool } from "pg";
671
- function _ts_decorate6(decorators, target, key, desc) {
672
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
673
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
937
+ // src/cache/constants.ts
938
+ var CACHE_PROVIDER = Symbol("CACHE_PROVIDER");
939
+
940
+ // src/cache/cache.service.ts
941
+ function _ts_decorate6(decorators, target, key, desc2) {
942
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
943
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
674
944
  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;
675
945
  return c > 3 && r && Object.defineProperty(target, key, r), r;
676
946
  }
@@ -685,12 +955,218 @@ function _ts_param2(paramIndex, decorator) {
685
955
  };
686
956
  }
687
957
  __name(_ts_param2, "_ts_param");
688
- var PrimaryDatabaseService = class _PrimaryDatabaseService {
958
+ var CacheService = class _CacheService {
689
959
  static {
690
- __name(this, "PrimaryDatabaseService");
960
+ __name(this, "CacheService");
691
961
  }
692
- options;
693
- logger = new Logger4(_PrimaryDatabaseService.name);
962
+ provider;
963
+ logger = new Logger4(_CacheService.name);
964
+ constructor(provider) {
965
+ this.provider = provider;
966
+ }
967
+ // Stores a value with mandatory TTL — errors are logged and swallowed so DB writes still succeed
968
+ async set(key, value, ttlSeconds) {
969
+ try {
970
+ await this.provider.set(key, value, ttlSeconds);
971
+ } catch (err) {
972
+ this.logger.error(`Cache set failed for key "${key}"`, err);
973
+ }
974
+ }
975
+ // Returns cached value or null on miss or any Redis error — callers fall back to DB
976
+ async get(key) {
977
+ try {
978
+ return await this.provider.get(key);
979
+ } catch (err) {
980
+ this.logger.error(`Cache get failed for key "${key}"`, err);
981
+ return null;
982
+ }
983
+ }
984
+ // Deletes one or more keys — errors are logged and swallowed
985
+ async del(...keys) {
986
+ try {
987
+ await this.provider.del(...keys);
988
+ } catch (err) {
989
+ this.logger.error(`Cache del failed for keys "${keys.join(", ")}"`, err);
990
+ }
991
+ }
992
+ // Returns all keys matching a glob pattern — returns empty array on error
993
+ async scanKeys(pattern) {
994
+ try {
995
+ return await this.provider.scanKeys(pattern);
996
+ } catch (err) {
997
+ this.logger.error(`Cache scanKeys failed for pattern "${pattern}"`, err);
998
+ return [];
999
+ }
1000
+ }
1001
+ // Returns raw memory info from the provider — returns empty string on error
1002
+ async getMemoryInfo() {
1003
+ try {
1004
+ return await this.provider.getMemoryInfo();
1005
+ } catch (err) {
1006
+ this.logger.error("Cache getMemoryInfo failed", err);
1007
+ return "";
1008
+ }
1009
+ }
1010
+ };
1011
+ CacheService = _ts_decorate6([
1012
+ Injectable4(),
1013
+ _ts_param2(0, Inject2(CACHE_PROVIDER)),
1014
+ _ts_metadata4("design:type", Function),
1015
+ _ts_metadata4("design:paramtypes", [
1016
+ typeof ICacheProvider === "undefined" ? Object : ICacheProvider
1017
+ ])
1018
+ ], CacheService);
1019
+
1020
+ // src/cache/providers/redis.provider.ts
1021
+ import { Injectable as Injectable5, Logger as Logger5 } from "@nestjs/common";
1022
+ import { ConfigService as ConfigService4 } from "@nestjs/config";
1023
+ import Redis from "ioredis";
1024
+ function _ts_decorate7(decorators, target, key, desc2) {
1025
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
1026
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
1027
+ 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;
1028
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1029
+ }
1030
+ __name(_ts_decorate7, "_ts_decorate");
1031
+ function _ts_metadata5(k, v) {
1032
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1033
+ }
1034
+ __name(_ts_metadata5, "_ts_metadata");
1035
+ var RedisCacheProvider = class _RedisCacheProvider {
1036
+ static {
1037
+ __name(this, "RedisCacheProvider");
1038
+ }
1039
+ configService;
1040
+ logger = new Logger5(_RedisCacheProvider.name);
1041
+ client;
1042
+ constructor(configService) {
1043
+ this.configService = configService;
1044
+ }
1045
+ // Creates the ioredis client and attaches connection/error listeners
1046
+ onModuleInit() {
1047
+ const url = this.configService.getOrThrow("REDIS_URL");
1048
+ this.client = new Redis(url, {
1049
+ lazyConnect: true,
1050
+ maxRetriesPerRequest: 3
1051
+ });
1052
+ this.client.on("connect", () => this.logger.log("Redis connected"));
1053
+ this.client.on("error", (err) => this.logger.error("Redis error", err));
1054
+ }
1055
+ // Gracefully closes the ioredis connection on app shutdown
1056
+ async onModuleDestroy() {
1057
+ await this.client.quit();
1058
+ this.logger.log("Redis disconnected");
1059
+ }
1060
+ // Serializes value to JSON and stores with a mandatory TTL
1061
+ async set(key, value, ttlSeconds) {
1062
+ const json = JSON.stringify(value);
1063
+ await this.client.setex(key, ttlSeconds, json);
1064
+ }
1065
+ // Reads the stored JSON string and parses back to the original type
1066
+ async get(key) {
1067
+ const json = await this.client.get(key);
1068
+ if (!json) return null;
1069
+ return JSON.parse(json);
1070
+ }
1071
+ // Deletes one or more keys in a single command
1072
+ async del(...keys) {
1073
+ if (keys.length > 0) {
1074
+ await this.client.del(...keys);
1075
+ }
1076
+ }
1077
+ // Cursor-iterates all keys matching a glob pattern — never uses KEYS command
1078
+ async scanKeys(pattern) {
1079
+ const keys = [];
1080
+ let cursor = "0";
1081
+ do {
1082
+ const [nextCursor, batch] = await this.client.scan(cursor, "MATCH", pattern, "COUNT", 100);
1083
+ cursor = nextCursor;
1084
+ keys.push(...batch);
1085
+ } while (cursor !== "0");
1086
+ return keys;
1087
+ }
1088
+ // Returns raw INFO memory output for memory monitoring
1089
+ async getMemoryInfo() {
1090
+ return this.client.info("memory");
1091
+ }
1092
+ };
1093
+ RedisCacheProvider = _ts_decorate7([
1094
+ Injectable5(),
1095
+ _ts_metadata5("design:type", Function),
1096
+ _ts_metadata5("design:paramtypes", [
1097
+ typeof ConfigService4 === "undefined" ? Object : ConfigService4
1098
+ ])
1099
+ ], RedisCacheProvider);
1100
+
1101
+ // src/cache/cache.module.ts
1102
+ function _ts_decorate8(decorators, target, key, desc2) {
1103
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
1104
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
1105
+ 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;
1106
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1107
+ }
1108
+ __name(_ts_decorate8, "_ts_decorate");
1109
+ var CacheModule = class {
1110
+ static {
1111
+ __name(this, "CacheModule");
1112
+ }
1113
+ };
1114
+ CacheModule = _ts_decorate8([
1115
+ Module3({
1116
+ imports: [
1117
+ ConfigModule2
1118
+ ],
1119
+ providers: [
1120
+ RedisCacheProvider,
1121
+ {
1122
+ provide: CACHE_PROVIDER,
1123
+ useExisting: RedisCacheProvider
1124
+ },
1125
+ CacheService
1126
+ ],
1127
+ exports: [
1128
+ RedisCacheProvider,
1129
+ CACHE_PROVIDER,
1130
+ CacheService
1131
+ ]
1132
+ })
1133
+ ], CacheModule);
1134
+
1135
+ // src/database/database.module.ts
1136
+ import { Global as Global3, Module as Module4 } from "@nestjs/common";
1137
+ import { Reflector as Reflector3 } from "@nestjs/core";
1138
+
1139
+ // src/database/constants.ts
1140
+ var DATABASE_MODULE_OPTIONS = Symbol("DATABASE_MODULE_OPTIONS");
1141
+
1142
+ // src/database/services/primary-database.service.ts
1143
+ import { Inject as Inject3, Injectable as Injectable6, InternalServerErrorException as InternalServerErrorException2, Logger as Logger6 } from "@nestjs/common";
1144
+ import { eq, or } from "drizzle-orm";
1145
+ import { drizzle } from "drizzle-orm/node-postgres";
1146
+ import { Pool } from "pg";
1147
+ function _ts_decorate9(decorators, target, key, desc2) {
1148
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
1149
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
1150
+ 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;
1151
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1152
+ }
1153
+ __name(_ts_decorate9, "_ts_decorate");
1154
+ function _ts_metadata6(k, v) {
1155
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1156
+ }
1157
+ __name(_ts_metadata6, "_ts_metadata");
1158
+ function _ts_param3(paramIndex, decorator) {
1159
+ return function(target, key) {
1160
+ decorator(target, key, paramIndex);
1161
+ };
1162
+ }
1163
+ __name(_ts_param3, "_ts_param");
1164
+ var PrimaryDatabaseService = class _PrimaryDatabaseService {
1165
+ static {
1166
+ __name(this, "PrimaryDatabaseService");
1167
+ }
1168
+ options;
1169
+ logger = new Logger6(_PrimaryDatabaseService.name);
694
1170
  pool = null;
695
1171
  db = null;
696
1172
  tenantConfigCache = /* @__PURE__ */ new Map();
@@ -707,10 +1183,21 @@ var PrimaryDatabaseService = class _PrimaryDatabaseService {
707
1183
  // Initializes connection to primary database using Drizzle
708
1184
  async initializeDrizzleClient() {
709
1185
  try {
710
- const databaseUrl = this.buildPrimaryDbUrl();
1186
+ const { host, port = 5432, username, password, database, schema, sslMode = "require" } = this.options.primaryDb;
711
1187
  this.pool = new Pool({
712
- connectionString: databaseUrl,
713
- max: this.options.maxConnections || 10
1188
+ host,
1189
+ port,
1190
+ user: username,
1191
+ password,
1192
+ database,
1193
+ max: this.options.maxConnections || 10,
1194
+ ssl: sslMode === "disable" ? false : {
1195
+ rejectUnauthorized: sslMode !== "no-verify"
1196
+ },
1197
+ // Pass schema as a PostgreSQL startup option — recognized by node-postgres, unlike the ?schema= URL param
1198
+ ...schema && {
1199
+ options: `-csearch_path=${schema}`
1200
+ }
714
1201
  });
715
1202
  this.logger.debug(`Schema keys passed to drizzle: [${Object.keys(this.options.drizzleSchema || {}).join(", ")}]`);
716
1203
  this.logger.debug(`Relations keys passed to drizzle: [${Object.keys(this.options.drizzleRelations || {}).join(", ")}]`);
@@ -721,34 +1208,11 @@ var PrimaryDatabaseService = class _PrimaryDatabaseService {
721
1208
  });
722
1209
  this.logger.debug(`Drizzle query keys after init: [${Object.keys(this.db.query || {}).join(", ")}]`);
723
1210
  await this.pool.query("SELECT 1");
724
- this.logger.log("Connected to primary database (tenant registry)");
1211
+ this.logger.log(`Connected to primary database (schema: ${schema ?? "public"})`);
725
1212
  } catch (error) {
726
1213
  this.logger.error("Failed to connect to primary database", error);
727
- throw new InternalServerErrorException("Failed to initialize tenant registry");
728
- }
729
- }
730
- // Builds the PostgreSQL connection URL from primary database config properties
731
- buildPrimaryDbUrl() {
732
- if (!this.options.primaryDb) {
733
- throw new Error("Primary database configuration not provided");
734
- }
735
- const { host, port = 5432, username, password, database, schema = "public", sslMode = "require" } = this.options.primaryDb;
736
- let url = `postgresql://${username}:${encodeURIComponent(password)}@${host}:${port}/${database}`;
737
- const params = new URLSearchParams();
738
- if (schema) {
739
- params.set("schema", schema);
1214
+ throw new InternalServerErrorException2("Failed to initialize tenant registry");
740
1215
  }
741
- params.set("sslmode", sslMode);
742
- const queryString = params.toString();
743
- if (queryString) {
744
- url += `?${queryString}`;
745
- }
746
- this.logger.debug(`Primary DB connection URL: ${this.maskPassword(url)}`);
747
- return url;
748
- }
749
- // Masks password in connection URL for safe logging
750
- maskPassword(url) {
751
- return url.replace(/:([^@]+)@/, ":****@");
752
1216
  }
753
1217
  // Retrieves tenant configuration by ID or subdomain, with in-memory caching
754
1218
  async getTenantInfo(tenantIdentifier) {
@@ -796,7 +1260,7 @@ var PrimaryDatabaseService = class _PrimaryDatabaseService {
796
1260
  return info;
797
1261
  } catch (error) {
798
1262
  this.logger.error(`Failed to fetch tenant info: ${tenantIdentifier}`, error);
799
- throw new InternalServerErrorException("Failed to resolve tenant");
1263
+ throw new InternalServerErrorException2("Failed to resolve tenant");
800
1264
  }
801
1265
  }
802
1266
  // Caches tenant info by both ID and subdomain with TTL expiration
@@ -846,24 +1310,24 @@ var PrimaryDatabaseService = class _PrimaryDatabaseService {
846
1310
  }
847
1311
  }
848
1312
  };
849
- PrimaryDatabaseService = _ts_decorate6([
850
- Injectable4(),
851
- _ts_param2(0, Inject2(DATABASE_MODULE_OPTIONS)),
852
- _ts_metadata4("design:type", Function),
853
- _ts_metadata4("design:paramtypes", [
1313
+ PrimaryDatabaseService = _ts_decorate9([
1314
+ Injectable6(),
1315
+ _ts_param3(0, Inject3(DATABASE_MODULE_OPTIONS)),
1316
+ _ts_metadata6("design:type", Function),
1317
+ _ts_metadata6("design:paramtypes", [
854
1318
  typeof DatabaseModuleOptions === "undefined" ? Object : DatabaseModuleOptions
855
1319
  ])
856
1320
  ], PrimaryDatabaseService);
857
1321
 
858
1322
  // src/database/services/tenant-context.service.ts
859
- import { Injectable as Injectable5, Scope as Scope3, UnauthorizedException as UnauthorizedException2 } from "@nestjs/common";
860
- function _ts_decorate7(decorators, target, key, desc) {
861
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
862
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1323
+ import { Injectable as Injectable7, Scope as Scope3, UnauthorizedException as UnauthorizedException3 } from "@nestjs/common";
1324
+ function _ts_decorate10(decorators, target, key, desc2) {
1325
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
1326
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
863
1327
  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;
864
1328
  return c > 3 && r && Object.defineProperty(target, key, r), r;
865
1329
  }
866
- __name(_ts_decorate7, "_ts_decorate");
1330
+ __name(_ts_decorate10, "_ts_decorate");
867
1331
  var TenantContextService = class {
868
1332
  static {
869
1333
  __name(this, "TenantContextService");
@@ -879,7 +1343,7 @@ var TenantContextService = class {
879
1343
  // Returns the tenant info for this request, throwing if context is not set
880
1344
  getTenant() {
881
1345
  if (!this.tenantInfo) {
882
- throw new UnauthorizedException2("Tenant context not set");
1346
+ throw new UnauthorizedException3("Tenant context not set");
883
1347
  }
884
1348
  return this.tenantInfo;
885
1349
  }
@@ -900,40 +1364,40 @@ var TenantContextService = class {
900
1364
  return this.tenantInfo?.subdomain ?? null;
901
1365
  }
902
1366
  };
903
- TenantContextService = _ts_decorate7([
904
- Injectable5({
1367
+ TenantContextService = _ts_decorate10([
1368
+ Injectable7({
905
1369
  scope: Scope3.REQUEST
906
1370
  })
907
1371
  ], TenantContextService);
908
1372
 
909
1373
  // src/database/services/tenant-database.service.ts
910
- import { Inject as Inject3, Injectable as Injectable6, InternalServerErrorException as InternalServerErrorException2, Logger as Logger5 } from "@nestjs/common";
1374
+ import { Inject as Inject4, Injectable as Injectable8, InternalServerErrorException as InternalServerErrorException3, Logger as Logger7 } from "@nestjs/common";
911
1375
  import { drizzle as drizzle2 } from "drizzle-orm/node-postgres";
912
1376
  import { Pool as Pool2 } from "pg";
913
- function _ts_decorate8(decorators, target, key, desc) {
914
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
915
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1377
+ function _ts_decorate11(decorators, target, key, desc2) {
1378
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
1379
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
916
1380
  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;
917
1381
  return c > 3 && r && Object.defineProperty(target, key, r), r;
918
1382
  }
919
- __name(_ts_decorate8, "_ts_decorate");
920
- function _ts_metadata5(k, v) {
1383
+ __name(_ts_decorate11, "_ts_decorate");
1384
+ function _ts_metadata7(k, v) {
921
1385
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
922
1386
  }
923
- __name(_ts_metadata5, "_ts_metadata");
924
- function _ts_param3(paramIndex, decorator) {
1387
+ __name(_ts_metadata7, "_ts_metadata");
1388
+ function _ts_param4(paramIndex, decorator) {
925
1389
  return function(target, key) {
926
1390
  decorator(target, key, paramIndex);
927
1391
  };
928
1392
  }
929
- __name(_ts_param3, "_ts_param");
1393
+ __name(_ts_param4, "_ts_param");
930
1394
  var TenantDatabaseService = class _TenantDatabaseService {
931
1395
  static {
932
1396
  __name(this, "TenantDatabaseService");
933
1397
  }
934
1398
  options;
935
1399
  tenantContext;
936
- logger = new Logger5(_TenantDatabaseService.name);
1400
+ logger = new Logger7(_TenantDatabaseService.name);
937
1401
  clients = /* @__PURE__ */ new Map();
938
1402
  clientLastUsed = /* @__PURE__ */ new Map();
939
1403
  cleanupInterval;
@@ -985,7 +1449,7 @@ var TenantDatabaseService = class _TenantDatabaseService {
985
1449
  };
986
1450
  } catch (error) {
987
1451
  this.logger.error(`Failed to create database connection for tenant: ${tenant.subdomain}`, error);
988
- throw new InternalServerErrorException2("Failed to connect to tenant database");
1452
+ throw new InternalServerErrorException3("Failed to connect to tenant database");
989
1453
  }
990
1454
  }
991
1455
  // Builds the PostgreSQL connection URL for a dedicated tenant database
@@ -1065,24 +1529,24 @@ var TenantDatabaseService = class _TenantDatabaseService {
1065
1529
  this.logger.log("All database connections closed");
1066
1530
  }
1067
1531
  };
1068
- TenantDatabaseService = _ts_decorate8([
1069
- Injectable6(),
1070
- _ts_param3(0, Inject3(DATABASE_MODULE_OPTIONS)),
1071
- _ts_metadata5("design:type", Function),
1072
- _ts_metadata5("design:paramtypes", [
1532
+ TenantDatabaseService = _ts_decorate11([
1533
+ Injectable8(),
1534
+ _ts_param4(0, Inject4(DATABASE_MODULE_OPTIONS)),
1535
+ _ts_metadata7("design:type", Function),
1536
+ _ts_metadata7("design:paramtypes", [
1073
1537
  typeof DatabaseModuleOptions === "undefined" ? Object : DatabaseModuleOptions,
1074
1538
  typeof TenantContextService === "undefined" ? Object : TenantContextService
1075
1539
  ])
1076
1540
  ], TenantDatabaseService);
1077
1541
 
1078
1542
  // src/database/database.module.ts
1079
- function _ts_decorate9(decorators, target, key, desc) {
1080
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1081
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1543
+ function _ts_decorate12(decorators, target, key, desc2) {
1544
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
1545
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
1082
1546
  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;
1083
1547
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1084
1548
  }
1085
- __name(_ts_decorate9, "_ts_decorate");
1549
+ __name(_ts_decorate12, "_ts_decorate");
1086
1550
  var DatabaseModule = class _DatabaseModule {
1087
1551
  static {
1088
1552
  __name(this, "DatabaseModule");
@@ -1128,14 +1592,14 @@ var DatabaseModule = class _DatabaseModule {
1128
1592
  };
1129
1593
  }
1130
1594
  };
1131
- DatabaseModule = _ts_decorate9([
1595
+ DatabaseModule = _ts_decorate12([
1132
1596
  Global3(),
1133
- Module3({})
1597
+ Module4({})
1134
1598
  ], DatabaseModule);
1135
1599
 
1136
1600
  // src/database/decorators/tenant.decorator.ts
1137
- import { createParamDecorator as createParamDecorator5 } from "@nestjs/common";
1138
- var Tenant = createParamDecorator5((_data, ctx) => {
1601
+ import { createParamDecorator as createParamDecorator7 } from "@nestjs/common";
1602
+ var Tenant = createParamDecorator7((_data, ctx) => {
1139
1603
  const request = ctx.switchToHttp().getRequest();
1140
1604
  const tenantContext = request.app?.get?.(TenantContextService);
1141
1605
  if (!tenantContext) {
@@ -1148,17 +1612,17 @@ var Tenant = createParamDecorator5((_data, ctx) => {
1148
1612
  import { ApiPropertyOptional } from "@nestjs/swagger";
1149
1613
  import { Type } from "class-transformer";
1150
1614
  import { IsInt, IsOptional, IsString, Min } from "class-validator";
1151
- function _ts_decorate10(decorators, target, key, desc) {
1152
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1153
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1615
+ function _ts_decorate13(decorators, target, key, desc2) {
1616
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
1617
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
1154
1618
  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;
1155
1619
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1156
1620
  }
1157
- __name(_ts_decorate10, "_ts_decorate");
1158
- function _ts_metadata6(k, v) {
1621
+ __name(_ts_decorate13, "_ts_decorate");
1622
+ function _ts_metadata8(k, v) {
1159
1623
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1160
1624
  }
1161
- __name(_ts_metadata6, "_ts_metadata");
1625
+ __name(_ts_metadata8, "_ts_metadata");
1162
1626
  var SelectOptionsQueryDto = class {
1163
1627
  static {
1164
1628
  __name(this, "SelectOptionsQueryDto");
@@ -1170,18 +1634,19 @@ var SelectOptionsQueryDto = class {
1170
1634
  excludeIds;
1171
1635
  valueKey;
1172
1636
  labelKey;
1637
+ descriptionKey;
1173
1638
  groupIdKey;
1174
1639
  };
1175
- _ts_decorate10([
1640
+ _ts_decorate13([
1176
1641
  ApiPropertyOptional({
1177
1642
  description: "Search term to filter by label",
1178
1643
  example: "united"
1179
1644
  }),
1180
1645
  IsOptional(),
1181
1646
  IsString(),
1182
- _ts_metadata6("design:type", String)
1647
+ _ts_metadata8("design:type", String)
1183
1648
  ], SelectOptionsQueryDto.prototype, "search", void 0);
1184
- _ts_decorate10([
1649
+ _ts_decorate13([
1185
1650
  ApiPropertyOptional({
1186
1651
  description: "Maximum number of results",
1187
1652
  example: 20,
@@ -1191,9 +1656,9 @@ _ts_decorate10([
1191
1656
  Type(() => Number),
1192
1657
  IsInt(),
1193
1658
  Min(1),
1194
- _ts_metadata6("design:type", Number)
1659
+ _ts_metadata8("design:type", Number)
1195
1660
  ], SelectOptionsQueryDto.prototype, "limit", void 0);
1196
- _ts_decorate10([
1661
+ _ts_decorate13([
1197
1662
  ApiPropertyOptional({
1198
1663
  description: "Number of results to skip",
1199
1664
  example: 0,
@@ -1203,27 +1668,27 @@ _ts_decorate10([
1203
1668
  Type(() => Number),
1204
1669
  IsInt(),
1205
1670
  Min(0),
1206
- _ts_metadata6("design:type", Number)
1671
+ _ts_metadata8("design:type", Number)
1207
1672
  ], SelectOptionsQueryDto.prototype, "offset", void 0);
1208
- _ts_decorate10([
1673
+ _ts_decorate13([
1209
1674
  ApiPropertyOptional({
1210
1675
  description: "Comma-separated values to fetch specific options",
1211
1676
  example: "1,2,3"
1212
1677
  }),
1213
1678
  IsOptional(),
1214
1679
  IsString(),
1215
- _ts_metadata6("design:type", String)
1680
+ _ts_metadata8("design:type", String)
1216
1681
  ], SelectOptionsQueryDto.prototype, "values", void 0);
1217
- _ts_decorate10([
1682
+ _ts_decorate13([
1218
1683
  ApiPropertyOptional({
1219
1684
  description: "Comma-separated IDs to exclude from results (already selected)",
1220
1685
  example: "5,10"
1221
1686
  }),
1222
1687
  IsOptional(),
1223
1688
  IsString(),
1224
- _ts_metadata6("design:type", String)
1689
+ _ts_metadata8("design:type", String)
1225
1690
  ], SelectOptionsQueryDto.prototype, "excludeIds", void 0);
1226
- _ts_decorate10([
1691
+ _ts_decorate13([
1227
1692
  ApiPropertyOptional({
1228
1693
  description: "Column name for option value",
1229
1694
  example: "id",
@@ -1231,9 +1696,9 @@ _ts_decorate10([
1231
1696
  }),
1232
1697
  IsOptional(),
1233
1698
  IsString(),
1234
- _ts_metadata6("design:type", String)
1699
+ _ts_metadata8("design:type", String)
1235
1700
  ], SelectOptionsQueryDto.prototype, "valueKey", void 0);
1236
- _ts_decorate10([
1701
+ _ts_decorate13([
1237
1702
  ApiPropertyOptional({
1238
1703
  description: "Column name for option label",
1239
1704
  example: "name",
@@ -1241,21 +1706,193 @@ _ts_decorate10([
1241
1706
  }),
1242
1707
  IsOptional(),
1243
1708
  IsString(),
1244
- _ts_metadata6("design:type", String)
1709
+ _ts_metadata8("design:type", String)
1245
1710
  ], SelectOptionsQueryDto.prototype, "labelKey", void 0);
1246
- _ts_decorate10([
1711
+ _ts_decorate13([
1712
+ ApiPropertyOptional({
1713
+ description: "Column name for option description",
1714
+ example: "description"
1715
+ }),
1716
+ IsOptional(),
1717
+ IsString(),
1718
+ _ts_metadata8("design:type", String)
1719
+ ], SelectOptionsQueryDto.prototype, "descriptionKey", void 0);
1720
+ _ts_decorate13([
1247
1721
  ApiPropertyOptional({
1248
1722
  description: "Column name for group ID",
1249
1723
  example: "regionId"
1250
1724
  }),
1251
1725
  IsOptional(),
1252
1726
  IsString(),
1253
- _ts_metadata6("design:type", String)
1727
+ _ts_metadata8("design:type", String)
1254
1728
  ], SelectOptionsQueryDto.prototype, "groupIdKey", void 0);
1255
1729
 
1730
+ // src/database/dto/success-response.dto.ts
1731
+ import { ApiProperty } from "@nestjs/swagger";
1732
+ import { IsBoolean, IsNotEmpty, IsString as IsString2 } from "class-validator";
1733
+ function _ts_decorate14(decorators, target, key, desc2) {
1734
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
1735
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
1736
+ 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;
1737
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1738
+ }
1739
+ __name(_ts_decorate14, "_ts_decorate");
1740
+ function _ts_metadata9(k, v) {
1741
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1742
+ }
1743
+ __name(_ts_metadata9, "_ts_metadata");
1744
+ var SuccessResponseDto = class {
1745
+ static {
1746
+ __name(this, "SuccessResponseDto");
1747
+ }
1748
+ success;
1749
+ message;
1750
+ };
1751
+ _ts_decorate14([
1752
+ ApiProperty({
1753
+ example: true
1754
+ }),
1755
+ IsNotEmpty(),
1756
+ IsBoolean(),
1757
+ _ts_metadata9("design:type", Boolean)
1758
+ ], SuccessResponseDto.prototype, "success", void 0);
1759
+ _ts_decorate14([
1760
+ ApiProperty({
1761
+ example: "Operation completed successfully"
1762
+ }),
1763
+ IsNotEmpty(),
1764
+ IsString2(),
1765
+ _ts_metadata9("design:type", String)
1766
+ ], SuccessResponseDto.prototype, "message", void 0);
1767
+
1768
+ // src/database/dto/table-response.dto.ts
1769
+ import { ApiProperty as ApiProperty2, ApiPropertyOptional as ApiPropertyOptional2 } from "@nestjs/swagger";
1770
+ function _ts_decorate15(decorators, target, key, desc2) {
1771
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
1772
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
1773
+ 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;
1774
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1775
+ }
1776
+ __name(_ts_decorate15, "_ts_decorate");
1777
+ function _ts_metadata10(k, v) {
1778
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1779
+ }
1780
+ __name(_ts_metadata10, "_ts_metadata");
1781
+ var TableResponseDto = class {
1782
+ static {
1783
+ __name(this, "TableResponseDto");
1784
+ }
1785
+ result;
1786
+ count;
1787
+ state;
1788
+ activeViewId;
1789
+ };
1790
+ _ts_decorate15([
1791
+ ApiProperty2(),
1792
+ _ts_metadata10("design:type", Array)
1793
+ ], TableResponseDto.prototype, "result", void 0);
1794
+ _ts_decorate15([
1795
+ ApiProperty2(),
1796
+ _ts_metadata10("design:type", Number)
1797
+ ], TableResponseDto.prototype, "count", void 0);
1798
+ _ts_decorate15([
1799
+ ApiProperty2(),
1800
+ _ts_metadata10("design:type", typeof TableViewState === "undefined" ? Object : TableViewState)
1801
+ ], TableResponseDto.prototype, "state", void 0);
1802
+ _ts_decorate15([
1803
+ ApiPropertyOptional2({
1804
+ nullable: true
1805
+ }),
1806
+ _ts_metadata10("design:type", Object)
1807
+ ], TableResponseDto.prototype, "activeViewId", void 0);
1808
+
1809
+ // src/database/filter/filter.processor.ts
1810
+ import { and, asc, desc, eq as eq2, gt, gte, ilike, lt, lte, ne, notIlike, or as or2 } from "drizzle-orm";
1811
+ var FilterProcessor = class {
1812
+ static {
1813
+ __name(this, "FilterProcessor");
1814
+ }
1815
+ // Returns undefined if no conditions (Drizzle accepts undefined as "no WHERE")
1816
+ static buildWhere(filters = [], fieldMap) {
1817
+ const conditions = filters.flatMap((f) => {
1818
+ const def = fieldMap[f.field];
1819
+ if (!def) return [];
1820
+ if ("expression" in def) return [
1821
+ def.expression(f.value)
1822
+ ];
1823
+ const { column: col } = def;
1824
+ const val = f.value;
1825
+ switch (f.operator) {
1826
+ case "equals":
1827
+ if (def.type === "boolean") return [
1828
+ eq2(col, val === "true" || val === 1)
1829
+ ];
1830
+ return [
1831
+ eq2(col, val)
1832
+ ];
1833
+ case "notEquals":
1834
+ if (def.type === "boolean") return [
1835
+ ne(col, val === "true" || val === 1)
1836
+ ];
1837
+ return [
1838
+ ne(col, val)
1839
+ ];
1840
+ case "contains":
1841
+ return [
1842
+ ilike(col, `%${val}%`)
1843
+ ];
1844
+ case "notContains":
1845
+ return [
1846
+ notIlike(col, `%${val}%`)
1847
+ ];
1848
+ case "gt":
1849
+ return [
1850
+ gt(col, val)
1851
+ ];
1852
+ case "gte":
1853
+ return [
1854
+ gte(col, val)
1855
+ ];
1856
+ case "lt":
1857
+ return [
1858
+ lt(col, val)
1859
+ ];
1860
+ case "lte":
1861
+ return [
1862
+ lte(col, val)
1863
+ ];
1864
+ default:
1865
+ return [];
1866
+ }
1867
+ });
1868
+ return conditions.length ? and(...conditions) : void 0;
1869
+ }
1870
+ // Builds a search WHERE — OR across all string fields when columnId is 'all', otherwise a single ilike
1871
+ static buildSearch(search, fieldMap) {
1872
+ if (!search?.value) return void 0;
1873
+ if (search.columnId === "all") {
1874
+ const conditions = Object.values(fieldMap).filter((def2) => "column" in def2 && def2.type === "string").map((def2) => ilike(def2.column, `%${search.value}%`));
1875
+ return conditions.length ? or2(...conditions) : void 0;
1876
+ }
1877
+ const def = fieldMap[search.columnId];
1878
+ if (!def || !("column" in def)) return void 0;
1879
+ return ilike(def.column, `%${search.value}%`);
1880
+ }
1881
+ // Maps each SortCondition to an asc/desc SQL expression
1882
+ static buildOrderBy(sort = [], fieldMap) {
1883
+ return sort.flatMap((s) => {
1884
+ const def = fieldMap[s.field];
1885
+ if (!def || !("column" in def)) return [];
1886
+ return [
1887
+ s.direction === "asc" ? asc(def.column) : desc(def.column)
1888
+ ];
1889
+ });
1890
+ }
1891
+ };
1892
+
1256
1893
  // src/database/repositories/primary-base.repository.ts
1257
- import { Logger as Logger6 } from "@nestjs/common";
1258
- import { and, asc, eq as eq2, getTableName, ilike, inArray, notInArray, sql } from "drizzle-orm";
1894
+ import { Logger as Logger8 } from "@nestjs/common";
1895
+ import { and as and2, asc as asc2, eq as eq3, getTableName, ilike as ilike2, inArray, notInArray, sql } from "drizzle-orm";
1259
1896
  function snakeToCamel(str) {
1260
1897
  return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
1261
1898
  }
@@ -1286,7 +1923,7 @@ var PrimaryBaseRepository = class {
1286
1923
  this.table = table;
1287
1924
  const dbTableName = getTableName(table);
1288
1925
  this.tableName = snakeToCamel(dbTableName);
1289
- this.logger = new Logger6(this.constructor.name);
1926
+ this.logger = new Logger8(this.constructor.name);
1290
1927
  this.logger.debug(`Initialized ${this.constructor.name}`);
1291
1928
  this.logger.debug(`Table name: '${dbTableName}' -> query key: '${this.tableName}'`);
1292
1929
  }
@@ -1319,12 +1956,32 @@ var PrimaryBaseRepository = class {
1319
1956
  this.logger.debug("Finding multiple records");
1320
1957
  return this.model.findMany(options);
1321
1958
  }
1959
+ // Builds a select query with optional custom fields, join, filter, ordering, and pagination
1960
+ buildSelectQuery(options) {
1961
+ const base = options?.select ? this.db.select(options.select).from(this.table) : this.db.select().from(this.table);
1962
+ const joined = options?.leftJoin ? base.leftJoin(options.leftJoin.table, options.leftJoin.on) : base;
1963
+ const filtered = options?.where ? joined.where(options.where) : joined;
1964
+ const ordered = options?.orderBy?.length ? filtered.orderBy(...options.orderBy) : filtered;
1965
+ const limited = options?.limit ? ordered.limit(options.limit) : ordered;
1966
+ return options?.offset ? limited.offset(options.offset) : limited;
1967
+ }
1968
+ // Returns paginated result and total count, with optional custom select, LEFT JOIN, and ordering
1969
+ async findAllAndCount(options) {
1970
+ const [count, result] = await Promise.all([
1971
+ this.count(options?.where),
1972
+ this.buildSelectQuery(options)
1973
+ ]);
1974
+ return {
1975
+ result,
1976
+ count
1977
+ };
1978
+ }
1322
1979
  // Updates a record by ID and returns the updated record
1323
1980
  async update(id, data) {
1324
1981
  this.logger.log(`Updating record with ID: ${id}`);
1325
1982
  const idColumn = this.table.id;
1326
1983
  if (!idColumn) throw new Error(`Table '${this.tableName}' has no 'id' column`);
1327
- const results = await this.db.update(this.table).set(data).where(eq2(idColumn, id)).returning();
1984
+ const results = await this.db.update(this.table).set(data).where(eq3(idColumn, id)).returning();
1328
1985
  const record = results[0];
1329
1986
  if (!record) throw new Error(`${this.tableName}: database operation returned no record`);
1330
1987
  return record;
@@ -1342,7 +1999,7 @@ var PrimaryBaseRepository = class {
1342
1999
  this.logger.log(`Deleting record with ID: ${id}`);
1343
2000
  const idColumn = this.table.id;
1344
2001
  if (!idColumn) throw new Error(`Table '${this.tableName}' has no 'id' column`);
1345
- const results = await this.db.delete(this.table).where(eq2(idColumn, id)).returning();
2002
+ const results = await this.db.delete(this.table).where(eq3(idColumn, id)).returning();
1346
2003
  const record = results[0];
1347
2004
  if (!record) throw new Error(`${this.tableName}: database operation returned no record`);
1348
2005
  return record;
@@ -1382,20 +2039,44 @@ var PrimaryBaseRepository = class {
1382
2039
  if (!valueCol) throw new Error(`Column '${config.value}' not found in table '${this.tableName}'`);
1383
2040
  const labelCol = tableColumns[config.label];
1384
2041
  if (!labelCol) throw new Error(`Column '${config.label}' not found in table '${this.tableName}'`);
2042
+ let descriptionCol = config.description ? tableColumns[config.description] : void 0;
2043
+ if (!descriptionCol && config.description && config.joins) {
2044
+ for (const join of config.joins) {
2045
+ const joinCols = join.table;
2046
+ if (joinCols[config.description]) {
2047
+ descriptionCol = joinCols[config.description];
2048
+ break;
2049
+ }
2050
+ }
2051
+ }
1385
2052
  if (parsedValues && parsedValues.length > 0) {
1386
2053
  const selectCols = {
1387
2054
  value: valueCol,
1388
2055
  label: labelCol
1389
2056
  };
2057
+ if (descriptionCol) selectCols.description = descriptionCol;
1390
2058
  if (config.groupId) {
1391
2059
  const groupIdCol = tableColumns[config.groupId];
1392
2060
  if (groupIdCol) selectCols.groupId = groupIdCol;
1393
2061
  }
1394
- const rows2 = await this.db.select(selectCols).from(this.table).where(inArray(valueCol, parsedValues));
2062
+ let valuesQuery = this.db.select(selectCols).from(this.table).$dynamic();
2063
+ if (config.joins) {
2064
+ for (const join of config.joins) {
2065
+ if (join.type === "inner") {
2066
+ valuesQuery = valuesQuery.innerJoin(join.table, join.on);
2067
+ } else {
2068
+ valuesQuery = valuesQuery.leftJoin(join.table, join.on);
2069
+ }
2070
+ }
2071
+ }
2072
+ const rows2 = await valuesQuery.where(inArray(valueCol, parsedValues));
1395
2073
  return {
1396
2074
  options: rows2.map((row) => ({
1397
2075
  value: row.value,
1398
2076
  label: String(row.label),
2077
+ ...descriptionCol && row.description != null ? {
2078
+ description: row.description
2079
+ } : {},
1399
2080
  ...config.groupId && row.groupId != null ? {
1400
2081
  groupId: row.groupId
1401
2082
  } : {}
@@ -1411,13 +2092,14 @@ var PrimaryBaseRepository = class {
1411
2092
  label: labelCol,
1412
2093
  totalCount: sql`count(*) over()`.mapWith(Number)
1413
2094
  };
2095
+ if (descriptionCol) selectFields.description = descriptionCol;
1414
2096
  if (config.groupId) {
1415
2097
  const groupIdCol = tableColumns[config.groupId];
1416
2098
  if (groupIdCol) selectFields.groupId = groupIdCol;
1417
2099
  }
1418
2100
  const conditions = [];
1419
2101
  if (config.search) {
1420
- conditions.push(ilike(labelCol, `%${config.search}%`));
2102
+ conditions.push(ilike2(labelCol, `%${config.search}%`));
1421
2103
  }
1422
2104
  if (parsedExcludeIds.length > 0) {
1423
2105
  conditions.push(notInArray(valueCol, parsedExcludeIds));
@@ -1426,30 +2108,45 @@ var PrimaryBaseRepository = class {
1426
2108
  for (const [field, val] of Object.entries(config.where)) {
1427
2109
  const column = tableColumns[field];
1428
2110
  if (column) {
1429
- conditions.push(eq2(column, val));
2111
+ conditions.push(eq3(column, val));
1430
2112
  }
1431
2113
  }
1432
2114
  }
2115
+ if (config.conditions) {
2116
+ conditions.push(...config.conditions);
2117
+ }
1433
2118
  const orderByKey = config.orderBy ? Object.keys(config.orderBy)[0] : void 0;
1434
2119
  const orderByCol = orderByKey ? tableColumns[orderByKey] ?? labelCol : labelCol;
1435
2120
  const limit = Number(config.limit) || 20;
1436
2121
  const offset = Number(config.offset) || 0;
1437
2122
  let query = this.db.select(selectFields).from(this.table).$dynamic();
2123
+ if (config.joins) {
2124
+ for (const join of config.joins) {
2125
+ if (join.type === "inner") {
2126
+ query = query.innerJoin(join.table, join.on);
2127
+ } else {
2128
+ query = query.leftJoin(join.table, join.on);
2129
+ }
2130
+ }
2131
+ }
1438
2132
  if (conditions.length > 0) {
1439
- query = query.where(conditions.length === 1 ? conditions[0] : and(...conditions));
2133
+ query = query.where(conditions.length === 1 ? conditions[0] : and2(...conditions));
1440
2134
  }
1441
2135
  const orderClauses = [];
1442
2136
  if (config.groupId) {
1443
2137
  const groupIdCol = tableColumns[config.groupId];
1444
- if (groupIdCol) orderClauses.push(asc(groupIdCol));
2138
+ if (groupIdCol) orderClauses.push(asc2(groupIdCol));
1445
2139
  }
1446
- orderClauses.push(asc(orderByCol));
2140
+ orderClauses.push(asc2(orderByCol));
1447
2141
  query = query.orderBy(...orderClauses).limit(limit).offset(offset);
1448
2142
  const rows = await query;
1449
2143
  const totalCount = rows.length > 0 ? rows[0].totalCount : 0;
1450
2144
  const options = rows.map((row) => ({
1451
2145
  value: row.value,
1452
2146
  label: String(row.label),
2147
+ ...descriptionCol && row.description != null ? {
2148
+ description: row.description
2149
+ } : {},
1453
2150
  ...config.groupId && row.groupId != null ? {
1454
2151
  groupId: row.groupId
1455
2152
  } : {}
@@ -1466,7 +2163,7 @@ var PrimaryBaseRepository = class {
1466
2163
  const groupRows = await this.db.select({
1467
2164
  id: groupIdCol,
1468
2165
  name: groupNameCol
1469
- }).from(config.groupTable).orderBy(asc(groupNameCol));
2166
+ }).from(config.groupTable).orderBy(asc2(groupNameCol));
1470
2167
  resolvedGroups = groupRows.map((r) => ({
1471
2168
  id: r.id,
1472
2169
  name: String(r.name)
@@ -1484,8 +2181,8 @@ var PrimaryBaseRepository = class {
1484
2181
  };
1485
2182
 
1486
2183
  // src/database/repositories/tenant-base.repository.ts
1487
- import { Logger as Logger7 } from "@nestjs/common";
1488
- import { and as and2, asc as asc2, eq as eq3, getTableName as getTableName2, ilike as ilike2, inArray as inArray2, notInArray as notInArray2, sql as sql2 } from "drizzle-orm";
2184
+ import { Logger as Logger9 } from "@nestjs/common";
2185
+ import { and as and3, asc as asc3, eq as eq4, getTableName as getTableName2, ilike as ilike3, inArray as inArray2, notInArray as notInArray2, sql as sql2 } from "drizzle-orm";
1489
2186
  var TenantBaseRepository = class {
1490
2187
  static {
1491
2188
  __name(this, "TenantBaseRepository");
@@ -1504,7 +2201,7 @@ var TenantBaseRepository = class {
1504
2201
  this.database = database;
1505
2202
  this.table = table;
1506
2203
  this.tableName = getTableName2(table);
1507
- this.logger = new Logger7(this.constructor.name);
2204
+ this.logger = new Logger9(this.constructor.name);
1508
2205
  this.logger.debug(`Initialized ${this.constructor.name}`);
1509
2206
  }
1510
2207
  // Creates a new record and returns it
@@ -1520,7 +2217,7 @@ var TenantBaseRepository = class {
1520
2217
  this.logger.debug(`Finding record by ID: ${id}`);
1521
2218
  const idColumn = this.table.id;
1522
2219
  if (!idColumn) throw new Error(`Table '${this.tableName}' has no 'id' column`);
1523
- const results = await this.db.select().from(this.table).where(eq3(idColumn, id)).limit(1);
2220
+ const results = await this.db.select().from(this.table).where(eq4(idColumn, id)).limit(1);
1524
2221
  return results[0] ?? null;
1525
2222
  }
1526
2223
  // Finds a single record matching the given SQL condition
@@ -1552,7 +2249,7 @@ var TenantBaseRepository = class {
1552
2249
  this.logger.log(`Updating record with ID: ${id}`);
1553
2250
  const idColumn = this.table.id;
1554
2251
  if (!idColumn) throw new Error(`Table '${this.tableName}' has no 'id' column`);
1555
- const results = await this.db.update(this.table).set(data).where(eq3(idColumn, id)).returning();
2252
+ const results = await this.db.update(this.table).set(data).where(eq4(idColumn, id)).returning();
1556
2253
  const record = results[0];
1557
2254
  if (!record) throw new Error(`${this.tableName}: database operation returned no record`);
1558
2255
  return record;
@@ -1570,7 +2267,7 @@ var TenantBaseRepository = class {
1570
2267
  this.logger.log(`Deleting record with ID: ${id}`);
1571
2268
  const idColumn = this.table.id;
1572
2269
  if (!idColumn) throw new Error(`Table '${this.tableName}' has no 'id' column`);
1573
- const results = await this.db.delete(this.table).where(eq3(idColumn, id)).returning();
2270
+ const results = await this.db.delete(this.table).where(eq4(idColumn, id)).returning();
1574
2271
  const record = results[0];
1575
2272
  if (!record) throw new Error(`${this.tableName}: database operation returned no record`);
1576
2273
  return record;
@@ -1645,7 +2342,7 @@ var TenantBaseRepository = class {
1645
2342
  }
1646
2343
  const conditions = [];
1647
2344
  if (config.search) {
1648
- conditions.push(ilike2(labelCol, `%${config.search}%`));
2345
+ conditions.push(ilike3(labelCol, `%${config.search}%`));
1649
2346
  }
1650
2347
  if (parsedExcludeIds.length > 0) {
1651
2348
  conditions.push(notInArray2(valueCol, parsedExcludeIds));
@@ -1654,7 +2351,7 @@ var TenantBaseRepository = class {
1654
2351
  for (const [field, val] of Object.entries(config.where)) {
1655
2352
  const column = tableColumns[field];
1656
2353
  if (column) {
1657
- conditions.push(eq3(column, val));
2354
+ conditions.push(eq4(column, val));
1658
2355
  }
1659
2356
  }
1660
2357
  }
@@ -1664,14 +2361,14 @@ var TenantBaseRepository = class {
1664
2361
  const offset = Number(config.offset) || 0;
1665
2362
  let query = this.db.select(selectFields).from(this.table).$dynamic();
1666
2363
  if (conditions.length > 0) {
1667
- query = query.where(conditions.length === 1 ? conditions[0] : and2(...conditions));
2364
+ query = query.where(conditions.length === 1 ? conditions[0] : and3(...conditions));
1668
2365
  }
1669
2366
  const orderClauses = [];
1670
2367
  if (config.groupId) {
1671
2368
  const groupIdCol = tableColumns[config.groupId];
1672
- if (groupIdCol) orderClauses.push(asc2(groupIdCol));
2369
+ if (groupIdCol) orderClauses.push(asc3(groupIdCol));
1673
2370
  }
1674
- orderClauses.push(asc2(orderByCol));
2371
+ orderClauses.push(asc3(orderByCol));
1675
2372
  query = query.orderBy(...orderClauses).limit(limit).offset(offset);
1676
2373
  const rows = await query;
1677
2374
  const totalCount = rows.length > 0 ? rows[0].totalCount : 0;
@@ -1694,7 +2391,7 @@ var TenantBaseRepository = class {
1694
2391
  const groupRows = await this.db.select({
1695
2392
  id: groupIdCol,
1696
2393
  name: groupNameCol
1697
- }).from(config.groupTable).orderBy(asc2(groupNameCol));
2394
+ }).from(config.groupTable).orderBy(asc3(groupNameCol));
1698
2395
  resolvedGroups = groupRows.map((r) => ({
1699
2396
  id: r.id,
1700
2397
  name: String(r.name)
@@ -1712,30 +2409,30 @@ var TenantBaseRepository = class {
1712
2409
  };
1713
2410
 
1714
2411
  // src/email/email.module.ts
1715
- import { Global as Global4, Module as Module4 } from "@nestjs/common";
1716
- import { ConfigModule as ConfigModule2 } from "@nestjs/config";
2412
+ import { Global as Global4, Module as Module5 } from "@nestjs/common";
2413
+ import { ConfigModule as ConfigModule3 } from "@nestjs/config";
1717
2414
 
1718
2415
  // src/email/email.service.ts
1719
2416
  import { BrevoClient, BrevoError, BrevoTimeoutError } from "@getbrevo/brevo";
1720
- import { Injectable as Injectable7, Logger as Logger8 } from "@nestjs/common";
1721
- import { ConfigService as ConfigService4 } from "@nestjs/config";
1722
- function _ts_decorate11(decorators, target, key, desc) {
1723
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1724
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2417
+ import { Injectable as Injectable9, Logger as Logger10 } from "@nestjs/common";
2418
+ import { ConfigService as ConfigService5 } from "@nestjs/config";
2419
+ function _ts_decorate16(decorators, target, key, desc2) {
2420
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
2421
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
1725
2422
  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;
1726
2423
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1727
2424
  }
1728
- __name(_ts_decorate11, "_ts_decorate");
1729
- function _ts_metadata7(k, v) {
2425
+ __name(_ts_decorate16, "_ts_decorate");
2426
+ function _ts_metadata11(k, v) {
1730
2427
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1731
2428
  }
1732
- __name(_ts_metadata7, "_ts_metadata");
2429
+ __name(_ts_metadata11, "_ts_metadata");
1733
2430
  var EmailService = class _EmailService {
1734
2431
  static {
1735
2432
  __name(this, "EmailService");
1736
2433
  }
1737
2434
  configService;
1738
- logger = new Logger8(_EmailService.name);
2435
+ logger = new Logger10(_EmailService.name);
1739
2436
  brevoClient;
1740
2437
  senderEmail;
1741
2438
  senderName;
@@ -2232,32 +2929,32 @@ This is an automated message, please do not reply.
2232
2929
  }
2233
2930
  }
2234
2931
  };
2235
- EmailService = _ts_decorate11([
2236
- Injectable7(),
2237
- _ts_metadata7("design:type", Function),
2238
- _ts_metadata7("design:paramtypes", [
2239
- typeof ConfigService4 === "undefined" ? Object : ConfigService4
2932
+ EmailService = _ts_decorate16([
2933
+ Injectable9(),
2934
+ _ts_metadata11("design:type", Function),
2935
+ _ts_metadata11("design:paramtypes", [
2936
+ typeof ConfigService5 === "undefined" ? Object : ConfigService5
2240
2937
  ])
2241
2938
  ], EmailService);
2242
2939
 
2243
2940
  // src/email/email.module.ts
2244
- function _ts_decorate12(decorators, target, key, desc) {
2245
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2246
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2941
+ function _ts_decorate17(decorators, target, key, desc2) {
2942
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
2943
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
2247
2944
  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;
2248
2945
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2249
2946
  }
2250
- __name(_ts_decorate12, "_ts_decorate");
2947
+ __name(_ts_decorate17, "_ts_decorate");
2251
2948
  var EmailModule = class {
2252
2949
  static {
2253
2950
  __name(this, "EmailModule");
2254
2951
  }
2255
2952
  };
2256
- EmailModule = _ts_decorate12([
2953
+ EmailModule = _ts_decorate17([
2257
2954
  Global4(),
2258
- Module4({
2955
+ Module5({
2259
2956
  imports: [
2260
- ConfigModule2
2957
+ ConfigModule3
2261
2958
  ],
2262
2959
  providers: [
2263
2960
  EmailService
@@ -2268,234 +2965,15 @@ EmailModule = _ts_decorate12([
2268
2965
  })
2269
2966
  ], EmailModule);
2270
2967
 
2271
- // src/exceptions/bad-gateway.exception.ts
2272
- import { HttpStatus } from "@nestjs/common";
2273
-
2274
- // src/exceptions/base-field.exception.ts
2275
- import { HttpException } from "@nestjs/common";
2276
- var HttpProblemException = class extends HttpException {
2277
- static {
2278
- __name(this, "HttpProblemException");
2279
- }
2280
- constructor(detailOrOptions, httpStatus) {
2281
- const options = typeof detailOrOptions === "string" ? {
2282
- detail: detailOrOptions
2283
- } : detailOrOptions;
2284
- super({
2285
- type: options.type ?? "about:blank",
2286
- label: options.label,
2287
- detail: options.detail,
2288
- errors: options.errors ?? []
2289
- }, httpStatus);
2290
- }
2291
- };
2292
-
2293
- // src/exceptions/bad-gateway.exception.ts
2294
- var BadGatewayException = class extends HttpProblemException {
2295
- static {
2296
- __name(this, "BadGatewayException");
2297
- }
2298
- constructor(detailOrOptions) {
2299
- super(detailOrOptions ?? "Bad Gateway", HttpStatus.BAD_GATEWAY);
2300
- }
2301
- };
2302
-
2303
- // src/exceptions/bad-request.exception.ts
2304
- import { HttpStatus as HttpStatus2 } from "@nestjs/common";
2305
- var BadRequestException = class extends HttpProblemException {
2306
- static {
2307
- __name(this, "BadRequestException");
2308
- }
2309
- constructor(detailOrOptions) {
2310
- super(detailOrOptions ?? "Bad Request", HttpStatus2.BAD_REQUEST);
2311
- }
2312
- };
2313
-
2314
- // src/exceptions/conflict.exception.ts
2315
- import { HttpStatus as HttpStatus3 } from "@nestjs/common";
2316
- var ConflictException = class extends HttpProblemException {
2317
- static {
2318
- __name(this, "ConflictException");
2319
- }
2320
- constructor(detailOrOptions) {
2321
- super(detailOrOptions ?? "Conflict", HttpStatus3.CONFLICT);
2322
- }
2323
- };
2324
-
2325
- // src/exceptions/forbidden.exception.ts
2326
- import { HttpStatus as HttpStatus4 } from "@nestjs/common";
2327
- var ForbiddenException2 = class extends HttpProblemException {
2328
- static {
2329
- __name(this, "ForbiddenException");
2330
- }
2331
- constructor(detailOrOptions) {
2332
- super(detailOrOptions ?? "Forbidden", HttpStatus4.FORBIDDEN);
2333
- }
2334
- };
2335
-
2336
- // src/exceptions/gone.exception.ts
2337
- import { HttpStatus as HttpStatus5 } from "@nestjs/common";
2338
- var GoneException = class extends HttpProblemException {
2339
- static {
2340
- __name(this, "GoneException");
2341
- }
2342
- constructor(detailOrOptions) {
2343
- super(detailOrOptions ?? "Gone", HttpStatus5.GONE);
2344
- }
2345
- };
2346
-
2347
- // src/exceptions/internal-server-error.exception.ts
2348
- import { HttpStatus as HttpStatus6 } from "@nestjs/common";
2349
- var InternalServerErrorException3 = class extends HttpProblemException {
2350
- static {
2351
- __name(this, "InternalServerErrorException");
2352
- }
2353
- constructor(detailOrOptions) {
2354
- super(detailOrOptions ?? "Internal Server Error", HttpStatus6.INTERNAL_SERVER_ERROR);
2355
- }
2356
- };
2357
-
2358
- // src/exceptions/method-not-allowed.exception.ts
2359
- import { HttpStatus as HttpStatus7 } from "@nestjs/common";
2360
- var MethodNotAllowedException = class extends HttpProblemException {
2361
- static {
2362
- __name(this, "MethodNotAllowedException");
2363
- }
2364
- constructor(detailOrOptions) {
2365
- super(detailOrOptions ?? "Method Not Allowed", HttpStatus7.METHOD_NOT_ALLOWED);
2366
- }
2367
- };
2368
-
2369
- // src/exceptions/not-acceptable.exception.ts
2370
- import { HttpStatus as HttpStatus8 } from "@nestjs/common";
2371
- var NotAcceptableException = class extends HttpProblemException {
2372
- static {
2373
- __name(this, "NotAcceptableException");
2374
- }
2375
- constructor(detailOrOptions) {
2376
- super(detailOrOptions ?? "Not Acceptable", HttpStatus8.NOT_ACCEPTABLE);
2377
- }
2378
- };
2379
-
2380
- // src/exceptions/not-found.exception.ts
2381
- import { HttpStatus as HttpStatus9 } from "@nestjs/common";
2382
- var NotFoundException = class extends HttpProblemException {
2383
- static {
2384
- __name(this, "NotFoundException");
2385
- }
2386
- constructor(detailOrOptions) {
2387
- super(detailOrOptions ?? "Not Found", HttpStatus9.NOT_FOUND);
2388
- }
2389
- };
2390
-
2391
- // src/exceptions/not-implemented.exception.ts
2392
- import { HttpStatus as HttpStatus10 } from "@nestjs/common";
2393
- var NotImplementedException = class extends HttpProblemException {
2394
- static {
2395
- __name(this, "NotImplementedException");
2396
- }
2397
- constructor(detailOrOptions) {
2398
- super(detailOrOptions ?? "Not Implemented", HttpStatus10.NOT_IMPLEMENTED);
2399
- }
2400
- };
2401
-
2402
- // src/exceptions/payload-too-large.exception.ts
2403
- import { HttpStatus as HttpStatus11 } from "@nestjs/common";
2404
- var PayloadTooLargeException = class extends HttpProblemException {
2405
- static {
2406
- __name(this, "PayloadTooLargeException");
2407
- }
2408
- constructor(detailOrOptions) {
2409
- super(detailOrOptions ?? "Payload Too Large", HttpStatus11.PAYLOAD_TOO_LARGE);
2410
- }
2411
- };
2412
-
2413
- // src/exceptions/request-timeout.exception.ts
2414
- import { HttpStatus as HttpStatus12 } from "@nestjs/common";
2415
- var RequestTimeoutException = class extends HttpProblemException {
2416
- static {
2417
- __name(this, "RequestTimeoutException");
2418
- }
2419
- constructor(detailOrOptions) {
2420
- super(detailOrOptions ?? "Request Timeout", HttpStatus12.REQUEST_TIMEOUT);
2421
- }
2422
- };
2423
-
2424
- // src/exceptions/service-unavailable.exception.ts
2425
- import { HttpStatus as HttpStatus13 } from "@nestjs/common";
2426
- var ServiceUnavailableException = class extends HttpProblemException {
2427
- static {
2428
- __name(this, "ServiceUnavailableException");
2429
- }
2430
- constructor(detailOrOptions) {
2431
- super(detailOrOptions ?? "Service Unavailable", HttpStatus13.SERVICE_UNAVAILABLE);
2432
- }
2433
- };
2434
-
2435
- // src/exceptions/too-many-requests.exception.ts
2436
- import { HttpStatus as HttpStatus14 } from "@nestjs/common";
2437
- var TooManyRequestsException = class extends HttpProblemException {
2438
- static {
2439
- __name(this, "TooManyRequestsException");
2440
- }
2441
- constructor(detailOrOptions) {
2442
- super(detailOrOptions ?? "Too Many Requests", HttpStatus14.TOO_MANY_REQUESTS);
2443
- }
2444
- };
2445
-
2446
- // src/exceptions/unauthorized.exception.ts
2447
- import { HttpStatus as HttpStatus15 } from "@nestjs/common";
2448
- var UnauthorizedException3 = class extends HttpProblemException {
2449
- static {
2450
- __name(this, "UnauthorizedException");
2451
- }
2452
- constructor(detailOrOptions) {
2453
- super(detailOrOptions ?? "Unauthorized", HttpStatus15.UNAUTHORIZED);
2454
- }
2455
- };
2456
-
2457
- // src/exceptions/unprocessable-entity.exception.ts
2458
- import { HttpStatus as HttpStatus16 } from "@nestjs/common";
2459
- var UnprocessableEntityException = class extends HttpProblemException {
2460
- static {
2461
- __name(this, "UnprocessableEntityException");
2462
- }
2463
- constructor(detailOrOptions) {
2464
- super(detailOrOptions ?? "Unprocessable Entity", HttpStatus16.UNPROCESSABLE_ENTITY);
2465
- }
2466
- };
2467
-
2468
- // src/exceptions/unsupported-media-type.exception.ts
2469
- import { HttpStatus as HttpStatus17 } from "@nestjs/common";
2470
- var UnsupportedMediaTypeException = class extends HttpProblemException {
2471
- static {
2472
- __name(this, "UnsupportedMediaTypeException");
2473
- }
2474
- constructor(detailOrOptions) {
2475
- super(detailOrOptions ?? "Unsupported Media Type", HttpStatus17.UNSUPPORTED_MEDIA_TYPE);
2476
- }
2477
- };
2478
-
2479
- // src/exceptions/validation.exception.ts
2480
- import { HttpStatus as HttpStatus18 } from "@nestjs/common";
2481
- var ValidationException = class extends HttpProblemException {
2482
- static {
2483
- __name(this, "ValidationException");
2484
- }
2485
- constructor(detailOrOptions) {
2486
- super(detailOrOptions ?? "Validation Failed", HttpStatus18.BAD_REQUEST);
2487
- }
2488
- };
2489
-
2490
2968
  // src/filters/http-exception.filter.ts
2491
- import { Catch, HttpException as HttpException2, HttpStatus as HttpStatus19, Logger as Logger9 } from "@nestjs/common";
2492
- function _ts_decorate13(decorators, target, key, desc) {
2493
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2494
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2969
+ import { Catch, HttpStatus as HttpStatus19, Logger as Logger11 } from "@nestjs/common";
2970
+ function _ts_decorate18(decorators, target, key, desc2) {
2971
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
2972
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
2495
2973
  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;
2496
2974
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2497
2975
  }
2498
- __name(_ts_decorate13, "_ts_decorate");
2976
+ __name(_ts_decorate18, "_ts_decorate");
2499
2977
  function getHttpStatusTitle(status) {
2500
2978
  const enumKey = Object.entries(HttpStatus19).find(([key, value]) => value === status && Number.isNaN(Number(key)))?.[0];
2501
2979
  if (!enumKey) {
@@ -2508,7 +2986,7 @@ var HttpExceptionFilter = class _HttpExceptionFilter {
2508
2986
  static {
2509
2987
  __name(this, "HttpExceptionFilter");
2510
2988
  }
2511
- logger = new Logger9(_HttpExceptionFilter.name);
2989
+ logger = new Logger11(_HttpExceptionFilter.name);
2512
2990
  catch(exception, host) {
2513
2991
  const ctx = host.switchToHttp();
2514
2992
  const response = ctx.getResponse();
@@ -2518,7 +2996,7 @@ var HttpExceptionFilter = class _HttpExceptionFilter {
2518
2996
  let label;
2519
2997
  let detail = "Internal server error";
2520
2998
  let errors = [];
2521
- if (exception instanceof HttpException2) {
2999
+ if (this.isHttpException(exception)) {
2522
3000
  status = exception.getStatus();
2523
3001
  const exceptionResponse = exception.getResponse();
2524
3002
  if (typeof exceptionResponse === "object" && exceptionResponse !== null) {
@@ -2548,10 +3026,14 @@ var HttpExceptionFilter = class _HttpExceptionFilter {
2548
3026
  } else if (typeof exceptionResponse === "string") {
2549
3027
  detail = exceptionResponse;
2550
3028
  }
3029
+ } else if (this.isAxiosError(exception)) {
3030
+ const axiosStatus = exception.response?.status;
3031
+ const axiosDetail = exception.response?.data?.message || exception.response?.data?.detail || exception.message;
3032
+ const url = exception.config?.url;
3033
+ status = HttpStatus19.BAD_GATEWAY;
3034
+ detail = `Upstream service error${axiosStatus ? ` (${axiosStatus})` : ""}: ${axiosDetail}`;
3035
+ this.logger.error(`Upstream API error [${axiosStatus}]: ${axiosDetail} \u2014 URL: ${url}`, exception.stack);
2551
3036
  } else {
2552
- const errorMessage = exception instanceof Error ? exception.message : "Unknown error";
2553
- const stack = exception instanceof Error ? exception.stack : void 0;
2554
- this.logger.error(`Unexpected error: ${errorMessage}`, stack);
2555
3037
  detail = "An unexpected error occurred";
2556
3038
  }
2557
3039
  const problemDetails = {
@@ -2567,17 +3049,25 @@ var HttpExceptionFilter = class _HttpExceptionFilter {
2567
3049
  };
2568
3050
  response.header("Content-Type", "application/problem+json").status(status).send(problemDetails);
2569
3051
  }
3052
+ // Duck-type check for HttpException — avoids instanceof failing across pnpm package instances
3053
+ isHttpException(error) {
3054
+ return error instanceof Error && typeof error.getStatus === "function" && typeof error.getResponse === "function";
3055
+ }
3056
+ // Duck-type check for AxiosError without importing axios
3057
+ isAxiosError(error) {
3058
+ return error instanceof Error && error.isAxiosError === true;
3059
+ }
2570
3060
  };
2571
- HttpExceptionFilter = _ts_decorate13([
3061
+ HttpExceptionFilter = _ts_decorate18([
2572
3062
  Catch()
2573
3063
  ], HttpExceptionFilter);
2574
3064
 
2575
3065
  // src/logger/interceptors/http-logger.interceptor.ts
2576
- import { Injectable as Injectable9, Optional as Optional2 } from "@nestjs/common";
3066
+ import { Injectable as Injectable11, Optional as Optional2 } from "@nestjs/common";
2577
3067
  import { catchError, tap } from "rxjs/operators";
2578
3068
 
2579
3069
  // src/logger/services/logger.service.ts
2580
- import { Injectable as Injectable8, Optional } from "@nestjs/common";
3070
+ import { Injectable as Injectable10, Optional } from "@nestjs/common";
2581
3071
  import { createLogger, format, transports } from "winston";
2582
3072
  import DailyRotateFile from "winston-daily-rotate-file";
2583
3073
 
@@ -2615,23 +3105,23 @@ function addCorrelationIdToResponse(reply, correlationId, headerName = DEFAULT_C
2615
3105
  __name(addCorrelationIdToResponse, "addCorrelationIdToResponse");
2616
3106
 
2617
3107
  // src/logger/services/logger.service.ts
2618
- function _ts_decorate14(decorators, target, key, desc) {
2619
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2620
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
3108
+ function _ts_decorate19(decorators, target, key, desc2) {
3109
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
3110
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
2621
3111
  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;
2622
3112
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2623
3113
  }
2624
- __name(_ts_decorate14, "_ts_decorate");
2625
- function _ts_metadata8(k, v) {
3114
+ __name(_ts_decorate19, "_ts_decorate");
3115
+ function _ts_metadata12(k, v) {
2626
3116
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2627
3117
  }
2628
- __name(_ts_metadata8, "_ts_metadata");
2629
- function _ts_param4(paramIndex, decorator) {
3118
+ __name(_ts_metadata12, "_ts_metadata");
3119
+ function _ts_param5(paramIndex, decorator) {
2630
3120
  return function(target, key) {
2631
3121
  decorator(target, key, paramIndex);
2632
3122
  };
2633
3123
  }
2634
- __name(_ts_param4, "_ts_param");
3124
+ __name(_ts_param5, "_ts_param");
2635
3125
  var LoggerService = class _LoggerService {
2636
3126
  static {
2637
3127
  __name(this, "LoggerService");
@@ -2671,9 +3161,9 @@ var LoggerService = class _LoggerService {
2671
3161
  }) : new transports.Console({
2672
3162
  level,
2673
3163
  format: format.combine(...baseFormatters, format.printf((info) => {
2674
- const { timestamp, level: level2, message, context, correlationId, trace } = info;
3164
+ const { timestamp: timestamp2, level: level2, message, context, correlationId, trace } = info;
2675
3165
  const parts = [
2676
- timestamp,
3166
+ timestamp2,
2677
3167
  level2.toUpperCase().padEnd(7),
2678
3168
  correlationId ? `[${correlationId.toString().slice(-6)}]` : "",
2679
3169
  context ? `[${context}]` : "",
@@ -2823,35 +3313,35 @@ ${trace}`;
2823
3313
  return childLogger;
2824
3314
  }
2825
3315
  };
2826
- LoggerService = _ts_decorate14([
2827
- Injectable8(),
2828
- _ts_param4(0, Optional()),
2829
- _ts_param4(1, Optional()),
2830
- _ts_metadata8("design:type", Function),
2831
- _ts_metadata8("design:paramtypes", [
3316
+ LoggerService = _ts_decorate19([
3317
+ Injectable10(),
3318
+ _ts_param5(0, Optional()),
3319
+ _ts_param5(1, Optional()),
3320
+ _ts_metadata12("design:type", Function),
3321
+ _ts_metadata12("design:paramtypes", [
2832
3322
  typeof LoggerModuleOptions === "undefined" ? Object : LoggerModuleOptions,
2833
3323
  typeof Logger === "undefined" ? Object : Logger
2834
3324
  ])
2835
3325
  ], LoggerService);
2836
3326
 
2837
3327
  // src/logger/interceptors/http-logger.interceptor.ts
2838
- function _ts_decorate15(decorators, target, key, desc) {
2839
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2840
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
3328
+ function _ts_decorate20(decorators, target, key, desc2) {
3329
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
3330
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
2841
3331
  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;
2842
3332
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2843
3333
  }
2844
- __name(_ts_decorate15, "_ts_decorate");
2845
- function _ts_metadata9(k, v) {
3334
+ __name(_ts_decorate20, "_ts_decorate");
3335
+ function _ts_metadata13(k, v) {
2846
3336
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2847
3337
  }
2848
- __name(_ts_metadata9, "_ts_metadata");
2849
- function _ts_param5(paramIndex, decorator) {
3338
+ __name(_ts_metadata13, "_ts_metadata");
3339
+ function _ts_param6(paramIndex, decorator) {
2850
3340
  return function(target, key) {
2851
3341
  decorator(target, key, paramIndex);
2852
3342
  };
2853
3343
  }
2854
- __name(_ts_param5, "_ts_param");
3344
+ __name(_ts_param6, "_ts_param");
2855
3345
  var HttpLoggerInterceptor = class {
2856
3346
  static {
2857
3347
  __name(this, "HttpLoggerInterceptor");
@@ -2954,32 +3444,32 @@ var HttpLoggerInterceptor = class {
2954
3444
  }
2955
3445
  }
2956
3446
  };
2957
- HttpLoggerInterceptor = _ts_decorate15([
2958
- Injectable9(),
2959
- _ts_param5(1, Optional2()),
2960
- _ts_metadata9("design:type", Function),
2961
- _ts_metadata9("design:paramtypes", [
3447
+ HttpLoggerInterceptor = _ts_decorate20([
3448
+ Injectable11(),
3449
+ _ts_param6(1, Optional2()),
3450
+ _ts_metadata13("design:type", Function),
3451
+ _ts_metadata13("design:paramtypes", [
2962
3452
  typeof LoggerService === "undefined" ? Object : LoggerService,
2963
3453
  typeof HttpLoggerOptions === "undefined" ? Object : HttpLoggerOptions
2964
3454
  ])
2965
3455
  ], HttpLoggerInterceptor);
2966
3456
 
2967
3457
  // src/logger/logger.module.ts
2968
- import { Global as Global5, Logger as Logger10, Module as Module5 } from "@nestjs/common";
3458
+ import { Global as Global5, Logger as Logger12, Module as Module6 } from "@nestjs/common";
2969
3459
 
2970
3460
  // src/logger/middleware/correlation-id.middleware.ts
2971
- import { Injectable as Injectable10 } from "@nestjs/common";
2972
- function _ts_decorate16(decorators, target, key, desc) {
2973
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2974
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
3461
+ import { Injectable as Injectable12 } from "@nestjs/common";
3462
+ function _ts_decorate21(decorators, target, key, desc2) {
3463
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
3464
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
2975
3465
  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;
2976
3466
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2977
3467
  }
2978
- __name(_ts_decorate16, "_ts_decorate");
2979
- function _ts_metadata10(k, v) {
3468
+ __name(_ts_decorate21, "_ts_decorate");
3469
+ function _ts_metadata14(k, v) {
2980
3470
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2981
3471
  }
2982
- __name(_ts_metadata10, "_ts_metadata");
3472
+ __name(_ts_metadata14, "_ts_metadata");
2983
3473
  var CorrelationIdMiddleware = class {
2984
3474
  static {
2985
3475
  __name(this, "CorrelationIdMiddleware");
@@ -3016,22 +3506,22 @@ var CorrelationIdMiddleware = class {
3016
3506
  }
3017
3507
  }
3018
3508
  };
3019
- CorrelationIdMiddleware = _ts_decorate16([
3020
- Injectable10(),
3021
- _ts_metadata10("design:type", Function),
3022
- _ts_metadata10("design:paramtypes", [
3509
+ CorrelationIdMiddleware = _ts_decorate21([
3510
+ Injectable12(),
3511
+ _ts_metadata14("design:type", Function),
3512
+ _ts_metadata14("design:paramtypes", [
3023
3513
  typeof CorrelationIdMiddlewareOptions === "undefined" ? Object : CorrelationIdMiddlewareOptions
3024
3514
  ])
3025
3515
  ], CorrelationIdMiddleware);
3026
3516
 
3027
3517
  // src/logger/logger.module.ts
3028
- function _ts_decorate17(decorators, target, key, desc) {
3029
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3030
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
3518
+ function _ts_decorate22(decorators, target, key, desc2) {
3519
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
3520
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
3031
3521
  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;
3032
3522
  return c > 3 && r && Object.defineProperty(target, key, r), r;
3033
3523
  }
3034
- __name(_ts_decorate17, "_ts_decorate");
3524
+ __name(_ts_decorate22, "_ts_decorate");
3035
3525
  var LOGGER_MODULE_OPTIONS = Symbol("LOGGER_MODULE_OPTIONS");
3036
3526
  var DEFAULT_LOGGER_OPTIONS = {
3037
3527
  provider: "winston",
@@ -3108,9 +3598,9 @@ function mergeWithDefaults(options = {}) {
3108
3598
  __name(mergeWithDefaults, "mergeWithDefaults");
3109
3599
  function createDefaultLoggerProvider(options) {
3110
3600
  return {
3111
- provide: Logger10,
3601
+ provide: Logger12,
3112
3602
  useFactory: /* @__PURE__ */ __name(() => {
3113
- const logger = new Logger10();
3603
+ const logger = new Logger12();
3114
3604
  if (options.level) {
3115
3605
  const levels = getLevelsUpTo(options.level);
3116
3606
  logger.setLogLevels?.(levels);
@@ -3140,7 +3630,7 @@ function createLoggerProviders(options = {}) {
3140
3630
  inject: [
3141
3631
  LOGGER_MODULE_OPTIONS,
3142
3632
  {
3143
- token: Logger10,
3633
+ token: Logger12,
3144
3634
  optional: true
3145
3635
  }
3146
3636
  ]
@@ -3219,10 +3709,10 @@ var LoggerModule = class _LoggerModule {
3219
3709
  ...asyncProviders,
3220
3710
  // Default logger provider
3221
3711
  {
3222
- provide: Logger10,
3712
+ provide: Logger12,
3223
3713
  useFactory: /* @__PURE__ */ __name((opts) => {
3224
3714
  if (opts.provider === "default") {
3225
- const logger = new Logger10();
3715
+ const logger = new Logger12();
3226
3716
  if (opts.level) {
3227
3717
  const levels = getLevelsUpTo(opts.level);
3228
3718
  logger.setLogLevels?.(levels);
@@ -3244,7 +3734,7 @@ var LoggerModule = class _LoggerModule {
3244
3734
  inject: [
3245
3735
  LOGGER_MODULE_OPTIONS,
3246
3736
  {
3247
- token: Logger10,
3737
+ token: Logger12,
3248
3738
  optional: true
3249
3739
  }
3250
3740
  ]
@@ -3343,13 +3833,13 @@ var LoggerModule = class _LoggerModule {
3343
3833
  throw new Error("LoggerModule.forRootAsync() requires one of: useFactory, useClass, or useExisting");
3344
3834
  }
3345
3835
  };
3346
- LoggerModule = _ts_decorate17([
3836
+ LoggerModule = _ts_decorate22([
3347
3837
  Global5(),
3348
- Module5({})
3838
+ Module6({})
3349
3839
  ], LoggerModule);
3350
3840
 
3351
3841
  // src/root/root.module.ts
3352
- import { Module as Module6 } from "@nestjs/common";
3842
+ import { Module as Module7 } from "@nestjs/common";
3353
3843
 
3354
3844
  // src/root/controllers/app.controller.ts
3355
3845
  import { Controller, Get } from "@nestjs/common";
@@ -3370,14 +3860,14 @@ function ApiHealthCheck() {
3370
3860
  __name(ApiHealthCheck, "ApiHealthCheck");
3371
3861
 
3372
3862
  // src/root/services/app.service.ts
3373
- import { Injectable as Injectable11 } from "@nestjs/common";
3374
- function _ts_decorate18(decorators, target, key, desc) {
3375
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3376
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
3863
+ import { Injectable as Injectable13 } from "@nestjs/common";
3864
+ function _ts_decorate23(decorators, target, key, desc2) {
3865
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
3866
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
3377
3867
  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;
3378
3868
  return c > 3 && r && Object.defineProperty(target, key, r), r;
3379
3869
  }
3380
- __name(_ts_decorate18, "_ts_decorate");
3870
+ __name(_ts_decorate23, "_ts_decorate");
3381
3871
  var AppService = class {
3382
3872
  static {
3383
3873
  __name(this, "AppService");
@@ -3387,22 +3877,22 @@ var AppService = class {
3387
3877
  return `Hello World!`;
3388
3878
  }
3389
3879
  };
3390
- AppService = _ts_decorate18([
3391
- Injectable11()
3880
+ AppService = _ts_decorate23([
3881
+ Injectable13()
3392
3882
  ], AppService);
3393
3883
 
3394
3884
  // src/root/controllers/app.controller.ts
3395
- function _ts_decorate19(decorators, target, key, desc) {
3396
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3397
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
3885
+ function _ts_decorate24(decorators, target, key, desc2) {
3886
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
3887
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
3398
3888
  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;
3399
3889
  return c > 3 && r && Object.defineProperty(target, key, r), r;
3400
3890
  }
3401
- __name(_ts_decorate19, "_ts_decorate");
3402
- function _ts_metadata11(k, v) {
3891
+ __name(_ts_decorate24, "_ts_decorate");
3892
+ function _ts_metadata15(k, v) {
3403
3893
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
3404
3894
  }
3405
- __name(_ts_metadata11, "_ts_metadata");
3895
+ __name(_ts_metadata15, "_ts_metadata");
3406
3896
  var AppController = class {
3407
3897
  static {
3408
3898
  __name(this, "AppController");
@@ -3416,19 +3906,19 @@ var AppController = class {
3416
3906
  return this.appService.getHello();
3417
3907
  }
3418
3908
  };
3419
- _ts_decorate19([
3909
+ _ts_decorate24([
3420
3910
  Get(),
3421
3911
  Public(),
3422
3912
  ApiHealthCheck(),
3423
- _ts_metadata11("design:type", Function),
3424
- _ts_metadata11("design:paramtypes", []),
3425
- _ts_metadata11("design:returntype", String)
3913
+ _ts_metadata15("design:type", Function),
3914
+ _ts_metadata15("design:paramtypes", []),
3915
+ _ts_metadata15("design:returntype", String)
3426
3916
  ], AppController.prototype, "getHello", null);
3427
- AppController = _ts_decorate19([
3917
+ AppController = _ts_decorate24([
3428
3918
  ApiTags("Health"),
3429
3919
  Controller(),
3430
- _ts_metadata11("design:type", Function),
3431
- _ts_metadata11("design:paramtypes", [
3920
+ _ts_metadata15("design:type", Function),
3921
+ _ts_metadata15("design:paramtypes", [
3432
3922
  typeof AppService === "undefined" ? Object : AppService
3433
3923
  ])
3434
3924
  ], AppController);
@@ -3465,23 +3955,23 @@ function ApiGetCsrfToken() {
3465
3955
  __name(ApiGetCsrfToken, "ApiGetCsrfToken");
3466
3956
 
3467
3957
  // src/root/controllers/csrf.controller.ts
3468
- function _ts_decorate20(decorators, target, key, desc) {
3469
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3470
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
3958
+ function _ts_decorate25(decorators, target, key, desc2) {
3959
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
3960
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
3471
3961
  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;
3472
3962
  return c > 3 && r && Object.defineProperty(target, key, r), r;
3473
3963
  }
3474
- __name(_ts_decorate20, "_ts_decorate");
3475
- function _ts_metadata12(k, v) {
3964
+ __name(_ts_decorate25, "_ts_decorate");
3965
+ function _ts_metadata16(k, v) {
3476
3966
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
3477
3967
  }
3478
- __name(_ts_metadata12, "_ts_metadata");
3479
- function _ts_param6(paramIndex, decorator) {
3968
+ __name(_ts_metadata16, "_ts_metadata");
3969
+ function _ts_param7(paramIndex, decorator) {
3480
3970
  return function(target, key) {
3481
3971
  decorator(target, key, paramIndex);
3482
3972
  };
3483
3973
  }
3484
- __name(_ts_param6, "_ts_param");
3974
+ __name(_ts_param7, "_ts_param");
3485
3975
  var CsrfController = class {
3486
3976
  static {
3487
3977
  __name(this, "CsrfController");
@@ -3494,40 +3984,40 @@ var CsrfController = class {
3494
3984
  };
3495
3985
  }
3496
3986
  };
3497
- _ts_decorate20([
3987
+ _ts_decorate25([
3498
3988
  Get2("token"),
3499
3989
  Public(),
3500
3990
  HttpCode(HttpStatus20.OK),
3501
3991
  ApiGetCsrfToken(),
3502
- _ts_param6(0, Res({
3992
+ _ts_param7(0, Res({
3503
3993
  passthrough: true
3504
3994
  })),
3505
- _ts_metadata12("design:type", Function),
3506
- _ts_metadata12("design:paramtypes", [
3995
+ _ts_metadata16("design:type", Function),
3996
+ _ts_metadata16("design:paramtypes", [
3507
3997
  typeof FastifyReply === "undefined" ? Object : FastifyReply
3508
3998
  ]),
3509
- _ts_metadata12("design:returntype", Object)
3999
+ _ts_metadata16("design:returntype", Object)
3510
4000
  ], CsrfController.prototype, "getToken", null);
3511
- CsrfController = _ts_decorate20([
4001
+ CsrfController = _ts_decorate25([
3512
4002
  ApiTags2("CSRF"),
3513
4003
  Controller2("csrf")
3514
4004
  ], CsrfController);
3515
4005
 
3516
4006
  // src/root/root.module.ts
3517
- function _ts_decorate21(decorators, target, key, desc) {
3518
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3519
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4007
+ function _ts_decorate26(decorators, target, key, desc2) {
4008
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
4009
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
3520
4010
  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;
3521
4011
  return c > 3 && r && Object.defineProperty(target, key, r), r;
3522
4012
  }
3523
- __name(_ts_decorate21, "_ts_decorate");
4013
+ __name(_ts_decorate26, "_ts_decorate");
3524
4014
  var RootModule = class {
3525
4015
  static {
3526
4016
  __name(this, "RootModule");
3527
4017
  }
3528
4018
  };
3529
- RootModule = _ts_decorate21([
3530
- Module6({
4019
+ RootModule = _ts_decorate26([
4020
+ Module7({
3531
4021
  controllers: [
3532
4022
  AppController,
3533
4023
  CsrfController
@@ -3747,23 +4237,1093 @@ function normalizePhoneNumber(phone) {
3747
4237
  return phone.startsWith("+") ? phone : `+${phone}`;
3748
4238
  }
3749
4239
  __name(normalizePhoneNumber, "normalizePhoneNumber");
4240
+
4241
+ // src/data-table/data-table.module.ts
4242
+ import { Module as Module8 } from "@nestjs/common";
4243
+ import { ConfigModule as ConfigModule4 } from "@nestjs/config";
4244
+
4245
+ // src/data-table/data-table.constants.ts
4246
+ var DATA_TABLE_VIEWS_TABLE = Symbol("DATA_TABLE_VIEWS_TABLE");
4247
+
4248
+ // src/data-table/state/controllers/data-table-state.controller.ts
4249
+ import { Body, Controller as Controller3, HttpCode as HttpCode2, HttpStatus as HttpStatus21, Logger as Logger14, Post } from "@nestjs/common";
4250
+ import { ApiBearerAuth, ApiTags as ApiTags3 } from "@nestjs/swagger";
4251
+
4252
+ // src/data-table/state/docs/data-table-state.docs.ts
4253
+ import { applyDecorators as applyDecorators3 } from "@nestjs/common";
4254
+ import { ApiBody, ApiOperation as ApiOperation3, ApiResponse as ApiResponse3 } from "@nestjs/swagger";
4255
+
4256
+ // src/data-table/state/dto/request/upsert-data-table-state.dto.ts
4257
+ import { ApiProperty as ApiProperty3, ApiPropertyOptional as ApiPropertyOptional3 } from "@nestjs/swagger";
4258
+ import { IsObject, IsOptional as IsOptional2, IsString as IsString3, IsUUID, MaxLength } from "class-validator";
4259
+ function _ts_decorate27(decorators, target, key, desc2) {
4260
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
4261
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
4262
+ 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;
4263
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
4264
+ }
4265
+ __name(_ts_decorate27, "_ts_decorate");
4266
+ function _ts_metadata17(k, v) {
4267
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4268
+ }
4269
+ __name(_ts_metadata17, "_ts_metadata");
4270
+ var UpsertDataTableStateDto = class {
4271
+ static {
4272
+ __name(this, "UpsertDataTableStateDto");
4273
+ }
4274
+ tableSlug;
4275
+ state;
4276
+ activeViewId;
4277
+ };
4278
+ _ts_decorate27([
4279
+ ApiProperty3({
4280
+ description: "Unique slug identifying the table",
4281
+ example: "cloud-providers"
4282
+ }),
4283
+ IsString3(),
4284
+ MaxLength(100),
4285
+ _ts_metadata17("design:type", String)
4286
+ ], UpsertDataTableStateDto.prototype, "tableSlug", void 0);
4287
+ _ts_decorate27([
4288
+ ApiProperty3({
4289
+ description: "Full table view state including filters, sort, and column visibility"
4290
+ }),
4291
+ IsObject(),
4292
+ _ts_metadata17("design:type", typeof TableViewState === "undefined" ? Object : TableViewState)
4293
+ ], UpsertDataTableStateDto.prototype, "state", void 0);
4294
+ _ts_decorate27([
4295
+ ApiPropertyOptional3(),
4296
+ IsOptional2(),
4297
+ IsUUID(),
4298
+ _ts_metadata17("design:type", Object)
4299
+ ], UpsertDataTableStateDto.prototype, "activeViewId", void 0);
4300
+
4301
+ // src/data-table/state/docs/data-table-state.docs.ts
4302
+ function ApiUpsertDataTableState() {
4303
+ return applyDecorators3(ApiOperation3({
4304
+ summary: "Save live table state",
4305
+ description: "Stores the current filter, sort, and column visibility state in Redis cache. Called on filter Apply and sort column click. State expires after TABLE_STATE_CACHE_TTL seconds."
4306
+ }), ApiBody({
4307
+ type: UpsertDataTableStateDto
4308
+ }), ApiResponse3({
4309
+ status: 200,
4310
+ description: "Live state cached."
4311
+ }), ApiResponse3({
4312
+ status: 400,
4313
+ description: "Invalid request body."
4314
+ }), ApiResponse3({
4315
+ status: 401,
4316
+ description: "Unauthorized."
4317
+ }));
4318
+ }
4319
+ __name(ApiUpsertDataTableState, "ApiUpsertDataTableState");
4320
+
4321
+ // src/data-table/state/services/data-table-state.service.ts
4322
+ import { Injectable as Injectable14, Logger as Logger13 } from "@nestjs/common";
4323
+ import { ConfigService as ConfigService6 } from "@nestjs/config";
4324
+ function _ts_decorate28(decorators, target, key, desc2) {
4325
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
4326
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
4327
+ 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;
4328
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
4329
+ }
4330
+ __name(_ts_decorate28, "_ts_decorate");
4331
+ function _ts_metadata18(k, v) {
4332
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4333
+ }
4334
+ __name(_ts_metadata18, "_ts_metadata");
4335
+ var EMPTY_TABLE_STATE = {
4336
+ filters: [],
4337
+ sort: [],
4338
+ columnVisibility: {},
4339
+ columnOrder: [],
4340
+ columnSizing: {},
4341
+ columnPinning: {
4342
+ left: [],
4343
+ right: []
4344
+ },
4345
+ lockedColumnSizing: false,
4346
+ density: "normal",
4347
+ filterOrder: [],
4348
+ filterVisibility: {},
4349
+ pagination: {
4350
+ limit: 20,
4351
+ offset: 0
4352
+ }
4353
+ };
4354
+ var DataTableStateService = class _DataTableStateService {
4355
+ static {
4356
+ __name(this, "DataTableStateService");
4357
+ }
4358
+ cacheService;
4359
+ configService;
4360
+ logger = new Logger13(_DataTableStateService.name);
4361
+ constructor(cacheService, configService) {
4362
+ this.cacheService = cacheService;
4363
+ this.configService = configService;
4364
+ }
4365
+ // Returns configured TTL for live table state in seconds, defaulting to 3600 (1h)
4366
+ get stateTtl() {
4367
+ return this.configService.get("TABLE_STATE_CACHE_TTL") ?? 3600;
4368
+ }
4369
+ // Saves live table state and active view ID to Redis; DB is not written
4370
+ async upsertCurrentState(userId, dto) {
4371
+ const key = `dt:${userId}:${dto.tableSlug}`;
4372
+ await this.cacheService.set(key, {
4373
+ state: dto.state,
4374
+ activeViewId: dto.activeViewId ?? null
4375
+ }, this.stateTtl);
4376
+ this.logger.log(`Cached live state for user: ${userId}, table: ${dto.tableSlug}`);
4377
+ }
4378
+ // Returns live table state and active view ID from Redis; returns empty state on miss — no DB query
4379
+ async getCurrentState(userId, tableSlug) {
4380
+ const key = `dt:${userId}:${tableSlug}`;
4381
+ const cached = await this.cacheService.get(key);
4382
+ return cached ?? {
4383
+ state: EMPTY_TABLE_STATE,
4384
+ activeViewId: null
4385
+ };
4386
+ }
4387
+ };
4388
+ DataTableStateService = _ts_decorate28([
4389
+ Injectable14(),
4390
+ _ts_metadata18("design:type", Function),
4391
+ _ts_metadata18("design:paramtypes", [
4392
+ typeof CacheService === "undefined" ? Object : CacheService,
4393
+ typeof ConfigService6 === "undefined" ? Object : ConfigService6
4394
+ ])
4395
+ ], DataTableStateService);
4396
+
4397
+ // src/data-table/state/controllers/data-table-state.controller.ts
4398
+ function _ts_decorate29(decorators, target, key, desc2) {
4399
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
4400
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
4401
+ 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;
4402
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
4403
+ }
4404
+ __name(_ts_decorate29, "_ts_decorate");
4405
+ function _ts_metadata19(k, v) {
4406
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4407
+ }
4408
+ __name(_ts_metadata19, "_ts_metadata");
4409
+ function _ts_param8(paramIndex, decorator) {
4410
+ return function(target, key) {
4411
+ decorator(target, key, paramIndex);
4412
+ };
4413
+ }
4414
+ __name(_ts_param8, "_ts_param");
4415
+ var DataTableStateController = class _DataTableStateController {
4416
+ static {
4417
+ __name(this, "DataTableStateController");
4418
+ }
4419
+ dataTableStateService;
4420
+ logger = new Logger14(_DataTableStateController.name);
4421
+ constructor(dataTableStateService) {
4422
+ this.dataTableStateService = dataTableStateService;
4423
+ }
4424
+ // Saves live table state to Redis cache for the authenticated user's table
4425
+ upsertCurrentState(userId, dto) {
4426
+ this.logger.log(`POST /table-states - User: ${userId}, table: ${dto.tableSlug}`);
4427
+ return this.dataTableStateService.upsertCurrentState(userId, dto);
4428
+ }
4429
+ };
4430
+ _ts_decorate29([
4431
+ Post(),
4432
+ HttpCode2(HttpStatus21.OK),
4433
+ ApiUpsertDataTableState(),
4434
+ _ts_param8(0, UserId()),
4435
+ _ts_param8(1, Body()),
4436
+ _ts_metadata19("design:type", Function),
4437
+ _ts_metadata19("design:paramtypes", [
4438
+ String,
4439
+ typeof UpsertDataTableStateDto === "undefined" ? Object : UpsertDataTableStateDto
4440
+ ]),
4441
+ _ts_metadata19("design:returntype", typeof Promise === "undefined" ? Object : Promise)
4442
+ ], DataTableStateController.prototype, "upsertCurrentState", null);
4443
+ DataTableStateController = _ts_decorate29([
4444
+ ApiTags3("Table States"),
4445
+ ApiBearerAuth(),
4446
+ Controller3("table-states"),
4447
+ _ts_metadata19("design:type", Function),
4448
+ _ts_metadata19("design:paramtypes", [
4449
+ typeof DataTableStateService === "undefined" ? Object : DataTableStateService
4450
+ ])
4451
+ ], DataTableStateController);
4452
+
4453
+ // src/data-table/views/controllers/data-table-views.controller.ts
4454
+ import { Body as Body2, Controller as Controller4, Delete, Get as Get3, HttpCode as HttpCode3, HttpStatus as HttpStatus22, Logger as Logger16, Param, Patch, Post as Post2, Query } from "@nestjs/common";
4455
+ import { ApiBearerAuth as ApiBearerAuth2, ApiTags as ApiTags4 } from "@nestjs/swagger";
4456
+
4457
+ // src/data-table/views/docs/data-table-views.docs.ts
4458
+ import { applyDecorators as applyDecorators4 } from "@nestjs/common";
4459
+ import { ApiBody as ApiBody2, ApiOperation as ApiOperation4, ApiParam, ApiQuery, ApiResponse as ApiResponse4 } from "@nestjs/swagger";
4460
+
4461
+ // src/data-table/views/dto/entity/data-table-view.dto.ts
4462
+ import { ApiProperty as ApiProperty4, ApiPropertyOptional as ApiPropertyOptional4 } from "@nestjs/swagger";
4463
+ function _ts_decorate30(decorators, target, key, desc2) {
4464
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
4465
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
4466
+ 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;
4467
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
4468
+ }
4469
+ __name(_ts_decorate30, "_ts_decorate");
4470
+ function _ts_metadata20(k, v) {
4471
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4472
+ }
4473
+ __name(_ts_metadata20, "_ts_metadata");
4474
+ var DataTableViewDto = class _DataTableViewDto {
4475
+ static {
4476
+ __name(this, "DataTableViewDto");
4477
+ }
4478
+ id;
4479
+ name;
4480
+ tableSlug;
4481
+ state;
4482
+ isShared;
4483
+ isOwn;
4484
+ createdAt;
4485
+ updatedAt;
4486
+ // Creates a response DTO from a DataTableView entity, computing isOwn by comparing userId
4487
+ static from(view, userId) {
4488
+ const dto = new _DataTableViewDto();
4489
+ dto.id = view.id;
4490
+ dto.name = view.name ?? null;
4491
+ dto.tableSlug = view.tableSlug;
4492
+ dto.state = view.state;
4493
+ dto.isShared = view.isShared;
4494
+ dto.isOwn = view.userId === userId;
4495
+ dto.createdAt = view.createdAt;
4496
+ dto.updatedAt = view.updatedAt ?? null;
4497
+ return dto;
4498
+ }
4499
+ };
4500
+ _ts_decorate30([
4501
+ ApiProperty4({
4502
+ description: "View unique identifier"
4503
+ }),
4504
+ _ts_metadata20("design:type", String)
4505
+ ], DataTableViewDto.prototype, "id", void 0);
4506
+ _ts_decorate30([
4507
+ ApiPropertyOptional4({
4508
+ description: "Display name of the view",
4509
+ nullable: true
4510
+ }),
4511
+ _ts_metadata20("design:type", Object)
4512
+ ], DataTableViewDto.prototype, "name", void 0);
4513
+ _ts_decorate30([
4514
+ ApiProperty4({
4515
+ description: "Slug of the table this view belongs to",
4516
+ example: "cloud-providers"
4517
+ }),
4518
+ _ts_metadata20("design:type", String)
4519
+ ], DataTableViewDto.prototype, "tableSlug", void 0);
4520
+ _ts_decorate30([
4521
+ ApiProperty4({
4522
+ description: "Stored filter, sort, and column visibility state"
4523
+ }),
4524
+ _ts_metadata20("design:type", typeof TableViewState === "undefined" ? Object : TableViewState)
4525
+ ], DataTableViewDto.prototype, "state", void 0);
4526
+ _ts_decorate30([
4527
+ ApiProperty4({
4528
+ description: "Whether the view is visible to all users",
4529
+ example: false
4530
+ }),
4531
+ _ts_metadata20("design:type", Boolean)
4532
+ ], DataTableViewDto.prototype, "isShared", void 0);
4533
+ _ts_decorate30([
4534
+ ApiProperty4({
4535
+ description: "Whether the requesting user owns this view",
4536
+ example: true
4537
+ }),
4538
+ _ts_metadata20("design:type", Boolean)
4539
+ ], DataTableViewDto.prototype, "isOwn", void 0);
4540
+ _ts_decorate30([
4541
+ ApiProperty4({
4542
+ description: "Creation timestamp"
4543
+ }),
4544
+ _ts_metadata20("design:type", typeof Date === "undefined" ? Object : Date)
4545
+ ], DataTableViewDto.prototype, "createdAt", void 0);
4546
+ _ts_decorate30([
4547
+ ApiPropertyOptional4({
4548
+ description: "Last updated timestamp",
4549
+ nullable: true
4550
+ }),
4551
+ _ts_metadata20("design:type", Object)
4552
+ ], DataTableViewDto.prototype, "updatedAt", void 0);
4553
+
4554
+ // src/data-table/views/dto/request/create-data-table-view.dto.ts
4555
+ import { ApiProperty as ApiProperty5, ApiPropertyOptional as ApiPropertyOptional5 } from "@nestjs/swagger";
4556
+ import { IsBoolean as IsBoolean2, IsObject as IsObject2, IsOptional as IsOptional3, IsString as IsString4, MaxLength as MaxLength2 } from "class-validator";
4557
+ function _ts_decorate31(decorators, target, key, desc2) {
4558
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
4559
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
4560
+ 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;
4561
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
4562
+ }
4563
+ __name(_ts_decorate31, "_ts_decorate");
4564
+ function _ts_metadata21(k, v) {
4565
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4566
+ }
4567
+ __name(_ts_metadata21, "_ts_metadata");
4568
+ var CreateDataTableViewDto = class {
4569
+ static {
4570
+ __name(this, "CreateDataTableViewDto");
4571
+ }
4572
+ name;
4573
+ tableSlug;
4574
+ state;
4575
+ isShared;
4576
+ };
4577
+ _ts_decorate31([
4578
+ ApiProperty5({
4579
+ description: "Display name for the saved view",
4580
+ example: "AWS Only"
4581
+ }),
4582
+ IsString4(),
4583
+ MaxLength2(100),
4584
+ _ts_metadata21("design:type", String)
4585
+ ], CreateDataTableViewDto.prototype, "name", void 0);
4586
+ _ts_decorate31([
4587
+ ApiProperty5({
4588
+ description: "Unique slug identifying the table",
4589
+ example: "cloud-providers"
4590
+ }),
4591
+ IsString4(),
4592
+ MaxLength2(100),
4593
+ _ts_metadata21("design:type", String)
4594
+ ], CreateDataTableViewDto.prototype, "tableSlug", void 0);
4595
+ _ts_decorate31([
4596
+ ApiProperty5({
4597
+ description: "Full table view state including filters, sort, and column visibility"
4598
+ }),
4599
+ IsObject2(),
4600
+ _ts_metadata21("design:type", typeof TableViewState === "undefined" ? Object : TableViewState)
4601
+ ], CreateDataTableViewDto.prototype, "state", void 0);
4602
+ _ts_decorate31([
4603
+ ApiPropertyOptional5({
4604
+ description: "Whether this view is visible to all users",
4605
+ example: false
4606
+ }),
4607
+ IsBoolean2(),
4608
+ IsOptional3(),
4609
+ _ts_metadata21("design:type", Boolean)
4610
+ ], CreateDataTableViewDto.prototype, "isShared", void 0);
4611
+
4612
+ // src/data-table/views/dto/request/rename-data-table-view.dto.ts
4613
+ import { ApiProperty as ApiProperty6 } from "@nestjs/swagger";
4614
+ import { IsString as IsString5, MaxLength as MaxLength3, MinLength } from "class-validator";
4615
+ function _ts_decorate32(decorators, target, key, desc2) {
4616
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
4617
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
4618
+ 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;
4619
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
4620
+ }
4621
+ __name(_ts_decorate32, "_ts_decorate");
4622
+ function _ts_metadata22(k, v) {
4623
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4624
+ }
4625
+ __name(_ts_metadata22, "_ts_metadata");
4626
+ var RenameDataTableViewDto = class {
4627
+ static {
4628
+ __name(this, "RenameDataTableViewDto");
4629
+ }
4630
+ name;
4631
+ };
4632
+ _ts_decorate32([
4633
+ ApiProperty6({
4634
+ description: "New display name for the view",
4635
+ example: "AWS Only"
4636
+ }),
4637
+ IsString5(),
4638
+ MinLength(1),
4639
+ MaxLength3(100),
4640
+ _ts_metadata22("design:type", String)
4641
+ ], RenameDataTableViewDto.prototype, "name", void 0);
4642
+
4643
+ // src/data-table/views/dto/request/toggle-share-data-table-view.dto.ts
4644
+ import { ApiProperty as ApiProperty7 } from "@nestjs/swagger";
4645
+ import { IsBoolean as IsBoolean3 } from "class-validator";
4646
+ function _ts_decorate33(decorators, target, key, desc2) {
4647
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
4648
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
4649
+ 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;
4650
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
4651
+ }
4652
+ __name(_ts_decorate33, "_ts_decorate");
4653
+ function _ts_metadata23(k, v) {
4654
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4655
+ }
4656
+ __name(_ts_metadata23, "_ts_metadata");
4657
+ var ToggleShareDataTableViewDto = class {
4658
+ static {
4659
+ __name(this, "ToggleShareDataTableViewDto");
4660
+ }
4661
+ isShared;
4662
+ };
4663
+ _ts_decorate33([
4664
+ ApiProperty7({
4665
+ description: "Whether the view should be visible to all users",
4666
+ example: true
4667
+ }),
4668
+ IsBoolean3(),
4669
+ _ts_metadata23("design:type", Boolean)
4670
+ ], ToggleShareDataTableViewDto.prototype, "isShared", void 0);
4671
+
4672
+ // src/data-table/views/dto/request/update-data-table-view.dto.ts
4673
+ import { ApiProperty as ApiProperty8 } from "@nestjs/swagger";
4674
+ import { IsObject as IsObject3 } from "class-validator";
4675
+ function _ts_decorate34(decorators, target, key, desc2) {
4676
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
4677
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
4678
+ 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;
4679
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
4680
+ }
4681
+ __name(_ts_decorate34, "_ts_decorate");
4682
+ function _ts_metadata24(k, v) {
4683
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4684
+ }
4685
+ __name(_ts_metadata24, "_ts_metadata");
4686
+ var UpdateDataTableViewDto = class {
4687
+ static {
4688
+ __name(this, "UpdateDataTableViewDto");
4689
+ }
4690
+ state;
4691
+ };
4692
+ _ts_decorate34([
4693
+ ApiProperty8({
4694
+ description: "Updated filter, sort, and column visibility state"
4695
+ }),
4696
+ IsObject3(),
4697
+ _ts_metadata24("design:type", typeof TableViewState === "undefined" ? Object : TableViewState)
4698
+ ], UpdateDataTableViewDto.prototype, "state", void 0);
4699
+
4700
+ // src/data-table/views/docs/data-table-views.docs.ts
4701
+ function ApiListDataTableViews() {
4702
+ return applyDecorators4(ApiOperation4({
4703
+ summary: "List named table views",
4704
+ description: "Returns the authenticated user's own named views plus all shared views for the given table slug."
4705
+ }), ApiQuery({
4706
+ name: "tableSlug",
4707
+ description: "Slug of the table to fetch views for",
4708
+ example: "cloud-providers",
4709
+ required: true
4710
+ }), ApiResponse4({
4711
+ status: 200,
4712
+ description: "Named views retrieved.",
4713
+ type: [
4714
+ DataTableViewDto
4715
+ ]
4716
+ }), ApiResponse4({
4717
+ status: 401,
4718
+ description: "Unauthorized."
4719
+ }));
4720
+ }
4721
+ __name(ApiListDataTableViews, "ApiListDataTableViews");
4722
+ function ApiCreateDataTableView() {
4723
+ return applyDecorators4(ApiOperation4({
4724
+ summary: "Create named table view",
4725
+ description: "Saves the current table state as a named view snapshot. The name must be unique per user+table."
4726
+ }), ApiBody2({
4727
+ type: CreateDataTableViewDto
4728
+ }), ApiResponse4({
4729
+ status: 201,
4730
+ description: "Named view created.",
4731
+ type: DataTableViewDto
4732
+ }), ApiResponse4({
4733
+ status: 400,
4734
+ description: "Invalid request body."
4735
+ }), ApiResponse4({
4736
+ status: 401,
4737
+ description: "Unauthorized."
4738
+ }));
4739
+ }
4740
+ __name(ApiCreateDataTableView, "ApiCreateDataTableView");
4741
+ function ApiUpdateDataTableView() {
4742
+ return applyDecorators4(ApiOperation4({
4743
+ summary: "Update named table view",
4744
+ description: "Updates the state of an existing named view. Only the owner can update."
4745
+ }), ApiParam({
4746
+ name: "id",
4747
+ description: "UUID of the table view to update"
4748
+ }), ApiBody2({
4749
+ type: UpdateDataTableViewDto
4750
+ }), ApiResponse4({
4751
+ status: 200,
4752
+ description: "View updated.",
4753
+ type: DataTableViewDto
4754
+ }), ApiResponse4({
4755
+ status: 400,
4756
+ description: "Validation failed or not owned by caller."
4757
+ }), ApiResponse4({
4758
+ status: 401,
4759
+ description: "Unauthorized."
4760
+ }), ApiResponse4({
4761
+ status: 404,
4762
+ description: "View not found."
4763
+ }));
4764
+ }
4765
+ __name(ApiUpdateDataTableView, "ApiUpdateDataTableView");
4766
+ function ApiRenameDataTableView() {
4767
+ return applyDecorators4(ApiOperation4({
4768
+ summary: "Rename a named table view",
4769
+ description: "Updates the display name of an existing view. The new name must be unique per user+table. Only the owner can rename."
4770
+ }), ApiParam({
4771
+ name: "id",
4772
+ description: "UUID of the table view to rename"
4773
+ }), ApiBody2({
4774
+ type: RenameDataTableViewDto
4775
+ }), ApiResponse4({
4776
+ status: 200,
4777
+ description: "View renamed.",
4778
+ type: DataTableViewDto
4779
+ }), ApiResponse4({
4780
+ status: 400,
4781
+ description: "Not owned by caller."
4782
+ }), ApiResponse4({
4783
+ status: 401,
4784
+ description: "Unauthorized."
4785
+ }), ApiResponse4({
4786
+ status: 404,
4787
+ description: "View not found."
4788
+ }), ApiResponse4({
4789
+ status: 409,
4790
+ description: "A view with this name already exists."
4791
+ }));
4792
+ }
4793
+ __name(ApiRenameDataTableView, "ApiRenameDataTableView");
4794
+ function ApiToggleShareDataTableView() {
4795
+ return applyDecorators4(ApiOperation4({
4796
+ summary: "Toggle view sharing",
4797
+ description: "Makes a view visible to all users (shared) or restricts it to the owner only (private). Only the owner can toggle sharing."
4798
+ }), ApiParam({
4799
+ name: "id",
4800
+ description: "UUID of the table view"
4801
+ }), ApiBody2({
4802
+ type: ToggleShareDataTableViewDto
4803
+ }), ApiResponse4({
4804
+ status: 200,
4805
+ description: "Sharing status updated.",
4806
+ type: DataTableViewDto
4807
+ }), ApiResponse4({
4808
+ status: 400,
4809
+ description: "Not owned by caller."
4810
+ }), ApiResponse4({
4811
+ status: 401,
4812
+ description: "Unauthorized."
4813
+ }), ApiResponse4({
4814
+ status: 404,
4815
+ description: "View not found."
4816
+ }));
4817
+ }
4818
+ __name(ApiToggleShareDataTableView, "ApiToggleShareDataTableView");
4819
+ function ApiDeleteDataTableView() {
4820
+ return applyDecorators4(ApiOperation4({
4821
+ summary: "Delete named table view",
4822
+ description: "Permanently deletes a named view. Only the owner can delete their own views."
4823
+ }), ApiParam({
4824
+ name: "id",
4825
+ description: "UUID of the table view to delete"
4826
+ }), ApiResponse4({
4827
+ status: 200,
4828
+ description: "View deleted.",
4829
+ type: DataTableViewDto
4830
+ }), ApiResponse4({
4831
+ status: 400,
4832
+ description: "Not owned by caller."
4833
+ }), ApiResponse4({
4834
+ status: 401,
4835
+ description: "Unauthorized."
4836
+ }), ApiResponse4({
4837
+ status: 404,
4838
+ description: "View not found."
4839
+ }));
4840
+ }
4841
+ __name(ApiDeleteDataTableView, "ApiDeleteDataTableView");
4842
+
4843
+ // src/data-table/views/services/data-table-views.service.ts
4844
+ import { createHash as createHash2 } from "crypto";
4845
+ import { Injectable as Injectable16, Logger as Logger15 } from "@nestjs/common";
4846
+ import { ConfigService as ConfigService7 } from "@nestjs/config";
4847
+
4848
+ // src/data-table/views/repositories/data-table-views.repository.ts
4849
+ import { Inject as Inject5, Injectable as Injectable15 } from "@nestjs/common";
4850
+ import { and as and4, eq as eq5 } from "drizzle-orm";
4851
+ function _ts_decorate35(decorators, target, key, desc2) {
4852
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
4853
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
4854
+ 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;
4855
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
4856
+ }
4857
+ __name(_ts_decorate35, "_ts_decorate");
4858
+ function _ts_metadata25(k, v) {
4859
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4860
+ }
4861
+ __name(_ts_metadata25, "_ts_metadata");
4862
+ function _ts_param9(paramIndex, decorator) {
4863
+ return function(target, key) {
4864
+ decorator(target, key, paramIndex);
4865
+ };
4866
+ }
4867
+ __name(_ts_param9, "_ts_param");
4868
+ var NAMED_VIEWS_LIMIT = 100;
4869
+ var DataTableViewsRepository = class extends PrimaryBaseRepository {
4870
+ static {
4871
+ __name(this, "DataTableViewsRepository");
4872
+ }
4873
+ constructor(database, table) {
4874
+ super(database, table);
4875
+ }
4876
+ // Returns personal (non-shared) named views owned by the user for a given table
4877
+ async findPersonalViewsBySlug(userId, tableSlug) {
4878
+ const t = this.table;
4879
+ return this.db.select().from(this.table).where(and4(eq5(t.tableSlug, tableSlug), eq5(t.userId, userId), eq5(t.isShared, false))).orderBy(t.createdAt).limit(NAMED_VIEWS_LIMIT);
4880
+ }
4881
+ // Returns all shared named views for a given table — visible to all users
4882
+ async findSharedViewsBySlug(tableSlug) {
4883
+ const t = this.table;
4884
+ return this.db.select().from(this.table).where(and4(eq5(t.tableSlug, tableSlug), eq5(t.isShared, true))).orderBy(t.createdAt).limit(NAMED_VIEWS_LIMIT);
4885
+ }
4886
+ };
4887
+ DataTableViewsRepository = _ts_decorate35([
4888
+ Injectable15(),
4889
+ _ts_param9(1, Inject5(DATA_TABLE_VIEWS_TABLE)),
4890
+ _ts_metadata25("design:type", Function),
4891
+ _ts_metadata25("design:paramtypes", [
4892
+ typeof PrimaryDatabaseService === "undefined" ? Object : PrimaryDatabaseService,
4893
+ typeof PgTable === "undefined" ? Object : PgTable
4894
+ ])
4895
+ ], DataTableViewsRepository);
4896
+
4897
+ // src/data-table/views/services/data-table-views.service.ts
4898
+ function _ts_decorate36(decorators, target, key, desc2) {
4899
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
4900
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
4901
+ 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;
4902
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
4903
+ }
4904
+ __name(_ts_decorate36, "_ts_decorate");
4905
+ function _ts_metadata26(k, v) {
4906
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4907
+ }
4908
+ __name(_ts_metadata26, "_ts_metadata");
4909
+ function computeChecksum(value) {
4910
+ return createHash2("sha256").update(JSON.stringify(value)).digest("hex");
4911
+ }
4912
+ __name(computeChecksum, "computeChecksum");
4913
+ var DataTableViewsService = class _DataTableViewsService {
4914
+ static {
4915
+ __name(this, "DataTableViewsService");
4916
+ }
4917
+ dataTableViewsRepository;
4918
+ cacheService;
4919
+ configService;
4920
+ logger = new Logger15(_DataTableViewsService.name);
4921
+ constructor(dataTableViewsRepository, cacheService, configService) {
4922
+ this.dataTableViewsRepository = dataTableViewsRepository;
4923
+ this.cacheService = cacheService;
4924
+ this.configService = configService;
4925
+ }
4926
+ // Builds the Redis key for a user's personal (non-shared) views for a given table
4927
+ personalViewsKey(userId, tableSlug) {
4928
+ return `views:personal:${userId}:${tableSlug}`;
4929
+ }
4930
+ // Builds the Redis key for all shared views for a given table — same key for all users
4931
+ sharedViewsKey(tableSlug) {
4932
+ return `views:shared:${tableSlug}`;
4933
+ }
4934
+ // Returns configured TTL for named views in seconds, defaulting to 86400 (24h)
4935
+ get viewsTtl() {
4936
+ return this.configService.get("TABLE_VIEWS_CACHE_TTL") ?? 86400;
4937
+ }
4938
+ // Fetches personal views from cache; falls back to DB and warms cache on miss
4939
+ async getOrCachePersonalViews(userId, tableSlug) {
4940
+ const key = this.personalViewsKey(userId, tableSlug);
4941
+ const cached = await this.cacheService.get(key);
4942
+ if (cached) {
4943
+ this.logger.debug(`Cache hit for personal views: user=${userId}, table=${tableSlug}`);
4944
+ return cached;
4945
+ }
4946
+ const rows = await this.dataTableViewsRepository.findPersonalViewsBySlug(userId, tableSlug);
4947
+ await this.cacheService.set(key, rows, this.viewsTtl);
4948
+ return rows;
4949
+ }
4950
+ // Fetches shared views from cache; falls back to DB and warms cache on miss
4951
+ async getOrCacheSharedViews(tableSlug) {
4952
+ const key = this.sharedViewsKey(tableSlug);
4953
+ const cached = await this.cacheService.get(key);
4954
+ if (cached) {
4955
+ this.logger.debug(`Cache hit for shared views: table=${tableSlug}`);
4956
+ return cached;
4957
+ }
4958
+ const rows = await this.dataTableViewsRepository.findSharedViewsBySlug(tableSlug);
4959
+ await this.cacheService.set(key, rows, this.viewsTtl);
4960
+ return rows;
4961
+ }
4962
+ // Deletes personal and/or shared cache keys based on which pools the mutation affects
4963
+ async invalidateViewsCache(userId, tableSlug, affectsPersonal, affectsShared) {
4964
+ const toDelete = [];
4965
+ if (affectsPersonal) toDelete.push(this.personalViewsKey(userId, tableSlug));
4966
+ if (affectsShared) toDelete.push(this.sharedViewsKey(tableSlug));
4967
+ if (toDelete.length > 0) await this.cacheService.del(...toDelete);
4968
+ }
4969
+ // Returns personal + shared named views — each pool fetched from cache or DB in parallel
4970
+ async findViews(userId, tableSlug) {
4971
+ const [personalRows, sharedRows] = await Promise.all([
4972
+ this.getOrCachePersonalViews(userId, tableSlug),
4973
+ this.getOrCacheSharedViews(tableSlug)
4974
+ ]);
4975
+ return [
4976
+ ...personalRows,
4977
+ ...sharedRows
4978
+ ].map((row) => DataTableViewDto.from(row, userId));
4979
+ }
4980
+ // Creates a named snapshot and invalidates the relevant cache pool
4981
+ async createView(userId, dto) {
4982
+ const view = await this.dataTableViewsRepository.create({
4983
+ userId,
4984
+ tableSlug: dto.tableSlug,
4985
+ name: dto.name,
4986
+ state: dto.state,
4987
+ isShared: dto.isShared ?? false
4988
+ });
4989
+ this.logger.log(`Created view "${dto.name}" for user: ${userId}, table: ${dto.tableSlug}`);
4990
+ const isShared = dto.isShared ?? false;
4991
+ await this.invalidateViewsCache(userId, dto.tableSlug, !isShared, isShared);
4992
+ return DataTableViewDto.from(view, userId);
4993
+ }
4994
+ // Updates the state of a named view — skips DB write if state is unchanged
4995
+ async updateView(userId, id, dto) {
4996
+ const view = await this.dataTableViewsRepository.findById(id);
4997
+ if (!view) throw new NotFoundException("Table view not found.");
4998
+ if (view.userId !== userId) throw new BadRequestException("You do not have permission to update this view.");
4999
+ if (computeChecksum(dto.state) === computeChecksum(view.state)) {
5000
+ this.logger.log(`State unchanged for view ${id} \u2014 skipping DB write`);
5001
+ return DataTableViewDto.from(view, userId);
5002
+ }
5003
+ const updated = await this.dataTableViewsRepository.update(id, {
5004
+ state: dto.state
5005
+ });
5006
+ this.logger.log(`Updated state for view ${id}, user: ${userId}`);
5007
+ await this.invalidateViewsCache(userId, view.tableSlug, !view.isShared, view.isShared);
5008
+ return DataTableViewDto.from(updated, userId);
5009
+ }
5010
+ // Toggles the sharing status of a named view — updates both personal and shared cache
5011
+ async toggleShareView(userId, id, isShared) {
5012
+ const view = await this.dataTableViewsRepository.findById(id);
5013
+ if (!view) throw new NotFoundException("Table view not found.");
5014
+ if (view.userId !== userId) throw new BadRequestException("You do not have permission to share this view.");
5015
+ const updated = await this.dataTableViewsRepository.update(id, {
5016
+ isShared
5017
+ });
5018
+ this.logger.log(`Set isShared=${isShared} for view ${id}, user: ${userId}`);
5019
+ await this.invalidateViewsCache(userId, view.tableSlug, true, true);
5020
+ return DataTableViewDto.from(updated, userId);
5021
+ }
5022
+ // Renames a named view — enforces unique name per user+table, invalidates personal cache
5023
+ async renameView(userId, id, name) {
5024
+ const view = await this.dataTableViewsRepository.findById(id);
5025
+ if (!view) throw new NotFoundException("Table view not found.");
5026
+ if (view.userId !== userId) throw new BadRequestException("You do not have permission to rename this view.");
5027
+ const existing = await this.dataTableViewsRepository.findOne({
5028
+ userId,
5029
+ tableSlug: view.tableSlug,
5030
+ name,
5031
+ isShared: false
5032
+ });
5033
+ if (existing && existing.id !== id) {
5034
+ throw new ConflictException({
5035
+ label: "Name Already Taken",
5036
+ detail: "A view with this name already exists for this table.",
5037
+ errors: [
5038
+ {
5039
+ field: "name",
5040
+ message: "Name already taken"
5041
+ }
5042
+ ]
5043
+ });
5044
+ }
5045
+ const updated = await this.dataTableViewsRepository.update(id, {
5046
+ name
5047
+ });
5048
+ this.logger.log(`Renamed view ${id} to "${name}" for user: ${userId}`);
5049
+ await this.invalidateViewsCache(userId, view.tableSlug, !view.isShared, view.isShared);
5050
+ return DataTableViewDto.from(updated, userId);
5051
+ }
5052
+ // Deletes a named view and invalidates the relevant cache pool
5053
+ async deleteView(userId, id) {
5054
+ const view = await this.dataTableViewsRepository.findById(id);
5055
+ if (!view) throw new NotFoundException("Table view not found.");
5056
+ if (view.userId !== userId) throw new BadRequestException("You do not have permission to delete this view.");
5057
+ await this.dataTableViewsRepository.delete(id);
5058
+ this.logger.log(`Deleted view ${id} for user: ${userId}`);
5059
+ await this.invalidateViewsCache(userId, view.tableSlug, !view.isShared, view.isShared);
5060
+ return DataTableViewDto.from(view, userId);
5061
+ }
5062
+ };
5063
+ DataTableViewsService = _ts_decorate36([
5064
+ Injectable16(),
5065
+ _ts_metadata26("design:type", Function),
5066
+ _ts_metadata26("design:paramtypes", [
5067
+ typeof DataTableViewsRepository === "undefined" ? Object : DataTableViewsRepository,
5068
+ typeof CacheService === "undefined" ? Object : CacheService,
5069
+ typeof ConfigService7 === "undefined" ? Object : ConfigService7
5070
+ ])
5071
+ ], DataTableViewsService);
5072
+
5073
+ // src/data-table/views/controllers/data-table-views.controller.ts
5074
+ function _ts_decorate37(decorators, target, key, desc2) {
5075
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
5076
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
5077
+ 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;
5078
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
5079
+ }
5080
+ __name(_ts_decorate37, "_ts_decorate");
5081
+ function _ts_metadata27(k, v) {
5082
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
5083
+ }
5084
+ __name(_ts_metadata27, "_ts_metadata");
5085
+ function _ts_param10(paramIndex, decorator) {
5086
+ return function(target, key) {
5087
+ decorator(target, key, paramIndex);
5088
+ };
5089
+ }
5090
+ __name(_ts_param10, "_ts_param");
5091
+ var DataTableViewsController = class _DataTableViewsController {
5092
+ static {
5093
+ __name(this, "DataTableViewsController");
5094
+ }
5095
+ dataTableViewsService;
5096
+ logger = new Logger16(_DataTableViewsController.name);
5097
+ constructor(dataTableViewsService) {
5098
+ this.dataTableViewsService = dataTableViewsService;
5099
+ }
5100
+ // Returns all named views for the given table — own plus shared
5101
+ findViews(userId, tableSlug) {
5102
+ this.logger.log(`GET /table-views?tableSlug=${tableSlug} - User: ${userId}`);
5103
+ return this.dataTableViewsService.findViews(userId, tableSlug);
5104
+ }
5105
+ // Creates a named snapshot of the current table state
5106
+ createView(userId, dto) {
5107
+ this.logger.log(`POST /table-views - User: ${userId}, table: ${dto.tableSlug}`);
5108
+ return this.dataTableViewsService.createView(userId, dto);
5109
+ }
5110
+ // Updates state of an existing named view
5111
+ updateView(userId, id, dto) {
5112
+ this.logger.log(`PATCH /table-views/${id} - User: ${userId}`);
5113
+ return this.dataTableViewsService.updateView(userId, id, dto);
5114
+ }
5115
+ // Renames an existing named view — enforces unique name per user+table
5116
+ renameView(userId, id, dto) {
5117
+ this.logger.log(`PATCH /table-views/${id}/rename - User: ${userId}`);
5118
+ return this.dataTableViewsService.renameView(userId, id, dto.name);
5119
+ }
5120
+ // Toggles sharing visibility of a named view
5121
+ toggleShareView(userId, id, dto) {
5122
+ this.logger.log(`PATCH /table-views/${id}/share - User: ${userId}`);
5123
+ return this.dataTableViewsService.toggleShareView(userId, id, dto.isShared);
5124
+ }
5125
+ // Deletes a named view owned by the authenticated user
5126
+ deleteView(userId, id) {
5127
+ this.logger.log(`DELETE /table-views/${id} - User: ${userId}`);
5128
+ return this.dataTableViewsService.deleteView(userId, id);
5129
+ }
5130
+ };
5131
+ _ts_decorate37([
5132
+ Get3(),
5133
+ ApiListDataTableViews(),
5134
+ _ts_param10(0, UserId()),
5135
+ _ts_param10(1, Query("tableSlug")),
5136
+ _ts_metadata27("design:type", Function),
5137
+ _ts_metadata27("design:paramtypes", [
5138
+ String,
5139
+ String
5140
+ ]),
5141
+ _ts_metadata27("design:returntype", typeof Promise === "undefined" ? Object : Promise)
5142
+ ], DataTableViewsController.prototype, "findViews", null);
5143
+ _ts_decorate37([
5144
+ Post2(),
5145
+ HttpCode3(HttpStatus22.CREATED),
5146
+ ApiCreateDataTableView(),
5147
+ _ts_param10(0, UserId()),
5148
+ _ts_param10(1, Body2()),
5149
+ _ts_metadata27("design:type", Function),
5150
+ _ts_metadata27("design:paramtypes", [
5151
+ String,
5152
+ typeof CreateDataTableViewDto === "undefined" ? Object : CreateDataTableViewDto
5153
+ ]),
5154
+ _ts_metadata27("design:returntype", typeof Promise === "undefined" ? Object : Promise)
5155
+ ], DataTableViewsController.prototype, "createView", null);
5156
+ _ts_decorate37([
5157
+ Patch(":id"),
5158
+ ApiUpdateDataTableView(),
5159
+ _ts_param10(0, UserId()),
5160
+ _ts_param10(1, Param("id")),
5161
+ _ts_param10(2, Body2()),
5162
+ _ts_metadata27("design:type", Function),
5163
+ _ts_metadata27("design:paramtypes", [
5164
+ String,
5165
+ String,
5166
+ typeof UpdateDataTableViewDto === "undefined" ? Object : UpdateDataTableViewDto
5167
+ ]),
5168
+ _ts_metadata27("design:returntype", typeof Promise === "undefined" ? Object : Promise)
5169
+ ], DataTableViewsController.prototype, "updateView", null);
5170
+ _ts_decorate37([
5171
+ Patch(":id/rename"),
5172
+ ApiRenameDataTableView(),
5173
+ _ts_param10(0, UserId()),
5174
+ _ts_param10(1, Param("id")),
5175
+ _ts_param10(2, Body2()),
5176
+ _ts_metadata27("design:type", Function),
5177
+ _ts_metadata27("design:paramtypes", [
5178
+ String,
5179
+ String,
5180
+ typeof RenameDataTableViewDto === "undefined" ? Object : RenameDataTableViewDto
5181
+ ]),
5182
+ _ts_metadata27("design:returntype", typeof Promise === "undefined" ? Object : Promise)
5183
+ ], DataTableViewsController.prototype, "renameView", null);
5184
+ _ts_decorate37([
5185
+ Patch(":id/share"),
5186
+ ApiToggleShareDataTableView(),
5187
+ _ts_param10(0, UserId()),
5188
+ _ts_param10(1, Param("id")),
5189
+ _ts_param10(2, Body2()),
5190
+ _ts_metadata27("design:type", Function),
5191
+ _ts_metadata27("design:paramtypes", [
5192
+ String,
5193
+ String,
5194
+ typeof ToggleShareDataTableViewDto === "undefined" ? Object : ToggleShareDataTableViewDto
5195
+ ]),
5196
+ _ts_metadata27("design:returntype", typeof Promise === "undefined" ? Object : Promise)
5197
+ ], DataTableViewsController.prototype, "toggleShareView", null);
5198
+ _ts_decorate37([
5199
+ Delete(":id"),
5200
+ ApiDeleteDataTableView(),
5201
+ _ts_param10(0, UserId()),
5202
+ _ts_param10(1, Param("id")),
5203
+ _ts_metadata27("design:type", Function),
5204
+ _ts_metadata27("design:paramtypes", [
5205
+ String,
5206
+ String
5207
+ ]),
5208
+ _ts_metadata27("design:returntype", typeof Promise === "undefined" ? Object : Promise)
5209
+ ], DataTableViewsController.prototype, "deleteView", null);
5210
+ DataTableViewsController = _ts_decorate37([
5211
+ ApiTags4("Table Views"),
5212
+ ApiBearerAuth2(),
5213
+ Controller4("table-views"),
5214
+ _ts_metadata27("design:type", Function),
5215
+ _ts_metadata27("design:paramtypes", [
5216
+ typeof DataTableViewsService === "undefined" ? Object : DataTableViewsService
5217
+ ])
5218
+ ], DataTableViewsController);
5219
+
5220
+ // src/data-table/data-table.module.ts
5221
+ function _ts_decorate38(decorators, target, key, desc2) {
5222
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
5223
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
5224
+ 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;
5225
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
5226
+ }
5227
+ __name(_ts_decorate38, "_ts_decorate");
5228
+ var DataTableModule = class _DataTableModule {
5229
+ static {
5230
+ __name(this, "DataTableModule");
5231
+ }
5232
+ static forRoot(options) {
5233
+ return {
5234
+ global: true,
5235
+ module: _DataTableModule,
5236
+ imports: [
5237
+ ConfigModule4,
5238
+ CacheModule
5239
+ ],
5240
+ controllers: [
5241
+ DataTableStateController,
5242
+ DataTableViewsController
5243
+ ],
5244
+ providers: [
5245
+ {
5246
+ provide: DATA_TABLE_VIEWS_TABLE,
5247
+ useValue: options.tableViews
5248
+ },
5249
+ DataTableViewsService,
5250
+ DataTableViewsRepository,
5251
+ DataTableStateService
5252
+ ],
5253
+ exports: [
5254
+ DataTableViewsService,
5255
+ DataTableStateService
5256
+ ]
5257
+ };
5258
+ }
5259
+ };
5260
+ DataTableModule = _ts_decorate38([
5261
+ Module8({})
5262
+ ], DataTableModule);
5263
+
5264
+ // src/drizzle-pg-core.ts
5265
+ var drizzle_pg_core_exports = {};
5266
+ __reExport(drizzle_pg_core_exports, pg_core_star);
5267
+ import * as pg_core_star from "drizzle-orm/pg-core";
5268
+
5269
+ // src/data-table/schema/data-table-views.table.ts
5270
+ function dataTableViewsColumns() {
5271
+ return {
5272
+ id: (0, drizzle_pg_core_exports.uuid)("id").primaryKey().defaultRandom(),
5273
+ userId: (0, drizzle_pg_core_exports.uuid)("user_id").notNull(),
5274
+ tableSlug: (0, drizzle_pg_core_exports.varchar)("table_slug", {
5275
+ length: 100
5276
+ }).notNull(),
5277
+ name: (0, drizzle_pg_core_exports.varchar)("name", {
5278
+ length: 100
5279
+ }).notNull(),
5280
+ state: (0, drizzle_pg_core_exports.jsonb)("state").notNull().$type(),
5281
+ isShared: (0, drizzle_pg_core_exports.boolean)("is_shared").notNull().default(false),
5282
+ createdAt: (0, drizzle_pg_core_exports.timestamp)("created_at", {
5283
+ withTimezone: true
5284
+ }).notNull().defaultNow(),
5285
+ updatedAt: (0, drizzle_pg_core_exports.timestamp)("updated_at", {
5286
+ withTimezone: true
5287
+ }).$onUpdate(() => /* @__PURE__ */ new Date())
5288
+ };
5289
+ }
5290
+ __name(dataTableViewsColumns, "dataTableViewsColumns");
5291
+ function dataTableViewsIndexes(table) {
5292
+ return [
5293
+ (0, drizzle_pg_core_exports.index)("table_views_user_table_idx").on(table.userId, table.tableSlug),
5294
+ (0, drizzle_pg_core_exports.index)("table_views_shared_slug_idx").on(table.tableSlug, table.isShared),
5295
+ (0, drizzle_pg_core_exports.uniqueIndex)("table_views_user_table_name_shared_unique").on(table.userId, table.tableSlug, table.name, table.isShared)
5296
+ ];
5297
+ }
5298
+ __name(dataTableViewsIndexes, "dataTableViewsIndexes");
3750
5299
  export {
3751
5300
  AccessToken,
3752
5301
  AuthConfigModule,
3753
5302
  BadGatewayException,
3754
5303
  BadRequestException,
5304
+ CACHE_PROVIDER,
5305
+ CacheModule,
5306
+ CacheService,
3755
5307
  ConflictException,
5308
+ CookieDomain,
3756
5309
  CorrelationIdMiddleware,
5310
+ CreateDataTableViewDto,
5311
+ DATA_TABLE_VIEWS_TABLE,
3757
5312
  DEFAULT_CORRELATION_HEADER,
5313
+ DataTableModule,
5314
+ DataTableStateService,
5315
+ DataTableViewDto,
5316
+ DataTableViewsService,
3758
5317
  DatabaseModule,
3759
5318
  EmailModule,
3760
5319
  EmailService,
3761
- ForbiddenException2 as ForbiddenException,
5320
+ FilterProcessor,
5321
+ ForbiddenException,
3762
5322
  GoneException,
3763
5323
  HttpExceptionFilter,
3764
5324
  HttpLoggerInterceptor,
3765
5325
  HttpProblemException,
3766
- InternalServerErrorException3 as InternalServerErrorException,
5326
+ InternalServerErrorException,
3767
5327
  JwtAuthService,
3768
5328
  LOGGER_MODULE_OPTIONS,
3769
5329
  LoggerModule,
@@ -3778,7 +5338,10 @@ export {
3778
5338
  PrimaryDatabaseService,
3779
5339
  Public,
3780
5340
  RESET_KEY,
5341
+ RedisCacheProvider,
5342
+ RefreshCookieOptions,
3781
5343
  RefreshTokenCookie,
5344
+ RenameDataTableViewDto,
3782
5345
  RequestTimeoutException,
3783
5346
  Reset,
3784
5347
  RootModule,
@@ -3787,21 +5350,28 @@ export {
3787
5350
  ServiceUnavailableException,
3788
5351
  SessionData,
3789
5352
  SkipCsrf,
5353
+ SuccessResponseDto,
5354
+ TableResponseDto,
3790
5355
  Tenant,
3791
5356
  TenantBaseRepository,
3792
5357
  TenantContextService,
3793
5358
  TenantDatabaseService,
5359
+ ToggleShareDataTableViewDto,
3794
5360
  TokenType,
3795
5361
  TooManyRequestsException,
3796
- UnauthorizedException3 as UnauthorizedException,
5362
+ UnauthorizedException,
3797
5363
  UnprocessableEntityException,
3798
5364
  UnsupportedMediaTypeException,
5365
+ UpdateDataTableViewDto,
5366
+ UpsertDataTableStateDto,
3799
5367
  UserId,
3800
5368
  ValidationException,
3801
5369
  VrittiAuthGuard,
3802
5370
  addCorrelationIdToResponse,
3803
5371
  configureApiSdk,
3804
5372
  correlationStorage,
5373
+ dataTableViewsColumns,
5374
+ dataTableViewsIndexes,
3805
5375
  defineConfig,
3806
5376
  extractCountryFromPhone,
3807
5377
  generateCorrelationId,
@@ -3810,6 +5380,7 @@ export {
3810
5380
  getHttpStatusTitle,
3811
5381
  getJwtExpiry,
3812
5382
  getRefreshCookieOptions,
5383
+ getRefreshCookieOptionsForHost,
3813
5384
  getTokenExpiry,
3814
5385
  hashToken,
3815
5386
  jwtConfigFactory,