@tsdevstack/nest-common 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +111 -0
- package/dist/auth/auth-user.interface.d.ts +62 -0
- package/dist/auth/auth.guard.d.ts +181 -0
- package/dist/auth/auth.guard.test.d.ts +1 -0
- package/dist/auth/auth.module.d.ts +45 -0
- package/dist/auth/index.d.ts +17 -0
- package/dist/auth/partner-api.decorator.d.ts +42 -0
- package/dist/auth/partner.decorator.d.ts +60 -0
- package/dist/auth/partner.decorator.test.d.ts +1 -0
- package/dist/auth/public.decorator.d.ts +42 -0
- package/dist/auth/public.decorator.test.d.ts +1 -0
- package/dist/auth/utils/extract-user-from-headers.d.ts +45 -0
- package/dist/auth/utils/extract-user-from-headers.test.d.ts +1 -0
- package/dist/auth/utils/index.d.ts +8 -0
- package/dist/auth/utils/parse-header-value.d.ts +40 -0
- package/dist/auth/utils/parse-header-value.test.d.ts +1 -0
- package/dist/auth/utils/to-camel-case.d.ts +18 -0
- package/dist/auth/utils/to-camel-case.test.d.ts +1 -0
- package/dist/bootstrap/create-app.d.ts +31 -0
- package/dist/bootstrap/create-app.test.d.ts +1 -0
- package/dist/bootstrap/start-worker.d.ts +24 -0
- package/dist/bootstrap/start-worker.test.d.ts +1 -0
- package/dist/bull/bull-config.module.d.ts +22 -0
- package/dist/bull/bull-config.module.test.d.ts +1 -0
- package/dist/bull/index.d.ts +1 -0
- package/dist/config/load-framework-config.d.ts +32 -0
- package/dist/config/load-framework-config.test.d.ts +1 -0
- package/dist/database/prisma-connection.d.ts +48 -0
- package/dist/database/prisma-connection.test.d.ts +1 -0
- package/dist/email-rate-limit/email-rate-limit.decorator.d.ts +8 -0
- package/dist/email-rate-limit/email-rate-limit.decorator.test.d.ts +1 -0
- package/dist/email-rate-limit/email-rate-limit.guard.d.ts +11 -0
- package/dist/email-rate-limit/email-rate-limit.guard.test.d.ts +1 -0
- package/dist/email-rate-limit/email-rate-limit.module.d.ts +2 -0
- package/dist/health/health.controller.d.ts +11 -0
- package/dist/health/health.controller.test.d.ts +1 -0
- package/dist/health/health.interface.d.ts +31 -0
- package/dist/health/health.module.d.ts +5 -0
- package/dist/health/health.service.d.ts +12 -0
- package/dist/health/health.service.test.d.ts +1 -0
- package/dist/health/index.d.ts +6 -0
- package/dist/health/indicators/memory.indicator.d.ts +7 -0
- package/dist/health/indicators/memory.indicator.test.d.ts +1 -0
- package/dist/health/indicators/redis.indicator.d.ts +7 -0
- package/dist/health/indicators/redis.indicator.test.d.ts +1 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.js +9 -0
- package/dist/index.mjs +9 -0
- package/dist/logging/index.d.ts +6 -0
- package/dist/logging/logger.interface.d.ts +29 -0
- package/dist/logging/logger.module.d.ts +14 -0
- package/dist/logging/logger.service.d.ts +31 -0
- package/dist/logging/logger.service.test.d.ts +1 -0
- package/dist/logging/logging.interceptor.d.ts +8 -0
- package/dist/logging/logging.interceptor.test.d.ts +1 -0
- package/dist/metrics/index.d.ts +5 -0
- package/dist/metrics/metrics.controller.d.ts +7 -0
- package/dist/metrics/metrics.controller.test.d.ts +1 -0
- package/dist/metrics/metrics.interceptor.d.ts +9 -0
- package/dist/metrics/metrics.interceptor.test.d.ts +1 -0
- package/dist/metrics/metrics.interface.d.ts +17 -0
- package/dist/metrics/metrics.module.d.ts +5 -0
- package/dist/metrics/metrics.service.d.ts +79 -0
- package/dist/metrics/metrics.service.test.d.ts +1 -0
- package/dist/notifications/index.d.ts +15 -0
- package/dist/notifications/interfaces/email-options.interface.d.ts +23 -0
- package/dist/notifications/interfaces/index.d.ts +6 -0
- package/dist/notifications/interfaces/push-options.interface.d.ts +16 -0
- package/dist/notifications/interfaces/sms-options.interface.d.ts +12 -0
- package/dist/notifications/notification.module.d.ts +2 -0
- package/dist/notifications/notification.module.test.d.ts +1 -0
- package/dist/notifications/notification.service.d.ts +28 -0
- package/dist/notifications/notification.service.test.d.ts +1 -0
- package/dist/notifications/providers/email/console.provider.d.ts +9 -0
- package/dist/notifications/providers/email/console.provider.test.d.ts +1 -0
- package/dist/notifications/providers/email/resend.provider.d.ts +24 -0
- package/dist/notifications/providers/email/resend.provider.test.d.ts +1 -0
- package/dist/notifications/providers/email-provider.interface.d.ts +17 -0
- package/dist/observability/index.d.ts +2 -0
- package/dist/observability/observability.interface.d.ts +32 -0
- package/dist/observability/observability.module.d.ts +24 -0
- package/dist/observability/observability.module.test.d.ts +1 -0
- package/dist/open-api-docs/create-swagger-document.d.ts +10 -0
- package/dist/open-api-docs/create-swagger-document.test.d.ts +1 -0
- package/dist/open-api-docs/generate-swagger-docs.d.ts +12 -0
- package/dist/open-api-docs/generate-swagger-docs.test.d.ts +1 -0
- package/dist/rate-limit/rate-limit-headers.interceptor.d.ts +5 -0
- package/dist/rate-limit/rate-limit-headers.interceptor.test.d.ts +1 -0
- package/dist/rate-limit/rate-limit.decorator.d.ts +11 -0
- package/dist/rate-limit/rate-limit.decorator.test.d.ts +1 -0
- package/dist/rate-limit/rate-limit.guard.d.ts +13 -0
- package/dist/rate-limit/rate-limit.guard.test.d.ts +1 -0
- package/dist/rate-limit/rate-limit.module.d.ts +2 -0
- package/dist/redis/redis.module.d.ts +2 -0
- package/dist/redis/redis.service.d.ts +17 -0
- package/dist/redis/redis.service.test.d.ts +1 -0
- package/dist/scheduler/index.d.ts +1 -0
- package/dist/scheduler/scheduler.guard.d.ts +73 -0
- package/dist/scheduler/scheduler.guard.test.d.ts +1 -0
- package/dist/secrets/index.d.ts +10 -0
- package/dist/secrets/providers/aws.provider.d.ts +56 -0
- package/dist/secrets/providers/aws.provider.test.d.ts +1 -0
- package/dist/secrets/providers/azure.provider.d.ts +70 -0
- package/dist/secrets/providers/azure.provider.test.d.ts +1 -0
- package/dist/secrets/providers/cloud-provider-adapter.d.ts +50 -0
- package/dist/secrets/providers/cloud-provider-adapter.test.d.ts +1 -0
- package/dist/secrets/providers/cloud-provider.interface.d.ts +86 -0
- package/dist/secrets/providers/gcp.provider.d.ts +64 -0
- package/dist/secrets/providers/gcp.provider.test.d.ts +1 -0
- package/dist/secrets/providers/local.provider.d.ts +82 -0
- package/dist/secrets/providers/local.provider.test.d.ts +1 -0
- package/dist/secrets/providers/provider-factory.d.ts +39 -0
- package/dist/secrets/providers/provider-factory.test.d.ts +1 -0
- package/dist/secrets/secrets.interface.d.ts +93 -0
- package/dist/secrets/secrets.module.d.ts +24 -0
- package/dist/secrets/secrets.service.d.ts +70 -0
- package/dist/secrets/secrets.service.test.d.ts +1 -0
- package/dist/service-client/base-service-client.d.ts +113 -0
- package/dist/service-client/base-service-client.test.d.ts +1 -0
- package/dist/service-client/filter-forward-headers.d.ts +11 -0
- package/dist/service-client/filter-forward-headers.test.d.ts +1 -0
- package/dist/telemetry/index.d.ts +4 -0
- package/dist/telemetry/telemetry.interface.d.ts +33 -0
- package/dist/telemetry/telemetry.module.d.ts +5 -0
- package/dist/telemetry/telemetry.service.d.ts +39 -0
- package/dist/telemetry/telemetry.service.test.d.ts +1 -0
- package/dist/telemetry/tracing.interceptor.d.ts +11 -0
- package/dist/telemetry/tracing.interceptor.test.d.ts +1 -0
- package/dist/utils/package-json.d.ts +25 -0
- package/package.json +102 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { OnModuleInit } from '@nestjs/common';
|
|
2
|
+
import { type Counter, type Histogram, type UpDownCounter, type Meter } from '@opentelemetry/api';
|
|
3
|
+
import { TelemetryService } from '../telemetry/telemetry.service';
|
|
4
|
+
import type { MetricsModuleOptions } from './metrics.interface';
|
|
5
|
+
export declare class MetricsService implements OnModuleInit {
|
|
6
|
+
private readonly telemetryService?;
|
|
7
|
+
private meter;
|
|
8
|
+
private prefix;
|
|
9
|
+
private _httpRequestDuration;
|
|
10
|
+
private _httpRequestTotal;
|
|
11
|
+
private _httpActiveConnections;
|
|
12
|
+
constructor(options: MetricsModuleOptions, telemetryService?: TelemetryService | undefined);
|
|
13
|
+
onModuleInit(): void;
|
|
14
|
+
/**
|
|
15
|
+
* Record HTTP request duration
|
|
16
|
+
*/
|
|
17
|
+
recordHttpRequestDuration(labels: {
|
|
18
|
+
method: string;
|
|
19
|
+
route: string;
|
|
20
|
+
status_code: string;
|
|
21
|
+
}, duration: number): void;
|
|
22
|
+
/**
|
|
23
|
+
* Increment HTTP request total
|
|
24
|
+
*/
|
|
25
|
+
incrementHttpRequestTotal(labels: {
|
|
26
|
+
method: string;
|
|
27
|
+
route: string;
|
|
28
|
+
status_code: string;
|
|
29
|
+
}): void;
|
|
30
|
+
/**
|
|
31
|
+
* Increment active connections
|
|
32
|
+
*/
|
|
33
|
+
incrementActiveConnections(): void;
|
|
34
|
+
/**
|
|
35
|
+
* Decrement active connections
|
|
36
|
+
*/
|
|
37
|
+
decrementActiveConnections(): void;
|
|
38
|
+
/**
|
|
39
|
+
* Get the meter for creating custom metrics
|
|
40
|
+
*/
|
|
41
|
+
getMeter(): Meter | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Create a custom counter
|
|
44
|
+
*/
|
|
45
|
+
createCounter(name: string, options?: {
|
|
46
|
+
description?: string;
|
|
47
|
+
unit?: string;
|
|
48
|
+
}): Counter | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Create a custom histogram
|
|
51
|
+
*/
|
|
52
|
+
createHistogram(name: string, options?: {
|
|
53
|
+
description?: string;
|
|
54
|
+
unit?: string;
|
|
55
|
+
}): Histogram | undefined;
|
|
56
|
+
/**
|
|
57
|
+
* Create a custom up/down counter (for gauge-like metrics)
|
|
58
|
+
*/
|
|
59
|
+
createUpDownCounter(name: string, options?: {
|
|
60
|
+
description?: string;
|
|
61
|
+
unit?: string;
|
|
62
|
+
}): UpDownCounter | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* Get metrics in Prometheus format (delegated to TelemetryService)
|
|
65
|
+
*/
|
|
66
|
+
getMetrics(): Promise<string>;
|
|
67
|
+
/**
|
|
68
|
+
* Collect metrics in Prometheus format
|
|
69
|
+
*/
|
|
70
|
+
private collectMetrics;
|
|
71
|
+
/**
|
|
72
|
+
* Get content type for Prometheus metrics
|
|
73
|
+
*/
|
|
74
|
+
getContentType(): string;
|
|
75
|
+
/**
|
|
76
|
+
* Get the TelemetryService (for controller access to exporter)
|
|
77
|
+
*/
|
|
78
|
+
getTelemetryService(): TelemetryService | undefined;
|
|
79
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Notifications Module
|
|
3
|
+
*
|
|
4
|
+
* Provides email (and future SMS/push) notification capabilities.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
export { NotificationModule } from './notification.module';
|
|
9
|
+
export { NotificationService, EMAIL_PROVIDER } from './notification.service';
|
|
10
|
+
export type { EmailOptions } from './interfaces/email-options.interface';
|
|
11
|
+
export type { SMSOptions } from './interfaces/sms-options.interface';
|
|
12
|
+
export type { PushOptions } from './interfaces/push-options.interface';
|
|
13
|
+
export type { EmailProvider } from './providers/email-provider.interface';
|
|
14
|
+
export { ConsoleEmailProvider } from './providers/email/console.provider';
|
|
15
|
+
export { ResendEmailProvider } from './providers/email/resend.provider';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Email Options Interface
|
|
3
|
+
*
|
|
4
|
+
* Options for sending an email via NotificationService.sendEmail()
|
|
5
|
+
*/
|
|
6
|
+
export interface EmailOptions {
|
|
7
|
+
/** Recipient email address(es) */
|
|
8
|
+
to: string | string[];
|
|
9
|
+
/** Email subject line */
|
|
10
|
+
subject: string;
|
|
11
|
+
/** HTML content of the email */
|
|
12
|
+
html?: string;
|
|
13
|
+
/** Plain text content (fallback if html not provided) */
|
|
14
|
+
text?: string;
|
|
15
|
+
/** Template name (for future template support) */
|
|
16
|
+
template?: string;
|
|
17
|
+
/** Data to pass to template (for future template support) */
|
|
18
|
+
data?: Record<string, unknown>;
|
|
19
|
+
/** From address (overrides default) */
|
|
20
|
+
from?: string;
|
|
21
|
+
/** Reply-to address */
|
|
22
|
+
replyTo?: string;
|
|
23
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Push Notification Options Interface (Stub)
|
|
3
|
+
*
|
|
4
|
+
* Options for sending push notifications via NotificationService.sendPush()
|
|
5
|
+
* Note: Push notification support is not implemented in v1.
|
|
6
|
+
*/
|
|
7
|
+
export interface PushOptions {
|
|
8
|
+
/** Device tokens to send notification to */
|
|
9
|
+
tokens: string[];
|
|
10
|
+
/** Notification title */
|
|
11
|
+
title: string;
|
|
12
|
+
/** Notification body */
|
|
13
|
+
body: string;
|
|
14
|
+
/** Additional data payload */
|
|
15
|
+
data?: Record<string, unknown>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMS Options Interface (Stub)
|
|
3
|
+
*
|
|
4
|
+
* Options for sending SMS via NotificationService.sendSMS()
|
|
5
|
+
* Note: SMS support is not implemented in v1.
|
|
6
|
+
*/
|
|
7
|
+
export interface SMSOptions {
|
|
8
|
+
/** Recipient phone number */
|
|
9
|
+
to: string;
|
|
10
|
+
/** Message body */
|
|
11
|
+
body: string;
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import './notification.module';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { EmailOptions } from './interfaces/email-options.interface';
|
|
2
|
+
import type { SMSOptions } from './interfaces/sms-options.interface';
|
|
3
|
+
import type { PushOptions } from './interfaces/push-options.interface';
|
|
4
|
+
import type { EmailProvider } from './providers/email-provider.interface';
|
|
5
|
+
export declare const EMAIL_PROVIDER = "EMAIL_PROVIDER";
|
|
6
|
+
export declare class NotificationService {
|
|
7
|
+
private readonly emailProvider;
|
|
8
|
+
constructor(emailProvider: EmailProvider);
|
|
9
|
+
/**
|
|
10
|
+
* Send an email
|
|
11
|
+
* Uses the configured email provider (Console for local, Resend for cloud)
|
|
12
|
+
*/
|
|
13
|
+
sendEmail(options: EmailOptions): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Send an SMS (not implemented)
|
|
16
|
+
* @throws Error - SMS not implemented in v1
|
|
17
|
+
*/
|
|
18
|
+
sendSMS(_options: SMSOptions): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Send a push notification (not implemented)
|
|
21
|
+
* @throws Error - Push not implemented in v1
|
|
22
|
+
*/
|
|
23
|
+
sendPush(_options: PushOptions): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Get the current email provider name
|
|
26
|
+
*/
|
|
27
|
+
getEmailProviderName(): string;
|
|
28
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { EmailOptions } from '../../interfaces/email-options.interface';
|
|
2
|
+
import type { EmailProvider } from '../email-provider.interface';
|
|
3
|
+
import { LoggerService } from '../../../logging/logger.service';
|
|
4
|
+
export declare class ConsoleEmailProvider implements EmailProvider {
|
|
5
|
+
private readonly logger;
|
|
6
|
+
constructor(logger?: LoggerService);
|
|
7
|
+
send(options: EmailOptions): Promise<void>;
|
|
8
|
+
getName(): string;
|
|
9
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resend Email Provider
|
|
3
|
+
*
|
|
4
|
+
* Sends emails via Resend API.
|
|
5
|
+
* Used for cloud environments (GCP, AWS, Azure).
|
|
6
|
+
*
|
|
7
|
+
* Requires secrets:
|
|
8
|
+
* - RESEND_API_KEY: Your Resend API key
|
|
9
|
+
* - EMAIL_FROM: Default sender address (optional, defaults to onboarding@resend.dev)
|
|
10
|
+
*/
|
|
11
|
+
import { OnModuleInit } from '@nestjs/common';
|
|
12
|
+
import type { EmailOptions } from '../../interfaces/email-options.interface';
|
|
13
|
+
import type { EmailProvider } from '../email-provider.interface';
|
|
14
|
+
import { SecretsService } from '../../../secrets/secrets.service';
|
|
15
|
+
export declare class ResendEmailProvider implements EmailProvider, OnModuleInit {
|
|
16
|
+
private readonly secrets;
|
|
17
|
+
private readonly logger;
|
|
18
|
+
private client;
|
|
19
|
+
private defaultFrom;
|
|
20
|
+
constructor(secrets: SecretsService);
|
|
21
|
+
onModuleInit(): Promise<void>;
|
|
22
|
+
send(options: EmailOptions): Promise<void>;
|
|
23
|
+
getName(): string;
|
|
24
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Email Provider Interface
|
|
3
|
+
*
|
|
4
|
+
* All email providers (Console, Resend) must implement this interface.
|
|
5
|
+
*/
|
|
6
|
+
import type { EmailOptions } from '../interfaces/email-options.interface';
|
|
7
|
+
export interface EmailProvider {
|
|
8
|
+
/**
|
|
9
|
+
* Send an email
|
|
10
|
+
* @param options - Email options (to, subject, html/text, etc.)
|
|
11
|
+
*/
|
|
12
|
+
send(options: EmailOptions): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Get the provider name (for logging/debugging)
|
|
15
|
+
*/
|
|
16
|
+
getName(): string;
|
|
17
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface ObservabilityModuleOptions {
|
|
2
|
+
/**
|
|
3
|
+
* Enable logging
|
|
4
|
+
* Default: true
|
|
5
|
+
*/
|
|
6
|
+
logging?: boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Enable metrics collection
|
|
9
|
+
* Default: true
|
|
10
|
+
*/
|
|
11
|
+
metrics?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Enable distributed tracing
|
|
14
|
+
* Default: true
|
|
15
|
+
*/
|
|
16
|
+
tracing?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Enable health endpoints
|
|
19
|
+
* Default: true
|
|
20
|
+
*/
|
|
21
|
+
health?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* OTLP base endpoint for tracing (Jaeger, OTEL Collector, etc.)
|
|
24
|
+
* Default: OTEL_EXPORTER_OTLP_ENDPOINT env var or 'http://localhost:4318'
|
|
25
|
+
*/
|
|
26
|
+
tracingEndpoint?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Service name for telemetry identification
|
|
29
|
+
* Default: SERVICE_NAME env var
|
|
30
|
+
*/
|
|
31
|
+
serviceName?: string;
|
|
32
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { DynamicModule } from '@nestjs/common';
|
|
2
|
+
import type { ObservabilityModuleOptions } from './observability.interface';
|
|
3
|
+
/**
|
|
4
|
+
* Unified observability module that provides logging, metrics, tracing, and health.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* ```typescript
|
|
8
|
+
* @Module({
|
|
9
|
+
* imports: [ObservabilityModule],
|
|
10
|
+
* })
|
|
11
|
+
* export class AppModule {}
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* Or with options:
|
|
15
|
+
* ```typescript
|
|
16
|
+
* @Module({
|
|
17
|
+
* imports: [ObservabilityModule.forRoot({ tracing: false })],
|
|
18
|
+
* })
|
|
19
|
+
* export class AppModule {}
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare class ObservabilityModule {
|
|
23
|
+
static forRoot(options?: ObservabilityModuleOptions): DynamicModule;
|
|
24
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { INestApplication } from "@nestjs/common";
|
|
2
|
+
import { OpenAPIObject } from "@nestjs/swagger";
|
|
3
|
+
export interface SwaggerConfig {
|
|
4
|
+
title: string;
|
|
5
|
+
description: string;
|
|
6
|
+
version?: string;
|
|
7
|
+
tags?: string[];
|
|
8
|
+
globalPrefix?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function createSwaggerDocument(app: INestApplication, config: SwaggerConfig): OpenAPIObject;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Type } from '@nestjs/common';
|
|
2
|
+
import { OpenAPIObject } from '@nestjs/swagger';
|
|
3
|
+
/**
|
|
4
|
+
* Generate Swagger/OpenAPI documentation
|
|
5
|
+
*
|
|
6
|
+
* Reads service metadata from package.json automatically.
|
|
7
|
+
* No validation is performed - validation happens at dev/build time via CLI.
|
|
8
|
+
*
|
|
9
|
+
* @param AppModule - The NestJS application module
|
|
10
|
+
* @returns OpenAPI document object
|
|
11
|
+
*/
|
|
12
|
+
export declare function generateSwaggerDocs<T>(AppModule: Type<T>): Promise<OpenAPIObject>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
export declare class RateLimitHeadersInterceptor implements NestInterceptor {
|
|
4
|
+
intercept(context: ExecutionContext, next: CallHandler): Observable<unknown>;
|
|
5
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ExecutionContext } from '@nestjs/common';
|
|
2
|
+
export interface RateLimitOptions {
|
|
3
|
+
windowMs?: number;
|
|
4
|
+
maxRequests?: number;
|
|
5
|
+
keyGenerator?: 'ip' | 'apiKey' | 'userId' | 'custom';
|
|
6
|
+
customKeyGenerator?: (context: ExecutionContext) => string;
|
|
7
|
+
skipIf?: (context: ExecutionContext) => boolean;
|
|
8
|
+
message?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare const RATE_LIMIT_KEY = "rateLimit";
|
|
11
|
+
export declare const RateLimitDecorator: (options: RateLimitOptions) => import("@nestjs/common").CustomDecorator<string>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { CanActivate, ExecutionContext } from "@nestjs/common";
|
|
2
|
+
import { Reflector } from "@nestjs/core";
|
|
3
|
+
import { RedisService } from "../redis/redis.service";
|
|
4
|
+
export declare class RateLimitGuard implements CanActivate {
|
|
5
|
+
private readonly redisService;
|
|
6
|
+
private readonly reflector;
|
|
7
|
+
private readonly logger;
|
|
8
|
+
constructor(redisService: RedisService, reflector: Reflector);
|
|
9
|
+
canActivate(context: ExecutionContext): Promise<boolean>;
|
|
10
|
+
private checkRateLimit;
|
|
11
|
+
private generateKey;
|
|
12
|
+
private getClientIp;
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { OnModuleDestroy, OnModuleInit } from '@nestjs/common';
|
|
2
|
+
import Redis from 'ioredis';
|
|
3
|
+
import { SecretsService } from '../secrets/secrets.service';
|
|
4
|
+
export declare class RedisService implements OnModuleInit, OnModuleDestroy {
|
|
5
|
+
private readonly secrets;
|
|
6
|
+
private redis;
|
|
7
|
+
private readonly logger;
|
|
8
|
+
constructor(secrets: SecretsService);
|
|
9
|
+
onModuleInit(): Promise<void>;
|
|
10
|
+
getClient(): Redis;
|
|
11
|
+
get(key: string): Promise<string | null>;
|
|
12
|
+
set(key: string, value: string, ttl?: number): Promise<boolean>;
|
|
13
|
+
incr(key: string): Promise<number | null>;
|
|
14
|
+
expire(key: string, seconds: number): Promise<boolean>;
|
|
15
|
+
del(key: string): Promise<boolean>;
|
|
16
|
+
onModuleDestroy(): void;
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SchedulerGuard } from './scheduler.guard';
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
|
2
|
+
import { SecretsService } from '../secrets/secrets.service';
|
|
3
|
+
/**
|
|
4
|
+
* SchedulerGuard
|
|
5
|
+
*
|
|
6
|
+
* Multi-cloud guard for scheduled job endpoints.
|
|
7
|
+
* Validates that requests come from the cloud scheduler, not external sources.
|
|
8
|
+
*
|
|
9
|
+
* Security model:
|
|
10
|
+
* - GCP: Full OIDC token validation (implemented)
|
|
11
|
+
* - AWS: EventBridge integration (not yet implemented - fails safe)
|
|
12
|
+
* - Azure: Logic Apps integration (not yet implemented - fails safe)
|
|
13
|
+
* - Development/Local: Skips validation for easy local testing
|
|
14
|
+
*
|
|
15
|
+
* Combined with @ApiExcludeController(), provides two-layer security:
|
|
16
|
+
* 1. @ApiExcludeController() keeps routes out of OpenAPI → no Kong route generated
|
|
17
|
+
* 2. SchedulerGuard validates OIDC token if someone hits endpoint directly
|
|
18
|
+
*
|
|
19
|
+
* Usage:
|
|
20
|
+
* ```typescript
|
|
21
|
+
* @ApiExcludeController() // Layer 1: Exclude from Kong
|
|
22
|
+
* @Controller('jobs')
|
|
23
|
+
* export class JobsController {
|
|
24
|
+
* @Post('cleanup-tokens')
|
|
25
|
+
* @UseGuards(SchedulerGuard) // Layer 2: Validate scheduler token
|
|
26
|
+
* async cleanupTokens() {
|
|
27
|
+
* // Only accessible from Cloud Scheduler
|
|
28
|
+
* }
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* Local testing:
|
|
33
|
+
* ```bash
|
|
34
|
+
* # SECRETS_PROVIDER=local skips validation
|
|
35
|
+
* curl -X POST http://localhost:3001/jobs/cleanup-tokens
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare class SchedulerGuard implements CanActivate {
|
|
39
|
+
private readonly secrets;
|
|
40
|
+
private readonly logger;
|
|
41
|
+
private readonly oauth2Client;
|
|
42
|
+
constructor(secrets: SecretsService);
|
|
43
|
+
canActivate(context: ExecutionContext): Promise<boolean>;
|
|
44
|
+
/**
|
|
45
|
+
* Validates AWS EventBridge job invocation via shared secret.
|
|
46
|
+
*
|
|
47
|
+
* AWS EventBridge cannot make authenticated HTTP calls directly, so we use
|
|
48
|
+
* a Job Invoker Lambda that adds the X-Job-Secret header from Secrets Manager.
|
|
49
|
+
* This validates that header matches the expected secret.
|
|
50
|
+
*
|
|
51
|
+
* @param request - HTTP request with X-Job-Secret header
|
|
52
|
+
* @returns true if secret matches, false otherwise
|
|
53
|
+
*/
|
|
54
|
+
private validateAwsJobSecret;
|
|
55
|
+
/**
|
|
56
|
+
* Validates Azure Container App Job invocation via shared secret.
|
|
57
|
+
*
|
|
58
|
+
* Azure Container App Jobs inject the JOB_SECRET env var from Terraform.
|
|
59
|
+
* The job's curl command sends it as X-Job-Secret header.
|
|
60
|
+
* This validates that header matches the expected secret from Key Vault.
|
|
61
|
+
*/
|
|
62
|
+
private validateAzureJobSecret;
|
|
63
|
+
/**
|
|
64
|
+
* Validates GCP Cloud Scheduler OIDC token.
|
|
65
|
+
*
|
|
66
|
+
* Cloud Scheduler sends requests with an OIDC token in the Authorization header.
|
|
67
|
+
* We verify the token was issued by Google for our service URL.
|
|
68
|
+
*
|
|
69
|
+
* @param request - HTTP request with Authorization header
|
|
70
|
+
* @returns true if token is valid, false otherwise
|
|
71
|
+
*/
|
|
72
|
+
private validateGcpOidc;
|
|
73
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secrets Management Module
|
|
3
|
+
*
|
|
4
|
+
* Provides unified secrets management across local development and cloud environments.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
export * from './secrets.interface';
|
|
9
|
+
export * from './secrets.service';
|
|
10
|
+
export * from './providers/local.provider';
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { CloudSecretsProvider, CloudProviderConfig } from './cloud-provider.interface';
|
|
2
|
+
export declare class AWSSecretsProvider implements CloudSecretsProvider {
|
|
3
|
+
private client;
|
|
4
|
+
private projectName;
|
|
5
|
+
private serviceName;
|
|
6
|
+
private region;
|
|
7
|
+
private cache;
|
|
8
|
+
private readonly CACHE_TTL_MS;
|
|
9
|
+
constructor(config: CloudProviderConfig);
|
|
10
|
+
/**
|
|
11
|
+
* Get secret with service-scoped → shared fallback and caching
|
|
12
|
+
*/
|
|
13
|
+
get(key: string): Promise<string | null>;
|
|
14
|
+
/**
|
|
15
|
+
* Set a secret with optional metadata tags
|
|
16
|
+
*/
|
|
17
|
+
set(key: string, value: string, metadata?: Record<string, string>): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Remove a secret
|
|
20
|
+
*/
|
|
21
|
+
remove(key: string): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* List all secrets for this service (both service-scoped and shared)
|
|
24
|
+
*/
|
|
25
|
+
list(): Promise<string[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Check if a secret exists (checks both service-scoped and shared)
|
|
28
|
+
*/
|
|
29
|
+
exists(key: string): Promise<boolean>;
|
|
30
|
+
getProviderName(): string;
|
|
31
|
+
/**
|
|
32
|
+
* Build secret name following convention: {projectName}-{scope}-{KEY}
|
|
33
|
+
*/
|
|
34
|
+
private buildSecretName;
|
|
35
|
+
/**
|
|
36
|
+
* Extract key from secret name
|
|
37
|
+
* Input: "tsdevstack-auth-service-DATABASE_URL" or "tsdevstack-shared-DATABASE_URL"
|
|
38
|
+
* Output: "DATABASE_URL"
|
|
39
|
+
*/
|
|
40
|
+
private extractKeyFromSecretName;
|
|
41
|
+
/**
|
|
42
|
+
* Fetch secret value from AWS
|
|
43
|
+
*/
|
|
44
|
+
private fetchSecretFromAWS;
|
|
45
|
+
/**
|
|
46
|
+
* Build AWS tags from metadata
|
|
47
|
+
* AWS supports up to 50 tags per secret
|
|
48
|
+
*/
|
|
49
|
+
private buildTags;
|
|
50
|
+
/**
|
|
51
|
+
* Cache management methods
|
|
52
|
+
*/
|
|
53
|
+
private getFromCache;
|
|
54
|
+
private setCache;
|
|
55
|
+
private invalidateCache;
|
|
56
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { CloudSecretsProvider, CloudProviderConfig } from './cloud-provider.interface';
|
|
2
|
+
export declare class AzureSecretsProvider implements CloudSecretsProvider {
|
|
3
|
+
private client;
|
|
4
|
+
private projectName;
|
|
5
|
+
private serviceName;
|
|
6
|
+
private keyVaultName;
|
|
7
|
+
private cache;
|
|
8
|
+
private readonly CACHE_TTL_MS;
|
|
9
|
+
constructor(config: CloudProviderConfig);
|
|
10
|
+
/**
|
|
11
|
+
* Get secret with service-scoped → shared fallback and caching
|
|
12
|
+
*/
|
|
13
|
+
get(key: string): Promise<string | null>;
|
|
14
|
+
/**
|
|
15
|
+
* Set a secret with optional metadata tags
|
|
16
|
+
*/
|
|
17
|
+
set(key: string, value: string, metadata?: Record<string, string>): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Remove a secret
|
|
20
|
+
* Note: Azure soft-deletes secrets by default (recoverable for 90 days)
|
|
21
|
+
*/
|
|
22
|
+
remove(key: string): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* List all secrets for this service (both service-scoped and shared)
|
|
25
|
+
*/
|
|
26
|
+
list(): Promise<string[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Check if a secret exists (checks both service-scoped and shared)
|
|
29
|
+
*/
|
|
30
|
+
exists(key: string): Promise<boolean>;
|
|
31
|
+
getProviderName(): string;
|
|
32
|
+
/**
|
|
33
|
+
* Build secret name following convention: {projectName}-{scope}-{KEY}
|
|
34
|
+
* Azure Key Vault only allows alphanumeric and hyphens
|
|
35
|
+
* Transform underscores to hyphens: DATABASE_URL → DATABASE-URL
|
|
36
|
+
*/
|
|
37
|
+
private buildSecretName;
|
|
38
|
+
/**
|
|
39
|
+
* Extract key from secret name and reverse transform
|
|
40
|
+
* Input: "tsdevstack-auth-service-DATABASE-URL" or "tsdevstack-shared-DATABASE-URL"
|
|
41
|
+
* Output: "DATABASE_URL"
|
|
42
|
+
*/
|
|
43
|
+
private extractKeyFromSecretName;
|
|
44
|
+
/**
|
|
45
|
+
* Fetch secret value from Azure
|
|
46
|
+
*/
|
|
47
|
+
private fetchSecretFromAzure;
|
|
48
|
+
/**
|
|
49
|
+
* Build Azure tags from metadata
|
|
50
|
+
* Azure supports up to 15 tags per secret
|
|
51
|
+
*/
|
|
52
|
+
private buildTags;
|
|
53
|
+
/**
|
|
54
|
+
* Transform key to Azure-compatible format
|
|
55
|
+
* Azure Key Vault only allows alphanumeric and hyphens
|
|
56
|
+
* DATABASE_URL → DATABASE-URL
|
|
57
|
+
*/
|
|
58
|
+
private transformKey;
|
|
59
|
+
/**
|
|
60
|
+
* Reverse transform Azure key back to standard format
|
|
61
|
+
* DATABASE-URL → DATABASE_URL
|
|
62
|
+
*/
|
|
63
|
+
private reverseTransformKey;
|
|
64
|
+
/**
|
|
65
|
+
* Cache management methods
|
|
66
|
+
*/
|
|
67
|
+
private getFromCache;
|
|
68
|
+
private setCache;
|
|
69
|
+
private invalidateCache;
|
|
70
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|