@pawells/nestjs-shared 1.0.0-dev.3052c75
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/LICENSE +21 -0
- package/README.md +802 -0
- package/build/LICENSE +21 -0
- package/build/README.md +802 -0
- package/build/common/common.module.d.ts +49 -0
- package/build/common/common.module.d.ts.map +1 -0
- package/build/common/common.module.js +178 -0
- package/build/common/common.module.js.map +1 -0
- package/build/common/constants/histogram-buckets.constants.d.ts +12 -0
- package/build/common/constants/histogram-buckets.constants.d.ts.map +1 -0
- package/build/common/constants/histogram-buckets.constants.js +51 -0
- package/build/common/constants/histogram-buckets.constants.js.map +1 -0
- package/build/common/constants/http-status.constants.d.ts +27 -0
- package/build/common/constants/http-status.constants.d.ts.map +1 -0
- package/build/common/constants/http-status.constants.js +27 -0
- package/build/common/constants/http-status.constants.js.map +1 -0
- package/build/common/constants/timeout.constants.d.ts +29 -0
- package/build/common/constants/timeout.constants.d.ts.map +1 -0
- package/build/common/constants/timeout.constants.js +45 -0
- package/build/common/constants/timeout.constants.js.map +1 -0
- package/build/common/controllers/metrics.controller.d.ts +23 -0
- package/build/common/controllers/metrics.controller.d.ts.map +1 -0
- package/build/common/controllers/metrics.controller.js +66 -0
- package/build/common/controllers/metrics.controller.js.map +1 -0
- package/build/common/decorators/common-decorators.d.ts +90 -0
- package/build/common/decorators/common-decorators.d.ts.map +1 -0
- package/build/common/decorators/common-decorators.js +101 -0
- package/build/common/decorators/common-decorators.js.map +1 -0
- package/build/common/decorators/decorator-factory.d.ts +108 -0
- package/build/common/decorators/decorator-factory.d.ts.map +1 -0
- package/build/common/decorators/decorator-factory.js +104 -0
- package/build/common/decorators/decorator-factory.js.map +1 -0
- package/build/common/decorators/guard.decorators.d.ts +48 -0
- package/build/common/decorators/guard.decorators.d.ts.map +1 -0
- package/build/common/decorators/guard.decorators.js +49 -0
- package/build/common/decorators/guard.decorators.js.map +1 -0
- package/build/common/decorators/index.d.ts +10 -0
- package/build/common/decorators/index.d.ts.map +1 -0
- package/build/common/decorators/index.js +11 -0
- package/build/common/decorators/index.js.map +1 -0
- package/build/common/decorators/instrument.decorator.d.ts +128 -0
- package/build/common/decorators/instrument.decorator.d.ts.map +1 -0
- package/build/common/decorators/instrument.decorator.js +165 -0
- package/build/common/decorators/instrument.decorator.js.map +1 -0
- package/build/common/decorators/metric.decorators.d.ts +42 -0
- package/build/common/decorators/metric.decorators.d.ts.map +1 -0
- package/build/common/decorators/metric.decorators.js +85 -0
- package/build/common/decorators/metric.decorators.js.map +1 -0
- package/build/common/decorators/request-property.decorator.d.ts +65 -0
- package/build/common/decorators/request-property.decorator.d.ts.map +1 -0
- package/build/common/decorators/request-property.decorator.js +102 -0
- package/build/common/decorators/request-property.decorator.js.map +1 -0
- package/build/common/errors/base-application-error.d.ts +98 -0
- package/build/common/errors/base-application-error.d.ts.map +1 -0
- package/build/common/errors/base-application-error.js +133 -0
- package/build/common/errors/base-application-error.js.map +1 -0
- package/build/common/errors/error-factory.d.ts +93 -0
- package/build/common/errors/error-factory.d.ts.map +1 -0
- package/build/common/errors/error-factory.js +105 -0
- package/build/common/errors/error-factory.js.map +1 -0
- package/build/common/errors/index.d.ts +13 -0
- package/build/common/errors/index.d.ts.map +1 -0
- package/build/common/errors/index.js +15 -0
- package/build/common/errors/index.js.map +1 -0
- package/build/common/factories/index.d.ts +5 -0
- package/build/common/factories/index.d.ts.map +1 -0
- package/build/common/factories/index.js +3 -0
- package/build/common/factories/index.js.map +1 -0
- package/build/common/factories/module-factory.d.ts +178 -0
- package/build/common/factories/module-factory.d.ts.map +1 -0
- package/build/common/factories/module-factory.js +253 -0
- package/build/common/factories/module-factory.js.map +1 -0
- package/build/common/factories/rate-limit-config.factory.d.ts +79 -0
- package/build/common/factories/rate-limit-config.factory.d.ts.map +1 -0
- package/build/common/factories/rate-limit-config.factory.js +115 -0
- package/build/common/factories/rate-limit-config.factory.js.map +1 -0
- package/build/common/factories/security-bootstrap.factory.d.ts +77 -0
- package/build/common/factories/security-bootstrap.factory.d.ts.map +1 -0
- package/build/common/factories/security-bootstrap.factory.js +222 -0
- package/build/common/factories/security-bootstrap.factory.js.map +1 -0
- package/build/common/filters/global-exception.filter.d.ts +78 -0
- package/build/common/filters/global-exception.filter.d.ts.map +1 -0
- package/build/common/filters/global-exception.filter.js +192 -0
- package/build/common/filters/global-exception.filter.js.map +1 -0
- package/build/common/filters/http-exception.filter.d.ts +37 -0
- package/build/common/filters/http-exception.filter.d.ts.map +1 -0
- package/build/common/filters/http-exception.filter.js +91 -0
- package/build/common/filters/http-exception.filter.js.map +1 -0
- package/build/common/guards/csrf.guard.d.ts +53 -0
- package/build/common/guards/csrf.guard.d.ts.map +1 -0
- package/build/common/guards/csrf.guard.js +109 -0
- package/build/common/guards/csrf.guard.js.map +1 -0
- package/build/common/guards/metrics.guard.d.ts +42 -0
- package/build/common/guards/metrics.guard.d.ts.map +1 -0
- package/build/common/guards/metrics.guard.js +124 -0
- package/build/common/guards/metrics.guard.js.map +1 -0
- package/build/common/index.d.ts +43 -0
- package/build/common/index.d.ts.map +1 -0
- package/build/common/index.js +50 -0
- package/build/common/index.js.map +1 -0
- package/build/common/interceptors/http-client.interceptor.d.ts +11 -0
- package/build/common/interceptors/http-client.interceptor.d.ts.map +1 -0
- package/build/common/interceptors/http-client.interceptor.js +69 -0
- package/build/common/interceptors/http-client.interceptor.js.map +1 -0
- package/build/common/interceptors/http-instrumentation.interceptor.d.ts +64 -0
- package/build/common/interceptors/http-instrumentation.interceptor.d.ts.map +1 -0
- package/build/common/interceptors/http-instrumentation.interceptor.js +148 -0
- package/build/common/interceptors/http-instrumentation.interceptor.js.map +1 -0
- package/build/common/interceptors/http-metrics.interceptor.d.ts +46 -0
- package/build/common/interceptors/http-metrics.interceptor.d.ts.map +1 -0
- package/build/common/interceptors/http-metrics.interceptor.js +120 -0
- package/build/common/interceptors/http-metrics.interceptor.js.map +1 -0
- package/build/common/interceptors/logging.interceptor.d.ts +22 -0
- package/build/common/interceptors/logging.interceptor.d.ts.map +1 -0
- package/build/common/interceptors/logging.interceptor.js +67 -0
- package/build/common/interceptors/logging.interceptor.js.map +1 -0
- package/build/common/interfaces/cache-provider.interface.d.ts +54 -0
- package/build/common/interfaces/cache-provider.interface.d.ts.map +1 -0
- package/build/common/interfaces/cache-provider.interface.js +6 -0
- package/build/common/interfaces/cache-provider.interface.js.map +1 -0
- package/build/common/interfaces/index.d.ts +7 -0
- package/build/common/interfaces/index.d.ts.map +1 -0
- package/build/common/interfaces/index.js +3 -0
- package/build/common/interfaces/index.js.map +1 -0
- package/build/common/interfaces/log-context.interface.d.ts +77 -0
- package/build/common/interfaces/log-context.interface.d.ts.map +1 -0
- package/build/common/interfaces/log-context.interface.js +2 -0
- package/build/common/interfaces/log-context.interface.js.map +1 -0
- package/build/common/interfaces/log-entry.interface.d.ts +26 -0
- package/build/common/interfaces/log-entry.interface.d.ts.map +1 -0
- package/build/common/interfaces/log-entry.interface.js +33 -0
- package/build/common/interfaces/log-entry.interface.js.map +1 -0
- package/build/common/interfaces/logger.interface.d.ts +62 -0
- package/build/common/interfaces/logger.interface.d.ts.map +1 -0
- package/build/common/interfaces/logger.interface.js +2 -0
- package/build/common/interfaces/logger.interface.js.map +1 -0
- package/build/common/interfaces/metrics-exporter.interface.d.ts +275 -0
- package/build/common/interfaces/metrics-exporter.interface.d.ts.map +1 -0
- package/build/common/interfaces/metrics-exporter.interface.js +8 -0
- package/build/common/interfaces/metrics-exporter.interface.js.map +1 -0
- package/build/common/metrics/base-metrics-collector.d.ts +81 -0
- package/build/common/metrics/base-metrics-collector.d.ts.map +1 -0
- package/build/common/metrics/base-metrics-collector.js +88 -0
- package/build/common/metrics/base-metrics-collector.js.map +1 -0
- package/build/common/metrics/index.d.ts +2 -0
- package/build/common/metrics/index.d.ts.map +1 -0
- package/build/common/metrics/index.js +2 -0
- package/build/common/metrics/index.js.map +1 -0
- package/build/common/metrics.module.d.ts +50 -0
- package/build/common/metrics.module.d.ts.map +1 -0
- package/build/common/metrics.module.js +77 -0
- package/build/common/metrics.module.js.map +1 -0
- package/build/common/modules/throttler.module.d.ts +69 -0
- package/build/common/modules/throttler.module.d.ts.map +1 -0
- package/build/common/modules/throttler.module.js +117 -0
- package/build/common/modules/throttler.module.js.map +1 -0
- package/build/common/pipes/base-validation.pipe.d.ts +67 -0
- package/build/common/pipes/base-validation.pipe.d.ts.map +1 -0
- package/build/common/pipes/base-validation.pipe.js +95 -0
- package/build/common/pipes/base-validation.pipe.js.map +1 -0
- package/build/common/pipes/validation.pipe.d.ts +32 -0
- package/build/common/pipes/validation.pipe.d.ts.map +1 -0
- package/build/common/pipes/validation.pipe.js +60 -0
- package/build/common/pipes/validation.pipe.js.map +1 -0
- package/build/common/registry/instrumentation-registry.d.ts +227 -0
- package/build/common/registry/instrumentation-registry.d.ts.map +1 -0
- package/build/common/registry/instrumentation-registry.js +414 -0
- package/build/common/registry/instrumentation-registry.js.map +1 -0
- package/build/common/services/audit-logger.service.d.ts +91 -0
- package/build/common/services/audit-logger.service.d.ts.map +1 -0
- package/build/common/services/audit-logger.service.js +180 -0
- package/build/common/services/audit-logger.service.js.map +1 -0
- package/build/common/services/csrf.service.d.ts +202 -0
- package/build/common/services/csrf.service.d.ts.map +1 -0
- package/build/common/services/csrf.service.js +478 -0
- package/build/common/services/csrf.service.js.map +1 -0
- package/build/common/services/error-categorizer.service.d.ts +82 -0
- package/build/common/services/error-categorizer.service.d.ts.map +1 -0
- package/build/common/services/error-categorizer.service.js +339 -0
- package/build/common/services/error-categorizer.service.js.map +1 -0
- package/build/common/services/error-sanitizer.service.d.ts +146 -0
- package/build/common/services/error-sanitizer.service.d.ts.map +1 -0
- package/build/common/services/error-sanitizer.service.js +287 -0
- package/build/common/services/error-sanitizer.service.js.map +1 -0
- package/build/common/services/health-check.service.d.ts +86 -0
- package/build/common/services/health-check.service.d.ts.map +1 -0
- package/build/common/services/health-check.service.js +132 -0
- package/build/common/services/health-check.service.js.map +1 -0
- package/build/common/services/http-client.service.d.ts +113 -0
- package/build/common/services/http-client.service.d.ts.map +1 -0
- package/build/common/services/http-client.service.js +294 -0
- package/build/common/services/http-client.service.js.map +1 -0
- package/build/common/services/logger.service.d.ts +189 -0
- package/build/common/services/logger.service.d.ts.map +1 -0
- package/build/common/services/logger.service.js +423 -0
- package/build/common/services/logger.service.js.map +1 -0
- package/build/common/services/metrics-registry.service.d.ts +98 -0
- package/build/common/services/metrics-registry.service.d.ts.map +1 -0
- package/build/common/services/metrics-registry.service.js +262 -0
- package/build/common/services/metrics-registry.service.js.map +1 -0
- package/build/common/services/nest-logger-adapter.service.d.ts +62 -0
- package/build/common/services/nest-logger-adapter.service.d.ts.map +1 -0
- package/build/common/services/nest-logger-adapter.service.js +120 -0
- package/build/common/services/nest-logger-adapter.service.js.map +1 -0
- package/build/common/utils/error.utils.d.ts +16 -0
- package/build/common/utils/error.utils.d.ts.map +1 -0
- package/build/common/utils/error.utils.js +26 -0
- package/build/common/utils/error.utils.js.map +1 -0
- package/build/common/utils/lazy-getter.types.d.ts +190 -0
- package/build/common/utils/lazy-getter.types.d.ts.map +1 -0
- package/build/common/utils/lazy-getter.types.js +114 -0
- package/build/common/utils/lazy-getter.types.js.map +1 -0
- package/build/common/utils/module.utils.d.ts +33 -0
- package/build/common/utils/module.utils.d.ts.map +1 -0
- package/build/common/utils/module.utils.js +48 -0
- package/build/common/utils/module.utils.js.map +1 -0
- package/build/common/utils/sanitization.utils.d.ts +69 -0
- package/build/common/utils/sanitization.utils.d.ts.map +1 -0
- package/build/common/utils/sanitization.utils.js +141 -0
- package/build/common/utils/sanitization.utils.js.map +1 -0
- package/build/config/config.module.d.ts +30 -0
- package/build/config/config.module.d.ts.map +1 -0
- package/build/config/config.module.js +49 -0
- package/build/config/config.module.js.map +1 -0
- package/build/config/config.service.d.ts +74 -0
- package/build/config/config.service.d.ts.map +1 -0
- package/build/config/config.service.js +145 -0
- package/build/config/config.service.js.map +1 -0
- package/build/config/config.types.d.ts +143 -0
- package/build/config/config.types.d.ts.map +1 -0
- package/build/config/config.types.js +2 -0
- package/build/config/config.types.js.map +1 -0
- package/build/config/decorators/config.decorators.d.ts +43 -0
- package/build/config/decorators/config.decorators.d.ts.map +1 -0
- package/build/config/decorators/config.decorators.js +68 -0
- package/build/config/decorators/config.decorators.js.map +1 -0
- package/build/config/decorators/index.d.ts +2 -0
- package/build/config/decorators/index.d.ts.map +1 -0
- package/build/config/decorators/index.js +2 -0
- package/build/config/decorators/index.js.map +1 -0
- package/build/config/index.d.ts +7 -0
- package/build/config/index.d.ts.map +1 -0
- package/build/config/index.js +9 -0
- package/build/config/index.js.map +1 -0
- package/build/config/validation.utils.d.ts +136 -0
- package/build/config/validation.utils.d.ts.map +1 -0
- package/build/config/validation.utils.js +263 -0
- package/build/config/validation.utils.js.map +1 -0
- package/build/errors/index.d.ts +9 -0
- package/build/errors/index.d.ts.map +1 -0
- package/build/errors/index.js +12 -0
- package/build/errors/index.js.map +1 -0
- package/build/guards/custom-throttle.guard.d.ts +28 -0
- package/build/guards/custom-throttle.guard.d.ts.map +1 -0
- package/build/guards/custom-throttle.guard.js +52 -0
- package/build/guards/custom-throttle.guard.js.map +1 -0
- package/build/guards/index.d.ts +2 -0
- package/build/guards/index.d.ts.map +1 -0
- package/build/guards/index.js +2 -0
- package/build/guards/index.js.map +1 -0
- package/build/index.d.ts +53 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +61 -0
- package/build/index.js.map +1 -0
- package/build/logging/index.d.ts +7 -0
- package/build/logging/index.d.ts.map +1 -0
- package/build/logging/index.js +7 -0
- package/build/logging/index.js.map +1 -0
- package/build/metrics/index.d.ts +6 -0
- package/build/metrics/index.d.ts.map +1 -0
- package/build/metrics/index.js +11 -0
- package/build/metrics/index.js.map +1 -0
- package/build/package.json +72 -0
- package/build/security/index.d.ts +8 -0
- package/build/security/index.d.ts.map +1 -0
- package/build/security/index.js +11 -0
- package/build/security/index.js.map +1 -0
- package/build/test-setup.d.ts +2 -0
- package/build/test-setup.d.ts.map +1 -0
- package/build/test-setup.js +40 -0
- package/build/test-setup.js.map +1 -0
- package/build/validation/index.d.ts +6 -0
- package/build/validation/index.d.ts.map +1 -0
- package/build/validation/index.js +8 -0
- package/build/validation/index.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
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;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var MetricsModule_1;
|
|
8
|
+
import { Module, Global } from '@nestjs/common';
|
|
9
|
+
import { MetricsRegistryService } from './services/metrics-registry.service.js';
|
|
10
|
+
import { HTTPMetricsInterceptor } from './interceptors/http-metrics.interceptor.js';
|
|
11
|
+
import { MetricsController } from './controllers/metrics.controller.js';
|
|
12
|
+
/**
|
|
13
|
+
* Metrics Module.
|
|
14
|
+
* Provides comprehensive Prometheus metrics collection and exposure for NestJS applications.
|
|
15
|
+
*
|
|
16
|
+
* Features:
|
|
17
|
+
* - HTTP request metrics (duration, count, size) with automatic cardinality prevention
|
|
18
|
+
* - Custom metric creation (counter, gauge, histogram)
|
|
19
|
+
* - Default Node.js metrics collection
|
|
20
|
+
* - Prometheus endpoint at /metrics
|
|
21
|
+
* - Metrics registry management
|
|
22
|
+
*
|
|
23
|
+
* @remarks
|
|
24
|
+
* - Imported as global module in CommonModule
|
|
25
|
+
* - Controlled by METRICS_ENABLED environment variable (default: true)
|
|
26
|
+
* - Automatically normalizes dynamic path segments to prevent unbounded label cardinality
|
|
27
|
+
* - MetricsController exports metrics at GET /metrics in Prometheus format
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* // Access metrics in any injectable
|
|
32
|
+
* constructor(private metrics: MetricsRegistryService) {}
|
|
33
|
+
*
|
|
34
|
+
* // Create and record custom metrics
|
|
35
|
+
* const counter = this.metrics.createCounter('orders_total', 'Total orders');
|
|
36
|
+
* counter.inc({ status: 'completed' });
|
|
37
|
+
*
|
|
38
|
+
* // Get metrics (typically called by MetricsController)
|
|
39
|
+
* const prometheusText = await this.metrics.getMetrics();
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
let MetricsModule = MetricsModule_1 = class MetricsModule {
|
|
43
|
+
/**
|
|
44
|
+
* Configure metrics module for root application
|
|
45
|
+
* Enables HTTP metrics collection and /metrics endpoint
|
|
46
|
+
*/
|
|
47
|
+
static forRoot() {
|
|
48
|
+
return {
|
|
49
|
+
module: MetricsModule_1,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Configure metrics module with async options
|
|
54
|
+
*/
|
|
55
|
+
static forRootAsync(options) {
|
|
56
|
+
return {
|
|
57
|
+
module: MetricsModule_1,
|
|
58
|
+
imports: options.imports,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
MetricsModule = MetricsModule_1 = __decorate([
|
|
63
|
+
Global(),
|
|
64
|
+
Module({
|
|
65
|
+
controllers: [MetricsController],
|
|
66
|
+
providers: [
|
|
67
|
+
MetricsRegistryService,
|
|
68
|
+
HTTPMetricsInterceptor,
|
|
69
|
+
],
|
|
70
|
+
exports: [
|
|
71
|
+
MetricsRegistryService,
|
|
72
|
+
HTTPMetricsInterceptor,
|
|
73
|
+
],
|
|
74
|
+
})
|
|
75
|
+
], MetricsModule);
|
|
76
|
+
export { MetricsModule };
|
|
77
|
+
//# sourceMappingURL=metrics.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.module.js","sourceRoot":"","sources":["../../src/common/metrics.module.ts"],"names":[],"mappings":";;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAiB,MAAM,gBAAgB,CAAC;AAE/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,EAAE,sBAAsB,EAAE,MAAM,4CAA4C,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAUxE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAcI,IAAM,aAAa,qBAAnB,MAAM,aAAa;IACzB;;;OAGG;IACI,MAAM,CAAC,OAAO;QACpB,OAAO;YACN,MAAM,EAAE,eAAa;SACrB,CAAC;IACH,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,YAAY,CAAC,OAAkC;QAC5D,OAAO;YACN,MAAM,EAAE,eAAa;YACrB,OAAO,EAAE,OAAO,CAAC,OAAO;SACxB,CAAC;IACH,CAAC;CACD,CAAA;AApBY,aAAa;IAZzB,MAAM,EAAE;IACR,MAAM,CAAC;QACP,WAAW,EAAE,CAAC,iBAAiB,CAAC;QAChC,SAAS,EAAE;YACV,sBAAsB;YACtB,sBAAsB;SACtB;QACD,OAAO,EAAE;YACR,sBAAsB;YACtB,sBAAsB;SACtB;KACD,CAAC;GACW,aAAa,CAoBzB"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SharedThrottlerModule
|
|
3
|
+
*
|
|
4
|
+
* Provides rate limiting / throttling functionality with optional Redis backend.
|
|
5
|
+
* Default: in-memory storage (suitable for single-instance deployments)
|
|
6
|
+
* With Redis: distributed rate limiting across multiple instances
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* ```typescript
|
|
10
|
+
* // In-memory (default, development)
|
|
11
|
+
* @Module({
|
|
12
|
+
* imports: [SharedThrottlerModule.forRoot()],
|
|
13
|
+
* })
|
|
14
|
+
* export class AppModule {}
|
|
15
|
+
*
|
|
16
|
+
* // With Redis (production)
|
|
17
|
+
* @Module({
|
|
18
|
+
* imports: [
|
|
19
|
+
* SharedThrottlerModule.forRootAsync({
|
|
20
|
+
* useFactory: () => ({
|
|
21
|
+
* redis: {
|
|
22
|
+
* host: process.env.REDIS_HOST,
|
|
23
|
+
* port: parseInt(process.env.REDIS_PORT || '6379', 10),
|
|
24
|
+
* },
|
|
25
|
+
* }),
|
|
26
|
+
* }),
|
|
27
|
+
* ],
|
|
28
|
+
* })
|
|
29
|
+
* export class AppModule {}
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
import { DynamicModule, ModuleMetadata, Type } from '@nestjs/common';
|
|
33
|
+
export interface SharedThrottlerConfig {
|
|
34
|
+
/** Time window in milliseconds (default: 15 * 60 * 1000 = 15 minutes) */
|
|
35
|
+
ttl?: number;
|
|
36
|
+
/** Maximum number of requests per window (default: 100) */
|
|
37
|
+
limit?: number;
|
|
38
|
+
/** Optional Redis configuration for distributed rate limiting */
|
|
39
|
+
redis?: {
|
|
40
|
+
host?: string;
|
|
41
|
+
port?: number;
|
|
42
|
+
password?: string;
|
|
43
|
+
username?: string;
|
|
44
|
+
db?: number;
|
|
45
|
+
[key: string]: any;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export declare class SharedThrottlerModule {
|
|
49
|
+
private static readonly logger;
|
|
50
|
+
private static readonly DEFAULT_WINDOW_MS;
|
|
51
|
+
private static readonly DEFAULT_MAX_REQUESTS;
|
|
52
|
+
private static readonly MS_PER_SECOND;
|
|
53
|
+
/**
|
|
54
|
+
* Configure in-memory throttling (default)
|
|
55
|
+
*/
|
|
56
|
+
static forRoot(config?: SharedThrottlerConfig): DynamicModule;
|
|
57
|
+
/**
|
|
58
|
+
* Configure with async options (supports Redis backend)
|
|
59
|
+
*/
|
|
60
|
+
static forRootAsync(options: {
|
|
61
|
+
useFactory?: (...args: any[]) => SharedThrottlerConfig | Promise<SharedThrottlerConfig>;
|
|
62
|
+
useClass?: Type<{
|
|
63
|
+
createThrottlerConfig(): SharedThrottlerConfig | Promise<SharedThrottlerConfig>;
|
|
64
|
+
}>;
|
|
65
|
+
inject?: any[];
|
|
66
|
+
imports?: ModuleMetadata['imports'];
|
|
67
|
+
}): DynamicModule;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=throttler.module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"throttler.module.d.ts","sourceRoot":"","sources":["../../../src/common/modules/throttler.module.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,EAEN,aAAa,EACb,cAAc,EACd,IAAI,EAGJ,MAAM,gBAAgB,CAAC;AAGxB,MAAM,WAAW,qBAAqB;IACrC,yEAAyE;IACzE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,KAAK,CAAC,EAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACnB,CAAC;CACF;AAED,qBACa,qBAAqB;IACjC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAA0C;IAGxE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAkB;IAG3D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAO;IAGnD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAQ;IAE7C;;OAEG;WACW,OAAO,CAAC,MAAM,CAAC,EAAE,qBAAqB,GAAG,aAAa;IAoBpE;;OAEG;WACW,YAAY,CACzB,OAAO,EAAE;QACR,UAAU,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;QACxF,QAAQ,CAAC,EAAE,IAAI,CAAC;YAAE,qBAAqB,IAAI,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAA;SAAE,CAAC,CAAC;QACrG,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;QACf,OAAO,CAAC,EAAE,cAAc,CAAC,SAAS,CAAC,CAAC;KACpC,GACC,aAAa;CAiDhB"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SharedThrottlerModule
|
|
3
|
+
*
|
|
4
|
+
* Provides rate limiting / throttling functionality with optional Redis backend.
|
|
5
|
+
* Default: in-memory storage (suitable for single-instance deployments)
|
|
6
|
+
* With Redis: distributed rate limiting across multiple instances
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* ```typescript
|
|
10
|
+
* // In-memory (default, development)
|
|
11
|
+
* @Module({
|
|
12
|
+
* imports: [SharedThrottlerModule.forRoot()],
|
|
13
|
+
* })
|
|
14
|
+
* export class AppModule {}
|
|
15
|
+
*
|
|
16
|
+
* // With Redis (production)
|
|
17
|
+
* @Module({
|
|
18
|
+
* imports: [
|
|
19
|
+
* SharedThrottlerModule.forRootAsync({
|
|
20
|
+
* useFactory: () => ({
|
|
21
|
+
* redis: {
|
|
22
|
+
* host: process.env.REDIS_HOST,
|
|
23
|
+
* port: parseInt(process.env.REDIS_PORT || '6379', 10),
|
|
24
|
+
* },
|
|
25
|
+
* }),
|
|
26
|
+
* }),
|
|
27
|
+
* ],
|
|
28
|
+
* })
|
|
29
|
+
* export class AppModule {}
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
33
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
34
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
35
|
+
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;
|
|
36
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
37
|
+
};
|
|
38
|
+
var SharedThrottlerModule_1;
|
|
39
|
+
import { Module, Logger, } from '@nestjs/common';
|
|
40
|
+
import { ThrottlerModule, ThrottlerGuard } from '@nestjs/throttler';
|
|
41
|
+
let SharedThrottlerModule = class SharedThrottlerModule {
|
|
42
|
+
static { SharedThrottlerModule_1 = this; }
|
|
43
|
+
static logger = new Logger(SharedThrottlerModule_1.name);
|
|
44
|
+
// eslint-disable-next-line no-magic-numbers
|
|
45
|
+
static DEFAULT_WINDOW_MS = 15 * 60 * 1000; // 15 minutes
|
|
46
|
+
// eslint-disable-next-line no-magic-numbers
|
|
47
|
+
static DEFAULT_MAX_REQUESTS = 100;
|
|
48
|
+
// eslint-disable-next-line no-magic-numbers
|
|
49
|
+
static MS_PER_SECOND = 1000;
|
|
50
|
+
/**
|
|
51
|
+
* Configure in-memory throttling (default)
|
|
52
|
+
*/
|
|
53
|
+
static forRoot(config) {
|
|
54
|
+
const ttl = config?.ttl ?? SharedThrottlerModule_1.DEFAULT_WINDOW_MS;
|
|
55
|
+
const limit = config?.limit ?? SharedThrottlerModule_1.DEFAULT_MAX_REQUESTS;
|
|
56
|
+
SharedThrottlerModule_1.logger.log(`Initializing SharedThrottlerModule with in-memory storage (ttl: ${ttl}ms, limit: ${limit})`);
|
|
57
|
+
return {
|
|
58
|
+
module: SharedThrottlerModule_1,
|
|
59
|
+
imports: [
|
|
60
|
+
ThrottlerModule.forRoot({
|
|
61
|
+
throttlers: [{ ttl: Math.round(ttl / SharedThrottlerModule_1.MS_PER_SECOND), limit }],
|
|
62
|
+
}),
|
|
63
|
+
],
|
|
64
|
+
providers: [ThrottlerGuard],
|
|
65
|
+
exports: [ThrottlerModule, ThrottlerGuard],
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Configure with async options (supports Redis backend)
|
|
70
|
+
*/
|
|
71
|
+
static forRootAsync(options) {
|
|
72
|
+
const providers = [];
|
|
73
|
+
// If useFactory is provided
|
|
74
|
+
if (options.useFactory) {
|
|
75
|
+
providers.push({
|
|
76
|
+
provide: 'SHARED_THROTTLER_CONFIG',
|
|
77
|
+
useFactory: options.useFactory,
|
|
78
|
+
inject: options.inject ?? [],
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
// If useClass is provided
|
|
82
|
+
if (options.useClass) {
|
|
83
|
+
providers.push(options.useClass, {
|
|
84
|
+
provide: 'SHARED_THROTTLER_CONFIG',
|
|
85
|
+
useFactory: (instance) => instance.createThrottlerConfig(),
|
|
86
|
+
inject: [options.useClass],
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
module: SharedThrottlerModule_1,
|
|
91
|
+
imports: [
|
|
92
|
+
ThrottlerModule.forRootAsync({
|
|
93
|
+
inject: ['SHARED_THROTTLER_CONFIG'],
|
|
94
|
+
useFactory: (config) => {
|
|
95
|
+
const ttl = config?.ttl ?? SharedThrottlerModule_1.DEFAULT_WINDOW_MS;
|
|
96
|
+
const limit = config?.limit ?? SharedThrottlerModule_1.DEFAULT_MAX_REQUESTS;
|
|
97
|
+
if (config?.redis) {
|
|
98
|
+
throw new Error('Redis backend for SharedThrottlerModule is not yet implemented. Remove the redis config or wait for the implementation.');
|
|
99
|
+
}
|
|
100
|
+
SharedThrottlerModule_1.logger.log(`Initializing SharedThrottlerModule with in-memory storage (ttl: ${ttl}ms, limit: ${limit})`);
|
|
101
|
+
return {
|
|
102
|
+
throttlers: [{ ttl: Math.round(ttl / SharedThrottlerModule_1.MS_PER_SECOND), limit }],
|
|
103
|
+
};
|
|
104
|
+
},
|
|
105
|
+
}),
|
|
106
|
+
...(options.imports ?? []),
|
|
107
|
+
],
|
|
108
|
+
providers: [...providers, ThrottlerGuard],
|
|
109
|
+
exports: [ThrottlerModule, ThrottlerGuard],
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
SharedThrottlerModule = SharedThrottlerModule_1 = __decorate([
|
|
114
|
+
Module({})
|
|
115
|
+
], SharedThrottlerModule);
|
|
116
|
+
export { SharedThrottlerModule };
|
|
117
|
+
//# sourceMappingURL=throttler.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"throttler.module.js","sourceRoot":"","sources":["../../../src/common/modules/throttler.module.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { PipeTransform, ArgumentMetadata } from '@nestjs/common';
|
|
2
|
+
import { ValidationError } from 'class-validator';
|
|
3
|
+
import { ClassTransformOptions } from 'class-transformer';
|
|
4
|
+
/**
|
|
5
|
+
* Base Validation Pipe
|
|
6
|
+
*
|
|
7
|
+
* Abstract base class for validation pipes that provides core validation logic
|
|
8
|
+
* while allowing subclasses to customize error formatting and validation options.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* export class MyValidationPipe extends BaseValidationPipe {
|
|
13
|
+
* protected formatValidationErrors(errors: ValidationError[]): any {
|
|
14
|
+
* // Custom error formatting
|
|
15
|
+
* return errors.map(error => ({
|
|
16
|
+
* field: error.property,
|
|
17
|
+
* message: Object.values(error.constraints || {}).join(', ')
|
|
18
|
+
* }));
|
|
19
|
+
* }
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare abstract class BaseValidationPipe implements PipeTransform<any> {
|
|
24
|
+
/**
|
|
25
|
+
* Transforms and validates input data
|
|
26
|
+
*
|
|
27
|
+
* @param value - The input value to validate
|
|
28
|
+
* @param metadata - Metadata about the argument
|
|
29
|
+
* @returns any - The validated and transformed value
|
|
30
|
+
*/
|
|
31
|
+
transform(value: any, metadata: ArgumentMetadata): Promise<any>;
|
|
32
|
+
/**
|
|
33
|
+
* Determines if the metatype should be validated
|
|
34
|
+
*
|
|
35
|
+
* @param metatype - The type to check
|
|
36
|
+
* @returns boolean - True if validation should be performed
|
|
37
|
+
*/
|
|
38
|
+
protected shouldValidate(metatype: any): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Gets validation options for class-validator
|
|
41
|
+
*
|
|
42
|
+
* @returns Validation options
|
|
43
|
+
*/
|
|
44
|
+
protected getValidationOptions(): any;
|
|
45
|
+
/**
|
|
46
|
+
* Gets transformation options for class-transformer
|
|
47
|
+
*
|
|
48
|
+
* @returns Transformation options
|
|
49
|
+
*/
|
|
50
|
+
protected getTransformOptions(): ClassTransformOptions;
|
|
51
|
+
/**
|
|
52
|
+
* Handles validation errors before formatting
|
|
53
|
+
*
|
|
54
|
+
* Subclasses can override this to add logging, metrics, etc.
|
|
55
|
+
*
|
|
56
|
+
* @param _errors - The validation errors (unused in base implementation)
|
|
57
|
+
*/
|
|
58
|
+
protected handleValidationErrors(_errors: ValidationError[]): void;
|
|
59
|
+
/**
|
|
60
|
+
* Formats validation errors for the response
|
|
61
|
+
*
|
|
62
|
+
* @param errors - The validation errors
|
|
63
|
+
* @returns Formatted error response
|
|
64
|
+
*/
|
|
65
|
+
protected abstract formatValidationErrors(errors: ValidationError[]): any;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=base-validation.pipe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-validation.pipe.d.ts","sourceRoot":"","sources":["../../../src/common/pipes/base-validation.pipe.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,aAAa,EAEb,gBAAgB,EAEhB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAY,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAgB,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAExE;;;;;;;;;;;;;;;;;;GAkBG;AACH,8BACsB,kBAAmB,YAAW,aAAa,CAAC,GAAG,CAAC;IACrE;;;;;;OAMG;IACU,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC;IAuB5E;;;;;OAKG;IACH,SAAS,CAAC,cAAc,CAAC,QAAQ,EAAE,GAAG,GAAG,OAAO;IAKhD;;;;OAIG;IACH,SAAS,CAAC,oBAAoB,IAAI,GAAG;IAIrC;;;;OAIG;IACH,SAAS,CAAC,mBAAmB,IAAI,qBAAqB;IAItD;;;;;;OAMG;IACH,SAAS,CAAC,sBAAsB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,IAAI;IAIlE;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,CAAC,sBAAsB,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,GAAG;CACzE"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
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;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { Injectable, BadRequestException, } from '@nestjs/common';
|
|
8
|
+
import { validate } from 'class-validator';
|
|
9
|
+
import { plainToClass } from 'class-transformer';
|
|
10
|
+
/**
|
|
11
|
+
* Base Validation Pipe
|
|
12
|
+
*
|
|
13
|
+
* Abstract base class for validation pipes that provides core validation logic
|
|
14
|
+
* while allowing subclasses to customize error formatting and validation options.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* export class MyValidationPipe extends BaseValidationPipe {
|
|
19
|
+
* protected formatValidationErrors(errors: ValidationError[]): any {
|
|
20
|
+
* // Custom error formatting
|
|
21
|
+
* return errors.map(error => ({
|
|
22
|
+
* field: error.property,
|
|
23
|
+
* message: Object.values(error.constraints || {}).join(', ')
|
|
24
|
+
* }));
|
|
25
|
+
* }
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
let BaseValidationPipe = class BaseValidationPipe {
|
|
30
|
+
/**
|
|
31
|
+
* Transforms and validates input data
|
|
32
|
+
*
|
|
33
|
+
* @param value - The input value to validate
|
|
34
|
+
* @param metadata - Metadata about the argument
|
|
35
|
+
* @returns any - The validated and transformed value
|
|
36
|
+
*/
|
|
37
|
+
async transform(value, metadata) {
|
|
38
|
+
const { metatype } = metadata;
|
|
39
|
+
// Skip validation for primitive types
|
|
40
|
+
if (!metatype || !this.shouldValidate(metatype)) {
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
// Transform plain object to class instance
|
|
44
|
+
const object = plainToClass(metatype, value, this.getTransformOptions());
|
|
45
|
+
// Validate the object
|
|
46
|
+
const errors = await validate(object, this.getValidationOptions());
|
|
47
|
+
if (errors.length > 0) {
|
|
48
|
+
this.handleValidationErrors(errors);
|
|
49
|
+
// If handleValidationErrors doesn't throw, format and throw
|
|
50
|
+
throw new BadRequestException(this.formatValidationErrors(errors));
|
|
51
|
+
}
|
|
52
|
+
return object;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Determines if the metatype should be validated
|
|
56
|
+
*
|
|
57
|
+
* @param metatype - The type to check
|
|
58
|
+
* @returns boolean - True if validation should be performed
|
|
59
|
+
*/
|
|
60
|
+
shouldValidate(metatype) {
|
|
61
|
+
const types = [String, Boolean, Number, Array, Object];
|
|
62
|
+
return !types.includes(metatype);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Gets validation options for class-validator
|
|
66
|
+
*
|
|
67
|
+
* @returns Validation options
|
|
68
|
+
*/
|
|
69
|
+
getValidationOptions() {
|
|
70
|
+
return {};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Gets transformation options for class-transformer
|
|
74
|
+
*
|
|
75
|
+
* @returns Transformation options
|
|
76
|
+
*/
|
|
77
|
+
getTransformOptions() {
|
|
78
|
+
return {};
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Handles validation errors before formatting
|
|
82
|
+
*
|
|
83
|
+
* Subclasses can override this to add logging, metrics, etc.
|
|
84
|
+
*
|
|
85
|
+
* @param _errors - The validation errors (unused in base implementation)
|
|
86
|
+
*/
|
|
87
|
+
handleValidationErrors(_errors) {
|
|
88
|
+
// Default: no-op, subclasses can add logging/metrics
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
BaseValidationPipe = __decorate([
|
|
92
|
+
Injectable()
|
|
93
|
+
], BaseValidationPipe);
|
|
94
|
+
export { BaseValidationPipe };
|
|
95
|
+
//# sourceMappingURL=base-validation.pipe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-validation.pipe.js","sourceRoot":"","sources":["../../../src/common/pipes/base-validation.pipe.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAEN,UAAU,EAEV,mBAAmB,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAmB,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAyB,MAAM,mBAAmB,CAAC;AAExE;;;;;;;;;;;;;;;;;;GAkBG;AAEI,IAAe,kBAAkB,GAAjC,MAAe,kBAAkB;IACvC;;;;;;OAMG;IACI,KAAK,CAAC,SAAS,CAAC,KAAU,EAAE,QAA0B;QAC5D,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC;QAE9B,sCAAsC;QACtC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjD,OAAO,KAAK,CAAC;QACd,CAAC;QAED,2CAA2C;QAC3C,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC;QAEzE,sBAAsB;QACtB,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,CAAC,CAAC;QAEnE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC;YACpC,4DAA4D;YAC5D,MAAM,IAAI,mBAAmB,CAAC,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,CAAC;QACpE,CAAC;QAED,OAAO,MAAM,CAAC;IACf,CAAC;IAED;;;;;OAKG;IACO,cAAc,CAAC,QAAa;QACrC,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QACvD,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAClC,CAAC;IAED;;;;OAIG;IACO,oBAAoB;QAC7B,OAAO,EAAE,CAAC;IACX,CAAC;IAED;;;;OAIG;IACO,mBAAmB;QAC5B,OAAO,EAAE,CAAC;IACX,CAAC;IAED;;;;;;OAMG;IACO,sBAAsB,CAAC,OAA0B;QAC1D,qDAAqD;IACtD,CAAC;CASD,CAAA;AA9EqB,kBAAkB;IADvC,UAAU,EAAE;GACS,kBAAkB,CA8EvC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ValidationError } from 'class-validator';
|
|
2
|
+
import { BaseValidationPipe } from './base-validation.pipe.js';
|
|
3
|
+
/**
|
|
4
|
+
* HTTP Validation Pipe.
|
|
5
|
+
* Validates incoming HTTP request data using class-validator and transforms using class-transformer.
|
|
6
|
+
* Extends BaseValidationPipe with HTTP-specific error formatting.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* - Automatically applied as a global pipe in CommonModule
|
|
10
|
+
* - Supports nested object validation with path prefixes
|
|
11
|
+
* - Recursively processes validation errors with depth traversal
|
|
12
|
+
* - Formats errors as string array for consistent HTTP responses
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* // Automatically applied globally; decorator is optional
|
|
17
|
+
* @Post()
|
|
18
|
+
* async createUser(@Body() createUserDto: CreateUserDto): Promise<User> {
|
|
19
|
+
* // DTO will be validated automatically
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare class ValidationPipe extends BaseValidationPipe {
|
|
24
|
+
/**
|
|
25
|
+
* Formats validation errors as string array for HTTP responses
|
|
26
|
+
*
|
|
27
|
+
* @param errors - The validation errors
|
|
28
|
+
* @returns string[] - Array of error messages
|
|
29
|
+
*/
|
|
30
|
+
protected formatValidationErrors(errors: ValidationError[]): string[];
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=validation.pipe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.pipe.d.ts","sourceRoot":"","sources":["../../../src/common/pipes/validation.pipe.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBACa,cAAe,SAAQ,kBAAkB;IACrD;;;;;OAKG;IACH,SAAS,CAAC,sBAAsB,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,EAAE;CA2BrE"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
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;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { Injectable } from '@nestjs/common';
|
|
8
|
+
import { BaseValidationPipe } from './base-validation.pipe.js';
|
|
9
|
+
/**
|
|
10
|
+
* HTTP Validation Pipe.
|
|
11
|
+
* Validates incoming HTTP request data using class-validator and transforms using class-transformer.
|
|
12
|
+
* Extends BaseValidationPipe with HTTP-specific error formatting.
|
|
13
|
+
*
|
|
14
|
+
* @remarks
|
|
15
|
+
* - Automatically applied as a global pipe in CommonModule
|
|
16
|
+
* - Supports nested object validation with path prefixes
|
|
17
|
+
* - Recursively processes validation errors with depth traversal
|
|
18
|
+
* - Formats errors as string array for consistent HTTP responses
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* // Automatically applied globally; decorator is optional
|
|
23
|
+
* @Post()
|
|
24
|
+
* async createUser(@Body() createUserDto: CreateUserDto): Promise<User> {
|
|
25
|
+
* // DTO will be validated automatically
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
let ValidationPipe = class ValidationPipe extends BaseValidationPipe {
|
|
30
|
+
/**
|
|
31
|
+
* Formats validation errors as string array for HTTP responses
|
|
32
|
+
*
|
|
33
|
+
* @param errors - The validation errors
|
|
34
|
+
* @returns string[] - Array of error messages
|
|
35
|
+
*/
|
|
36
|
+
formatValidationErrors(errors) {
|
|
37
|
+
const result = [];
|
|
38
|
+
const processError = (error, parentPath = '') => {
|
|
39
|
+
const currentPath = parentPath ? `${parentPath}.${error.property}` : error.property;
|
|
40
|
+
// If error has constraints, add them to result
|
|
41
|
+
if (error.constraints && Object.keys(error.constraints).length > 0) {
|
|
42
|
+
const messages = Object.values(error.constraints).join(', ');
|
|
43
|
+
result.push(`${currentPath}: ${messages}`);
|
|
44
|
+
}
|
|
45
|
+
// If error has children, recurse
|
|
46
|
+
if (error.children && error.children.length > 0) {
|
|
47
|
+
error.children.forEach(childError => processError(childError, currentPath));
|
|
48
|
+
}
|
|
49
|
+
// Skip fields with no constraints and no children — no message to add
|
|
50
|
+
// (do not add empty entries like "email: ")
|
|
51
|
+
};
|
|
52
|
+
errors.forEach(error => processError(error));
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
ValidationPipe = __decorate([
|
|
57
|
+
Injectable()
|
|
58
|
+
], ValidationPipe);
|
|
59
|
+
export { ValidationPipe };
|
|
60
|
+
//# sourceMappingURL=validation.pipe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.pipe.js","sourceRoot":"","sources":["../../../src/common/pipes/validation.pipe.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;GAmBG;AAEI,IAAM,cAAc,GAApB,MAAM,cAAe,SAAQ,kBAAkB;IACrD;;;;;OAKG;IACO,sBAAsB,CAAC,MAAyB;QACzD,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,MAAM,YAAY,GAAG,CAAC,KAAsB,EAAE,aAAqB,EAAE,EAAQ,EAAE;YAC9E,MAAM,WAAW,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC;YAEpF,+CAA+C;YAC/C,IAAI,KAAK,CAAC,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpE,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC7D,MAAM,CAAC,IAAI,CAAC,GAAG,WAAW,KAAK,QAAQ,EAAE,CAAC,CAAC;YAC5C,CAAC;YAED,iCAAiC;YACjC,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACjD,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CACnC,YAAY,CAAC,UAAU,EAAE,WAAW,CAAC,CACrC,CAAC;YACH,CAAC;YAED,sEAAsE;YACtE,4CAA4C;QAC7C,CAAC,CAAC;QAEF,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;QAE7C,OAAO,MAAM,CAAC;IACf,CAAC;CACD,CAAA;AAlCY,cAAc;IAD1B,UAAU,EAAE;GACA,cAAc,CAkC1B"}
|