@xfilecom/core-sdk 1.3.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +664 -0
- package/dist/core.module.d.ts +39 -0
- package/dist/core.module.js +188 -0
- package/dist/core.module.js.map +1 -0
- package/dist/database/database.constants.d.ts +2 -0
- package/dist/database/database.constants.js +6 -0
- package/dist/database/database.constants.js.map +1 -0
- package/dist/database/database.module.d.ts +19 -0
- package/dist/database/database.module.js +56 -0
- package/dist/database/database.module.js.map +1 -0
- package/dist/database/database.query.d.ts +103 -0
- package/dist/database/database.query.example.d.ts +36 -0
- package/dist/database/database.query.example.js +148 -0
- package/dist/database/database.query.example.js.map +1 -0
- package/dist/database/database.query.js +369 -0
- package/dist/database/database.query.js.map +1 -0
- package/dist/database/database.service.d.ts +18 -0
- package/dist/database/database.service.js +110 -0
- package/dist/database/database.service.js.map +1 -0
- package/dist/database/example-usage.d.ts +0 -0
- package/dist/database/example-usage.js +1 -0
- package/dist/database/example-usage.js.map +1 -0
- package/dist/decorators/public.decorator.d.ts +2 -0
- package/dist/decorators/public.decorator.js +8 -0
- package/dist/decorators/public.decorator.js.map +1 -0
- package/dist/decorators/roles.decorator.d.ts +2 -0
- package/dist/decorators/roles.decorator.js +8 -0
- package/dist/decorators/roles.decorator.js.map +1 -0
- package/dist/decorators/user.decorator.d.ts +7 -0
- package/dist/decorators/user.decorator.js +10 -0
- package/dist/decorators/user.decorator.js.map +1 -0
- package/dist/filters/exception.filter.d.ts +36 -0
- package/dist/filters/exception.filter.js +201 -0
- package/dist/filters/exception.filter.js.map +1 -0
- package/dist/guards/jwt-auth.guard.d.ts +14 -0
- package/dist/guards/jwt-auth.guard.js +103 -0
- package/dist/guards/jwt-auth.guard.js.map +1 -0
- package/dist/guards/roles.guard.d.ts +7 -0
- package/dist/guards/roles.guard.js +47 -0
- package/dist/guards/roles.guard.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +91 -0
- package/dist/index.js.map +1 -0
- package/dist/interceptors/database-check.interceptor.d.ts +12 -0
- package/dist/interceptors/database-check.interceptor.js +60 -0
- package/dist/interceptors/database-check.interceptor.js.map +1 -0
- package/dist/interceptors/error-handling.interceptor.d.ts +8 -0
- package/dist/interceptors/error-handling.interceptor.js +33 -0
- package/dist/interceptors/error-handling.interceptor.js.map +1 -0
- package/dist/interceptors/logging.interceptor.d.ts +21 -0
- package/dist/interceptors/logging.interceptor.js +167 -0
- package/dist/interceptors/logging.interceptor.js.map +1 -0
- package/dist/interceptors/response-transform.interceptor.d.ts +5 -0
- package/dist/interceptors/response-transform.interceptor.js +30 -0
- package/dist/interceptors/response-transform.interceptor.js.map +1 -0
- package/dist/utils/auth.helpers.d.ts +19 -0
- package/dist/utils/auth.helpers.js +77 -0
- package/dist/utils/auth.helpers.js.map +1 -0
- package/dist/utils/config-loader.utils.d.ts +22 -0
- package/dist/utils/config-loader.utils.js +77 -0
- package/dist/utils/config-loader.utils.js.map +1 -0
- package/dist/utils/config.validator.d.ts +13 -0
- package/dist/utils/config.validator.js +82 -0
- package/dist/utils/config.validator.js.map +1 -0
- package/dist/utils/controller.helpers.d.ts +58 -0
- package/dist/utils/controller.helpers.js +104 -0
- package/dist/utils/controller.helpers.js.map +1 -0
- package/dist/utils/crypto.utils.d.ts +12 -0
- package/dist/utils/crypto.utils.js +53 -0
- package/dist/utils/crypto.utils.js.map +1 -0
- package/dist/utils/email-hash.utils.d.ts +7 -0
- package/dist/utils/email-hash.utils.js +42 -0
- package/dist/utils/email-hash.utils.js.map +1 -0
- package/dist/utils/env.utils.d.ts +8 -0
- package/dist/utils/env.utils.js +27 -0
- package/dist/utils/env.utils.js.map +1 -0
- package/dist/utils/error.utils.d.ts +6 -0
- package/dist/utils/error.utils.js +65 -0
- package/dist/utils/error.utils.js.map +1 -0
- package/dist/utils/hash-verification.utils.d.ts +35 -0
- package/dist/utils/hash-verification.utils.js +133 -0
- package/dist/utils/hash-verification.utils.js.map +1 -0
- package/dist/utils/logger.helpers.d.ts +71 -0
- package/dist/utils/logger.helpers.js +293 -0
- package/dist/utils/logger.helpers.js.map +1 -0
- package/dist/utils/logging.config.d.ts +6 -0
- package/dist/utils/logging.config.js +42 -0
- package/dist/utils/logging.config.js.map +1 -0
- package/dist/utils/service.helpers.d.ts +22 -0
- package/dist/utils/service.helpers.js +73 -0
- package/dist/utils/service.helpers.js.map +1 -0
- package/dist/utils/yaml-config.loader.d.ts +15 -0
- package/dist/utils/yaml-config.loader.js +219 -0
- package/dist/utils/yaml-config.loader.js.map +1 -0
- package/package.json +47 -0
- package/scripts/publish-to-gitlab.mjs +209 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ErrorHandlingInterceptor = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
const rxjs_1 = require("rxjs");
|
|
15
|
+
const operators_1 = require("rxjs/operators");
|
|
16
|
+
const error_utils_1 = require("../utils/error.utils");
|
|
17
|
+
let ErrorHandlingInterceptor = class ErrorHandlingInterceptor {
|
|
18
|
+
constructor(errorUtils) {
|
|
19
|
+
this.errorUtils = errorUtils;
|
|
20
|
+
}
|
|
21
|
+
intercept(context, next) {
|
|
22
|
+
return next.handle().pipe((0, operators_1.catchError)((error) => {
|
|
23
|
+
const errorDto = this.errorUtils.fromException(error);
|
|
24
|
+
return (0, rxjs_1.throwError)(() => errorDto);
|
|
25
|
+
}));
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
exports.ErrorHandlingInterceptor = ErrorHandlingInterceptor;
|
|
29
|
+
exports.ErrorHandlingInterceptor = ErrorHandlingInterceptor = __decorate([
|
|
30
|
+
(0, common_1.Injectable)(),
|
|
31
|
+
__metadata("design:paramtypes", [error_utils_1.ErrorUtils])
|
|
32
|
+
], ErrorHandlingInterceptor);
|
|
33
|
+
//# sourceMappingURL=error-handling.interceptor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handling.interceptor.js","sourceRoot":"","sources":["../../src/interceptors/error-handling.interceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAKwB;AACxB,+BAA8C;AAC9C,8CAA4C;AAC5C,sDAAkD;AAG3C,IAAM,wBAAwB,GAA9B,MAAM,wBAAwB;IACnC,YAA6B,UAAsB;QAAtB,eAAU,GAAV,UAAU,CAAY;IAAG,CAAC;IAEvD,SAAS,CAAC,OAAyB,EAAE,IAAiB;QACpD,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CACvB,IAAA,sBAAU,EAAC,CAAC,KAAK,EAAE,EAAE;YACnB,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YACtD,OAAO,IAAA,iBAAU,EAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC;QACpC,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;CACF,CAAA;AAXY,4DAAwB;mCAAxB,wBAAwB;IADpC,IAAA,mBAAU,GAAE;qCAE8B,wBAAU;GADxC,wBAAwB,CAWpC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { LogLevelName, LoggerHelpers } from '../utils/logger.helpers';
|
|
4
|
+
export interface LoggingInterceptorOptions {
|
|
5
|
+
logLevel?: 'none' | LogLevelName;
|
|
6
|
+
logRequestBody?: boolean;
|
|
7
|
+
logResponseBody?: boolean;
|
|
8
|
+
excludeFields?: string[];
|
|
9
|
+
maxBodyLength?: number;
|
|
10
|
+
}
|
|
11
|
+
export declare class LoggingInterceptor implements NestInterceptor {
|
|
12
|
+
private readonly logger;
|
|
13
|
+
private readonly options;
|
|
14
|
+
constructor(logger?: LoggerHelpers, options?: LoggingInterceptorOptions);
|
|
15
|
+
private shouldLog;
|
|
16
|
+
intercept(context: ExecutionContext, next: CallHandler): Observable<any>;
|
|
17
|
+
private sanitizeData;
|
|
18
|
+
private formatBody;
|
|
19
|
+
private logHttpRequest;
|
|
20
|
+
private logRpcRequest;
|
|
21
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.LoggingInterceptor = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const operators_1 = require("rxjs/operators");
|
|
18
|
+
const logger_helpers_1 = require("../utils/logger.helpers");
|
|
19
|
+
let LoggingInterceptor = class LoggingInterceptor {
|
|
20
|
+
constructor(logger, options) {
|
|
21
|
+
this.logger = logger || new logger_helpers_1.LoggerHelpers('Request');
|
|
22
|
+
this.options = {
|
|
23
|
+
logLevel: options?.logLevel ?? 'log',
|
|
24
|
+
logRequestBody: options?.logRequestBody ?? false,
|
|
25
|
+
logResponseBody: options?.logResponseBody ?? false,
|
|
26
|
+
excludeFields: options?.excludeFields ?? ['password', 'passwordConfirm', 'token', 'secret', 'authorization'],
|
|
27
|
+
maxBodyLength: options?.maxBodyLength ?? 1000,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
shouldLog(level) {
|
|
31
|
+
if (this.options.logLevel === 'none')
|
|
32
|
+
return false;
|
|
33
|
+
return (0, logger_helpers_1.isLevelEnabled)(level, this.options.logLevel);
|
|
34
|
+
}
|
|
35
|
+
intercept(context, next) {
|
|
36
|
+
const contextType = context.getType();
|
|
37
|
+
const now = Date.now();
|
|
38
|
+
if (contextType === 'http') {
|
|
39
|
+
return this.logHttpRequest(context, next, now);
|
|
40
|
+
}
|
|
41
|
+
if (contextType === 'rpc') {
|
|
42
|
+
return this.logRpcRequest(context, next, now);
|
|
43
|
+
}
|
|
44
|
+
return next.handle().pipe((0, operators_1.tap)({
|
|
45
|
+
next: () => {
|
|
46
|
+
if (this.shouldLog('log')) {
|
|
47
|
+
const delay = Date.now() - now;
|
|
48
|
+
this.logger.log(`Request completed in ${delay}ms`);
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
error: (error) => {
|
|
52
|
+
if (this.shouldLog('error')) {
|
|
53
|
+
const delay = Date.now() - now;
|
|
54
|
+
this.logger.error(`Request failed in ${delay}ms - ${error.message}`, error);
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
}));
|
|
58
|
+
}
|
|
59
|
+
sanitizeData(data) {
|
|
60
|
+
if (!data || typeof data !== 'object') {
|
|
61
|
+
return data;
|
|
62
|
+
}
|
|
63
|
+
if (Array.isArray(data)) {
|
|
64
|
+
return data.map(item => this.sanitizeData(item));
|
|
65
|
+
}
|
|
66
|
+
const sanitized = { ...data };
|
|
67
|
+
this.options.excludeFields.forEach(field => {
|
|
68
|
+
if (sanitized[field] !== undefined) {
|
|
69
|
+
sanitized[field] = '***REDACTED***';
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
return sanitized;
|
|
73
|
+
}
|
|
74
|
+
formatBody(body) {
|
|
75
|
+
if (!body) {
|
|
76
|
+
return '';
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
const sanitized = this.sanitizeData(body);
|
|
80
|
+
const bodyStr = JSON.stringify(sanitized);
|
|
81
|
+
if (bodyStr.length > this.options.maxBodyLength) {
|
|
82
|
+
return bodyStr.substring(0, this.options.maxBodyLength) + '... (truncated)';
|
|
83
|
+
}
|
|
84
|
+
return bodyStr;
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
return '[Unable to stringify body]';
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
logHttpRequest(context, next, startTime) {
|
|
91
|
+
const request = context.switchToHttp().getRequest();
|
|
92
|
+
const { method, url, ip, body, query, params } = request;
|
|
93
|
+
const userAgent = request.headers?.['user-agent'] || 'unknown';
|
|
94
|
+
let requestLog = `${method} ${url} - ${ip} - ${userAgent}`;
|
|
95
|
+
if (this.options.logRequestBody && body && Object.keys(body).length > 0) {
|
|
96
|
+
const bodyStr = this.formatBody(body);
|
|
97
|
+
requestLog += `\n Request Body: ${bodyStr}`;
|
|
98
|
+
}
|
|
99
|
+
if (query && Object.keys(query).length > 0) {
|
|
100
|
+
const sanitizedQuery = this.sanitizeData(query);
|
|
101
|
+
requestLog += `\n Query: ${JSON.stringify(sanitizedQuery)}`;
|
|
102
|
+
}
|
|
103
|
+
if (params && Object.keys(params).length > 0) {
|
|
104
|
+
requestLog += `\n Params: ${JSON.stringify(params)}`;
|
|
105
|
+
}
|
|
106
|
+
if (this.shouldLog('log')) {
|
|
107
|
+
this.logger.log(requestLog);
|
|
108
|
+
}
|
|
109
|
+
return next.handle().pipe((0, operators_1.map)((data) => {
|
|
110
|
+
if (this.shouldLog('log')) {
|
|
111
|
+
if (this.options.logResponseBody && data !== undefined) {
|
|
112
|
+
const response = context.switchToHttp().getResponse();
|
|
113
|
+
const { statusCode } = response;
|
|
114
|
+
const delay = Date.now() - startTime;
|
|
115
|
+
const bodyStr = this.formatBody(data);
|
|
116
|
+
this.logger.log(`${method} ${url} ${statusCode} - ${delay}ms\n Response Body: ${bodyStr}`);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
const response = context.switchToHttp().getResponse();
|
|
120
|
+
const { statusCode } = response;
|
|
121
|
+
const delay = Date.now() - startTime;
|
|
122
|
+
this.logger.log(`${method} ${url} ${statusCode} - ${delay}ms`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return data;
|
|
126
|
+
}), (0, operators_1.tap)({
|
|
127
|
+
error: (error) => {
|
|
128
|
+
if (!this.shouldLog('error'))
|
|
129
|
+
return;
|
|
130
|
+
const delay = Date.now() - startTime;
|
|
131
|
+
const statusCode = error.status || 500;
|
|
132
|
+
const errorBody = this.options.logResponseBody && error.response
|
|
133
|
+
? `\n Error Response: ${this.formatBody(error.response)}`
|
|
134
|
+
: '';
|
|
135
|
+
this.logger.error(`${method} ${url} ${statusCode} - ${delay}ms - ${error.message}${errorBody}`, error);
|
|
136
|
+
},
|
|
137
|
+
}));
|
|
138
|
+
}
|
|
139
|
+
logRpcRequest(context, next, startTime) {
|
|
140
|
+
const data = context.switchToRpc().getData();
|
|
141
|
+
const pattern = context.switchToRpc().getContext()?.pattern || 'unknown';
|
|
142
|
+
if (this.shouldLog('log')) {
|
|
143
|
+
this.logger.log(`RPC ${pattern} - ${JSON.stringify(data)}`);
|
|
144
|
+
}
|
|
145
|
+
return next.handle().pipe((0, operators_1.tap)({
|
|
146
|
+
next: () => {
|
|
147
|
+
if (this.shouldLog('log')) {
|
|
148
|
+
const delay = Date.now() - startTime;
|
|
149
|
+
this.logger.log(`RPC ${pattern} - completed in ${delay}ms`);
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
error: (error) => {
|
|
153
|
+
if (this.shouldLog('error')) {
|
|
154
|
+
const delay = Date.now() - startTime;
|
|
155
|
+
this.logger.error(`RPC ${pattern} - failed in ${delay}ms - ${error.message}`, error);
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
}));
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
exports.LoggingInterceptor = LoggingInterceptor;
|
|
162
|
+
exports.LoggingInterceptor = LoggingInterceptor = __decorate([
|
|
163
|
+
(0, common_1.Injectable)(),
|
|
164
|
+
__param(0, (0, common_1.Optional)()),
|
|
165
|
+
__metadata("design:paramtypes", [logger_helpers_1.LoggerHelpers, Object])
|
|
166
|
+
], LoggingInterceptor);
|
|
167
|
+
//# sourceMappingURL=logging.interceptor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logging.interceptor.js","sourceRoot":"","sources":["../../src/interceptors/logging.interceptor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
export declare class ResponseTransformInterceptor implements NestInterceptor {
|
|
4
|
+
intercept(context: ExecutionContext, next: CallHandler): Observable<any>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.ResponseTransformInterceptor = void 0;
|
|
10
|
+
const common_1 = require("@nestjs/common");
|
|
11
|
+
const operators_1 = require("rxjs/operators");
|
|
12
|
+
const controller_helpers_1 = require("../utils/controller.helpers");
|
|
13
|
+
let ResponseTransformInterceptor = class ResponseTransformInterceptor {
|
|
14
|
+
intercept(context, next) {
|
|
15
|
+
return next.handle().pipe((0, operators_1.map)((data) => {
|
|
16
|
+
if (data && typeof data === 'object' && 'code' in data && 'data' in data && 'error' in data) {
|
|
17
|
+
return data;
|
|
18
|
+
}
|
|
19
|
+
if (data !== null && data !== undefined) {
|
|
20
|
+
return new controller_helpers_1.CommonResponseDto(Array.isArray(data) ? data : [data]);
|
|
21
|
+
}
|
|
22
|
+
return new controller_helpers_1.CommonResponseDto([]);
|
|
23
|
+
}));
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
exports.ResponseTransformInterceptor = ResponseTransformInterceptor;
|
|
27
|
+
exports.ResponseTransformInterceptor = ResponseTransformInterceptor = __decorate([
|
|
28
|
+
(0, common_1.Injectable)()
|
|
29
|
+
], ResponseTransformInterceptor);
|
|
30
|
+
//# sourceMappingURL=response-transform.interceptor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-transform.interceptor.js","sourceRoot":"","sources":["../../src/interceptors/response-transform.interceptor.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAKwB;AAExB,8CAAqC;AACrC,oEAAgE;AAGzD,IAAM,4BAA4B,GAAlC,MAAM,4BAA4B;IACvC,SAAS,CAAC,OAAyB,EAAE,IAAiB;QACpD,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CACvB,IAAA,eAAG,EAAC,CAAC,IAAI,EAAE,EAAE;YAEX,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;gBAC5F,OAAO,IAAI,CAAC;YACd,CAAC;YAED,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACxC,OAAO,IAAI,sCAAiB,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YACpE,CAAC;YACD,OAAO,IAAI,sCAAiB,CAAC,EAAE,CAAC,CAAC;QACnC,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;CACF,CAAA;AAhBY,oEAA4B;uCAA5B,4BAA4B;IADxC,IAAA,mBAAU,GAAE;GACA,4BAA4B,CAgBxC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface JwtPayload {
|
|
2
|
+
sub: string | number;
|
|
3
|
+
email?: string;
|
|
4
|
+
[key: string]: any;
|
|
5
|
+
}
|
|
6
|
+
export declare class AuthHelpers {
|
|
7
|
+
private readonly logger;
|
|
8
|
+
private readonly jwtSecret;
|
|
9
|
+
private readonly jwtExpiresIn;
|
|
10
|
+
private readonly saltRounds;
|
|
11
|
+
constructor(jwtSecret?: string, jwtExpiresIn?: string, saltRounds?: number);
|
|
12
|
+
hashPassword(password: string): Promise<string>;
|
|
13
|
+
comparePassword(password: string, hashedPassword: string): Promise<boolean>;
|
|
14
|
+
generateToken(payload: JwtPayload): string;
|
|
15
|
+
verifyToken(token: string): JwtPayload | null;
|
|
16
|
+
decodeToken(token: string): JwtPayload | null;
|
|
17
|
+
generateRefreshToken(payload: JwtPayload, expiresIn?: string): string;
|
|
18
|
+
getUserIdFromToken(token: string): string | number | null;
|
|
19
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var AuthHelpers_1;
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.AuthHelpers = void 0;
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const bcrypt = require("bcrypt");
|
|
19
|
+
const jwt = require("jsonwebtoken");
|
|
20
|
+
let AuthHelpers = AuthHelpers_1 = class AuthHelpers {
|
|
21
|
+
constructor(jwtSecret, jwtExpiresIn, saltRounds) {
|
|
22
|
+
this.logger = new common_1.Logger(AuthHelpers_1.name);
|
|
23
|
+
this.jwtSecret = jwtSecret || process.env.JWT_SECRET || 'your-secret-key';
|
|
24
|
+
this.jwtExpiresIn = jwtExpiresIn || process.env.JWT_EXPIRES_IN || '7d';
|
|
25
|
+
this.saltRounds = saltRounds || parseInt(process.env.BCRYPT_SALT_ROUNDS || '10', 10);
|
|
26
|
+
}
|
|
27
|
+
async hashPassword(password) {
|
|
28
|
+
return await bcrypt.hash(password, this.saltRounds);
|
|
29
|
+
}
|
|
30
|
+
async comparePassword(password, hashedPassword) {
|
|
31
|
+
return await bcrypt.compare(password, hashedPassword);
|
|
32
|
+
}
|
|
33
|
+
generateToken(payload) {
|
|
34
|
+
return jwt.sign(payload, this.jwtSecret, {
|
|
35
|
+
expiresIn: this.jwtExpiresIn,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
verifyToken(token) {
|
|
39
|
+
try {
|
|
40
|
+
return jwt.verify(token, this.jwtSecret);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
this.logger.warn(`Token verification failed: ${error.message}`);
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
decodeToken(token) {
|
|
48
|
+
try {
|
|
49
|
+
return jwt.decode(token);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
this.logger.warn(`Token decode failed: ${error.message}`);
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
generateRefreshToken(payload, expiresIn = '30d') {
|
|
57
|
+
return jwt.sign(payload, this.jwtSecret, {
|
|
58
|
+
expiresIn,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
getUserIdFromToken(token) {
|
|
62
|
+
const payload = this.verifyToken(token);
|
|
63
|
+
return payload?.sub || null;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
exports.AuthHelpers = AuthHelpers;
|
|
67
|
+
exports.AuthHelpers = AuthHelpers = AuthHelpers_1 = __decorate([
|
|
68
|
+
(0, common_1.Injectable)(),
|
|
69
|
+
__param(0, (0, common_1.Optional)()),
|
|
70
|
+
__param(0, (0, common_1.Inject)('JWT_SECRET')),
|
|
71
|
+
__param(1, (0, common_1.Optional)()),
|
|
72
|
+
__param(1, (0, common_1.Inject)('JWT_EXPIRES_IN')),
|
|
73
|
+
__param(2, (0, common_1.Optional)()),
|
|
74
|
+
__param(2, (0, common_1.Inject)('BCRYPT_SALT_ROUNDS')),
|
|
75
|
+
__metadata("design:paramtypes", [String, String, Number])
|
|
76
|
+
], AuthHelpers);
|
|
77
|
+
//# sourceMappingURL=auth.helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.helpers.js","sourceRoot":"","sources":["../../src/utils/auth.helpers.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAsE;AACtE,iCAAiC;AACjC,oCAAoC;AAgB7B,IAAM,WAAW,mBAAjB,MAAM,WAAW;IAMtB,YACoC,SAAkB,EACd,YAAqB,EACjB,UAAmB;QAR9C,WAAM,GAAG,IAAI,eAAM,CAAC,aAAW,CAAC,IAAI,CAAC,CAAC;QAUrD,IAAI,CAAC,SAAS,GAAG,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,iBAAiB,CAAC;QAC1E,IAAI,CAAC,YAAY,GAAG,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,IAAI,CAAC;QACvE,IAAI,CAAC,UAAU,GAAG,UAAU,IAAI,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;IACvF,CAAC;IAKD,KAAK,CAAC,YAAY,CAAC,QAAgB;QACjC,OAAO,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACtD,CAAC;IAKD,KAAK,CAAC,eAAe,CAAC,QAAgB,EAAE,cAAsB;QAC5D,OAAO,MAAM,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IACxD,CAAC;IAKD,aAAa,CAAC,OAAmB;QAC/B,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,EAAE;YACvC,SAAS,EAAE,IAAI,CAAC,YAAY;SACV,CAAC,CAAC;IACxB,CAAC;IAKD,WAAW,CAAC,KAAa;QACvB,IAAI,CAAC;YACH,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAe,CAAC;QACzD,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,8BAA8B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAChE,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAKD,WAAW,CAAC,KAAa;QACvB,IAAI,CAAC;YACH,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,CAAe,CAAC;QACzC,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,wBAAwB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAC1D,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAKD,oBAAoB,CAAC,OAAmB,EAAE,YAAoB,KAAK;QACjE,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,EAAE;YACvC,SAAS;SACS,CAAC,CAAC;IACxB,CAAC;IAKD,kBAAkB,CAAC,KAAa;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACxC,OAAO,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC;IAC9B,CAAC;CACF,CAAA;AA/EY,kCAAW;sBAAX,WAAW;IADvB,IAAA,mBAAU,GAAE;IAQR,WAAA,IAAA,iBAAQ,GAAE,CAAA;IAAE,WAAA,IAAA,eAAM,EAAC,YAAY,CAAC,CAAA;IAChC,WAAA,IAAA,iBAAQ,GAAE,CAAA;IAAE,WAAA,IAAA,eAAM,EAAC,gBAAgB,CAAC,CAAA;IACpC,WAAA,IAAA,iBAAQ,GAAE,CAAA;IAAE,WAAA,IAAA,eAAM,EAAC,oBAAoB,CAAC,CAAA;;GAThC,WAAW,CA+EvB"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type LoadApplicationYamlOptions } from './yaml-config.loader';
|
|
2
|
+
export declare const DEFAULT_CONFIG_ROOT_CANDIDATES: readonly ["libs/config/config", "../../libs/config/config", "../libs/config/config", "."];
|
|
3
|
+
export interface ResolveConfigRootDirOptions {
|
|
4
|
+
cwd?: string;
|
|
5
|
+
candidates?: string[];
|
|
6
|
+
configFilenames?: readonly string[];
|
|
7
|
+
}
|
|
8
|
+
export declare function resolveConfigRootDir(options?: ResolveConfigRootDirOptions): string;
|
|
9
|
+
export interface CreateConfigLoaderOptions {
|
|
10
|
+
rootDir?: string;
|
|
11
|
+
env?: string;
|
|
12
|
+
syncEnvKeys?: Record<string, string>;
|
|
13
|
+
globalKey?: string;
|
|
14
|
+
loadOptions?: Omit<LoadApplicationYamlOptions, 'rootDir' | 'env' | 'syncEnvKeys'>;
|
|
15
|
+
}
|
|
16
|
+
export interface GetServiceConfigOverrides {
|
|
17
|
+
portEnvKey?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function createConfigLoader(options?: CreateConfigLoaderOptions): {
|
|
20
|
+
getFullConfig: () => Record<string, unknown>;
|
|
21
|
+
getServiceConfig: (serviceKey: string, overrides?: GetServiceConfigOverrides) => Record<string, unknown>;
|
|
22
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_CONFIG_ROOT_CANDIDATES = void 0;
|
|
4
|
+
exports.resolveConfigRootDir = resolveConfigRootDir;
|
|
5
|
+
exports.createConfigLoader = createConfigLoader;
|
|
6
|
+
const fs = require("fs");
|
|
7
|
+
const path = require("path");
|
|
8
|
+
const yaml_config_loader_1 = require("./yaml-config.loader");
|
|
9
|
+
exports.DEFAULT_CONFIG_ROOT_CANDIDATES = [
|
|
10
|
+
'libs/config/config',
|
|
11
|
+
'../../libs/config/config',
|
|
12
|
+
'../libs/config/config',
|
|
13
|
+
'.',
|
|
14
|
+
];
|
|
15
|
+
function resolveConfigRootDir(options = {}) {
|
|
16
|
+
const cwd = path.resolve(options.cwd ?? (typeof process !== 'undefined' ? process.cwd() : '.'));
|
|
17
|
+
const candidates = options.candidates ?? [...exports.DEFAULT_CONFIG_ROOT_CANDIDATES];
|
|
18
|
+
const configFilenames = options.configFilenames ?? yaml_config_loader_1.DEFAULT_CONFIG_FILENAMES;
|
|
19
|
+
for (const candidate of candidates) {
|
|
20
|
+
const dir = path.isAbsolute(candidate) ? candidate : path.join(cwd, candidate);
|
|
21
|
+
const resolved = path.resolve(dir);
|
|
22
|
+
for (const filename of configFilenames) {
|
|
23
|
+
const filePath = path.join(resolved, filename);
|
|
24
|
+
try {
|
|
25
|
+
if (fs.existsSync(filePath)) {
|
|
26
|
+
return resolved;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return cwd;
|
|
34
|
+
}
|
|
35
|
+
const globalConfigCache = new Map();
|
|
36
|
+
function createConfigLoader(options = {}) {
|
|
37
|
+
const rootDir = options.rootDir ??
|
|
38
|
+
resolveConfigRootDir({ cwd: typeof process !== 'undefined' ? process.cwd() : '.' });
|
|
39
|
+
const globalKey = options.globalKey ?? 'default';
|
|
40
|
+
const load = () => {
|
|
41
|
+
const cached = globalConfigCache.get(globalKey);
|
|
42
|
+
if (cached)
|
|
43
|
+
return cached;
|
|
44
|
+
const config = (0, yaml_config_loader_1.loadApplicationYamlSync)({
|
|
45
|
+
rootDir,
|
|
46
|
+
env: options.env,
|
|
47
|
+
syncEnvKeys: options.syncEnvKeys,
|
|
48
|
+
...options.loadOptions,
|
|
49
|
+
});
|
|
50
|
+
globalConfigCache.set(globalKey, config);
|
|
51
|
+
return config;
|
|
52
|
+
};
|
|
53
|
+
function getFullConfig() {
|
|
54
|
+
return load();
|
|
55
|
+
}
|
|
56
|
+
function getServiceConfig(serviceKey, overrides) {
|
|
57
|
+
const full = getFullConfig();
|
|
58
|
+
const common = full.common ?? {};
|
|
59
|
+
const service = full[serviceKey] ?? {};
|
|
60
|
+
const merged = { ...common, ...service };
|
|
61
|
+
if (overrides?.portEnvKey && typeof process !== 'undefined') {
|
|
62
|
+
const portStr = process.env[overrides.portEnvKey];
|
|
63
|
+
if (portStr != null && portStr !== '') {
|
|
64
|
+
const port = parseInt(portStr, 10);
|
|
65
|
+
if (!Number.isNaN(port)) {
|
|
66
|
+
merged.server = {
|
|
67
|
+
...merged.server,
|
|
68
|
+
port,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return merged;
|
|
74
|
+
}
|
|
75
|
+
return { getFullConfig, getServiceConfig };
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=config-loader.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-loader.utils.js","sourceRoot":"","sources":["../../src/utils/config-loader.utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare class ConfigValidator {
|
|
2
|
+
private static readonly logger;
|
|
3
|
+
static validateRequired(requiredVars: string[], throwOnMissing?: boolean): void;
|
|
4
|
+
static validateDatabaseConfig(throwOnMissing?: boolean): void;
|
|
5
|
+
static validateJwtConfig(throwOnMissing?: boolean, jwtOptions?: {
|
|
6
|
+
secret?: string;
|
|
7
|
+
expiresIn?: string;
|
|
8
|
+
}): void;
|
|
9
|
+
static validatePort(port: string | undefined, defaultPort: number): number;
|
|
10
|
+
static parseBoolean(value: string | undefined, defaultValue?: boolean): boolean;
|
|
11
|
+
static parseArray(value: string | undefined): string[];
|
|
12
|
+
static parseNumber(value: string | undefined, defaultValue: number, min?: number, max?: number): number;
|
|
13
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConfigValidator = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
class ConfigValidator {
|
|
6
|
+
static validateRequired(requiredVars, throwOnMissing = false) {
|
|
7
|
+
const missing = [];
|
|
8
|
+
for (const varName of requiredVars) {
|
|
9
|
+
if (!process.env[varName]) {
|
|
10
|
+
missing.push(varName);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
if (missing.length > 0) {
|
|
14
|
+
const message = `Missing required environment variables: ${missing.join(', ')}`;
|
|
15
|
+
if (throwOnMissing) {
|
|
16
|
+
throw new Error(message);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
this.logger.warn(message);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
static validateDatabaseConfig(throwOnMissing = false) {
|
|
24
|
+
this.validateRequired(['DB_HOST', 'DB_PORT', 'DB_USER', 'DB_NAME'], throwOnMissing);
|
|
25
|
+
if (!process.env.DB_PASSWORD) {
|
|
26
|
+
this.logger.warn('DB_PASSWORD is not set. Database connection may fail if password is required.');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
static validateJwtConfig(throwOnMissing = false, jwtOptions) {
|
|
30
|
+
if (jwtOptions?.secret != null && String(jwtOptions.secret).trim() !== '') {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
this.validateRequired(['JWT_SECRET'], throwOnMissing);
|
|
34
|
+
}
|
|
35
|
+
static validatePort(port, defaultPort) {
|
|
36
|
+
if (!port) {
|
|
37
|
+
return defaultPort;
|
|
38
|
+
}
|
|
39
|
+
const portNum = parseInt(port, 10);
|
|
40
|
+
if (isNaN(portNum) || portNum < 1 || portNum > 65535) {
|
|
41
|
+
this.logger.warn(`Invalid port number: ${port}. Using default: ${defaultPort}`);
|
|
42
|
+
return defaultPort;
|
|
43
|
+
}
|
|
44
|
+
return portNum;
|
|
45
|
+
}
|
|
46
|
+
static parseBoolean(value, defaultValue = false) {
|
|
47
|
+
if (!value) {
|
|
48
|
+
return defaultValue;
|
|
49
|
+
}
|
|
50
|
+
return value.toLowerCase() === 'true' || value === '1';
|
|
51
|
+
}
|
|
52
|
+
static parseArray(value) {
|
|
53
|
+
if (value == null || value === '')
|
|
54
|
+
return [];
|
|
55
|
+
return value
|
|
56
|
+
.split(',')
|
|
57
|
+
.map((s) => s.trim())
|
|
58
|
+
.filter(Boolean);
|
|
59
|
+
}
|
|
60
|
+
static parseNumber(value, defaultValue, min, max) {
|
|
61
|
+
if (!value) {
|
|
62
|
+
return defaultValue;
|
|
63
|
+
}
|
|
64
|
+
const num = parseInt(value, 10);
|
|
65
|
+
if (isNaN(num)) {
|
|
66
|
+
this.logger.warn(`Invalid number: ${value}. Using default: ${defaultValue}`);
|
|
67
|
+
return defaultValue;
|
|
68
|
+
}
|
|
69
|
+
if (min !== undefined && num < min) {
|
|
70
|
+
this.logger.warn(`Number ${num} is less than minimum ${min}. Using minimum value.`);
|
|
71
|
+
return min;
|
|
72
|
+
}
|
|
73
|
+
if (max !== undefined && num > max) {
|
|
74
|
+
this.logger.warn(`Number ${num} is greater than maximum ${max}. Using maximum value.`);
|
|
75
|
+
return max;
|
|
76
|
+
}
|
|
77
|
+
return num;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
exports.ConfigValidator = ConfigValidator;
|
|
81
|
+
ConfigValidator.logger = new common_1.Logger(ConfigValidator.name);
|
|
82
|
+
//# sourceMappingURL=config.validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.validator.js","sourceRoot":"","sources":["../../src/utils/config.validator.ts"],"names":[],"mappings":"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"}
|