@vritti/api-sdk 0.2.10 → 0.3.2
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/cache.cjs +252 -0
- package/dist/cache.cjs.map +1 -0
- package/dist/cache.d.cts +25 -0
- package/dist/cache.d.ts +25 -0
- package/dist/cache.js +214 -0
- package/dist/cache.js.map +1 -0
- package/dist/cache.service-_SuJIcNA.d.cts +20 -0
- package/dist/cache.service-_SuJIcNA.d.ts +20 -0
- package/dist/catalog-resolver.cjs +364 -0
- package/dist/catalog-resolver.cjs.map +1 -0
- package/dist/catalog-resolver.d.cts +109 -0
- package/dist/catalog-resolver.d.ts +109 -0
- package/dist/catalog-resolver.js +330 -0
- package/dist/catalog-resolver.js.map +1 -0
- package/dist/email.cjs +691 -0
- package/dist/email.cjs.map +1 -0
- package/dist/email.d.cts +35 -0
- package/dist/email.d.ts +35 -0
- package/dist/email.js +665 -0
- package/dist/email.js.map +1 -0
- package/dist/fastify-augmentation-CQPBNS5a.d.cts +105 -0
- package/dist/fastify-augmentation-CQPBNS5a.d.ts +105 -0
- package/dist/icons.cjs +13803 -0
- package/dist/icons.cjs.map +1 -0
- package/dist/icons.d.cts +8 -0
- package/dist/icons.d.ts +8 -0
- package/dist/icons.js +13778 -0
- package/dist/icons.js.map +1 -0
- package/dist/index.cjs +742 -1367
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +103 -181
- package/dist/index.d.ts +103 -181
- package/dist/index.js +601 -1233
- package/dist/index.js.map +1 -1
- package/dist/license.cjs +104 -0
- package/dist/license.cjs.map +1 -0
- package/dist/license.d.cts +32 -0
- package/dist/license.d.ts +32 -0
- package/dist/license.js +75 -0
- package/dist/license.js.map +1 -0
- package/dist/money.cjs +93 -6
- package/dist/money.cjs.map +1 -1
- package/dist/money.d.cts +13 -1
- package/dist/money.d.ts +13 -1
- package/dist/money.js +115 -3
- package/dist/money.js.map +1 -1
- package/dist/nats.cjs +196 -179
- package/dist/nats.cjs.map +1 -1
- package/dist/nats.d.cts +13 -11
- package/dist/nats.d.ts +13 -11
- package/dist/nats.js +172 -155
- package/dist/nats.js.map +1 -1
- package/dist/types-DQRwj5rr.d.cts +113 -0
- package/dist/types-DQRwj5rr.d.ts +113 -0
- package/package.json +55 -1
package/dist/index.js
CHANGED
|
@@ -3,10 +3,6 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
3
3
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
4
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
5
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
6
|
var __copyProps = (to, from, except, desc3) => {
|
|
11
7
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
8
|
for (let key of __getOwnPropNames(from))
|
|
@@ -32,6 +28,7 @@ var AUTH_CONFIG_DEFAULTS = {
|
|
|
32
28
|
authHeaderName: "authorization",
|
|
33
29
|
tokenPrefix: "Bearer",
|
|
34
30
|
csrfExemptSessionTypes: [],
|
|
31
|
+
csrfExemptTransports: [],
|
|
35
32
|
refreshTokenBindingExemptSessionTypes: []
|
|
36
33
|
}
|
|
37
34
|
};
|
|
@@ -53,6 +50,18 @@ import { Global, Module } from "@nestjs/common";
|
|
|
53
50
|
// src/request/services/request.service.ts
|
|
54
51
|
import { Inject, Injectable, Scope } from "@nestjs/common";
|
|
55
52
|
import { REQUEST } from "@nestjs/core";
|
|
53
|
+
|
|
54
|
+
// src/context/resolve-request.ts
|
|
55
|
+
function resolveInjectedRequest(injected) {
|
|
56
|
+
const candidate = injected;
|
|
57
|
+
if (candidate && candidate.headers === void 0 && candidate.req) {
|
|
58
|
+
return candidate.req;
|
|
59
|
+
}
|
|
60
|
+
return injected;
|
|
61
|
+
}
|
|
62
|
+
__name(resolveInjectedRequest, "resolveInjectedRequest");
|
|
63
|
+
|
|
64
|
+
// src/request/services/request.service.ts
|
|
56
65
|
function _ts_decorate(decorators, target, key, desc3) {
|
|
57
66
|
var c = arguments.length, r = c < 3 ? target : desc3 === null ? desc3 = Object.getOwnPropertyDescriptor(target, key) : desc3, d;
|
|
58
67
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc3);
|
|
@@ -74,12 +83,17 @@ var RequestService = class {
|
|
|
74
83
|
static {
|
|
75
84
|
__name(this, "RequestService");
|
|
76
85
|
}
|
|
77
|
-
|
|
86
|
+
injectedRequest;
|
|
78
87
|
config;
|
|
79
|
-
constructor(
|
|
80
|
-
this.
|
|
88
|
+
constructor(injectedRequest, config) {
|
|
89
|
+
this.injectedRequest = injectedRequest;
|
|
81
90
|
this.config = config;
|
|
82
91
|
}
|
|
92
|
+
// For GraphQL, @Inject(REQUEST) is the { req, reply } context wrapper, not the Fastify request;
|
|
93
|
+
// unwrap so every accessor below works identically across both transports.
|
|
94
|
+
get request() {
|
|
95
|
+
return resolveInjectedRequest(this.injectedRequest);
|
|
96
|
+
}
|
|
83
97
|
// Extracts the bearer access token from the Authorization header
|
|
84
98
|
getAccessToken() {
|
|
85
99
|
const authHeader = this.request.headers?.[this.config.guard.authHeaderName];
|
|
@@ -160,6 +174,50 @@ import { ForbiddenException, Inject as Inject3, Injectable as Injectable3, Logge
|
|
|
160
174
|
import { SSE_METADATA } from "@nestjs/common/constants";
|
|
161
175
|
import { Reflector } from "@nestjs/core";
|
|
162
176
|
|
|
177
|
+
// src/context/extractors/graphql.extractor.ts
|
|
178
|
+
var graphqlExtractor = {
|
|
179
|
+
getRequest: /* @__PURE__ */ __name((host) => host.getArgByIndex(2).req, "getRequest"),
|
|
180
|
+
getResponse: /* @__PURE__ */ __name((host) => host.getArgByIndex(2).reply, "getResponse")
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
// src/context/extractors/http.extractor.ts
|
|
184
|
+
var httpExtractor = {
|
|
185
|
+
getRequest: /* @__PURE__ */ __name((host) => host.switchToHttp().getRequest(), "getRequest"),
|
|
186
|
+
getResponse: /* @__PURE__ */ __name((host) => host.switchToHttp().getResponse(), "getResponse")
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
// src/context/context.registry.ts
|
|
190
|
+
var registry = /* @__PURE__ */ new Map([
|
|
191
|
+
[
|
|
192
|
+
"http",
|
|
193
|
+
httpExtractor
|
|
194
|
+
],
|
|
195
|
+
[
|
|
196
|
+
"graphql",
|
|
197
|
+
graphqlExtractor
|
|
198
|
+
]
|
|
199
|
+
]);
|
|
200
|
+
function registerTransport(type, extractor) {
|
|
201
|
+
registry.set(type, extractor);
|
|
202
|
+
}
|
|
203
|
+
__name(registerTransport, "registerTransport");
|
|
204
|
+
function resolveExtractor(type) {
|
|
205
|
+
return registry.get(type) ?? httpExtractor;
|
|
206
|
+
}
|
|
207
|
+
__name(resolveExtractor, "resolveExtractor");
|
|
208
|
+
|
|
209
|
+
// src/context/get-request.ts
|
|
210
|
+
function getRequestFromContext(host) {
|
|
211
|
+
return resolveExtractor(host.getType()).getRequest(host);
|
|
212
|
+
}
|
|
213
|
+
__name(getRequestFromContext, "getRequestFromContext");
|
|
214
|
+
|
|
215
|
+
// src/context/get-response.ts
|
|
216
|
+
function getResponseFromContext(host) {
|
|
217
|
+
return resolveExtractor(host.getType()).getResponse(host);
|
|
218
|
+
}
|
|
219
|
+
__name(getResponseFromContext, "getResponseFromContext");
|
|
220
|
+
|
|
163
221
|
// src/auth/decorators/require-session.decorator.ts
|
|
164
222
|
import { SetMetadata } from "@nestjs/common";
|
|
165
223
|
var REQUIRE_SESSION_KEY = "requiredSessionTypes";
|
|
@@ -178,7 +236,8 @@ import { JwtService } from "@nestjs/jwt";
|
|
|
178
236
|
function parseExpiryToMs(expiry) {
|
|
179
237
|
const match = expiry.match(/^(\d+)([smhdwy])$/);
|
|
180
238
|
if (!match) throw new Error(`Invalid expiry format: ${expiry}`);
|
|
181
|
-
const
|
|
239
|
+
const [, digits = "", unit = ""] = match;
|
|
240
|
+
const value = Number.parseInt(digits, 10);
|
|
182
241
|
const multipliers = {
|
|
183
242
|
s: 1e3,
|
|
184
243
|
m: 6e4,
|
|
@@ -187,7 +246,9 @@ function parseExpiryToMs(expiry) {
|
|
|
187
246
|
w: 6048e5,
|
|
188
247
|
y: 31536e6
|
|
189
248
|
};
|
|
190
|
-
|
|
249
|
+
const multiplier = multipliers[unit];
|
|
250
|
+
if (multiplier === void 0) throw new Error(`Invalid expiry format: ${expiry}`);
|
|
251
|
+
return value * multiplier;
|
|
191
252
|
}
|
|
192
253
|
__name(parseExpiryToMs, "parseExpiryToMs");
|
|
193
254
|
|
|
@@ -374,14 +435,15 @@ var VrittiAuthGuard = class _VrittiAuthGuard {
|
|
|
374
435
|
this.config = config;
|
|
375
436
|
}
|
|
376
437
|
async canActivate(context) {
|
|
377
|
-
const request = context
|
|
378
|
-
const reply = context
|
|
438
|
+
const request = getRequestFromContext(context);
|
|
439
|
+
const reply = getResponseFromContext(context);
|
|
379
440
|
const route = `${request.method} ${request.url}`;
|
|
380
441
|
request.authConfig = this.config;
|
|
442
|
+
const csrfExemptTransports = this.config.guard.csrfExemptTransports ?? [];
|
|
381
443
|
const skipCsrf = this.reflector.getAllAndOverride(SKIP_CSRF_KEY, [
|
|
382
444
|
context.getHandler(),
|
|
383
445
|
context.getClass()
|
|
384
|
-
]);
|
|
446
|
+
]) || csrfExemptTransports.includes(context.getType());
|
|
385
447
|
const isPublic = this.reflector.getAllAndOverride("isPublic", [
|
|
386
448
|
context.getHandler(),
|
|
387
449
|
context.getClass()
|
|
@@ -594,15 +656,21 @@ AuthConfigModule = _ts_decorate5([
|
|
|
594
656
|
// src/auth/decorators/access-token.decorator.ts
|
|
595
657
|
import { createParamDecorator } from "@nestjs/common";
|
|
596
658
|
var AccessToken = createParamDecorator((_data, ctx) => {
|
|
597
|
-
const request = ctx
|
|
659
|
+
const request = getRequestFromContext(ctx);
|
|
598
660
|
const authHeader = request.headers.authorization;
|
|
599
661
|
return authHeader?.replace("Bearer ", "") || "";
|
|
600
662
|
});
|
|
601
663
|
|
|
602
|
-
// src/auth/decorators/
|
|
664
|
+
// src/auth/decorators/client-ip.decorator.ts
|
|
603
665
|
import { createParamDecorator as createParamDecorator2 } from "@nestjs/common";
|
|
604
|
-
var
|
|
605
|
-
|
|
666
|
+
var ClientIp = createParamDecorator2((_data, ctx) => {
|
|
667
|
+
return getRequestFromContext(ctx).ip;
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
// src/auth/decorators/cookie-domain.decorator.ts
|
|
671
|
+
import { createParamDecorator as createParamDecorator3 } from "@nestjs/common";
|
|
672
|
+
var CookieDomain = createParamDecorator3((_data, ctx) => {
|
|
673
|
+
const request = getRequestFromContext(ctx);
|
|
606
674
|
const forwarded = request.headers["x-forwarded-host"];
|
|
607
675
|
const raw = Array.isArray(forwarded) ? forwarded[0] : forwarded;
|
|
608
676
|
const hostStr = raw ?? request.hostname;
|
|
@@ -612,16 +680,16 @@ var CookieDomain = createParamDecorator2((_data, ctx) => {
|
|
|
612
680
|
});
|
|
613
681
|
|
|
614
682
|
// src/auth/decorators/cookie-name.decorator.ts
|
|
615
|
-
import { createParamDecorator as
|
|
616
|
-
var CookieName =
|
|
617
|
-
const request = ctx
|
|
683
|
+
import { createParamDecorator as createParamDecorator4 } from "@nestjs/common";
|
|
684
|
+
var CookieName = createParamDecorator4((_data, ctx) => {
|
|
685
|
+
const request = getRequestFromContext(ctx);
|
|
618
686
|
return request.authConfig?.cookie.refreshCookieName ?? AUTH_CONFIG_DEFAULTS.cookie.refreshCookieName;
|
|
619
687
|
});
|
|
620
688
|
|
|
621
689
|
// src/auth/decorators/hostname.decorator.ts
|
|
622
|
-
import { createParamDecorator as
|
|
623
|
-
var Hostname =
|
|
624
|
-
const request = ctx
|
|
690
|
+
import { createParamDecorator as createParamDecorator5 } from "@nestjs/common";
|
|
691
|
+
var Hostname = createParamDecorator5((_data, ctx) => {
|
|
692
|
+
const request = getRequestFromContext(ctx);
|
|
625
693
|
const forwarded = request.headers["x-forwarded-host"];
|
|
626
694
|
const raw = Array.isArray(forwarded) ? forwarded[0] : forwarded;
|
|
627
695
|
const hostStr = raw ?? request.hostname;
|
|
@@ -633,7 +701,7 @@ import { SetMetadata as SetMetadata3 } from "@nestjs/common";
|
|
|
633
701
|
var Public = /* @__PURE__ */ __name(() => SetMetadata3("isPublic", true), "Public");
|
|
634
702
|
|
|
635
703
|
// src/auth/decorators/refresh-cookie-options.decorator.ts
|
|
636
|
-
import { createParamDecorator as
|
|
704
|
+
import { createParamDecorator as createParamDecorator6 } from "@nestjs/common";
|
|
637
705
|
|
|
638
706
|
// src/exceptions/bad-gateway.exception.ts
|
|
639
707
|
import { HttpStatus } from "@nestjs/common";
|
|
@@ -873,8 +941,8 @@ function buildCookieOptionsForHost(cookieConfig, hostname) {
|
|
|
873
941
|
};
|
|
874
942
|
}
|
|
875
943
|
__name(buildCookieOptionsForHost, "buildCookieOptionsForHost");
|
|
876
|
-
var RefreshCookieOptions =
|
|
877
|
-
const request = ctx
|
|
944
|
+
var RefreshCookieOptions = createParamDecorator6((_data, ctx) => {
|
|
945
|
+
const request = getRequestFromContext(ctx);
|
|
878
946
|
const forwarded = request.headers["x-forwarded-host"];
|
|
879
947
|
const raw = Array.isArray(forwarded) ? forwarded[0] : forwarded;
|
|
880
948
|
const hostStr = raw ?? request.hostname;
|
|
@@ -884,18 +952,18 @@ var RefreshCookieOptions = createParamDecorator5((_data, ctx) => {
|
|
|
884
952
|
});
|
|
885
953
|
|
|
886
954
|
// src/auth/decorators/refresh-token-cookie.decorator.ts
|
|
887
|
-
import { createParamDecorator as
|
|
888
|
-
var RefreshTokenCookie =
|
|
889
|
-
const request = ctx
|
|
955
|
+
import { createParamDecorator as createParamDecorator7 } from "@nestjs/common";
|
|
956
|
+
var RefreshTokenCookie = createParamDecorator7((_data, ctx) => {
|
|
957
|
+
const request = getRequestFromContext(ctx);
|
|
890
958
|
const cookies = request.cookies ?? {};
|
|
891
959
|
const cookieName = request.authConfig?.cookie.refreshCookieName ?? AUTH_CONFIG_DEFAULTS.cookie.refreshCookieName;
|
|
892
960
|
return cookies[cookieName];
|
|
893
961
|
});
|
|
894
962
|
|
|
895
963
|
// src/auth/decorators/session-data.decorator.ts
|
|
896
|
-
import { createParamDecorator as
|
|
897
|
-
var SessionData =
|
|
898
|
-
const request = ctx
|
|
964
|
+
import { createParamDecorator as createParamDecorator8 } from "@nestjs/common";
|
|
965
|
+
var SessionData = createParamDecorator8((_data, ctx) => {
|
|
966
|
+
const request = getRequestFromContext(ctx);
|
|
899
967
|
const sessionInfo = request.sessionInfo;
|
|
900
968
|
if (!sessionInfo?.sessionId) {
|
|
901
969
|
throw new Error("Session info not found on request. Ensure route is protected by auth guard.");
|
|
@@ -908,9 +976,9 @@ var SessionData = createParamDecorator7((_data, ctx) => {
|
|
|
908
976
|
});
|
|
909
977
|
|
|
910
978
|
// src/auth/decorators/subdomain.decorator.ts
|
|
911
|
-
import { createParamDecorator as
|
|
912
|
-
var Subdomain =
|
|
913
|
-
const request = ctx
|
|
979
|
+
import { createParamDecorator as createParamDecorator9 } from "@nestjs/common";
|
|
980
|
+
var Subdomain = createParamDecorator9((_data, ctx) => {
|
|
981
|
+
const request = getRequestFromContext(ctx);
|
|
914
982
|
const origin = request.headers.origin;
|
|
915
983
|
if (origin) {
|
|
916
984
|
try {
|
|
@@ -925,10 +993,17 @@ var Subdomain = createParamDecorator8((_data, ctx) => {
|
|
|
925
993
|
return void 0;
|
|
926
994
|
});
|
|
927
995
|
|
|
996
|
+
// src/auth/decorators/user-agent.decorator.ts
|
|
997
|
+
import { createParamDecorator as createParamDecorator10 } from "@nestjs/common";
|
|
998
|
+
var UserAgent = createParamDecorator10((_data, ctx) => {
|
|
999
|
+
const userAgent = getRequestFromContext(ctx).headers["user-agent"];
|
|
1000
|
+
return Array.isArray(userAgent) ? userAgent[0] : userAgent;
|
|
1001
|
+
});
|
|
1002
|
+
|
|
928
1003
|
// src/auth/decorators/user-id.decorator.ts
|
|
929
|
-
import { createParamDecorator as
|
|
930
|
-
var UserId =
|
|
931
|
-
const request = ctx
|
|
1004
|
+
import { createParamDecorator as createParamDecorator11 } from "@nestjs/common";
|
|
1005
|
+
var UserId = createParamDecorator11((_data, ctx) => {
|
|
1006
|
+
const request = getRequestFromContext(ctx);
|
|
932
1007
|
const sessionInfo = request.sessionInfo;
|
|
933
1008
|
if (!sessionInfo?.userId) {
|
|
934
1009
|
throw new Error("User ID not found on request. Ensure route is protected by auth guard.");
|
|
@@ -936,6 +1011,10 @@ var UserId = createParamDecorator9((_data, ctx) => {
|
|
|
936
1011
|
return sessionInfo.userId;
|
|
937
1012
|
});
|
|
938
1013
|
|
|
1014
|
+
// src/data-table/data-table.module.ts
|
|
1015
|
+
import { Module as Module4 } from "@nestjs/common";
|
|
1016
|
+
import { ConfigModule as ConfigModule3 } from "@nestjs/config";
|
|
1017
|
+
|
|
939
1018
|
// src/cache/cache.module.ts
|
|
940
1019
|
import { Module as Module3 } from "@nestjs/common";
|
|
941
1020
|
import { ConfigModule as ConfigModule2 } from "@nestjs/config";
|
|
@@ -1141,10 +1220,6 @@ CacheModule = _ts_decorate8([
|
|
|
1141
1220
|
})
|
|
1142
1221
|
], CacheModule);
|
|
1143
1222
|
|
|
1144
|
-
// src/data-table/data-table.module.ts
|
|
1145
|
-
import { Module as Module4 } from "@nestjs/common";
|
|
1146
|
-
import { ConfigModule as ConfigModule3 } from "@nestjs/config";
|
|
1147
|
-
|
|
1148
1223
|
// src/data-table/data-table.constants.ts
|
|
1149
1224
|
var DATA_TABLE_VIEWS_TABLE = Symbol("DATA_TABLE_VIEWS_TABLE");
|
|
1150
1225
|
|
|
@@ -1755,7 +1830,8 @@ import { and as and2, eq as eq2 } from "drizzle-orm";
|
|
|
1755
1830
|
|
|
1756
1831
|
// src/database/repositories/primary-base.repository.ts
|
|
1757
1832
|
import { Logger as Logger8 } from "@nestjs/common";
|
|
1758
|
-
import { and, asc, desc, eq, getTableName, ilike, inArray, notInArray, sql } from "drizzle-orm";
|
|
1833
|
+
import { and, asc, desc, eq, getTableName, getViewName, ilike, inArray, is, notInArray, sql } from "drizzle-orm";
|
|
1834
|
+
import { PgViewBase } from "drizzle-orm/pg-core/view-base";
|
|
1759
1835
|
function snakeToCamel(str) {
|
|
1760
1836
|
return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
1761
1837
|
}
|
|
@@ -1769,10 +1845,14 @@ var PrimaryBaseRepository = class {
|
|
|
1769
1845
|
logger;
|
|
1770
1846
|
sequence;
|
|
1771
1847
|
tableName;
|
|
1848
|
+
isView;
|
|
1772
1849
|
get db() {
|
|
1773
1850
|
return this.database.drizzleClient;
|
|
1774
1851
|
}
|
|
1775
1852
|
get model() {
|
|
1853
|
+
if (this.isView) {
|
|
1854
|
+
throw new Error(`${this.constructor.name}: relational queries (.model) are not supported on the view '${this.tableName}'. Use findForSelect / findAllAndCount instead.`);
|
|
1855
|
+
}
|
|
1776
1856
|
const query = this.database.drizzleClient.query;
|
|
1777
1857
|
const queryKeys = Object.keys(query || {});
|
|
1778
1858
|
this.logger.debug(`Looking for '${this.tableName}' in query keys: [${queryKeys.join(", ")}]`);
|
|
@@ -1785,7 +1865,8 @@ var PrimaryBaseRepository = class {
|
|
|
1785
1865
|
constructor(database, table, options) {
|
|
1786
1866
|
this.database = database;
|
|
1787
1867
|
this.table = table;
|
|
1788
|
-
|
|
1868
|
+
this.isView = is(table, PgViewBase);
|
|
1869
|
+
const dbTableName = this.isView ? getViewName(table) : getTableName(table);
|
|
1789
1870
|
this.tableName = snakeToCamel(dbTableName);
|
|
1790
1871
|
this.sequence = options?.sequence;
|
|
1791
1872
|
this.logger = new Logger8(this.constructor.name);
|
|
@@ -1910,6 +1991,19 @@ var PrimaryBaseRepository = class {
|
|
|
1910
1991
|
count: countResult[0].count
|
|
1911
1992
|
};
|
|
1912
1993
|
}
|
|
1994
|
+
// Fetches limit+1 rows for keyset/cursor pagination and trims, returning rows plus hasMore.
|
|
1995
|
+
// The WHERE must already include the keyset "after" predicate; orderBy must be a total order.
|
|
1996
|
+
async findKeyset(options) {
|
|
1997
|
+
const rows = await this.buildSelectQuery({
|
|
1998
|
+
...options,
|
|
1999
|
+
limit: options.limit + 1
|
|
2000
|
+
});
|
|
2001
|
+
const hasMore = rows.length > options.limit;
|
|
2002
|
+
return {
|
|
2003
|
+
rows: hasMore ? rows.slice(0, options.limit) : rows,
|
|
2004
|
+
hasMore
|
|
2005
|
+
};
|
|
2006
|
+
}
|
|
1913
2007
|
// Updates a record by ID and returns the updated record
|
|
1914
2008
|
async update(id, data, tx) {
|
|
1915
2009
|
this.logger.log(`Updating record with ID: ${id}`);
|
|
@@ -2901,7 +2995,7 @@ _ts_decorate23([
|
|
|
2901
2995
|
_ts_metadata18("design:type", typeof T === "undefined" ? Object : T)
|
|
2902
2996
|
], CreateResponseDto.prototype, "data", void 0);
|
|
2903
2997
|
|
|
2904
|
-
// src/database/dto/
|
|
2998
|
+
// src/database/dto/cursor-list-response.dto.ts
|
|
2905
2999
|
import { ApiProperty as ApiProperty8, ApiPropertyOptional as ApiPropertyOptional4 } from "@nestjs/swagger";
|
|
2906
3000
|
function _ts_decorate24(decorators, target, key, desc3) {
|
|
2907
3001
|
var c = arguments.length, r = c < 3 ? target : desc3 === null ? desc3 = Object.getOwnPropertyDescriptor(target, key) : desc3, d;
|
|
@@ -2914,6 +3008,42 @@ function _ts_metadata19(k, v) {
|
|
|
2914
3008
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2915
3009
|
}
|
|
2916
3010
|
__name(_ts_metadata19, "_ts_metadata");
|
|
3011
|
+
var CursorListResponseDto = class {
|
|
3012
|
+
static {
|
|
3013
|
+
__name(this, "CursorListResponseDto");
|
|
3014
|
+
}
|
|
3015
|
+
items;
|
|
3016
|
+
nextCursor;
|
|
3017
|
+
hasMore;
|
|
3018
|
+
};
|
|
3019
|
+
_ts_decorate24([
|
|
3020
|
+
ApiProperty8(),
|
|
3021
|
+
_ts_metadata19("design:type", Array)
|
|
3022
|
+
], CursorListResponseDto.prototype, "items", void 0);
|
|
3023
|
+
_ts_decorate24([
|
|
3024
|
+
ApiPropertyOptional4({
|
|
3025
|
+
nullable: true
|
|
3026
|
+
}),
|
|
3027
|
+
_ts_metadata19("design:type", Object)
|
|
3028
|
+
], CursorListResponseDto.prototype, "nextCursor", void 0);
|
|
3029
|
+
_ts_decorate24([
|
|
3030
|
+
ApiProperty8(),
|
|
3031
|
+
_ts_metadata19("design:type", Boolean)
|
|
3032
|
+
], CursorListResponseDto.prototype, "hasMore", void 0);
|
|
3033
|
+
|
|
3034
|
+
// src/database/dto/import-response.dto.ts
|
|
3035
|
+
import { ApiProperty as ApiProperty9, ApiPropertyOptional as ApiPropertyOptional5 } from "@nestjs/swagger";
|
|
3036
|
+
function _ts_decorate25(decorators, target, key, desc3) {
|
|
3037
|
+
var c = arguments.length, r = c < 3 ? target : desc3 === null ? desc3 = Object.getOwnPropertyDescriptor(target, key) : desc3, d;
|
|
3038
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc3);
|
|
3039
|
+
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;
|
|
3040
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3041
|
+
}
|
|
3042
|
+
__name(_ts_decorate25, "_ts_decorate");
|
|
3043
|
+
function _ts_metadata20(k, v) {
|
|
3044
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
3045
|
+
}
|
|
3046
|
+
__name(_ts_metadata20, "_ts_metadata");
|
|
2917
3047
|
var ValidatedRowDto = class {
|
|
2918
3048
|
static {
|
|
2919
3049
|
__name(this, "ValidatedRowDto");
|
|
@@ -2923,34 +3053,34 @@ var ValidatedRowDto = class {
|
|
|
2923
3053
|
valid;
|
|
2924
3054
|
errors;
|
|
2925
3055
|
};
|
|
2926
|
-
|
|
2927
|
-
|
|
3056
|
+
_ts_decorate25([
|
|
3057
|
+
ApiProperty9({
|
|
2928
3058
|
example: 1
|
|
2929
3059
|
}),
|
|
2930
|
-
|
|
3060
|
+
_ts_metadata20("design:type", Number)
|
|
2931
3061
|
], ValidatedRowDto.prototype, "index", void 0);
|
|
2932
|
-
|
|
2933
|
-
|
|
3062
|
+
_ts_decorate25([
|
|
3063
|
+
ApiProperty9({
|
|
2934
3064
|
example: {
|
|
2935
3065
|
code: "products",
|
|
2936
3066
|
name: "Products"
|
|
2937
3067
|
}
|
|
2938
3068
|
}),
|
|
2939
|
-
|
|
3069
|
+
_ts_metadata20("design:type", typeof Record === "undefined" ? Object : Record)
|
|
2940
3070
|
], ValidatedRowDto.prototype, "data", void 0);
|
|
2941
|
-
|
|
2942
|
-
|
|
3071
|
+
_ts_decorate25([
|
|
3072
|
+
ApiProperty9({
|
|
2943
3073
|
example: true
|
|
2944
3074
|
}),
|
|
2945
|
-
|
|
3075
|
+
_ts_metadata20("design:type", Boolean)
|
|
2946
3076
|
], ValidatedRowDto.prototype, "valid", void 0);
|
|
2947
|
-
|
|
2948
|
-
|
|
3077
|
+
_ts_decorate25([
|
|
3078
|
+
ApiProperty9({
|
|
2949
3079
|
example: [
|
|
2950
3080
|
"Code already exists"
|
|
2951
3081
|
]
|
|
2952
3082
|
}),
|
|
2953
|
-
|
|
3083
|
+
_ts_metadata20("design:type", Array)
|
|
2954
3084
|
], ValidatedRowDto.prototype, "errors", void 0);
|
|
2955
3085
|
var ImportSummaryDto = class {
|
|
2956
3086
|
static {
|
|
@@ -2960,23 +3090,23 @@ var ImportSummaryDto = class {
|
|
|
2960
3090
|
valid;
|
|
2961
3091
|
invalid;
|
|
2962
3092
|
};
|
|
2963
|
-
|
|
2964
|
-
|
|
3093
|
+
_ts_decorate25([
|
|
3094
|
+
ApiProperty9({
|
|
2965
3095
|
example: 10
|
|
2966
3096
|
}),
|
|
2967
|
-
|
|
3097
|
+
_ts_metadata20("design:type", Number)
|
|
2968
3098
|
], ImportSummaryDto.prototype, "total", void 0);
|
|
2969
|
-
|
|
2970
|
-
|
|
3099
|
+
_ts_decorate25([
|
|
3100
|
+
ApiProperty9({
|
|
2971
3101
|
example: 8
|
|
2972
3102
|
}),
|
|
2973
|
-
|
|
3103
|
+
_ts_metadata20("design:type", Number)
|
|
2974
3104
|
], ImportSummaryDto.prototype, "valid", void 0);
|
|
2975
|
-
|
|
2976
|
-
|
|
3105
|
+
_ts_decorate25([
|
|
3106
|
+
ApiProperty9({
|
|
2977
3107
|
example: 2
|
|
2978
3108
|
}),
|
|
2979
|
-
|
|
3109
|
+
_ts_metadata20("design:type", Number)
|
|
2980
3110
|
], ImportSummaryDto.prototype, "invalid", void 0);
|
|
2981
3111
|
var ImportResponseDto = class {
|
|
2982
3112
|
static {
|
|
@@ -2990,66 +3120,66 @@ var ImportResponseDto = class {
|
|
|
2990
3120
|
rows;
|
|
2991
3121
|
summary;
|
|
2992
3122
|
};
|
|
2993
|
-
|
|
2994
|
-
|
|
3123
|
+
_ts_decorate25([
|
|
3124
|
+
ApiProperty9({
|
|
2995
3125
|
example: true
|
|
2996
3126
|
}),
|
|
2997
|
-
|
|
3127
|
+
_ts_metadata20("design:type", Boolean)
|
|
2998
3128
|
], ImportResponseDto.prototype, "success", void 0);
|
|
2999
|
-
|
|
3000
|
-
|
|
3129
|
+
_ts_decorate25([
|
|
3130
|
+
ApiProperty9({
|
|
3001
3131
|
example: "Import complete."
|
|
3002
3132
|
}),
|
|
3003
|
-
|
|
3133
|
+
_ts_metadata20("design:type", String)
|
|
3004
3134
|
], ImportResponseDto.prototype, "message", void 0);
|
|
3005
|
-
|
|
3006
|
-
|
|
3135
|
+
_ts_decorate25([
|
|
3136
|
+
ApiPropertyOptional5({
|
|
3007
3137
|
example: 3
|
|
3008
3138
|
}),
|
|
3009
|
-
|
|
3139
|
+
_ts_metadata20("design:type", Number)
|
|
3010
3140
|
], ImportResponseDto.prototype, "created", void 0);
|
|
3011
|
-
|
|
3012
|
-
|
|
3141
|
+
_ts_decorate25([
|
|
3142
|
+
ApiPropertyOptional5({
|
|
3013
3143
|
example: 2
|
|
3014
3144
|
}),
|
|
3015
|
-
|
|
3145
|
+
_ts_metadata20("design:type", Number)
|
|
3016
3146
|
], ImportResponseDto.prototype, "updated", void 0);
|
|
3017
|
-
|
|
3018
|
-
|
|
3147
|
+
_ts_decorate25([
|
|
3148
|
+
ApiPropertyOptional5({
|
|
3019
3149
|
example: 1
|
|
3020
3150
|
}),
|
|
3021
|
-
|
|
3151
|
+
_ts_metadata20("design:type", Number)
|
|
3022
3152
|
], ImportResponseDto.prototype, "skipped", void 0);
|
|
3023
|
-
|
|
3024
|
-
|
|
3153
|
+
_ts_decorate25([
|
|
3154
|
+
ApiPropertyOptional5({
|
|
3025
3155
|
type: [
|
|
3026
3156
|
ValidatedRowDto
|
|
3027
3157
|
]
|
|
3028
3158
|
}),
|
|
3029
|
-
|
|
3159
|
+
_ts_metadata20("design:type", Array)
|
|
3030
3160
|
], ImportResponseDto.prototype, "rows", void 0);
|
|
3031
|
-
|
|
3032
|
-
|
|
3161
|
+
_ts_decorate25([
|
|
3162
|
+
ApiPropertyOptional5({
|
|
3033
3163
|
type: ImportSummaryDto
|
|
3034
3164
|
}),
|
|
3035
|
-
|
|
3165
|
+
_ts_metadata20("design:type", typeof ImportSummaryDto === "undefined" ? Object : ImportSummaryDto)
|
|
3036
3166
|
], ImportResponseDto.prototype, "summary", void 0);
|
|
3037
3167
|
|
|
3038
3168
|
// src/database/dto/select-options-query.dto.ts
|
|
3039
|
-
import { ApiPropertyOptional as
|
|
3169
|
+
import { ApiPropertyOptional as ApiPropertyOptional6 } from "@nestjs/swagger";
|
|
3040
3170
|
import { Type } from "class-transformer";
|
|
3041
3171
|
import { IsIn, IsInt, IsOptional as IsOptional3, IsString as IsString4, Min } from "class-validator";
|
|
3042
|
-
function
|
|
3172
|
+
function _ts_decorate26(decorators, target, key, desc3) {
|
|
3043
3173
|
var c = arguments.length, r = c < 3 ? target : desc3 === null ? desc3 = Object.getOwnPropertyDescriptor(target, key) : desc3, d;
|
|
3044
3174
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc3);
|
|
3045
3175
|
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;
|
|
3046
3176
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3047
3177
|
}
|
|
3048
|
-
__name(
|
|
3049
|
-
function
|
|
3178
|
+
__name(_ts_decorate26, "_ts_decorate");
|
|
3179
|
+
function _ts_metadata21(k, v) {
|
|
3050
3180
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
3051
3181
|
}
|
|
3052
|
-
__name(
|
|
3182
|
+
__name(_ts_metadata21, "_ts_metadata");
|
|
3053
3183
|
var SelectOptionsQueryDto = class {
|
|
3054
3184
|
static {
|
|
3055
3185
|
__name(this, "SelectOptionsQueryDto");
|
|
@@ -3067,17 +3197,17 @@ var SelectOptionsQueryDto = class {
|
|
|
3067
3197
|
orderByKey;
|
|
3068
3198
|
orderDirection;
|
|
3069
3199
|
};
|
|
3070
|
-
|
|
3071
|
-
|
|
3200
|
+
_ts_decorate26([
|
|
3201
|
+
ApiPropertyOptional6({
|
|
3072
3202
|
description: "Search term to filter by label",
|
|
3073
3203
|
example: "united"
|
|
3074
3204
|
}),
|
|
3075
3205
|
IsOptional3(),
|
|
3076
3206
|
IsString4(),
|
|
3077
|
-
|
|
3207
|
+
_ts_metadata21("design:type", String)
|
|
3078
3208
|
], SelectOptionsQueryDto.prototype, "search", void 0);
|
|
3079
|
-
|
|
3080
|
-
|
|
3209
|
+
_ts_decorate26([
|
|
3210
|
+
ApiPropertyOptional6({
|
|
3081
3211
|
description: "Maximum number of results",
|
|
3082
3212
|
example: 20,
|
|
3083
3213
|
default: 20
|
|
@@ -3086,10 +3216,10 @@ _ts_decorate25([
|
|
|
3086
3216
|
Type(() => Number),
|
|
3087
3217
|
IsInt(),
|
|
3088
3218
|
Min(1),
|
|
3089
|
-
|
|
3219
|
+
_ts_metadata21("design:type", Number)
|
|
3090
3220
|
], SelectOptionsQueryDto.prototype, "limit", void 0);
|
|
3091
|
-
|
|
3092
|
-
|
|
3221
|
+
_ts_decorate26([
|
|
3222
|
+
ApiPropertyOptional6({
|
|
3093
3223
|
description: "Number of results to skip",
|
|
3094
3224
|
example: 0,
|
|
3095
3225
|
default: 0
|
|
@@ -3098,85 +3228,85 @@ _ts_decorate25([
|
|
|
3098
3228
|
Type(() => Number),
|
|
3099
3229
|
IsInt(),
|
|
3100
3230
|
Min(0),
|
|
3101
|
-
|
|
3231
|
+
_ts_metadata21("design:type", Number)
|
|
3102
3232
|
], SelectOptionsQueryDto.prototype, "offset", void 0);
|
|
3103
|
-
|
|
3104
|
-
|
|
3233
|
+
_ts_decorate26([
|
|
3234
|
+
ApiPropertyOptional6({
|
|
3105
3235
|
description: "Comma-separated values to fetch specific options",
|
|
3106
3236
|
example: "1,2,3"
|
|
3107
3237
|
}),
|
|
3108
3238
|
IsOptional3(),
|
|
3109
3239
|
IsString4(),
|
|
3110
|
-
|
|
3240
|
+
_ts_metadata21("design:type", String)
|
|
3111
3241
|
], SelectOptionsQueryDto.prototype, "values", void 0);
|
|
3112
|
-
|
|
3113
|
-
|
|
3242
|
+
_ts_decorate26([
|
|
3243
|
+
ApiPropertyOptional6({
|
|
3114
3244
|
description: "Comma-separated IDs to exclude from results (already selected)",
|
|
3115
3245
|
example: "5,10"
|
|
3116
3246
|
}),
|
|
3117
3247
|
IsOptional3(),
|
|
3118
3248
|
IsString4(),
|
|
3119
|
-
|
|
3249
|
+
_ts_metadata21("design:type", String)
|
|
3120
3250
|
], SelectOptionsQueryDto.prototype, "excludeIds", void 0);
|
|
3121
|
-
|
|
3122
|
-
|
|
3251
|
+
_ts_decorate26([
|
|
3252
|
+
ApiPropertyOptional6({
|
|
3123
3253
|
description: "Column name for option value",
|
|
3124
3254
|
example: "id",
|
|
3125
3255
|
default: "id"
|
|
3126
3256
|
}),
|
|
3127
3257
|
IsOptional3(),
|
|
3128
3258
|
IsString4(),
|
|
3129
|
-
|
|
3259
|
+
_ts_metadata21("design:type", String)
|
|
3130
3260
|
], SelectOptionsQueryDto.prototype, "valueKey", void 0);
|
|
3131
|
-
|
|
3132
|
-
|
|
3261
|
+
_ts_decorate26([
|
|
3262
|
+
ApiPropertyOptional6({
|
|
3133
3263
|
description: "Column name for option label",
|
|
3134
3264
|
example: "name",
|
|
3135
3265
|
default: "name"
|
|
3136
3266
|
}),
|
|
3137
3267
|
IsOptional3(),
|
|
3138
3268
|
IsString4(),
|
|
3139
|
-
|
|
3269
|
+
_ts_metadata21("design:type", String)
|
|
3140
3270
|
], SelectOptionsQueryDto.prototype, "labelKey", void 0);
|
|
3141
|
-
|
|
3142
|
-
|
|
3271
|
+
_ts_decorate26([
|
|
3272
|
+
ApiPropertyOptional6({
|
|
3143
3273
|
description: "Column name for option description",
|
|
3144
3274
|
example: "description"
|
|
3145
3275
|
}),
|
|
3146
3276
|
IsOptional3(),
|
|
3147
3277
|
IsString4(),
|
|
3148
|
-
|
|
3278
|
+
_ts_metadata21("design:type", String)
|
|
3149
3279
|
], SelectOptionsQueryDto.prototype, "descriptionKey", void 0);
|
|
3150
|
-
|
|
3151
|
-
|
|
3280
|
+
_ts_decorate26([
|
|
3281
|
+
ApiPropertyOptional6({
|
|
3152
3282
|
description: "Comma-separated column names to include in option.additionals",
|
|
3153
3283
|
example: "locationName,availableQuantity"
|
|
3154
3284
|
}),
|
|
3155
3285
|
IsOptional3(),
|
|
3156
3286
|
IsString4(),
|
|
3157
|
-
|
|
3287
|
+
_ts_metadata21("design:type", String)
|
|
3158
3288
|
], SelectOptionsQueryDto.prototype, "additionalKeys", void 0);
|
|
3159
|
-
|
|
3160
|
-
|
|
3289
|
+
_ts_decorate26([
|
|
3290
|
+
ApiPropertyOptional6({
|
|
3161
3291
|
description: "Column name for group ID",
|
|
3162
3292
|
example: "regionId"
|
|
3163
3293
|
}),
|
|
3164
3294
|
IsOptional3(),
|
|
3165
3295
|
IsString4(),
|
|
3166
|
-
|
|
3296
|
+
_ts_metadata21("design:type", String)
|
|
3167
3297
|
], SelectOptionsQueryDto.prototype, "groupIdKey", void 0);
|
|
3168
|
-
|
|
3169
|
-
|
|
3298
|
+
_ts_decorate26([
|
|
3299
|
+
ApiPropertyOptional6({
|
|
3170
3300
|
description: "Column name to sort options by",
|
|
3171
3301
|
example: "name",
|
|
3172
3302
|
default: "name"
|
|
3173
3303
|
}),
|
|
3174
3304
|
IsOptional3(),
|
|
3175
3305
|
IsString4(),
|
|
3176
|
-
|
|
3306
|
+
_ts_metadata21("design:type", String)
|
|
3177
3307
|
], SelectOptionsQueryDto.prototype, "orderByKey", void 0);
|
|
3178
|
-
|
|
3179
|
-
|
|
3308
|
+
_ts_decorate26([
|
|
3309
|
+
ApiPropertyOptional6({
|
|
3180
3310
|
description: "Sort direction for options",
|
|
3181
3311
|
example: "asc",
|
|
3182
3312
|
default: "asc",
|
|
@@ -3191,23 +3321,23 @@ _ts_decorate25([
|
|
|
3191
3321
|
"asc",
|
|
3192
3322
|
"desc"
|
|
3193
3323
|
]),
|
|
3194
|
-
|
|
3324
|
+
_ts_metadata21("design:type", String)
|
|
3195
3325
|
], SelectOptionsQueryDto.prototype, "orderDirection", void 0);
|
|
3196
3326
|
|
|
3197
3327
|
// src/database/dto/success-response.dto.ts
|
|
3198
|
-
import { ApiProperty as
|
|
3328
|
+
import { ApiProperty as ApiProperty10 } from "@nestjs/swagger";
|
|
3199
3329
|
import { IsBoolean as IsBoolean3, IsNotEmpty, IsString as IsString5 } from "class-validator";
|
|
3200
|
-
function
|
|
3330
|
+
function _ts_decorate27(decorators, target, key, desc3) {
|
|
3201
3331
|
var c = arguments.length, r = c < 3 ? target : desc3 === null ? desc3 = Object.getOwnPropertyDescriptor(target, key) : desc3, d;
|
|
3202
3332
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc3);
|
|
3203
3333
|
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;
|
|
3204
3334
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3205
3335
|
}
|
|
3206
|
-
__name(
|
|
3207
|
-
function
|
|
3336
|
+
__name(_ts_decorate27, "_ts_decorate");
|
|
3337
|
+
function _ts_metadata22(k, v) {
|
|
3208
3338
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
3209
3339
|
}
|
|
3210
|
-
__name(
|
|
3340
|
+
__name(_ts_metadata22, "_ts_metadata");
|
|
3211
3341
|
var SuccessResponseDto = class {
|
|
3212
3342
|
static {
|
|
3213
3343
|
__name(this, "SuccessResponseDto");
|
|
@@ -3215,36 +3345,36 @@ var SuccessResponseDto = class {
|
|
|
3215
3345
|
success;
|
|
3216
3346
|
message;
|
|
3217
3347
|
};
|
|
3218
|
-
|
|
3219
|
-
|
|
3348
|
+
_ts_decorate27([
|
|
3349
|
+
ApiProperty10({
|
|
3220
3350
|
example: true
|
|
3221
3351
|
}),
|
|
3222
3352
|
IsNotEmpty(),
|
|
3223
3353
|
IsBoolean3(),
|
|
3224
|
-
|
|
3354
|
+
_ts_metadata22("design:type", Boolean)
|
|
3225
3355
|
], SuccessResponseDto.prototype, "success", void 0);
|
|
3226
|
-
|
|
3227
|
-
|
|
3356
|
+
_ts_decorate27([
|
|
3357
|
+
ApiProperty10({
|
|
3228
3358
|
example: "Operation completed successfully"
|
|
3229
3359
|
}),
|
|
3230
3360
|
IsNotEmpty(),
|
|
3231
3361
|
IsString5(),
|
|
3232
|
-
|
|
3362
|
+
_ts_metadata22("design:type", String)
|
|
3233
3363
|
], SuccessResponseDto.prototype, "message", void 0);
|
|
3234
3364
|
|
|
3235
3365
|
// src/database/dto/table-response.dto.ts
|
|
3236
|
-
import { ApiProperty as
|
|
3237
|
-
function
|
|
3366
|
+
import { ApiProperty as ApiProperty11, ApiPropertyOptional as ApiPropertyOptional7 } from "@nestjs/swagger";
|
|
3367
|
+
function _ts_decorate28(decorators, target, key, desc3) {
|
|
3238
3368
|
var c = arguments.length, r = c < 3 ? target : desc3 === null ? desc3 = Object.getOwnPropertyDescriptor(target, key) : desc3, d;
|
|
3239
3369
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc3);
|
|
3240
3370
|
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;
|
|
3241
3371
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3242
3372
|
}
|
|
3243
|
-
__name(
|
|
3244
|
-
function
|
|
3373
|
+
__name(_ts_decorate28, "_ts_decorate");
|
|
3374
|
+
function _ts_metadata23(k, v) {
|
|
3245
3375
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
3246
3376
|
}
|
|
3247
|
-
__name(
|
|
3377
|
+
__name(_ts_metadata23, "_ts_metadata");
|
|
3248
3378
|
var TableResponseDto = class {
|
|
3249
3379
|
static {
|
|
3250
3380
|
__name(this, "TableResponseDto");
|
|
@@ -3254,25 +3384,55 @@ var TableResponseDto = class {
|
|
|
3254
3384
|
state;
|
|
3255
3385
|
activeViewId;
|
|
3256
3386
|
};
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3387
|
+
_ts_decorate28([
|
|
3388
|
+
ApiProperty11(),
|
|
3389
|
+
_ts_metadata23("design:type", Array)
|
|
3260
3390
|
], TableResponseDto.prototype, "result", void 0);
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3391
|
+
_ts_decorate28([
|
|
3392
|
+
ApiProperty11(),
|
|
3393
|
+
_ts_metadata23("design:type", Number)
|
|
3264
3394
|
], TableResponseDto.prototype, "count", void 0);
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3395
|
+
_ts_decorate28([
|
|
3396
|
+
ApiProperty11(),
|
|
3397
|
+
_ts_metadata23("design:type", typeof TableViewState === "undefined" ? Object : TableViewState)
|
|
3268
3398
|
], TableResponseDto.prototype, "state", void 0);
|
|
3269
|
-
|
|
3270
|
-
|
|
3399
|
+
_ts_decorate28([
|
|
3400
|
+
ApiPropertyOptional7({
|
|
3271
3401
|
nullable: true
|
|
3272
3402
|
}),
|
|
3273
|
-
|
|
3403
|
+
_ts_metadata23("design:type", Object)
|
|
3274
3404
|
], TableResponseDto.prototype, "activeViewId", void 0);
|
|
3275
3405
|
|
|
3406
|
+
// src/database/filter/cursor.codec.ts
|
|
3407
|
+
var CursorCodec = class {
|
|
3408
|
+
static {
|
|
3409
|
+
__name(this, "CursorCodec");
|
|
3410
|
+
}
|
|
3411
|
+
// Encodes ORDER BY boundary values (id tie-breaker last) into a base64url JSON string
|
|
3412
|
+
static encode(values) {
|
|
3413
|
+
const serialized = values.map((v) => {
|
|
3414
|
+
if (v instanceof Date) return {
|
|
3415
|
+
__t: "date",
|
|
3416
|
+
v: v.toISOString()
|
|
3417
|
+
};
|
|
3418
|
+
if (v === null || v === void 0) return null;
|
|
3419
|
+
if (typeof v === "string" || typeof v === "number" || typeof v === "boolean") return v;
|
|
3420
|
+
return String(v);
|
|
3421
|
+
});
|
|
3422
|
+
const json = JSON.stringify(serialized);
|
|
3423
|
+
return Buffer.from(json, "utf8").toString("base64url");
|
|
3424
|
+
}
|
|
3425
|
+
// Decodes a cursor back into the ordered boundary values, rehydrating ISO strings as Dates
|
|
3426
|
+
static decode(cursor) {
|
|
3427
|
+
const json = Buffer.from(cursor, "base64url").toString("utf8");
|
|
3428
|
+
const parsed = JSON.parse(json);
|
|
3429
|
+
return parsed.map((v) => {
|
|
3430
|
+
if (v && typeof v === "object" && "__t" in v && v.__t === "date") return new Date(v.v);
|
|
3431
|
+
return v;
|
|
3432
|
+
});
|
|
3433
|
+
}
|
|
3434
|
+
};
|
|
3435
|
+
|
|
3276
3436
|
// src/database/filter/filter.processor.ts
|
|
3277
3437
|
import { and as and3, asc as asc2, desc as desc2, eq as eq3, gt, gte, ilike as ilike2, inArray as inArray2, lt, lte, ne, notIlike, notInArray as notInArray2, or } from "drizzle-orm";
|
|
3278
3438
|
var FilterProcessor = class {
|
|
@@ -3383,351 +3543,41 @@ var FilterOperators = {
|
|
|
3383
3543
|
IS_NOT_ANY_OF: "isNotAnyOf"
|
|
3384
3544
|
};
|
|
3385
3545
|
|
|
3386
|
-
// src/
|
|
3387
|
-
import {
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
base: 10n,
|
|
3404
|
-
exponent: 2n
|
|
3405
|
-
};
|
|
3406
|
-
var HRK = {
|
|
3407
|
-
code: "HRK",
|
|
3408
|
-
base: 10n,
|
|
3409
|
-
exponent: 2n
|
|
3410
|
-
};
|
|
3411
|
-
var XAG = {
|
|
3412
|
-
code: "XAG",
|
|
3413
|
-
base: 10n,
|
|
3414
|
-
exponent: 0n
|
|
3415
|
-
};
|
|
3416
|
-
var XAU = {
|
|
3417
|
-
code: "XAU",
|
|
3418
|
-
base: 10n,
|
|
3419
|
-
exponent: 0n
|
|
3420
|
-
};
|
|
3421
|
-
var XDR = {
|
|
3422
|
-
code: "XDR",
|
|
3423
|
-
base: 10n,
|
|
3424
|
-
exponent: 0n
|
|
3425
|
-
};
|
|
3426
|
-
var XPD = {
|
|
3427
|
-
code: "XPD",
|
|
3428
|
-
base: 10n,
|
|
3429
|
-
exponent: 0n
|
|
3430
|
-
};
|
|
3431
|
-
var XPT = {
|
|
3432
|
-
code: "XPT",
|
|
3433
|
-
base: 10n,
|
|
3434
|
-
exponent: 0n
|
|
3435
|
-
};
|
|
3436
|
-
var ZWL = {
|
|
3437
|
-
code: "ZWL",
|
|
3438
|
-
base: 10n,
|
|
3439
|
-
exponent: 2n
|
|
3440
|
-
};
|
|
3441
|
-
var SUPPORTED_CURRENCIES = {
|
|
3442
|
-
AED,
|
|
3443
|
-
AFN,
|
|
3444
|
-
ALL,
|
|
3445
|
-
AMD,
|
|
3446
|
-
ANG,
|
|
3447
|
-
AOA,
|
|
3448
|
-
ARS,
|
|
3449
|
-
AUD,
|
|
3450
|
-
AWG,
|
|
3451
|
-
AZN,
|
|
3452
|
-
BAM,
|
|
3453
|
-
BBD,
|
|
3454
|
-
BDT,
|
|
3455
|
-
BGN,
|
|
3456
|
-
BHD,
|
|
3457
|
-
BIF,
|
|
3458
|
-
BMD,
|
|
3459
|
-
BND,
|
|
3460
|
-
BOB,
|
|
3461
|
-
BOV,
|
|
3462
|
-
BRL,
|
|
3463
|
-
BSD,
|
|
3464
|
-
BTN,
|
|
3465
|
-
BWP,
|
|
3466
|
-
BYN,
|
|
3467
|
-
BZD,
|
|
3468
|
-
CAD,
|
|
3469
|
-
CDF,
|
|
3470
|
-
CHE,
|
|
3471
|
-
CHF,
|
|
3472
|
-
CHW,
|
|
3473
|
-
CLF,
|
|
3474
|
-
CLP,
|
|
3475
|
-
CNY,
|
|
3476
|
-
COP,
|
|
3477
|
-
COU,
|
|
3478
|
-
CRC,
|
|
3479
|
-
CUP,
|
|
3480
|
-
CVE,
|
|
3481
|
-
CZK,
|
|
3482
|
-
DJF,
|
|
3483
|
-
DKK,
|
|
3484
|
-
DOP,
|
|
3485
|
-
DZD,
|
|
3486
|
-
EGP,
|
|
3487
|
-
ERN,
|
|
3488
|
-
ETB,
|
|
3489
|
-
EUR,
|
|
3490
|
-
FJD,
|
|
3491
|
-
FKP,
|
|
3492
|
-
GBP,
|
|
3493
|
-
GEL,
|
|
3494
|
-
GHS,
|
|
3495
|
-
GIP,
|
|
3496
|
-
GMD,
|
|
3497
|
-
GNF,
|
|
3498
|
-
GTQ,
|
|
3499
|
-
GYD,
|
|
3500
|
-
HKD,
|
|
3501
|
-
HNL,
|
|
3502
|
-
HRK,
|
|
3503
|
-
HTG,
|
|
3504
|
-
HUF,
|
|
3505
|
-
IDR,
|
|
3506
|
-
ILS,
|
|
3507
|
-
INR,
|
|
3508
|
-
IQD,
|
|
3509
|
-
IRR,
|
|
3510
|
-
ISK,
|
|
3511
|
-
JMD,
|
|
3512
|
-
JOD,
|
|
3513
|
-
JPY,
|
|
3514
|
-
KES,
|
|
3515
|
-
KGS,
|
|
3516
|
-
KHR,
|
|
3517
|
-
KMF,
|
|
3518
|
-
KPW,
|
|
3519
|
-
KRW,
|
|
3520
|
-
KWD,
|
|
3521
|
-
KYD,
|
|
3522
|
-
KZT,
|
|
3523
|
-
LAK,
|
|
3524
|
-
LBP,
|
|
3525
|
-
LKR,
|
|
3526
|
-
LRD,
|
|
3527
|
-
LSL,
|
|
3528
|
-
LYD,
|
|
3529
|
-
MAD,
|
|
3530
|
-
MDL,
|
|
3531
|
-
MGA,
|
|
3532
|
-
MKD,
|
|
3533
|
-
MMK,
|
|
3534
|
-
MNT,
|
|
3535
|
-
MOP,
|
|
3536
|
-
MRU,
|
|
3537
|
-
MUR,
|
|
3538
|
-
MVR,
|
|
3539
|
-
MWK,
|
|
3540
|
-
MXN,
|
|
3541
|
-
MXV,
|
|
3542
|
-
MYR,
|
|
3543
|
-
MZN,
|
|
3544
|
-
NAD,
|
|
3545
|
-
NGN,
|
|
3546
|
-
NIO,
|
|
3547
|
-
NOK,
|
|
3548
|
-
NPR,
|
|
3549
|
-
NZD,
|
|
3550
|
-
OMR,
|
|
3551
|
-
PAB,
|
|
3552
|
-
PEN,
|
|
3553
|
-
PGK,
|
|
3554
|
-
PHP,
|
|
3555
|
-
PKR,
|
|
3556
|
-
PLN,
|
|
3557
|
-
PYG,
|
|
3558
|
-
QAR,
|
|
3559
|
-
RON,
|
|
3560
|
-
RSD,
|
|
3561
|
-
RUB,
|
|
3562
|
-
RWF,
|
|
3563
|
-
SAR,
|
|
3564
|
-
SBD,
|
|
3565
|
-
SCR,
|
|
3566
|
-
SDG,
|
|
3567
|
-
SEK,
|
|
3568
|
-
SGD,
|
|
3569
|
-
SHP,
|
|
3570
|
-
SLE,
|
|
3571
|
-
SOS,
|
|
3572
|
-
SRD,
|
|
3573
|
-
SSP,
|
|
3574
|
-
STN,
|
|
3575
|
-
SVC,
|
|
3576
|
-
SYP,
|
|
3577
|
-
SZL,
|
|
3578
|
-
THB,
|
|
3579
|
-
TJS,
|
|
3580
|
-
TMT,
|
|
3581
|
-
TND,
|
|
3582
|
-
TOP,
|
|
3583
|
-
TRY,
|
|
3584
|
-
TTD,
|
|
3585
|
-
TWD,
|
|
3586
|
-
TZS,
|
|
3587
|
-
UAH,
|
|
3588
|
-
UGX,
|
|
3589
|
-
USD,
|
|
3590
|
-
USN,
|
|
3591
|
-
UYI,
|
|
3592
|
-
UYU,
|
|
3593
|
-
UYW,
|
|
3594
|
-
UZS,
|
|
3595
|
-
VED,
|
|
3596
|
-
VES,
|
|
3597
|
-
VND,
|
|
3598
|
-
VUV,
|
|
3599
|
-
WST,
|
|
3600
|
-
XAD,
|
|
3601
|
-
XAF,
|
|
3602
|
-
XAG,
|
|
3603
|
-
XAU,
|
|
3604
|
-
XCD,
|
|
3605
|
-
XCG,
|
|
3606
|
-
XDR,
|
|
3607
|
-
XOF,
|
|
3608
|
-
XPD,
|
|
3609
|
-
XPF,
|
|
3610
|
-
XPT,
|
|
3611
|
-
YER,
|
|
3612
|
-
ZAR,
|
|
3613
|
-
ZMW,
|
|
3614
|
-
ZWG,
|
|
3615
|
-
ZWL
|
|
3616
|
-
};
|
|
3617
|
-
function resolveCurrency(currencyCode) {
|
|
3618
|
-
return SUPPORTED_CURRENCIES[currencyCode];
|
|
3619
|
-
}
|
|
3620
|
-
__name(resolveCurrency, "resolveCurrency");
|
|
3621
|
-
function minorToMajor(minor, currencyCode, transform) {
|
|
3622
|
-
const currency = resolveCurrency(currencyCode);
|
|
3623
|
-
const amount = dinero({
|
|
3624
|
-
amount: minor,
|
|
3625
|
-
currency
|
|
3626
|
-
});
|
|
3627
|
-
if (!transform) {
|
|
3628
|
-
return toDecimal(amount);
|
|
3629
|
-
}
|
|
3630
|
-
return toDecimal(amount, ({ value, currency: resolvedCurrency }) => transform({
|
|
3631
|
-
value,
|
|
3632
|
-
currency: resolvedCurrency
|
|
3633
|
-
}));
|
|
3634
|
-
}
|
|
3635
|
-
__name(minorToMajor, "minorToMajor");
|
|
3636
|
-
function majorToMinor(major, currencyCode, field = "amount") {
|
|
3637
|
-
const { exponent } = resolveCurrency(currencyCode);
|
|
3638
|
-
const scale = typeof exponent === "bigint" ? Number(exponent) : exponent;
|
|
3639
|
-
const trimmed = major.trim();
|
|
3640
|
-
if (!/^-?\d+(\.\d+)?$/.test(trimmed)) {
|
|
3641
|
-
throw new ValidationException({
|
|
3642
|
-
detail: `Invalid amount: "${major}".`,
|
|
3643
|
-
errors: [
|
|
3644
|
-
{
|
|
3645
|
-
field,
|
|
3646
|
-
message: "Enter a valid number."
|
|
3647
|
-
}
|
|
3648
|
-
]
|
|
3649
|
-
});
|
|
3650
|
-
}
|
|
3651
|
-
const isNegative = trimmed.startsWith("-");
|
|
3652
|
-
const unsignedValue = isNegative ? trimmed.slice(1) : trimmed;
|
|
3653
|
-
const [wholePart, fractionalPart = ""] = unsignedValue.split(".");
|
|
3654
|
-
if (fractionalPart.length > scale) {
|
|
3655
|
-
throw new ValidationException({
|
|
3656
|
-
detail: `Too many decimal places for ${currencyCode}. Maximum allowed is ${scale}.`,
|
|
3657
|
-
errors: [
|
|
3658
|
-
{
|
|
3659
|
-
field,
|
|
3660
|
-
message: `${currencyCode} allows up to ${scale} decimal place${scale === 1 ? "" : "s"}.`
|
|
3661
|
-
}
|
|
3662
|
-
]
|
|
3663
|
-
});
|
|
3664
|
-
}
|
|
3665
|
-
const paddedFraction = fractionalPart.padEnd(scale, "0");
|
|
3666
|
-
const normalizedDigits = `${wholePart}${paddedFraction}`.replace(/^0+(?=\d)/, "");
|
|
3667
|
-
const minor = BigInt(normalizedDigits || "0");
|
|
3668
|
-
return isNegative ? -minor : minor;
|
|
3669
|
-
}
|
|
3670
|
-
__name(majorToMinor, "majorToMinor");
|
|
3671
|
-
|
|
3672
|
-
// src/decorators/is-currency.decorator.ts
|
|
3673
|
-
function IsCurrency(validationOptions) {
|
|
3674
|
-
return (target, propertyName) => {
|
|
3675
|
-
registerDecorator({
|
|
3676
|
-
name: "isCurrency",
|
|
3677
|
-
target: target.constructor,
|
|
3678
|
-
propertyName: String(propertyName),
|
|
3679
|
-
options: validationOptions,
|
|
3680
|
-
validator: {
|
|
3681
|
-
validate(value) {
|
|
3682
|
-
if (!value || typeof value !== "object") return false;
|
|
3683
|
-
const { currency, value: amount } = value;
|
|
3684
|
-
if (typeof currency !== "string" || typeof amount !== "string") return false;
|
|
3685
|
-
if (!(currency in SUPPORTED_CURRENCIES)) return false;
|
|
3686
|
-
try {
|
|
3687
|
-
majorToMinor(amount, currency);
|
|
3688
|
-
return true;
|
|
3689
|
-
} catch {
|
|
3690
|
-
return false;
|
|
3691
|
-
}
|
|
3692
|
-
},
|
|
3693
|
-
defaultMessage(args) {
|
|
3694
|
-
return `${args.property} must be {currency, value} where currency is a valid ISO 4217 code and value precision matches the currency exponent.`;
|
|
3695
|
-
}
|
|
3696
|
-
}
|
|
3697
|
-
});
|
|
3698
|
-
};
|
|
3699
|
-
}
|
|
3700
|
-
__name(IsCurrency, "IsCurrency");
|
|
3701
|
-
|
|
3702
|
-
// src/decorators/is-currency-code.decorator.ts
|
|
3703
|
-
import { registerDecorator as registerDecorator2 } from "class-validator";
|
|
3704
|
-
function IsCurrencyCode(validationOptions) {
|
|
3705
|
-
return (target, propertyName) => {
|
|
3706
|
-
registerDecorator2({
|
|
3707
|
-
name: "isCurrencyCode",
|
|
3708
|
-
target: target.constructor,
|
|
3709
|
-
propertyName: String(propertyName),
|
|
3710
|
-
options: validationOptions,
|
|
3711
|
-
validator: {
|
|
3712
|
-
validate(value) {
|
|
3713
|
-
if (typeof value !== "string") return false;
|
|
3714
|
-
return value in SUPPORTED_CURRENCIES;
|
|
3715
|
-
},
|
|
3716
|
-
defaultMessage(args) {
|
|
3717
|
-
return `${args.property} must be a valid ISO 4217 currency code.`;
|
|
3718
|
-
}
|
|
3546
|
+
// src/database/filter/keyset.processor.ts
|
|
3547
|
+
import { and as and4, eq as eq4, gt as gt2, lt as lt2, or as or2 } from "drizzle-orm";
|
|
3548
|
+
var KeysetProcessor = class {
|
|
3549
|
+
static {
|
|
3550
|
+
__name(this, "KeysetProcessor");
|
|
3551
|
+
}
|
|
3552
|
+
// Builds the "after this row" predicate for keyset pagination via lexicographic OR-expansion.
|
|
3553
|
+
// Correct for multi-column AND mixed directions: OR over i of [ AND over j<i of eq(col_j, v_j) AND cmp(col_i, v_i) ].
|
|
3554
|
+
static buildAfter(orderBy, values) {
|
|
3555
|
+
const groups = [];
|
|
3556
|
+
for (let i = 0; i < orderBy.length; i++) {
|
|
3557
|
+
const current = orderBy[i];
|
|
3558
|
+
if (!current) continue;
|
|
3559
|
+
const conditions = [];
|
|
3560
|
+
for (let j = 0; j < i; j++) {
|
|
3561
|
+
const prior = orderBy[j];
|
|
3562
|
+
if (prior) conditions.push(eq4(prior.column, values[j]));
|
|
3719
3563
|
}
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3564
|
+
const cmp = current.direction === "asc" ? gt2 : lt2;
|
|
3565
|
+
conditions.push(cmp(current.column, values[i]));
|
|
3566
|
+
const group = conditions.length === 1 ? conditions[0] : and4(...conditions);
|
|
3567
|
+
if (group) groups.push(group);
|
|
3568
|
+
}
|
|
3569
|
+
const first = groups[0];
|
|
3570
|
+
if (groups.length === 1 && first) return first;
|
|
3571
|
+
return or2(...groups);
|
|
3572
|
+
}
|
|
3573
|
+
};
|
|
3724
3574
|
|
|
3725
3575
|
// src/decorators/is-date-time.decorator.ts
|
|
3726
|
-
import { registerDecorator
|
|
3576
|
+
import { registerDecorator } from "class-validator";
|
|
3727
3577
|
var UTC_ISO_DATETIME_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?Z$/;
|
|
3728
3578
|
function IsDateTime(validationOptions) {
|
|
3729
3579
|
return (target, propertyName) => {
|
|
3730
|
-
|
|
3580
|
+
registerDecorator({
|
|
3731
3581
|
name: "isDateTime",
|
|
3732
3582
|
target: target.constructor,
|
|
3733
3583
|
propertyName: String(propertyName),
|
|
@@ -3748,7 +3598,7 @@ function IsDateTime(validationOptions) {
|
|
|
3748
3598
|
__name(IsDateTime, "IsDateTime");
|
|
3749
3599
|
|
|
3750
3600
|
// src/decorators/uploaded-file.decorator.ts
|
|
3751
|
-
import { createParamDecorator as
|
|
3601
|
+
import { createParamDecorator as createParamDecorator12 } from "@nestjs/common";
|
|
3752
3602
|
async function collectFiles(request, fieldName) {
|
|
3753
3603
|
if (!fieldName) {
|
|
3754
3604
|
const file = await request.file();
|
|
@@ -3771,7 +3621,7 @@ async function collectFiles(request, fieldName) {
|
|
|
3771
3621
|
};
|
|
3772
3622
|
}
|
|
3773
3623
|
__name(collectFiles, "collectFiles");
|
|
3774
|
-
var UploadedFile =
|
|
3624
|
+
var UploadedFile = createParamDecorator12(async (fieldName, ctx) => {
|
|
3775
3625
|
const request = ctx.switchToHttp().getRequest();
|
|
3776
3626
|
const { files } = await collectFiles(request, fieldName);
|
|
3777
3627
|
const file = files[0];
|
|
@@ -3795,7 +3645,7 @@ var UploadedFile = createParamDecorator10(async (fieldName, ctx) => {
|
|
|
3795
3645
|
mimetype: file.mimetype
|
|
3796
3646
|
};
|
|
3797
3647
|
});
|
|
3798
|
-
var UploadedFiles =
|
|
3648
|
+
var UploadedFiles = createParamDecorator12(async (fieldName, ctx) => {
|
|
3799
3649
|
const request = ctx.switchToHttp().getRequest();
|
|
3800
3650
|
const { files } = await collectFiles(request, fieldName);
|
|
3801
3651
|
if (files.length === 0) {
|
|
@@ -3823,682 +3673,203 @@ var UploadedFiles = createParamDecorator10(async (fieldName, ctx) => {
|
|
|
3823
3673
|
return results;
|
|
3824
3674
|
});
|
|
3825
3675
|
|
|
3826
|
-
// src/
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3676
|
+
// src/filters/error-code.ts
|
|
3677
|
+
import { HttpStatus as HttpStatus21 } from "@nestjs/common";
|
|
3678
|
+
var ErrorCode = /* @__PURE__ */ (function(ErrorCode2) {
|
|
3679
|
+
ErrorCode2["UNAUTHENTICATED"] = "UNAUTHENTICATED";
|
|
3680
|
+
ErrorCode2["FORBIDDEN"] = "FORBIDDEN";
|
|
3681
|
+
ErrorCode2["NOT_FOUND"] = "NOT_FOUND";
|
|
3682
|
+
ErrorCode2["VALIDATION_FAILED"] = "VALIDATION_FAILED";
|
|
3683
|
+
ErrorCode2["CONFLICT"] = "CONFLICT";
|
|
3684
|
+
ErrorCode2["RATE_LIMITED"] = "RATE_LIMITED";
|
|
3685
|
+
ErrorCode2["BAD_REQUEST"] = "BAD_REQUEST";
|
|
3686
|
+
ErrorCode2["INTERNAL"] = "INTERNAL";
|
|
3687
|
+
return ErrorCode2;
|
|
3688
|
+
})({});
|
|
3689
|
+
function errorCodeFromStatus(status) {
|
|
3690
|
+
switch (status) {
|
|
3691
|
+
case HttpStatus21.UNAUTHORIZED:
|
|
3692
|
+
return "UNAUTHENTICATED";
|
|
3693
|
+
case HttpStatus21.FORBIDDEN:
|
|
3694
|
+
return "FORBIDDEN";
|
|
3695
|
+
case HttpStatus21.NOT_FOUND:
|
|
3696
|
+
return "NOT_FOUND";
|
|
3697
|
+
case HttpStatus21.BAD_REQUEST:
|
|
3698
|
+
case HttpStatus21.UNPROCESSABLE_ENTITY:
|
|
3699
|
+
return "VALIDATION_FAILED";
|
|
3700
|
+
case HttpStatus21.CONFLICT:
|
|
3701
|
+
return "CONFLICT";
|
|
3702
|
+
case HttpStatus21.TOO_MANY_REQUESTS:
|
|
3703
|
+
return "RATE_LIMITED";
|
|
3704
|
+
default:
|
|
3705
|
+
if (status >= 400 && status < 500) {
|
|
3706
|
+
return "BAD_REQUEST";
|
|
3707
|
+
}
|
|
3708
|
+
return "INTERNAL";
|
|
3839
3709
|
}
|
|
3840
|
-
}
|
|
3841
|
-
|
|
3842
|
-
// src/email/email.module.ts
|
|
3843
|
-
import { Global as Global4, Module as Module6 } from "@nestjs/common";
|
|
3844
|
-
import { ConfigModule as ConfigModule4 } from "@nestjs/config";
|
|
3710
|
+
}
|
|
3711
|
+
__name(errorCodeFromStatus, "errorCodeFromStatus");
|
|
3845
3712
|
|
|
3846
|
-
// src/
|
|
3847
|
-
import {
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3713
|
+
// src/filters/problem-extraction.ts
|
|
3714
|
+
import { HttpStatus as HttpStatus22 } from "@nestjs/common";
|
|
3715
|
+
function getHttpStatusTitle(status) {
|
|
3716
|
+
const enumKey = Object.entries(HttpStatus22).find(([key, value]) => value === status && Number.isNaN(Number(key)))?.[0];
|
|
3717
|
+
if (!enumKey) {
|
|
3718
|
+
return "Error";
|
|
3719
|
+
}
|
|
3720
|
+
return enumKey.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
3855
3721
|
}
|
|
3856
|
-
__name(
|
|
3857
|
-
function
|
|
3858
|
-
|
|
3722
|
+
__name(getHttpStatusTitle, "getHttpStatusTitle");
|
|
3723
|
+
function extractValidationFieldErrors(message) {
|
|
3724
|
+
return message.map((msg) => {
|
|
3725
|
+
if (typeof msg === "object" && "property" in msg && "constraints" in msg) {
|
|
3726
|
+
const constraintValues = Object.values(msg.constraints);
|
|
3727
|
+
return {
|
|
3728
|
+
field: msg.property,
|
|
3729
|
+
message: constraintValues[0] ?? "Validation failed"
|
|
3730
|
+
};
|
|
3731
|
+
}
|
|
3732
|
+
return null;
|
|
3733
|
+
}).filter((error) => error !== null);
|
|
3859
3734
|
}
|
|
3860
|
-
__name(
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3735
|
+
__name(extractValidationFieldErrors, "extractValidationFieldErrors");
|
|
3736
|
+
function extractProblemFromResponse(exceptionResponse, problemFallbackDetail) {
|
|
3737
|
+
let type = "about:blank";
|
|
3738
|
+
let label;
|
|
3739
|
+
let detail;
|
|
3740
|
+
let errors = [];
|
|
3741
|
+
if (typeof exceptionResponse === "string") {
|
|
3742
|
+
detail = exceptionResponse;
|
|
3743
|
+
return {
|
|
3744
|
+
type,
|
|
3745
|
+
label,
|
|
3746
|
+
detail,
|
|
3747
|
+
errors
|
|
3748
|
+
};
|
|
3864
3749
|
}
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
if (
|
|
3874
|
-
|
|
3875
|
-
|
|
3750
|
+
if (exceptionResponse !== null && typeof exceptionResponse === "object") {
|
|
3751
|
+
const responseObj = exceptionResponse;
|
|
3752
|
+
if ("type" in responseObj || "label" in responseObj || "errors" in responseObj) {
|
|
3753
|
+
const problemResponse = responseObj;
|
|
3754
|
+
type = problemResponse.type ?? "about:blank";
|
|
3755
|
+
label = problemResponse.label;
|
|
3756
|
+
detail = problemResponse.detail ?? problemFallbackDetail;
|
|
3757
|
+
errors = problemResponse.errors ?? [];
|
|
3758
|
+
} else if ("message" in responseObj && Array.isArray(responseObj.message)) {
|
|
3759
|
+
errors = extractValidationFieldErrors(responseObj.message);
|
|
3760
|
+
detail = "Validation failed";
|
|
3761
|
+
} else if ("message" in responseObj) {
|
|
3762
|
+
const message = responseObj.message;
|
|
3763
|
+
detail = Array.isArray(message) ? message.join(", ") : message;
|
|
3876
3764
|
}
|
|
3877
|
-
this.brevoClient = new BrevoClient({
|
|
3878
|
-
apiKey,
|
|
3879
|
-
maxRetries: 3
|
|
3880
|
-
});
|
|
3881
|
-
const senderEmail = this.configService.get("SENDER_EMAIL");
|
|
3882
|
-
const senderName = this.configService.get("SENDER_NAME");
|
|
3883
|
-
if (!senderEmail || !senderName) {
|
|
3884
|
-
this.logger.error("Sender email or name is not configured.");
|
|
3885
|
-
throw new Error("Email service configuration error: Missing SENDER_EMAIL or SENDER_NAME");
|
|
3886
|
-
}
|
|
3887
|
-
this.senderEmail = senderEmail;
|
|
3888
|
-
this.senderName = senderName;
|
|
3889
|
-
this.logger.log("Brevo email service initialized successfully");
|
|
3890
|
-
}
|
|
3891
|
-
// Sends an email verification OTP to the given recipient
|
|
3892
|
-
async sendVerificationEmail(email, otp, expiresAt, displayName) {
|
|
3893
|
-
const name = displayName || "there";
|
|
3894
|
-
const expiryMinutes = Math.ceil((expiresAt.getTime() - Date.now()) / 6e4);
|
|
3895
|
-
const subject = "Verify Your Email - Vritti AI Cloud";
|
|
3896
|
-
const htmlContent = `
|
|
3897
|
-
<!DOCTYPE html>
|
|
3898
|
-
<html>
|
|
3899
|
-
<head>
|
|
3900
|
-
<meta charset="UTF-8">
|
|
3901
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3902
|
-
</head>
|
|
3903
|
-
<body style="margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; background-color: #f5f5f5;">
|
|
3904
|
-
<table role="presentation" style="width: 100%; border-collapse: collapse;">
|
|
3905
|
-
<tr>
|
|
3906
|
-
<td style="padding: 40px 20px;">
|
|
3907
|
-
<table role="presentation" style="max-width: 600px; margin: 0 auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
|
|
3908
|
-
<!-- Header -->
|
|
3909
|
-
<tr>
|
|
3910
|
-
<td style="padding: 40px 40px 20px; text-align: center; border-bottom: 1px solid #e0e0e0;">
|
|
3911
|
-
<h1 style="margin: 0; color: #1a1a1a; font-size: 24px; font-weight: 600;">Email Verification</h1>
|
|
3912
|
-
</td>
|
|
3913
|
-
</tr>
|
|
3914
|
-
|
|
3915
|
-
<!-- Content -->
|
|
3916
|
-
<tr>
|
|
3917
|
-
<td style="padding: 40px;">
|
|
3918
|
-
<p style="margin: 0 0 20px; color: #333333; font-size: 16px; line-height: 1.6;">
|
|
3919
|
-
Hello <strong>${name}</strong>,
|
|
3920
|
-
</p>
|
|
3921
|
-
<p style="margin: 0 0 30px; color: #333333; font-size: 16px; line-height: 1.6;">
|
|
3922
|
-
Thank you for signing up with Vritti AI Cloud. Please use the following verification code to complete your registration:
|
|
3923
|
-
</p>
|
|
3924
|
-
|
|
3925
|
-
<!-- OTP Box -->
|
|
3926
|
-
<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 30px; border-radius: 8px; text-align: center; margin: 30px 0;">
|
|
3927
|
-
<div style="color: #ffffff; font-size: 36px; font-weight: bold; letter-spacing: 10px; font-family: 'Courier New', monospace;">
|
|
3928
|
-
${otp}
|
|
3929
|
-
</div>
|
|
3930
|
-
</div>
|
|
3931
|
-
|
|
3932
|
-
<p style="margin: 30px 0 20px; color: #666666; font-size: 14px; line-height: 1.6;">
|
|
3933
|
-
<strong>Important:</strong> This code will expire in <strong>${expiryMinutes} minute${expiryMinutes === 1 ? "" : "s"}</strong>.
|
|
3934
|
-
</p>
|
|
3935
|
-
<p style="margin: 0; color: #666666; font-size: 14px; line-height: 1.6;">
|
|
3936
|
-
If you didn't request this verification, please ignore this email.
|
|
3937
|
-
</p>
|
|
3938
|
-
</td>
|
|
3939
|
-
</tr>
|
|
3940
|
-
|
|
3941
|
-
<!-- Footer -->
|
|
3942
|
-
<tr>
|
|
3943
|
-
<td style="padding: 30px 40px; border-top: 1px solid #e0e0e0; text-align: center;">
|
|
3944
|
-
<p style="margin: 0; color: #999999; font-size: 12px; line-height: 1.5;">
|
|
3945
|
-
Vritti AI Cloud - Cloud Management Platform
|
|
3946
|
-
</p>
|
|
3947
|
-
<p style="margin: 8px 0 0; color: #999999; font-size: 12px; line-height: 1.5;">
|
|
3948
|
-
This is an automated message, please do not reply.
|
|
3949
|
-
</p>
|
|
3950
|
-
</td>
|
|
3951
|
-
</tr>
|
|
3952
|
-
</table>
|
|
3953
|
-
</td>
|
|
3954
|
-
</tr>
|
|
3955
|
-
</table>
|
|
3956
|
-
</body>
|
|
3957
|
-
</html>
|
|
3958
|
-
`;
|
|
3959
|
-
const textContent = `
|
|
3960
|
-
Hello ${name},
|
|
3961
|
-
|
|
3962
|
-
Thank you for signing up with Vritti AI Cloud. Please use the following verification code to complete your registration:
|
|
3963
|
-
|
|
3964
|
-
Verification Code: ${otp}
|
|
3965
|
-
|
|
3966
|
-
This code will expire in ${expiryMinutes} minute${expiryMinutes === 1 ? "" : "s"}.
|
|
3967
|
-
|
|
3968
|
-
If you didn't request this verification, please ignore this email.
|
|
3969
|
-
|
|
3970
|
-
---
|
|
3971
|
-
Vritti AI Cloud - Cloud Management Platform
|
|
3972
|
-
This is an automated message, please do not reply.
|
|
3973
|
-
`.trim();
|
|
3974
|
-
await this.sendEmail({
|
|
3975
|
-
to: [
|
|
3976
|
-
{
|
|
3977
|
-
email,
|
|
3978
|
-
name
|
|
3979
|
-
}
|
|
3980
|
-
],
|
|
3981
|
-
subject,
|
|
3982
|
-
htmlContent,
|
|
3983
|
-
textContent
|
|
3984
|
-
});
|
|
3985
|
-
this.logger.log(`Verification email sent to ${email}`);
|
|
3986
|
-
}
|
|
3987
|
-
// Sends a password reset OTP to the given recipient
|
|
3988
|
-
async sendPasswordResetEmail(email, otp, expiresAt, displayName) {
|
|
3989
|
-
const name = displayName || "there";
|
|
3990
|
-
const expiryMinutes = Math.ceil((expiresAt.getTime() - Date.now()) / 6e4);
|
|
3991
|
-
const subject = "Reset Your Password - Vritti AI Cloud";
|
|
3992
|
-
const htmlContent = `
|
|
3993
|
-
<!DOCTYPE html>
|
|
3994
|
-
<html>
|
|
3995
|
-
<head>
|
|
3996
|
-
<meta charset="UTF-8">
|
|
3997
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3998
|
-
</head>
|
|
3999
|
-
<body style="margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; background-color: #f5f5f5;">
|
|
4000
|
-
<table role="presentation" style="width: 100%; border-collapse: collapse;">
|
|
4001
|
-
<tr>
|
|
4002
|
-
<td style="padding: 40px 20px;">
|
|
4003
|
-
<table role="presentation" style="max-width: 600px; margin: 0 auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
|
|
4004
|
-
<!-- Header -->
|
|
4005
|
-
<tr>
|
|
4006
|
-
<td style="padding: 40px 40px 20px; text-align: center; border-bottom: 1px solid #e0e0e0;">
|
|
4007
|
-
<h1 style="margin: 0; color: #1a1a1a; font-size: 24px; font-weight: 600;">Password Reset</h1>
|
|
4008
|
-
</td>
|
|
4009
|
-
</tr>
|
|
4010
|
-
|
|
4011
|
-
<!-- Content -->
|
|
4012
|
-
<tr>
|
|
4013
|
-
<td style="padding: 40px;">
|
|
4014
|
-
<p style="margin: 0 0 20px; color: #333333; font-size: 16px; line-height: 1.6;">
|
|
4015
|
-
Hello <strong>${name}</strong>,
|
|
4016
|
-
</p>
|
|
4017
|
-
<p style="margin: 0 0 30px; color: #333333; font-size: 16px; line-height: 1.6;">
|
|
4018
|
-
We received a request to reset your password. Use the following code to complete the process:
|
|
4019
|
-
</p>
|
|
4020
|
-
|
|
4021
|
-
<!-- OTP Box -->
|
|
4022
|
-
<div style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); padding: 30px; border-radius: 8px; text-align: center; margin: 30px 0;">
|
|
4023
|
-
<div style="color: #ffffff; font-size: 36px; font-weight: bold; letter-spacing: 10px; font-family: 'Courier New', monospace;">
|
|
4024
|
-
${otp}
|
|
4025
|
-
</div>
|
|
4026
|
-
</div>
|
|
4027
|
-
|
|
4028
|
-
<p style="margin: 30px 0 20px; color: #666666; font-size: 14px; line-height: 1.6;">
|
|
4029
|
-
<strong>Important:</strong> This code will expire in <strong>${expiryMinutes} minute${expiryMinutes === 1 ? "" : "s"}</strong>.
|
|
4030
|
-
</p>
|
|
4031
|
-
<p style="margin: 0 0 20px; color: #666666; font-size: 14px; line-height: 1.6;">
|
|
4032
|
-
If you didn't request a password reset, please ignore this email and your password will remain unchanged.
|
|
4033
|
-
</p>
|
|
4034
|
-
<div style="background-color: #fff3cd; border-left: 4px solid #ffc107; padding: 15px; margin-top: 20px; border-radius: 4px;">
|
|
4035
|
-
<p style="margin: 0; color: #856404; font-size: 13px; line-height: 1.5;">
|
|
4036
|
-
<strong>Security Tip:</strong> Never share this code with anyone. Vritti will never ask for your verification code.
|
|
4037
|
-
</p>
|
|
4038
|
-
</div>
|
|
4039
|
-
</td>
|
|
4040
|
-
</tr>
|
|
4041
|
-
|
|
4042
|
-
<!-- Footer -->
|
|
4043
|
-
<tr>
|
|
4044
|
-
<td style="padding: 30px 40px; border-top: 1px solid #e0e0e0; text-align: center;">
|
|
4045
|
-
<p style="margin: 0; color: #999999; font-size: 12px; line-height: 1.5;">
|
|
4046
|
-
Vritti AI Cloud - Cloud Management Platform
|
|
4047
|
-
</p>
|
|
4048
|
-
<p style="margin: 8px 0 0; color: #999999; font-size: 12px; line-height: 1.5;">
|
|
4049
|
-
This is an automated message, please do not reply.
|
|
4050
|
-
</p>
|
|
4051
|
-
</td>
|
|
4052
|
-
</tr>
|
|
4053
|
-
</table>
|
|
4054
|
-
</td>
|
|
4055
|
-
</tr>
|
|
4056
|
-
</table>
|
|
4057
|
-
</body>
|
|
4058
|
-
</html>
|
|
4059
|
-
`;
|
|
4060
|
-
const textContent = `
|
|
4061
|
-
Hello ${name},
|
|
4062
|
-
|
|
4063
|
-
We received a request to reset your password. Use the following code to complete the process:
|
|
4064
|
-
|
|
4065
|
-
Reset Code: ${otp}
|
|
4066
|
-
|
|
4067
|
-
This code will expire in ${expiryMinutes} minute${expiryMinutes === 1 ? "" : "s"}.
|
|
4068
|
-
|
|
4069
|
-
If you didn't request a password reset, please ignore this email and your password will remain unchanged.
|
|
4070
|
-
|
|
4071
|
-
SECURITY TIP: Never share this code with anyone. Vritti will never ask for your verification code.
|
|
4072
|
-
|
|
4073
|
-
---
|
|
4074
|
-
Vritti AI Cloud - Cloud Management Platform
|
|
4075
|
-
This is an automated message, please do not reply.
|
|
4076
|
-
`.trim();
|
|
4077
|
-
await this.sendEmail({
|
|
4078
|
-
to: [
|
|
4079
|
-
{
|
|
4080
|
-
email,
|
|
4081
|
-
name
|
|
4082
|
-
}
|
|
4083
|
-
],
|
|
4084
|
-
subject,
|
|
4085
|
-
htmlContent,
|
|
4086
|
-
textContent
|
|
4087
|
-
});
|
|
4088
|
-
this.logger.log(`Password reset email sent to ${email}`);
|
|
4089
|
-
}
|
|
4090
|
-
// Sends an email change notification to the old address with a revert link
|
|
4091
|
-
async sendEmailChangeNotification(oldEmail, newEmail, revertToken, revertExpiresAt, displayName) {
|
|
4092
|
-
const name = displayName || "there";
|
|
4093
|
-
const subject = "Your Email Address Has Been Changed - Vritti AI Cloud";
|
|
4094
|
-
const hoursUntilExpiry = Math.floor((revertExpiresAt.getTime() - Date.now()) / (1e3 * 60 * 60));
|
|
4095
|
-
const revertLink = `https://local.vrittiai.com:3012/settings/profile/revert-email?token=${revertToken}`;
|
|
4096
|
-
const htmlContent = `
|
|
4097
|
-
<!DOCTYPE html>
|
|
4098
|
-
<html>
|
|
4099
|
-
<head>
|
|
4100
|
-
<meta charset="UTF-8">
|
|
4101
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
4102
|
-
</head>
|
|
4103
|
-
<body style="margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; background-color: #f5f5f5;">
|
|
4104
|
-
<table role="presentation" style="width: 100%; border-collapse: collapse;">
|
|
4105
|
-
<tr>
|
|
4106
|
-
<td style="padding: 40px 20px;">
|
|
4107
|
-
<table role="presentation" style="max-width: 600px; margin: 0 auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
|
|
4108
|
-
<!-- Header -->
|
|
4109
|
-
<tr>
|
|
4110
|
-
<td style="padding: 40px 40px 20px; text-align: center; border-bottom: 1px solid #e0e0e0;">
|
|
4111
|
-
<h1 style="margin: 0; color: #1a1a1a; font-size: 24px; font-weight: 600;">Email Address Changed</h1>
|
|
4112
|
-
</td>
|
|
4113
|
-
</tr>
|
|
4114
|
-
|
|
4115
|
-
<!-- Content -->
|
|
4116
|
-
<tr>
|
|
4117
|
-
<td style="padding: 40px;">
|
|
4118
|
-
<p style="margin: 0 0 20px; color: #333333; font-size: 16px; line-height: 1.6;">
|
|
4119
|
-
Hello <strong>${name}</strong>,
|
|
4120
|
-
</p>
|
|
4121
|
-
<p style="margin: 0 0 30px; color: #333333; font-size: 16px; line-height: 1.6;">
|
|
4122
|
-
We're writing to inform you that your Vritti AI Cloud email address has been successfully changed.
|
|
4123
|
-
</p>
|
|
4124
|
-
|
|
4125
|
-
<div style="background-color: #f8f9fa; padding: 20px; border-radius: 8px; margin: 30px 0;">
|
|
4126
|
-
<p style="margin: 0 0 10px; color: #666666; font-size: 14px;">
|
|
4127
|
-
<strong>Previous Email:</strong>
|
|
4128
|
-
</p>
|
|
4129
|
-
<p style="margin: 0 0 20px; color: #333333; font-size: 16px; font-family: monospace;">
|
|
4130
|
-
${oldEmail}
|
|
4131
|
-
</p>
|
|
4132
|
-
<p style="margin: 0 0 10px; color: #666666; font-size: 14px;">
|
|
4133
|
-
<strong>New Email:</strong>
|
|
4134
|
-
</p>
|
|
4135
|
-
<p style="margin: 0; color: #333333; font-size: 16px; font-family: monospace;">
|
|
4136
|
-
${newEmail}
|
|
4137
|
-
</p>
|
|
4138
|
-
</div>
|
|
4139
|
-
|
|
4140
|
-
<div style="background-color: #fff3cd; border-left: 4px solid #ffc107; padding: 20px; margin: 30px 0; border-radius: 4px;">
|
|
4141
|
-
<p style="margin: 0 0 15px; color: #856404; font-size: 14px; line-height: 1.6;">
|
|
4142
|
-
<strong>Didn't make this change?</strong>
|
|
4143
|
-
</p>
|
|
4144
|
-
<p style="margin: 0 0 20px; color: #856404; font-size: 14px; line-height: 1.6;">
|
|
4145
|
-
If you did not authorize this change, you can revert it within the next <strong>${hoursUntilExpiry} hours</strong> by clicking the button below:
|
|
4146
|
-
</p>
|
|
4147
|
-
<div style="text-align: center;">
|
|
4148
|
-
<a href="${revertLink}" style="display: inline-block; padding: 12px 30px; background-color: #dc3545; color: #ffffff; text-decoration: none; border-radius: 6px; font-weight: 600; font-size: 14px;">
|
|
4149
|
-
Revert Email Change
|
|
4150
|
-
</a>
|
|
4151
|
-
</div>
|
|
4152
|
-
</div>
|
|
4153
|
-
|
|
4154
|
-
<p style="margin: 30px 0 0; color: #666666; font-size: 14px; line-height: 1.6;">
|
|
4155
|
-
If you made this change, you can safely ignore this email.
|
|
4156
|
-
</p>
|
|
4157
|
-
</td>
|
|
4158
|
-
</tr>
|
|
4159
|
-
|
|
4160
|
-
<!-- Footer -->
|
|
4161
|
-
<tr>
|
|
4162
|
-
<td style="padding: 30px 40px; border-top: 1px solid #e0e0e0; text-align: center;">
|
|
4163
|
-
<p style="margin: 0; color: #999999; font-size: 12px; line-height: 1.5;">
|
|
4164
|
-
Vritti AI Cloud - Cloud Management Platform
|
|
4165
|
-
</p>
|
|
4166
|
-
<p style="margin: 8px 0 0; color: #999999; font-size: 12px; line-height: 1.5;">
|
|
4167
|
-
This is an automated message, please do not reply.
|
|
4168
|
-
</p>
|
|
4169
|
-
</td>
|
|
4170
|
-
</tr>
|
|
4171
|
-
</table>
|
|
4172
|
-
</td>
|
|
4173
|
-
</tr>
|
|
4174
|
-
</table>
|
|
4175
|
-
</body>
|
|
4176
|
-
</html>
|
|
4177
|
-
`;
|
|
4178
|
-
const textContent = `
|
|
4179
|
-
Hello ${name},
|
|
4180
|
-
|
|
4181
|
-
We're writing to inform you that your Vritti AI Cloud email address has been successfully changed.
|
|
4182
|
-
|
|
4183
|
-
Previous Email: ${oldEmail}
|
|
4184
|
-
New Email: ${newEmail}
|
|
4185
|
-
|
|
4186
|
-
DIDN'T MAKE THIS CHANGE?
|
|
4187
|
-
|
|
4188
|
-
If you did not authorize this change, you can revert it within the next ${hoursUntilExpiry} hours by visiting:
|
|
4189
|
-
${revertLink}
|
|
4190
|
-
|
|
4191
|
-
If you made this change, you can safely ignore this email.
|
|
4192
|
-
|
|
4193
|
-
---
|
|
4194
|
-
Vritti AI Cloud - Cloud Management Platform
|
|
4195
|
-
This is an automated message, please do not reply.
|
|
4196
|
-
`.trim();
|
|
4197
|
-
await this.sendEmail({
|
|
4198
|
-
to: [
|
|
4199
|
-
{
|
|
4200
|
-
email: oldEmail,
|
|
4201
|
-
name
|
|
4202
|
-
}
|
|
4203
|
-
],
|
|
4204
|
-
subject,
|
|
4205
|
-
htmlContent,
|
|
4206
|
-
textContent
|
|
4207
|
-
});
|
|
4208
|
-
this.logger.log(`Email change notification sent to ${oldEmail}`);
|
|
4209
|
-
}
|
|
4210
|
-
// Sends a confirmation to the restored email address after a revert
|
|
4211
|
-
async sendEmailRevertConfirmation(email, displayName) {
|
|
4212
|
-
const name = displayName || "there";
|
|
4213
|
-
const subject = "Email Address Change Reverted - Vritti AI Cloud";
|
|
4214
|
-
const htmlContent = `
|
|
4215
|
-
<!DOCTYPE html>
|
|
4216
|
-
<html>
|
|
4217
|
-
<head>
|
|
4218
|
-
<meta charset="UTF-8">
|
|
4219
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
4220
|
-
</head>
|
|
4221
|
-
<body style="margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; background-color: #f5f5f5;">
|
|
4222
|
-
<table role="presentation" style="width: 100%; border-collapse: collapse;">
|
|
4223
|
-
<tr>
|
|
4224
|
-
<td style="padding: 40px 20px;">
|
|
4225
|
-
<table role="presentation" style="max-width: 600px; margin: 0 auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
|
|
4226
|
-
<!-- Header -->
|
|
4227
|
-
<tr>
|
|
4228
|
-
<td style="padding: 40px 40px 20px; text-align: center; border-bottom: 1px solid #e0e0e0;">
|
|
4229
|
-
<h1 style="margin: 0; color: #1a1a1a; font-size: 24px; font-weight: 600;">Email Change Reverted</h1>
|
|
4230
|
-
</td>
|
|
4231
|
-
</tr>
|
|
4232
|
-
|
|
4233
|
-
<!-- Content -->
|
|
4234
|
-
<tr>
|
|
4235
|
-
<td style="padding: 40px;">
|
|
4236
|
-
<p style="margin: 0 0 20px; color: #333333; font-size: 16px; line-height: 1.6;">
|
|
4237
|
-
Hello <strong>${name}</strong>,
|
|
4238
|
-
</p>
|
|
4239
|
-
<p style="margin: 0 0 30px; color: #333333; font-size: 16px; line-height: 1.6;">
|
|
4240
|
-
Your recent email address change has been successfully reverted. Your email is now:
|
|
4241
|
-
</p>
|
|
4242
|
-
|
|
4243
|
-
<div style="background-color: #d4edda; padding: 20px; border-radius: 8px; margin: 30px 0; text-align: center;">
|
|
4244
|
-
<p style="margin: 0; color: #155724; font-size: 18px; font-weight: 600; font-family: monospace;">
|
|
4245
|
-
${email}
|
|
4246
|
-
</p>
|
|
4247
|
-
</div>
|
|
4248
|
-
|
|
4249
|
-
<p style="margin: 30px 0 20px; color: #666666; font-size: 14px; line-height: 1.6;">
|
|
4250
|
-
If you did not request this revert, please contact our support team immediately.
|
|
4251
|
-
</p>
|
|
4252
|
-
</td>
|
|
4253
|
-
</tr>
|
|
4254
|
-
|
|
4255
|
-
<!-- Footer -->
|
|
4256
|
-
<tr>
|
|
4257
|
-
<td style="padding: 30px 40px; border-top: 1px solid #e0e0e0; text-align: center;">
|
|
4258
|
-
<p style="margin: 0; color: #999999; font-size: 12px; line-height: 1.5;">
|
|
4259
|
-
Vritti AI Cloud - Cloud Management Platform
|
|
4260
|
-
</p>
|
|
4261
|
-
<p style="margin: 8px 0 0; color: #999999; font-size: 12px; line-height: 1.5;">
|
|
4262
|
-
This is an automated message, please do not reply.
|
|
4263
|
-
</p>
|
|
4264
|
-
</td>
|
|
4265
|
-
</tr>
|
|
4266
|
-
</table>
|
|
4267
|
-
</td>
|
|
4268
|
-
</tr>
|
|
4269
|
-
</table>
|
|
4270
|
-
</body>
|
|
4271
|
-
</html>
|
|
4272
|
-
`;
|
|
4273
|
-
const textContent = `
|
|
4274
|
-
Hello ${name},
|
|
4275
|
-
|
|
4276
|
-
Your recent email address change has been successfully reverted. Your email is now:
|
|
4277
|
-
|
|
4278
|
-
${email}
|
|
4279
|
-
|
|
4280
|
-
If you did not request this revert, please contact our support team immediately.
|
|
4281
|
-
|
|
4282
|
-
---
|
|
4283
|
-
Vritti AI Cloud - Cloud Management Platform
|
|
4284
|
-
This is an automated message, please do not reply.
|
|
4285
|
-
`.trim();
|
|
4286
|
-
await this.sendEmail({
|
|
4287
|
-
to: [
|
|
4288
|
-
{
|
|
4289
|
-
email,
|
|
4290
|
-
name
|
|
4291
|
-
}
|
|
4292
|
-
],
|
|
4293
|
-
subject,
|
|
4294
|
-
htmlContent,
|
|
4295
|
-
textContent
|
|
4296
|
-
});
|
|
4297
|
-
this.logger.log(`Email revert confirmation sent to ${email}`);
|
|
4298
|
-
}
|
|
4299
|
-
// Sends an invite email to a new portal user with their set-password link
|
|
4300
|
-
async sendInviteEmail(params) {
|
|
4301
|
-
const { to, name, inviteUrl } = params;
|
|
4302
|
-
const subject = "You have been invited to Vritti AI";
|
|
4303
|
-
const htmlContent = `
|
|
4304
|
-
<!DOCTYPE html>
|
|
4305
|
-
<html>
|
|
4306
|
-
<head>
|
|
4307
|
-
<meta charset="UTF-8">
|
|
4308
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
4309
|
-
</head>
|
|
4310
|
-
<body style="margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; background-color: #f5f5f5;">
|
|
4311
|
-
<table role="presentation" style="width: 100%; border-collapse: collapse;">
|
|
4312
|
-
<tr>
|
|
4313
|
-
<td style="padding: 40px 20px;">
|
|
4314
|
-
<table role="presentation" style="max-width: 600px; margin: 0 auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
|
|
4315
|
-
<!-- Header -->
|
|
4316
|
-
<tr>
|
|
4317
|
-
<td style="padding: 40px 40px 20px; text-align: center; border-bottom: 1px solid #e0e0e0;">
|
|
4318
|
-
<h1 style="margin: 0; color: #1a1a1a; font-size: 24px; font-weight: 600;">You're Invited</h1>
|
|
4319
|
-
</td>
|
|
4320
|
-
</tr>
|
|
4321
|
-
|
|
4322
|
-
<!-- Content -->
|
|
4323
|
-
<tr>
|
|
4324
|
-
<td style="padding: 40px;">
|
|
4325
|
-
<p style="margin: 0 0 20px; color: #333333; font-size: 16px; line-height: 1.6;">
|
|
4326
|
-
Hello <strong>${name}</strong>,
|
|
4327
|
-
</p>
|
|
4328
|
-
<p style="margin: 0 0 30px; color: #333333; font-size: 16px; line-height: 1.6;">
|
|
4329
|
-
You have been invited to join Vritti AI. Click the button below to set your password and get started.
|
|
4330
|
-
</p>
|
|
4331
|
-
|
|
4332
|
-
<div style="text-align: center; margin: 30px 0;">
|
|
4333
|
-
<a href="${inviteUrl}" style="display: inline-block; padding: 14px 32px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: #ffffff; text-decoration: none; border-radius: 6px; font-weight: 600; font-size: 16px;">
|
|
4334
|
-
Set Your Password
|
|
4335
|
-
</a>
|
|
4336
|
-
</div>
|
|
4337
|
-
|
|
4338
|
-
<p style="margin: 30px 0 0; color: #666666; font-size: 14px; line-height: 1.6;">
|
|
4339
|
-
If you did not expect this invitation, you can safely ignore this email.
|
|
4340
|
-
</p>
|
|
4341
|
-
</td>
|
|
4342
|
-
</tr>
|
|
4343
|
-
|
|
4344
|
-
<!-- Footer -->
|
|
4345
|
-
<tr>
|
|
4346
|
-
<td style="padding: 30px 40px; border-top: 1px solid #e0e0e0; text-align: center;">
|
|
4347
|
-
<p style="margin: 0; color: #999999; font-size: 12px; line-height: 1.5;">
|
|
4348
|
-
Vritti AI Cloud - Cloud Management Platform
|
|
4349
|
-
</p>
|
|
4350
|
-
<p style="margin: 8px 0 0; color: #999999; font-size: 12px; line-height: 1.5;">
|
|
4351
|
-
This is an automated message, please do not reply.
|
|
4352
|
-
</p>
|
|
4353
|
-
</td>
|
|
4354
|
-
</tr>
|
|
4355
|
-
</table>
|
|
4356
|
-
</td>
|
|
4357
|
-
</tr>
|
|
4358
|
-
</table>
|
|
4359
|
-
</body>
|
|
4360
|
-
</html>
|
|
4361
|
-
`;
|
|
4362
|
-
const textContent = `
|
|
4363
|
-
Hello ${name},
|
|
4364
|
-
|
|
4365
|
-
You have been invited to join Vritti AI. Visit the link below to set your password and get started:
|
|
4366
|
-
|
|
4367
|
-
${inviteUrl}
|
|
4368
|
-
|
|
4369
|
-
If you did not expect this invitation, you can safely ignore this email.
|
|
4370
|
-
|
|
4371
|
-
---
|
|
4372
|
-
Vritti AI Cloud - Cloud Management Platform
|
|
4373
|
-
This is an automated message, please do not reply.
|
|
4374
|
-
`.trim();
|
|
4375
|
-
await this.sendEmail({
|
|
4376
|
-
to: [
|
|
4377
|
-
{
|
|
4378
|
-
email: to,
|
|
4379
|
-
name
|
|
4380
|
-
}
|
|
4381
|
-
],
|
|
4382
|
-
subject,
|
|
4383
|
-
htmlContent,
|
|
4384
|
-
textContent
|
|
4385
|
-
});
|
|
4386
|
-
this.logger.log(`Invite email sent to ${to}`);
|
|
4387
3765
|
}
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
|
|
3766
|
+
return {
|
|
3767
|
+
type,
|
|
3768
|
+
label,
|
|
3769
|
+
detail,
|
|
3770
|
+
errors
|
|
3771
|
+
};
|
|
3772
|
+
}
|
|
3773
|
+
__name(extractProblemFromResponse, "extractProblemFromResponse");
|
|
3774
|
+
|
|
3775
|
+
// src/filters/graphql-format-error.ts
|
|
3776
|
+
function isHttpExceptionLike(error) {
|
|
3777
|
+
return error instanceof Error && typeof error.getStatus === "function" && typeof error.getResponse === "function";
|
|
3778
|
+
}
|
|
3779
|
+
__name(isHttpExceptionLike, "isHttpExceptionLike");
|
|
3780
|
+
function isProblemLike(error) {
|
|
3781
|
+
if (error == null || typeof error !== "object") {
|
|
3782
|
+
return false;
|
|
4399
3783
|
}
|
|
4400
|
-
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
htmlContent: "<p>Test</p>"
|
|
4415
|
-
});
|
|
4416
|
-
return true;
|
|
4417
|
-
} catch (err) {
|
|
4418
|
-
if (err instanceof BrevoError && err.statusCode === 400) {
|
|
4419
|
-
return true;
|
|
4420
|
-
}
|
|
4421
|
-
this.logger.error("Brevo connection verification failed:", err);
|
|
4422
|
-
return false;
|
|
3784
|
+
const o = error;
|
|
3785
|
+
return typeof o.status === "number" || typeof o.statusCode === "number";
|
|
3786
|
+
}
|
|
3787
|
+
__name(isProblemLike, "isProblemLike");
|
|
3788
|
+
function findProblemSource(error) {
|
|
3789
|
+
let current = error;
|
|
3790
|
+
for (let depth = 0; current && depth < 10; depth++) {
|
|
3791
|
+
if (isHttpExceptionLike(current)) {
|
|
3792
|
+
const status = current.getStatus();
|
|
3793
|
+
return {
|
|
3794
|
+
status,
|
|
3795
|
+
response: current.getResponse(),
|
|
3796
|
+
fallback: current.message ?? getHttpStatusTitle(status)
|
|
3797
|
+
};
|
|
4423
3798
|
}
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
name: this.senderName
|
|
4432
|
-
},
|
|
4433
|
-
to: emailData.to,
|
|
4434
|
-
subject: emailData.subject,
|
|
4435
|
-
htmlContent: emailData.htmlContent,
|
|
4436
|
-
textContent: emailData.textContent
|
|
4437
|
-
});
|
|
4438
|
-
this.logger.debug(`Email sent successfully. Message ID: ${result.messageId}`);
|
|
4439
|
-
} catch (err) {
|
|
4440
|
-
if (err instanceof BrevoTimeoutError) {
|
|
4441
|
-
this.logger.error("Brevo request timed out after retries.");
|
|
4442
|
-
throw new Error("Email sending failed: timeout");
|
|
4443
|
-
}
|
|
4444
|
-
if (err instanceof BrevoError) {
|
|
4445
|
-
if (err.statusCode === 429) {
|
|
4446
|
-
this.logger.error("Brevo rate limit exceeded after retries.");
|
|
4447
|
-
throw new Error("Email sending failed: rate limit exceeded");
|
|
4448
|
-
}
|
|
4449
|
-
if (err.statusCode === 401) {
|
|
4450
|
-
this.logger.error("Brevo authentication failed. Check your API key.");
|
|
4451
|
-
throw new Error("Email service authentication failed");
|
|
4452
|
-
}
|
|
4453
|
-
if (err.statusCode === 400) {
|
|
4454
|
-
this.logger.error("Bad request to Brevo API:", err.message);
|
|
4455
|
-
throw new Error(`Invalid email parameters: ${err.message}`);
|
|
4456
|
-
}
|
|
4457
|
-
this.logger.error(`Brevo API error ${err.statusCode}:`, err.message);
|
|
4458
|
-
throw new Error(`Email sending failed: ${err.message}`);
|
|
4459
|
-
}
|
|
4460
|
-
throw err;
|
|
3799
|
+
if (isProblemLike(current)) {
|
|
3800
|
+
const status = current.status ?? current.statusCode ?? 500;
|
|
3801
|
+
return {
|
|
3802
|
+
status,
|
|
3803
|
+
response: current,
|
|
3804
|
+
fallback: current.detail ?? current.message ?? getHttpStatusTitle(status)
|
|
3805
|
+
};
|
|
4461
3806
|
}
|
|
3807
|
+
const next = current;
|
|
3808
|
+
current = next.originalError ?? next.thrownValue;
|
|
4462
3809
|
}
|
|
4463
|
-
|
|
4464
|
-
EmailService = _ts_decorate28([
|
|
4465
|
-
Injectable10(),
|
|
4466
|
-
_ts_metadata23("design:type", Function),
|
|
4467
|
-
_ts_metadata23("design:paramtypes", [
|
|
4468
|
-
typeof ConfigService5 === "undefined" ? Object : ConfigService5
|
|
4469
|
-
])
|
|
4470
|
-
], EmailService);
|
|
4471
|
-
|
|
4472
|
-
// src/email/email.module.ts
|
|
4473
|
-
function _ts_decorate29(decorators, target, key, desc3) {
|
|
4474
|
-
var c = arguments.length, r = c < 3 ? target : desc3 === null ? desc3 = Object.getOwnPropertyDescriptor(target, key) : desc3, d;
|
|
4475
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc3);
|
|
4476
|
-
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;
|
|
4477
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3810
|
+
return void 0;
|
|
4478
3811
|
}
|
|
4479
|
-
__name(
|
|
4480
|
-
var
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
3812
|
+
__name(findProblemSource, "findProblemSource");
|
|
3813
|
+
var GENERIC_INTERNAL_MESSAGE = "Internal server error";
|
|
3814
|
+
function createGraphqlFormatError(opts) {
|
|
3815
|
+
const { isProduction, getTraceId } = opts;
|
|
3816
|
+
return (formattedError, error) => {
|
|
3817
|
+
const gqlError = error ?? void 0;
|
|
3818
|
+
const source = findProblemSource(gqlError);
|
|
3819
|
+
let status = 500;
|
|
3820
|
+
let detail;
|
|
3821
|
+
let label;
|
|
3822
|
+
let fieldErrors = [];
|
|
3823
|
+
if (source) {
|
|
3824
|
+
status = source.status;
|
|
3825
|
+
const extracted = extractProblemFromResponse(source.response, source.fallback);
|
|
3826
|
+
detail = extracted.detail;
|
|
3827
|
+
label = extracted.label;
|
|
3828
|
+
fieldErrors = extracted.errors;
|
|
3829
|
+
}
|
|
3830
|
+
const code = errorCodeFromStatus(status);
|
|
3831
|
+
let message = detail ?? formattedError.message;
|
|
3832
|
+
if (code === "INTERNAL" && isProduction) {
|
|
3833
|
+
message = GENERIC_INTERNAL_MESSAGE;
|
|
3834
|
+
}
|
|
3835
|
+
const incoming = {
|
|
3836
|
+
...formattedError.extensions ?? {}
|
|
3837
|
+
};
|
|
3838
|
+
const traceId = getTraceId?.();
|
|
3839
|
+
const timestamp2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
3840
|
+
const extensions = {
|
|
3841
|
+
...incoming,
|
|
3842
|
+
// Always our canonical code — overrides Apollo's default INTERNAL_SERVER_ERROR.
|
|
3843
|
+
code,
|
|
3844
|
+
...traceId !== void 0 ? {
|
|
3845
|
+
traceId
|
|
3846
|
+
} : {},
|
|
3847
|
+
timestamp: timestamp2,
|
|
3848
|
+
...label !== void 0 ? {
|
|
3849
|
+
label
|
|
3850
|
+
} : {},
|
|
3851
|
+
...fieldErrors.length > 0 ? {
|
|
3852
|
+
fieldErrors
|
|
3853
|
+
} : {}
|
|
3854
|
+
};
|
|
3855
|
+
if (isProduction) {
|
|
3856
|
+
delete extensions.stacktrace;
|
|
3857
|
+
delete extensions.exception;
|
|
3858
|
+
delete extensions.originalError;
|
|
3859
|
+
}
|
|
3860
|
+
const result = {
|
|
3861
|
+
message,
|
|
3862
|
+
extensions
|
|
3863
|
+
};
|
|
3864
|
+
if (formattedError.locations) result.locations = formattedError.locations;
|
|
3865
|
+
if (formattedError.path) result.path = formattedError.path;
|
|
3866
|
+
return result;
|
|
3867
|
+
};
|
|
3868
|
+
}
|
|
3869
|
+
__name(createGraphqlFormatError, "createGraphqlFormatError");
|
|
4499
3870
|
|
|
4500
3871
|
// src/filters/http-exception.filter.ts
|
|
4501
|
-
import { Catch, HttpStatus as
|
|
3872
|
+
import { Catch, HttpStatus as HttpStatus23, Logger as Logger12 } from "@nestjs/common";
|
|
4502
3873
|
|
|
4503
3874
|
// src/filters/pg-error.translator.ts
|
|
4504
3875
|
var PG_UNIQUE_VIOLATION = "23505";
|
|
@@ -4529,33 +3900,25 @@ function findPgError(error, depth = 0) {
|
|
|
4529
3900
|
__name(findPgError, "findPgError");
|
|
4530
3901
|
|
|
4531
3902
|
// src/filters/http-exception.filter.ts
|
|
4532
|
-
function
|
|
3903
|
+
function _ts_decorate29(decorators, target, key, desc3) {
|
|
4533
3904
|
var c = arguments.length, r = c < 3 ? target : desc3 === null ? desc3 = Object.getOwnPropertyDescriptor(target, key) : desc3, d;
|
|
4534
3905
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc3);
|
|
4535
3906
|
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;
|
|
4536
3907
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4537
3908
|
}
|
|
4538
|
-
__name(
|
|
4539
|
-
function getHttpStatusTitle(status) {
|
|
4540
|
-
const enumKey = Object.entries(HttpStatus21).find(([key, value]) => value === status && Number.isNaN(Number(key)))?.[0];
|
|
4541
|
-
if (!enumKey) {
|
|
4542
|
-
return "Error";
|
|
4543
|
-
}
|
|
4544
|
-
return enumKey.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
4545
|
-
}
|
|
4546
|
-
__name(getHttpStatusTitle, "getHttpStatusTitle");
|
|
3909
|
+
__name(_ts_decorate29, "_ts_decorate");
|
|
4547
3910
|
var HttpExceptionFilter = class _HttpExceptionFilter {
|
|
4548
3911
|
static {
|
|
4549
3912
|
__name(this, "HttpExceptionFilter");
|
|
4550
3913
|
}
|
|
4551
|
-
logger = new
|
|
3914
|
+
logger = new Logger12(_HttpExceptionFilter.name);
|
|
4552
3915
|
catch(exception, host) {
|
|
4553
3916
|
const ctx = host.switchToHttp();
|
|
4554
3917
|
const response = ctx.getResponse();
|
|
4555
3918
|
const request = ctx.getRequest();
|
|
4556
3919
|
const translatedPgError = tryTranslatePgError(exception);
|
|
4557
3920
|
if (translatedPgError) exception = translatedPgError;
|
|
4558
|
-
let status =
|
|
3921
|
+
let status = HttpStatus23.INTERNAL_SERVER_ERROR;
|
|
4559
3922
|
let type = "about:blank";
|
|
4560
3923
|
let label;
|
|
4561
3924
|
let detail = "Internal server error";
|
|
@@ -4563,33 +3926,11 @@ var HttpExceptionFilter = class _HttpExceptionFilter {
|
|
|
4563
3926
|
if (this.isHttpException(exception)) {
|
|
4564
3927
|
status = exception.getStatus();
|
|
4565
3928
|
const exceptionResponse = exception.getResponse();
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
label = problemResponse.label;
|
|
4572
|
-
detail = problemResponse.detail ?? exception.message ?? getHttpStatusTitle(status);
|
|
4573
|
-
errors = problemResponse.errors ?? [];
|
|
4574
|
-
} else if ("message" in responseObj && Array.isArray(responseObj.message)) {
|
|
4575
|
-
errors = responseObj.message.map((msg) => {
|
|
4576
|
-
if (typeof msg === "object" && "property" in msg && "constraints" in msg) {
|
|
4577
|
-
const constraintValues = Object.values(msg.constraints);
|
|
4578
|
-
return {
|
|
4579
|
-
field: msg.property,
|
|
4580
|
-
message: constraintValues[0] ?? "Validation failed"
|
|
4581
|
-
};
|
|
4582
|
-
}
|
|
4583
|
-
return null;
|
|
4584
|
-
}).filter((error) => error !== null);
|
|
4585
|
-
detail = "Validation failed";
|
|
4586
|
-
} else if ("message" in responseObj) {
|
|
4587
|
-
const message = responseObj.message;
|
|
4588
|
-
detail = Array.isArray(message) ? message.join(", ") : message;
|
|
4589
|
-
}
|
|
4590
|
-
} else if (typeof exceptionResponse === "string") {
|
|
4591
|
-
detail = exceptionResponse;
|
|
4592
|
-
}
|
|
3929
|
+
const extracted = extractProblemFromResponse(exceptionResponse, exception.message ?? getHttpStatusTitle(status));
|
|
3930
|
+
type = extracted.type;
|
|
3931
|
+
label = extracted.label;
|
|
3932
|
+
detail = extracted.detail ?? detail;
|
|
3933
|
+
errors = extracted.errors;
|
|
4593
3934
|
} else if (this.isProblemLikeObject(exception)) {
|
|
4594
3935
|
const problemObj = exception;
|
|
4595
3936
|
const statusCandidate = problemObj.status ?? problemObj.statusCode;
|
|
@@ -4604,7 +3945,7 @@ var HttpExceptionFilter = class _HttpExceptionFilter {
|
|
|
4604
3945
|
const axiosStatus = exception.response?.status;
|
|
4605
3946
|
const axiosDetail = exception.response?.data?.message || exception.response?.data?.detail || exception.message;
|
|
4606
3947
|
const url = exception.config?.url;
|
|
4607
|
-
status =
|
|
3948
|
+
status = HttpStatus23.BAD_GATEWAY;
|
|
4608
3949
|
detail = `Upstream service error${axiosStatus ? ` (${axiosStatus})` : ""}: ${axiosDetail}`;
|
|
4609
3950
|
this.logger.error(`Upstream API error [${axiosStatus}]: ${axiosDetail} \u2014 URL: ${url}`, exception.stack);
|
|
4610
3951
|
} else {
|
|
@@ -4637,16 +3978,41 @@ var HttpExceptionFilter = class _HttpExceptionFilter {
|
|
|
4637
3978
|
return typeof obj.status === "number" || typeof obj.statusCode === "number" || typeof obj.detail === "string" || Array.isArray(obj.errors);
|
|
4638
3979
|
}
|
|
4639
3980
|
};
|
|
4640
|
-
HttpExceptionFilter =
|
|
3981
|
+
HttpExceptionFilter = _ts_decorate29([
|
|
4641
3982
|
Catch()
|
|
4642
3983
|
], HttpExceptionFilter);
|
|
4643
3984
|
|
|
3985
|
+
// src/filters/transport-aware-exception.filter.ts
|
|
3986
|
+
import { Catch as Catch2 } from "@nestjs/common";
|
|
3987
|
+
function _ts_decorate30(decorators, target, key, desc3) {
|
|
3988
|
+
var c = arguments.length, r = c < 3 ? target : desc3 === null ? desc3 = Object.getOwnPropertyDescriptor(target, key) : desc3, d;
|
|
3989
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc3);
|
|
3990
|
+
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;
|
|
3991
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3992
|
+
}
|
|
3993
|
+
__name(_ts_decorate30, "_ts_decorate");
|
|
3994
|
+
var TransportAwareExceptionFilter = class {
|
|
3995
|
+
static {
|
|
3996
|
+
__name(this, "TransportAwareExceptionFilter");
|
|
3997
|
+
}
|
|
3998
|
+
httpFilter = new HttpExceptionFilter();
|
|
3999
|
+
catch(exception, host) {
|
|
4000
|
+
if (host.getType() !== "http") {
|
|
4001
|
+
throw exception;
|
|
4002
|
+
}
|
|
4003
|
+
this.httpFilter.catch(exception, host);
|
|
4004
|
+
}
|
|
4005
|
+
};
|
|
4006
|
+
TransportAwareExceptionFilter = _ts_decorate30([
|
|
4007
|
+
Catch2()
|
|
4008
|
+
], TransportAwareExceptionFilter);
|
|
4009
|
+
|
|
4644
4010
|
// src/logger/interceptors/http-logger.interceptor.ts
|
|
4645
|
-
import { Injectable as
|
|
4011
|
+
import { Injectable as Injectable11, Optional as Optional2 } from "@nestjs/common";
|
|
4646
4012
|
import { catchError, tap } from "rxjs/operators";
|
|
4647
4013
|
|
|
4648
4014
|
// src/logger/services/logger.service.ts
|
|
4649
|
-
import { Injectable as
|
|
4015
|
+
import { Injectable as Injectable10, Optional } from "@nestjs/common";
|
|
4650
4016
|
import { createLogger, format, transports } from "winston";
|
|
4651
4017
|
import DailyRotateFile from "winston-daily-rotate-file";
|
|
4652
4018
|
|
|
@@ -4893,7 +4259,7 @@ ${trace}`;
|
|
|
4893
4259
|
}
|
|
4894
4260
|
};
|
|
4895
4261
|
LoggerService = _ts_decorate31([
|
|
4896
|
-
|
|
4262
|
+
Injectable10(),
|
|
4897
4263
|
_ts_param9(0, Optional()),
|
|
4898
4264
|
_ts_param9(1, Optional()),
|
|
4899
4265
|
_ts_metadata24("design:type", Function),
|
|
@@ -5032,7 +4398,7 @@ var HttpLoggerInterceptor = class {
|
|
|
5032
4398
|
}
|
|
5033
4399
|
};
|
|
5034
4400
|
HttpLoggerInterceptor = _ts_decorate32([
|
|
5035
|
-
|
|
4401
|
+
Injectable11(),
|
|
5036
4402
|
_ts_param10(1, Optional2()),
|
|
5037
4403
|
_ts_metadata25("design:type", Function),
|
|
5038
4404
|
_ts_metadata25("design:paramtypes", [
|
|
@@ -5042,10 +4408,10 @@ HttpLoggerInterceptor = _ts_decorate32([
|
|
|
5042
4408
|
], HttpLoggerInterceptor);
|
|
5043
4409
|
|
|
5044
4410
|
// src/logger/logger.module.ts
|
|
5045
|
-
import { Global as
|
|
4411
|
+
import { Global as Global4, Logger as Logger13, Module as Module6 } from "@nestjs/common";
|
|
5046
4412
|
|
|
5047
4413
|
// src/logger/middleware/correlation-id.middleware.ts
|
|
5048
|
-
import { Injectable as
|
|
4414
|
+
import { Injectable as Injectable12 } from "@nestjs/common";
|
|
5049
4415
|
function _ts_decorate33(decorators, target, key, desc3) {
|
|
5050
4416
|
var c = arguments.length, r = c < 3 ? target : desc3 === null ? desc3 = Object.getOwnPropertyDescriptor(target, key) : desc3, d;
|
|
5051
4417
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc3);
|
|
@@ -5094,7 +4460,7 @@ var CorrelationIdMiddleware = class {
|
|
|
5094
4460
|
}
|
|
5095
4461
|
};
|
|
5096
4462
|
CorrelationIdMiddleware = _ts_decorate33([
|
|
5097
|
-
|
|
4463
|
+
Injectable12(),
|
|
5098
4464
|
_ts_metadata26("design:type", Function),
|
|
5099
4465
|
_ts_metadata26("design:paramtypes", [
|
|
5100
4466
|
typeof CorrelationIdMiddlewareOptions === "undefined" ? Object : CorrelationIdMiddlewareOptions
|
|
@@ -5185,9 +4551,9 @@ function mergeWithDefaults2(options = {}) {
|
|
|
5185
4551
|
__name(mergeWithDefaults2, "mergeWithDefaults");
|
|
5186
4552
|
function createDefaultLoggerProvider(options) {
|
|
5187
4553
|
return {
|
|
5188
|
-
provide:
|
|
4554
|
+
provide: Logger13,
|
|
5189
4555
|
useFactory: /* @__PURE__ */ __name(() => {
|
|
5190
|
-
const logger = new
|
|
4556
|
+
const logger = new Logger13();
|
|
5191
4557
|
if (options.level) {
|
|
5192
4558
|
const levels = getLevelsUpTo(options.level);
|
|
5193
4559
|
logger.setLogLevels?.(levels);
|
|
@@ -5217,7 +4583,7 @@ function createLoggerProviders(options = {}) {
|
|
|
5217
4583
|
inject: [
|
|
5218
4584
|
LOGGER_MODULE_OPTIONS,
|
|
5219
4585
|
{
|
|
5220
|
-
token:
|
|
4586
|
+
token: Logger13,
|
|
5221
4587
|
optional: true
|
|
5222
4588
|
}
|
|
5223
4589
|
]
|
|
@@ -5296,10 +4662,10 @@ var LoggerModule = class _LoggerModule {
|
|
|
5296
4662
|
...asyncProviders,
|
|
5297
4663
|
// Default logger provider
|
|
5298
4664
|
{
|
|
5299
|
-
provide:
|
|
4665
|
+
provide: Logger13,
|
|
5300
4666
|
useFactory: /* @__PURE__ */ __name((opts) => {
|
|
5301
4667
|
if (opts.provider === "default") {
|
|
5302
|
-
const logger = new
|
|
4668
|
+
const logger = new Logger13();
|
|
5303
4669
|
if (opts.level) {
|
|
5304
4670
|
const levels = getLevelsUpTo(opts.level);
|
|
5305
4671
|
logger.setLogLevels?.(levels);
|
|
@@ -5321,7 +4687,7 @@ var LoggerModule = class _LoggerModule {
|
|
|
5321
4687
|
inject: [
|
|
5322
4688
|
LOGGER_MODULE_OPTIONS,
|
|
5323
4689
|
{
|
|
5324
|
-
token:
|
|
4690
|
+
token: Logger13,
|
|
5325
4691
|
optional: true
|
|
5326
4692
|
}
|
|
5327
4693
|
]
|
|
@@ -5421,12 +4787,12 @@ var LoggerModule = class _LoggerModule {
|
|
|
5421
4787
|
}
|
|
5422
4788
|
};
|
|
5423
4789
|
LoggerModule = _ts_decorate34([
|
|
5424
|
-
|
|
5425
|
-
|
|
4790
|
+
Global4(),
|
|
4791
|
+
Module6({})
|
|
5426
4792
|
], LoggerModule);
|
|
5427
4793
|
|
|
5428
4794
|
// src/root/root.module.ts
|
|
5429
|
-
import { Module as
|
|
4795
|
+
import { Module as Module7 } from "@nestjs/common";
|
|
5430
4796
|
|
|
5431
4797
|
// src/root/controllers/app.controller.ts
|
|
5432
4798
|
import { Controller as Controller3, Get as Get2 } from "@nestjs/common";
|
|
@@ -5447,7 +4813,7 @@ function ApiHealthCheck() {
|
|
|
5447
4813
|
__name(ApiHealthCheck, "ApiHealthCheck");
|
|
5448
4814
|
|
|
5449
4815
|
// src/root/services/app.service.ts
|
|
5450
|
-
import { Injectable as
|
|
4816
|
+
import { Injectable as Injectable13 } from "@nestjs/common";
|
|
5451
4817
|
function _ts_decorate35(decorators, target, key, desc3) {
|
|
5452
4818
|
var c = arguments.length, r = c < 3 ? target : desc3 === null ? desc3 = Object.getOwnPropertyDescriptor(target, key) : desc3, d;
|
|
5453
4819
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc3);
|
|
@@ -5465,7 +4831,7 @@ var AppService = class {
|
|
|
5465
4831
|
}
|
|
5466
4832
|
};
|
|
5467
4833
|
AppService = _ts_decorate35([
|
|
5468
|
-
|
|
4834
|
+
Injectable13()
|
|
5469
4835
|
], AppService);
|
|
5470
4836
|
|
|
5471
4837
|
// src/root/controllers/app.controller.ts
|
|
@@ -5511,7 +4877,7 @@ AppController = _ts_decorate36([
|
|
|
5511
4877
|
], AppController);
|
|
5512
4878
|
|
|
5513
4879
|
// src/root/controllers/csrf.controller.ts
|
|
5514
|
-
import { Controller as Controller4, Get as Get3, HttpCode as HttpCode3, HttpStatus as
|
|
4880
|
+
import { Controller as Controller4, Get as Get3, HttpCode as HttpCode3, HttpStatus as HttpStatus24, Res } from "@nestjs/common";
|
|
5515
4881
|
import { ApiTags as ApiTags4 } from "@nestjs/swagger";
|
|
5516
4882
|
|
|
5517
4883
|
// src/root/docs/csrf.docs.ts
|
|
@@ -5574,7 +4940,7 @@ var CsrfController = class {
|
|
|
5574
4940
|
_ts_decorate37([
|
|
5575
4941
|
Get3("token"),
|
|
5576
4942
|
Public(),
|
|
5577
|
-
HttpCode3(
|
|
4943
|
+
HttpCode3(HttpStatus24.OK),
|
|
5578
4944
|
ApiGetCsrfToken(),
|
|
5579
4945
|
_ts_param11(0, Res({
|
|
5580
4946
|
passthrough: true
|
|
@@ -5604,7 +4970,7 @@ var RootModule = class {
|
|
|
5604
4970
|
}
|
|
5605
4971
|
};
|
|
5606
4972
|
RootModule = _ts_decorate38([
|
|
5607
|
-
|
|
4973
|
+
Module7({
|
|
5608
4974
|
controllers: [
|
|
5609
4975
|
AppController,
|
|
5610
4976
|
CsrfController
|
|
@@ -5837,16 +5203,15 @@ export {
|
|
|
5837
5203
|
AuthConfigModule,
|
|
5838
5204
|
BadGatewayException,
|
|
5839
5205
|
BadRequestException,
|
|
5840
|
-
|
|
5841
|
-
CacheModule,
|
|
5842
|
-
CacheService,
|
|
5206
|
+
ClientIp,
|
|
5843
5207
|
ConflictException,
|
|
5844
5208
|
CookieDomain,
|
|
5845
5209
|
CookieName,
|
|
5846
5210
|
CorrelationIdMiddleware,
|
|
5847
5211
|
CreateDataTableViewDto,
|
|
5848
5212
|
CreateResponseDto,
|
|
5849
|
-
|
|
5213
|
+
CursorCodec,
|
|
5214
|
+
CursorListResponseDto,
|
|
5850
5215
|
DATA_TABLE_VIEWS_TABLE,
|
|
5851
5216
|
DEFAULT_CORRELATION_HEADER,
|
|
5852
5217
|
DataTableModule,
|
|
@@ -5854,8 +5219,7 @@ export {
|
|
|
5854
5219
|
DataTableViewDto,
|
|
5855
5220
|
DataTableViewsService,
|
|
5856
5221
|
DatabaseModule,
|
|
5857
|
-
|
|
5858
|
-
EmailService,
|
|
5222
|
+
ErrorCode,
|
|
5859
5223
|
FilterOperators,
|
|
5860
5224
|
FilterProcessor,
|
|
5861
5225
|
ForbiddenException2 as ForbiddenException,
|
|
@@ -5867,9 +5231,8 @@ export {
|
|
|
5867
5231
|
ImportResponseDto,
|
|
5868
5232
|
ImportSummaryDto,
|
|
5869
5233
|
InternalServerErrorException,
|
|
5870
|
-
IsCurrency,
|
|
5871
|
-
IsCurrencyCode,
|
|
5872
5234
|
IsDateTime,
|
|
5235
|
+
KeysetProcessor,
|
|
5873
5236
|
LOGGER_MODULE_OPTIONS,
|
|
5874
5237
|
LoggerModule,
|
|
5875
5238
|
LoggerService,
|
|
@@ -5882,7 +5245,6 @@ export {
|
|
|
5882
5245
|
PrimaryDatabaseService,
|
|
5883
5246
|
Public,
|
|
5884
5247
|
REQUIRE_SESSION_KEY,
|
|
5885
|
-
RedisCacheProvider,
|
|
5886
5248
|
RefreshCookieOptions,
|
|
5887
5249
|
RefreshTokenCookie,
|
|
5888
5250
|
RenameDataTableViewDto,
|
|
@@ -5890,7 +5252,6 @@ export {
|
|
|
5890
5252
|
RequireSession,
|
|
5891
5253
|
RootModule,
|
|
5892
5254
|
SKIP_CSRF_KEY,
|
|
5893
|
-
SUPPORTED_CURRENCIES,
|
|
5894
5255
|
SelectOptionsQueryDto,
|
|
5895
5256
|
ServiceUnavailableException,
|
|
5896
5257
|
SessionData,
|
|
@@ -5902,6 +5263,7 @@ export {
|
|
|
5902
5263
|
TokenService,
|
|
5903
5264
|
TokenType,
|
|
5904
5265
|
TooManyRequestsException,
|
|
5266
|
+
TransportAwareExceptionFilter,
|
|
5905
5267
|
UnauthorizedException3 as UnauthorizedException,
|
|
5906
5268
|
UnprocessableEntityException,
|
|
5907
5269
|
UnsupportedMediaTypeException,
|
|
@@ -5909,24 +5271,30 @@ export {
|
|
|
5909
5271
|
UploadedFile,
|
|
5910
5272
|
UploadedFiles,
|
|
5911
5273
|
UpsertDataTableStateDto,
|
|
5274
|
+
UserAgent,
|
|
5912
5275
|
UserId,
|
|
5913
5276
|
ValidatedRowDto,
|
|
5914
5277
|
ValidationException,
|
|
5915
5278
|
VrittiAuthGuard,
|
|
5916
5279
|
addCorrelationIdToResponse,
|
|
5917
5280
|
correlationStorage,
|
|
5281
|
+
createGraphqlFormatError,
|
|
5918
5282
|
dataTableViewsColumns,
|
|
5919
5283
|
dataTableViewsIndexes,
|
|
5284
|
+
errorCodeFromStatus,
|
|
5920
5285
|
extractCountryFromPhone,
|
|
5921
5286
|
gcd,
|
|
5922
5287
|
generateCorrelationId,
|
|
5923
5288
|
getCorrelationContext,
|
|
5924
5289
|
getHttpStatusTitle,
|
|
5290
|
+
getRequestFromContext,
|
|
5291
|
+
getResponseFromContext,
|
|
5925
5292
|
hashToken,
|
|
5926
|
-
majorToMinor,
|
|
5927
|
-
minorToMajor,
|
|
5928
5293
|
normalizePhoneNumber,
|
|
5929
5294
|
parseExpiryToMs,
|
|
5295
|
+
registerTransport,
|
|
5296
|
+
resolveExtractor,
|
|
5297
|
+
resolveInjectedRequest,
|
|
5930
5298
|
runWithCorrelationContext,
|
|
5931
5299
|
updateCorrelationContext,
|
|
5932
5300
|
verifyTokenHash
|