@pipeline-builder/pipeline-core 3.1.1
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 +202 -0
- package/README.md +32 -0
- package/lib/config/app-config.d.ts +81 -0
- package/lib/config/app-config.js +151 -0
- package/lib/config/billing-config.d.ts +17 -0
- package/lib/config/billing-config.js +95 -0
- package/lib/config/config-types.d.ts +213 -0
- package/lib/config/config-types.js +5 -0
- package/lib/config/infrastructure-config.d.ts +55 -0
- package/lib/config/infrastructure-config.js +200 -0
- package/lib/config/server-config.d.ts +53 -0
- package/lib/config/server-config.js +180 -0
- package/lib/core/artifact-manager.d.ts +62 -0
- package/lib/core/artifact-manager.js +86 -0
- package/lib/core/id-generator.d.ts +26 -0
- package/lib/core/id-generator.js +44 -0
- package/lib/core/metadata-builder.d.ts +13 -0
- package/lib/core/metadata-builder.js +81 -0
- package/lib/core/network-types.d.ts +200 -0
- package/lib/core/network-types.js +5 -0
- package/lib/core/network.d.ts +20 -0
- package/lib/core/network.js +84 -0
- package/lib/core/pipeline-helpers.d.ts +53 -0
- package/lib/core/pipeline-helpers.js +273 -0
- package/lib/core/pipeline-types.d.ts +136 -0
- package/lib/core/pipeline-types.js +140 -0
- package/lib/core/role-types.d.ts +254 -0
- package/lib/core/role-types.js +5 -0
- package/lib/core/role.d.ts +14 -0
- package/lib/core/role.js +118 -0
- package/lib/core/security-group-types.d.ts +84 -0
- package/lib/core/security-group-types.js +5 -0
- package/lib/core/security-group.d.ts +14 -0
- package/lib/core/security-group.js +34 -0
- package/lib/handlers/plugin-lookup-handler.d.ts +32 -0
- package/lib/handlers/plugin-lookup-handler.js +313 -0
- package/lib/handlers/pnpm-lock.yaml +12 -0
- package/lib/index.d.ts +54 -0
- package/lib/index.js +112 -0
- package/lib/pipeline/pipeline-builder.d.ts +82 -0
- package/lib/pipeline/pipeline-builder.js +292 -0
- package/lib/pipeline/pipeline-configuration.d.ts +72 -0
- package/lib/pipeline/pipeline-configuration.js +196 -0
- package/lib/pipeline/plugin-lookup.d.ts +100 -0
- package/lib/pipeline/plugin-lookup.js +247 -0
- package/lib/pipeline/source-builder.d.ts +47 -0
- package/lib/pipeline/source-builder.js +111 -0
- package/lib/pipeline/source-types.d.ts +191 -0
- package/lib/pipeline/source-types.js +5 -0
- package/lib/pipeline/stage-builder.d.ts +71 -0
- package/lib/pipeline/stage-builder.js +118 -0
- package/lib/pipeline/step-types.d.ts +307 -0
- package/lib/pipeline/step-types.js +5 -0
- package/package.json +137 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import type { QuotaTier } from '@pipeline-builder/api-core';
|
|
2
|
+
import type { Duration, RemovalPolicy } from 'aws-cdk-lib';
|
|
3
|
+
import type { ComputeType } from 'aws-cdk-lib/aws-codebuild';
|
|
4
|
+
import type { Architecture, Runtime } from 'aws-cdk-lib/aws-lambda';
|
|
5
|
+
import type { RetentionDays } from 'aws-cdk-lib/aws-logs';
|
|
6
|
+
import type { Algorithm } from 'jsonwebtoken';
|
|
7
|
+
/**
|
|
8
|
+
* Type-safe configuration interface
|
|
9
|
+
*/
|
|
10
|
+
export interface AppConfig {
|
|
11
|
+
readonly server: ServerConfig;
|
|
12
|
+
readonly auth: AuthConfig;
|
|
13
|
+
readonly database: DatabaseConfig;
|
|
14
|
+
readonly registry: RegistryConfig;
|
|
15
|
+
readonly redis: RedisConfig;
|
|
16
|
+
readonly pluginBuild: PluginBuildConfig;
|
|
17
|
+
readonly dockerConfig: BuildConfig;
|
|
18
|
+
readonly observability: ObservabilityConfig;
|
|
19
|
+
readonly compliance: ComplianceConfig;
|
|
20
|
+
readonly aws: AWSConfig;
|
|
21
|
+
readonly rateLimit: RateLimitConfig;
|
|
22
|
+
readonly billing: BillingConfig;
|
|
23
|
+
}
|
|
24
|
+
/** Express server configuration. */
|
|
25
|
+
export interface ServerConfig {
|
|
26
|
+
/** HTTP listen port (env: `PORT`). */
|
|
27
|
+
readonly port: number;
|
|
28
|
+
readonly cors: {
|
|
29
|
+
/** Whether to include credentials in CORS responses (env: `CORS_CREDENTIALS`). */
|
|
30
|
+
readonly credentials: boolean;
|
|
31
|
+
/** Allowed origin(s) — single string, array, or `'*'` (env: `CORS_ORIGIN`). */
|
|
32
|
+
readonly origin: string | string[];
|
|
33
|
+
};
|
|
34
|
+
/** Number of reverse proxy hops to trust (env: `TRUST_PROXY`). */
|
|
35
|
+
readonly trustProxy: number;
|
|
36
|
+
/** Frontend base URL, used as CORS fallback (env: `PLATFORM_BASE_URL`). */
|
|
37
|
+
readonly platformUrl: string;
|
|
38
|
+
readonly httpClient: {
|
|
39
|
+
/** Default HTTP request timeout in ms (env: `HTTP_CLIENT_TIMEOUT`). */
|
|
40
|
+
readonly timeout: number;
|
|
41
|
+
/** Maximum retry attempts for failed requests (env: `HTTP_CLIENT_MAX_RETRIES`). */
|
|
42
|
+
readonly maxRetries: number;
|
|
43
|
+
/** Base delay between retries in ms (env: `HTTP_CLIENT_RETRY_DELAY_MS`). */
|
|
44
|
+
readonly retryDelayMs: number;
|
|
45
|
+
};
|
|
46
|
+
readonly sse: {
|
|
47
|
+
/** Max SSE clients per request (env: `SSE_MAX_CLIENTS_PER_REQUEST`). */
|
|
48
|
+
readonly maxClientsPerRequest: number;
|
|
49
|
+
/** SSE client timeout in ms (env: `SSE_CLIENT_TIMEOUT_MS`). */
|
|
50
|
+
readonly clientTimeoutMs: number;
|
|
51
|
+
/** SSE cleanup interval in ms (env: `SSE_CLEANUP_INTERVAL_MS`). */
|
|
52
|
+
readonly cleanupIntervalMs: number;
|
|
53
|
+
};
|
|
54
|
+
readonly services: {
|
|
55
|
+
readonly pluginHost: string;
|
|
56
|
+
readonly pluginPort: number;
|
|
57
|
+
readonly pipelineHost: string;
|
|
58
|
+
readonly pipelinePort: number;
|
|
59
|
+
readonly messageHost: string;
|
|
60
|
+
readonly messagePort: number;
|
|
61
|
+
readonly complianceHost: string;
|
|
62
|
+
readonly compliancePort: number;
|
|
63
|
+
readonly billingHost: string;
|
|
64
|
+
readonly billingPort: number;
|
|
65
|
+
readonly billingTimeout: number;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/** JWT and refresh token authentication configuration. */
|
|
69
|
+
export interface AuthConfig {
|
|
70
|
+
readonly jwt: {
|
|
71
|
+
/** Signing secret for access tokens (env: `JWT_SECRET`). */
|
|
72
|
+
readonly secret: string;
|
|
73
|
+
/** Token lifetime in seconds (env: `JWT_EXPIRES_IN`). */
|
|
74
|
+
readonly expiresIn: number;
|
|
75
|
+
/** Signing algorithm, e.g. `'HS256'` (env: `JWT_ALGORITHM`). */
|
|
76
|
+
readonly algorithm: Algorithm;
|
|
77
|
+
/** bcrypt salt rounds for password hashing (env: `JWT_SALT_ROUNDS`). */
|
|
78
|
+
readonly saltRounds: number;
|
|
79
|
+
};
|
|
80
|
+
readonly refreshToken: {
|
|
81
|
+
/** Signing secret for refresh tokens (env: `REFRESH_TOKEN_SECRET`). */
|
|
82
|
+
readonly secret: string;
|
|
83
|
+
/** Token lifetime in seconds (env: `REFRESH_TOKEN_EXPIRES_IN`). */
|
|
84
|
+
readonly expiresIn: number;
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/** PostgreSQL and Drizzle ORM database configuration. */
|
|
88
|
+
export interface DatabaseConfig {
|
|
89
|
+
readonly postgres: {
|
|
90
|
+
/** PostgreSQL host (env: `DB_HOST`). */
|
|
91
|
+
readonly host: string;
|
|
92
|
+
/** PostgreSQL port (env: `DB_PORT`). */
|
|
93
|
+
readonly port: number;
|
|
94
|
+
/** Database name (env: `DATABASE`). */
|
|
95
|
+
readonly database: string;
|
|
96
|
+
/** Database user (env: `DB_USER`). */
|
|
97
|
+
readonly user: string;
|
|
98
|
+
/** Database password (env: `DB_PASSWORD`). */
|
|
99
|
+
readonly password: string;
|
|
100
|
+
};
|
|
101
|
+
readonly drizzle: {
|
|
102
|
+
/** Maximum connection pool size (env: `DRIZZLE_MAX_POOL_SIZE`). */
|
|
103
|
+
readonly maxPoolSize: number;
|
|
104
|
+
/** Idle connection timeout in ms (env: `DRIZZLE_IDLE_TIMEOUT_MILLIS`). */
|
|
105
|
+
readonly idleTimeoutMillis: number;
|
|
106
|
+
/** New connection timeout in ms (env: `DRIZZLE_CONNECTION_TIMEOUT_MILLIS`). */
|
|
107
|
+
readonly connectionTimeoutMillis: number;
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
export interface RegistryConfig {
|
|
111
|
+
readonly host: string;
|
|
112
|
+
readonly port: number;
|
|
113
|
+
readonly user: string;
|
|
114
|
+
readonly token: string;
|
|
115
|
+
/** Docker network for build/push (empty string = default). */
|
|
116
|
+
readonly network: string;
|
|
117
|
+
/** Use plain HTTP instead of HTTPS (env: `DOCKER_REGISTRY_HTTP`). Defaults to true. */
|
|
118
|
+
readonly http: boolean;
|
|
119
|
+
/** Skip TLS certificate verification for self-signed certs (env: `DOCKER_REGISTRY_INSECURE`). Defaults to true. */
|
|
120
|
+
readonly insecure: boolean;
|
|
121
|
+
}
|
|
122
|
+
export interface RedisConfig {
|
|
123
|
+
readonly host: string;
|
|
124
|
+
readonly port: number;
|
|
125
|
+
}
|
|
126
|
+
export interface PluginBuildConfig {
|
|
127
|
+
readonly concurrency: number;
|
|
128
|
+
readonly maxAttempts: number;
|
|
129
|
+
readonly backoffDelayMs: number;
|
|
130
|
+
readonly workerTimeoutMs: number;
|
|
131
|
+
readonly tempDirMaxAgeMs: number;
|
|
132
|
+
readonly dlqMaxAttempts: number;
|
|
133
|
+
readonly dlqBackoffBaseMs: number;
|
|
134
|
+
readonly dlqMaxSize: number;
|
|
135
|
+
}
|
|
136
|
+
export interface BuildConfig {
|
|
137
|
+
/** Build strategy: 'podman' (default), 'docker', or 'kaniko'. */
|
|
138
|
+
readonly strategy: 'docker' | 'kaniko' | 'podman';
|
|
139
|
+
/** Root directory for build temp files. */
|
|
140
|
+
readonly tempRoot: string;
|
|
141
|
+
/** Build timeout in milliseconds. */
|
|
142
|
+
readonly timeoutMs: number;
|
|
143
|
+
/** Push timeout in milliseconds. */
|
|
144
|
+
readonly pushTimeoutMs: number;
|
|
145
|
+
/** Path to Kaniko executor binary (only used when strategy=kaniko). */
|
|
146
|
+
readonly kanikoExecutor: string;
|
|
147
|
+
/** Kaniko layer cache directory (only used when strategy=kaniko). */
|
|
148
|
+
readonly kanikoCacheDir: string;
|
|
149
|
+
}
|
|
150
|
+
export interface ObservabilityConfig {
|
|
151
|
+
readonly logLevel: string;
|
|
152
|
+
readonly logFormat: string;
|
|
153
|
+
readonly serviceName: string;
|
|
154
|
+
readonly tracing: {
|
|
155
|
+
readonly enabled: boolean;
|
|
156
|
+
readonly endpoint: string;
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
export interface ComplianceConfig {
|
|
160
|
+
readonly scanSchedulerIntervalMs: number;
|
|
161
|
+
}
|
|
162
|
+
export interface AWSConfig {
|
|
163
|
+
readonly lambda: {
|
|
164
|
+
readonly runtime: Runtime;
|
|
165
|
+
readonly timeout: Duration;
|
|
166
|
+
readonly memorySize: number;
|
|
167
|
+
readonly architecture: Architecture;
|
|
168
|
+
readonly reservedConcurrentExecutions?: number;
|
|
169
|
+
};
|
|
170
|
+
readonly logging: {
|
|
171
|
+
readonly groupName: string;
|
|
172
|
+
readonly retention: RetentionDays;
|
|
173
|
+
readonly removalPolicy: RemovalPolicy;
|
|
174
|
+
};
|
|
175
|
+
readonly codeBuild: {
|
|
176
|
+
readonly computeType: ComputeType;
|
|
177
|
+
};
|
|
178
|
+
/** When true, resolve synth plugin via custom resource Lambda at deploy time.
|
|
179
|
+
* When false (default), use fallback synth commands (pipeline-manager synth). */
|
|
180
|
+
readonly resolvedSynthPlugin: boolean;
|
|
181
|
+
}
|
|
182
|
+
/** Express rate limiting configuration. */
|
|
183
|
+
export interface RateLimitConfig {
|
|
184
|
+
/** Maximum requests per window (env: `LIMITER_MAX`). */
|
|
185
|
+
readonly max: number;
|
|
186
|
+
/** Rate limit window in milliseconds (env: `LIMITER_WINDOWMS`). */
|
|
187
|
+
readonly windowMs: number;
|
|
188
|
+
/** Include legacy `X-RateLimit-*` headers. */
|
|
189
|
+
readonly legacyHeaders: boolean;
|
|
190
|
+
/** Include standard `RateLimit-*` headers (RFC 6585). */
|
|
191
|
+
readonly standardHeaders: boolean;
|
|
192
|
+
}
|
|
193
|
+
/** Price configuration for a single billing plan (in cents). */
|
|
194
|
+
export interface BillingPlanPrices {
|
|
195
|
+
readonly monthly: number;
|
|
196
|
+
readonly annual: number;
|
|
197
|
+
}
|
|
198
|
+
/** Full billing plan definition used for seeding and runtime configuration. */
|
|
199
|
+
export interface BillingPlanConfig {
|
|
200
|
+
readonly id: string;
|
|
201
|
+
readonly name: string;
|
|
202
|
+
readonly description: string;
|
|
203
|
+
readonly tier: QuotaTier;
|
|
204
|
+
readonly prices: BillingPlanPrices;
|
|
205
|
+
readonly features: readonly string[];
|
|
206
|
+
readonly isActive: boolean;
|
|
207
|
+
readonly isDefault: boolean;
|
|
208
|
+
readonly sortOrder: number;
|
|
209
|
+
}
|
|
210
|
+
/** Billing plans configuration. */
|
|
211
|
+
export interface BillingConfig {
|
|
212
|
+
readonly plans: readonly BillingPlanConfig[];
|
|
213
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLXR5cGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbmZpZy9jb25maWctdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0MiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHR5cGUgeyBRdW90YVRpZXIgfSBmcm9tICdAcGlwZWxpbmUtYnVpbGRlci9hcGktY29yZSc7XG5pbXBvcnQgdHlwZSB7IER1cmF0aW9uLCBSZW1vdmFsUG9saWN5IH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHR5cGUgeyBDb21wdXRlVHlwZSB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1jb2RlYnVpbGQnO1xuaW1wb3J0IHR5cGUgeyBBcmNoaXRlY3R1cmUsIFJ1bnRpbWUgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbGFtYmRhJztcbmltcG9ydCB0eXBlIHsgUmV0ZW50aW9uRGF5cyB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1sb2dzJztcbmltcG9ydCB0eXBlIHsgQWxnb3JpdGhtIH0gZnJvbSAnanNvbndlYnRva2VuJztcblxuLyoqXG4gKiBUeXBlLXNhZmUgY29uZmlndXJhdGlvbiBpbnRlcmZhY2VcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBcHBDb25maWcge1xuICByZWFkb25seSBzZXJ2ZXI6IFNlcnZlckNvbmZpZztcbiAgcmVhZG9ubHkgYXV0aDogQXV0aENvbmZpZztcbiAgcmVhZG9ubHkgZGF0YWJhc2U6IERhdGFiYXNlQ29uZmlnO1xuICByZWFkb25seSByZWdpc3RyeTogUmVnaXN0cnlDb25maWc7XG4gIHJlYWRvbmx5IHJlZGlzOiBSZWRpc0NvbmZpZztcbiAgcmVhZG9ubHkgcGx1Z2luQnVpbGQ6IFBsdWdpbkJ1aWxkQ29uZmlnO1xuICByZWFkb25seSBkb2NrZXJDb25maWc6IEJ1aWxkQ29uZmlnO1xuICByZWFkb25seSBvYnNlcnZhYmlsaXR5OiBPYnNlcnZhYmlsaXR5Q29uZmlnO1xuICByZWFkb25seSBjb21wbGlhbmNlOiBDb21wbGlhbmNlQ29uZmlnO1xuICByZWFkb25seSBhd3M6IEFXU0NvbmZpZztcbiAgcmVhZG9ubHkgcmF0ZUxpbWl0OiBSYXRlTGltaXRDb25maWc7XG4gIHJlYWRvbmx5IGJpbGxpbmc6IEJpbGxpbmdDb25maWc7XG59XG5cbi8qKiBFeHByZXNzIHNlcnZlciBjb25maWd1cmF0aW9uLiAqL1xuZXhwb3J0IGludGVyZmFjZSBTZXJ2ZXJDb25maWcge1xuICAvKiogSFRUUCBsaXN0ZW4gcG9ydCAoZW52OiBgUE9SVGApLiAqL1xuICByZWFkb25seSBwb3J0OiBudW1iZXI7XG4gIHJlYWRvbmx5IGNvcnM6IHtcbiAgICAvKiogV2hldGhlciB0byBpbmNsdWRlIGNyZWRlbnRpYWxzIGluIENPUlMgcmVzcG9uc2VzIChlbnY6IGBDT1JTX0NSRURFTlRJQUxTYCkuICovXG4gICAgcmVhZG9ubHkgY3JlZGVudGlhbHM6IGJvb2xlYW47XG4gICAgLyoqIEFsbG93ZWQgb3JpZ2luKHMpIOKAlCBzaW5nbGUgc3RyaW5nLCBhcnJheSwgb3IgYCcqJ2AgKGVudjogYENPUlNfT1JJR0lOYCkuICovXG4gICAgcmVhZG9ubHkgb3JpZ2luOiBzdHJpbmcgfCBzdHJpbmdbXTtcbiAgfTtcbiAgLyoqIE51bWJlciBvZiByZXZlcnNlIHByb3h5IGhvcHMgdG8gdHJ1c3QgKGVudjogYFRSVVNUX1BST1hZYCkuICovXG4gIHJlYWRvbmx5IHRydXN0UHJveHk6IG51bWJlcjtcbiAgLyoqIEZyb250ZW5kIGJhc2UgVVJMLCB1c2VkIGFzIENPUlMgZmFsbGJhY2sgKGVudjogYFBMQVRGT1JNX0JBU0VfVVJMYCkuICovXG4gIHJlYWRvbmx5IHBsYXRmb3JtVXJsOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGh0dHBDbGllbnQ6IHtcbiAgICAvKiogRGVmYXVsdCBIVFRQIHJlcXVlc3QgdGltZW91dCBpbiBtcyAoZW52OiBgSFRUUF9DTElFTlRfVElNRU9VVGApLiAqL1xuICAgIHJlYWRvbmx5IHRpbWVvdXQ6IG51bWJlcjtcbiAgICAvKiogTWF4aW11bSByZXRyeSBhdHRlbXB0cyBmb3IgZmFpbGVkIHJlcXVlc3RzIChlbnY6IGBIVFRQX0NMSUVOVF9NQVhfUkVUUklFU2ApLiAqL1xuICAgIHJlYWRvbmx5IG1heFJldHJpZXM6IG51bWJlcjtcbiAgICAvKiogQmFzZSBkZWxheSBiZXR3ZWVuIHJldHJpZXMgaW4gbXMgKGVudjogYEhUVFBfQ0xJRU5UX1JFVFJZX0RFTEFZX01TYCkuICovXG4gICAgcmVhZG9ubHkgcmV0cnlEZWxheU1zOiBudW1iZXI7XG4gIH07XG4gIHJlYWRvbmx5IHNzZToge1xuICAgIC8qKiBNYXggU1NFIGNsaWVudHMgcGVyIHJlcXVlc3QgKGVudjogYFNTRV9NQVhfQ0xJRU5UU19QRVJfUkVRVUVTVGApLiAqL1xuICAgIHJlYWRvbmx5IG1heENsaWVudHNQZXJSZXF1ZXN0OiBudW1iZXI7XG4gICAgLyoqIFNTRSBjbGllbnQgdGltZW91dCBpbiBtcyAoZW52OiBgU1NFX0NMSUVOVF9USU1FT1VUX01TYCkuICovXG4gICAgcmVhZG9ubHkgY2xpZW50VGltZW91dE1zOiBudW1iZXI7XG4gICAgLyoqIFNTRSBjbGVhbnVwIGludGVydmFsIGluIG1zIChlbnY6IGBTU0VfQ0xFQU5VUF9JTlRFUlZBTF9NU2ApLiAqL1xuICAgIHJlYWRvbmx5IGNsZWFudXBJbnRlcnZhbE1zOiBudW1iZXI7XG4gIH07XG4gIHJlYWRvbmx5IHNlcnZpY2VzOiB7XG4gICAgcmVhZG9ubHkgcGx1Z2luSG9zdDogc3RyaW5nO1xuICAgIHJlYWRvbmx5IHBsdWdpblBvcnQ6IG51bWJlcjtcbiAgICByZWFkb25seSBwaXBlbGluZUhvc3Q6IHN0cmluZztcbiAgICByZWFkb25seSBwaXBlbGluZVBvcnQ6IG51bWJlcjtcbiAgICByZWFkb25seSBtZXNzYWdlSG9zdDogc3RyaW5nO1xuICAgIHJlYWRvbmx5IG1lc3NhZ2VQb3J0OiBudW1iZXI7XG4gICAgcmVhZG9ubHkgY29tcGxpYW5jZUhvc3Q6IHN0cmluZztcbiAgICByZWFkb25seSBjb21wbGlhbmNlUG9ydDogbnVtYmVyO1xuICAgIHJlYWRvbmx5IGJpbGxpbmdIb3N0OiBzdHJpbmc7XG4gICAgcmVhZG9ubHkgYmlsbGluZ1BvcnQ6IG51bWJlcjtcbiAgICByZWFkb25seSBiaWxsaW5nVGltZW91dDogbnVtYmVyO1xuICB9O1xufVxuXG4vKiogSldUIGFuZCByZWZyZXNoIHRva2VuIGF1dGhlbnRpY2F0aW9uIGNvbmZpZ3VyYXRpb24uICovXG5leHBvcnQgaW50ZXJmYWNlIEF1dGhDb25maWcge1xuICByZWFkb25seSBqd3Q6IHtcbiAgICAvKiogU2lnbmluZyBzZWNyZXQgZm9yIGFjY2VzcyB0b2tlbnMgKGVudjogYEpXVF9TRUNSRVRgKS4gKi9cbiAgICByZWFkb25seSBzZWNyZXQ6IHN0cmluZztcbiAgICAvKiogVG9rZW4gbGlmZXRpbWUgaW4gc2Vjb25kcyAoZW52OiBgSldUX0VYUElSRVNfSU5gKS4gKi9cbiAgICByZWFkb25seSBleHBpcmVzSW46IG51bWJlcjtcbiAgICAvKiogU2lnbmluZyBhbGdvcml0aG0sIGUuZy4gYCdIUzI1NidgIChlbnY6IGBKV1RfQUxHT1JJVEhNYCkuICovXG4gICAgcmVhZG9ubHkgYWxnb3JpdGhtOiBBbGdvcml0aG07XG4gICAgLyoqIGJjcnlwdCBzYWx0IHJvdW5kcyBmb3IgcGFzc3dvcmQgaGFzaGluZyAoZW52OiBgSldUX1NBTFRfUk9VTkRTYCkuICovXG4gICAgcmVhZG9ubHkgc2FsdFJvdW5kczogbnVtYmVyO1xuICB9O1xuICByZWFkb25seSByZWZyZXNoVG9rZW46IHtcbiAgICAvKiogU2lnbmluZyBzZWNyZXQgZm9yIHJlZnJlc2ggdG9rZW5zIChlbnY6IGBSRUZSRVNIX1RPS0VOX1NFQ1JFVGApLiAqL1xuICAgIHJlYWRvbmx5IHNlY3JldDogc3RyaW5nO1xuICAgIC8qKiBUb2tlbiBsaWZldGltZSBpbiBzZWNvbmRzIChlbnY6IGBSRUZSRVNIX1RPS0VOX0VYUElSRVNfSU5gKS4gKi9cbiAgICByZWFkb25seSBleHBpcmVzSW46IG51bWJlcjtcbiAgfTtcbn1cblxuLyoqIFBvc3RncmVTUUwgYW5kIERyaXp6bGUgT1JNIGRhdGFiYXNlIGNvbmZpZ3VyYXRpb24uICovXG5leHBvcnQgaW50ZXJmYWNlIERhdGFiYXNlQ29uZmlnIHtcbiAgcmVhZG9ubHkgcG9zdGdyZXM6IHtcbiAgICAvKiogUG9zdGdyZVNRTCBob3N0IChlbnY6IGBEQl9IT1NUYCkuICovXG4gICAgcmVhZG9ubHkgaG9zdDogc3RyaW5nO1xuICAgIC8qKiBQb3N0Z3JlU1FMIHBvcnQgKGVudjogYERCX1BPUlRgKS4gKi9cbiAgICByZWFkb25seSBwb3J0OiBudW1iZXI7XG4gICAgLyoqIERhdGFiYXNlIG5hbWUgKGVudjogYERBVEFCQVNFYCkuICovXG4gICAgcmVhZG9ubHkgZGF0YWJhc2U6IHN0cmluZztcbiAgICAvKiogRGF0YWJhc2UgdXNlciAoZW52OiBgREJfVVNFUmApLiAqL1xuICAgIHJlYWRvbmx5IHVzZXI6IHN0cmluZztcbiAgICAvKiogRGF0YWJhc2UgcGFzc3dvcmQgKGVudjogYERCX1BBU1NXT1JEYCkuICovXG4gICAgcmVhZG9ubHkgcGFzc3dvcmQ6IHN0cmluZztcbiAgfTtcbiAgcmVhZG9ubHkgZHJpenpsZToge1xuICAgIC8qKiBNYXhpbXVtIGNvbm5lY3Rpb24gcG9vbCBzaXplIChlbnY6IGBEUklaWkxFX01BWF9QT09MX1NJWkVgKS4gKi9cbiAgICByZWFkb25seSBtYXhQb29sU2l6ZTogbnVtYmVyO1xuICAgIC8qKiBJZGxlIGNvbm5lY3Rpb24gdGltZW91dCBpbiBtcyAoZW52OiBgRFJJWlpMRV9JRExFX1RJTUVPVVRfTUlMTElTYCkuICovXG4gICAgcmVhZG9ubHkgaWRsZVRpbWVvdXRNaWxsaXM6IG51bWJlcjtcbiAgICAvKiogTmV3IGNvbm5lY3Rpb24gdGltZW91dCBpbiBtcyAoZW52OiBgRFJJWlpMRV9DT05ORUNUSU9OX1RJTUVPVVRfTUlMTElTYCkuICovXG4gICAgcmVhZG9ubHkgY29ubmVjdGlvblRpbWVvdXRNaWxsaXM6IG51bWJlcjtcbiAgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZWdpc3RyeUNvbmZpZyB7XG4gIHJlYWRvbmx5IGhvc3Q6IHN0cmluZztcbiAgcmVhZG9ubHkgcG9ydDogbnVtYmVyO1xuICByZWFkb25seSB1c2VyOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHRva2VuOiBzdHJpbmc7XG4gIC8qKiBEb2NrZXIgbmV0d29yayBmb3IgYnVpbGQvcHVzaCAoZW1wdHkgc3RyaW5nID0gZGVmYXVsdCkuICovXG4gIHJlYWRvbmx5IG5ldHdvcms6IHN0cmluZztcbiAgLyoqIFVzZSBwbGFpbiBIVFRQIGluc3RlYWQgb2YgSFRUUFMgKGVudjogYERPQ0tFUl9SRUdJU1RSWV9IVFRQYCkuIERlZmF1bHRzIHRvIHRydWUuICovXG4gIHJlYWRvbmx5IGh0dHA6IGJvb2xlYW47XG4gIC8qKiBTa2lwIFRMUyBjZXJ0aWZpY2F0ZSB2ZXJpZmljYXRpb24gZm9yIHNlbGYtc2lnbmVkIGNlcnRzIChlbnY6IGBET0NLRVJfUkVHSVNUUllfSU5TRUNVUkVgKS4gRGVmYXVsdHMgdG8gdHJ1ZS4gKi9cbiAgcmVhZG9ubHkgaW5zZWN1cmU6IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVkaXNDb25maWcge1xuICByZWFkb25seSBob3N0OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHBvcnQ6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQbHVnaW5CdWlsZENvbmZpZyB7XG4gIHJlYWRvbmx5IGNvbmN1cnJlbmN5OiBudW1iZXI7XG4gIHJlYWRvbmx5IG1heEF0dGVtcHRzOiBudW1iZXI7XG4gIHJlYWRvbmx5IGJhY2tvZmZEZWxheU1zOiBudW1iZXI7XG4gIHJlYWRvbmx5IHdvcmtlclRpbWVvdXRNczogbnVtYmVyO1xuICByZWFkb25seSB0ZW1wRGlyTWF4QWdlTXM6IG51bWJlcjtcbiAgcmVhZG9ubHkgZGxxTWF4QXR0ZW1wdHM6IG51bWJlcjtcbiAgcmVhZG9ubHkgZGxxQmFja29mZkJhc2VNczogbnVtYmVyO1xuICByZWFkb25seSBkbHFNYXhTaXplOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQnVpbGRDb25maWcge1xuICAvKiogQnVpbGQgc3RyYXRlZ3k6ICdwb2RtYW4nIChkZWZhdWx0KSwgJ2RvY2tlcicsIG9yICdrYW5pa28nLiAqL1xuICByZWFkb25seSBzdHJhdGVneTogJ2RvY2tlcicgfCAna2FuaWtvJyB8ICdwb2RtYW4nO1xuICAvKiogUm9vdCBkaXJlY3RvcnkgZm9yIGJ1aWxkIHRlbXAgZmlsZXMuICovXG4gIHJlYWRvbmx5IHRlbXBSb290OiBzdHJpbmc7XG4gIC8qKiBCdWlsZCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcy4gKi9cbiAgcmVhZG9ubHkgdGltZW91dE1zOiBudW1iZXI7XG4gIC8qKiBQdXNoIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzLiAqL1xuICByZWFkb25seSBwdXNoVGltZW91dE1zOiBudW1iZXI7XG4gIC8qKiBQYXRoIHRvIEthbmlrbyBleGVjdXRvciBiaW5hcnkgKG9ubHkgdXNlZCB3aGVuIHN0cmF0ZWd5PWthbmlrbykuICovXG4gIHJlYWRvbmx5IGthbmlrb0V4ZWN1dG9yOiBzdHJpbmc7XG4gIC8qKiBLYW5pa28gbGF5ZXIgY2FjaGUgZGlyZWN0b3J5IChvbmx5IHVzZWQgd2hlbiBzdHJhdGVneT1rYW5pa28pLiAqL1xuICByZWFkb25seSBrYW5pa29DYWNoZURpcjogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE9ic2VydmFiaWxpdHlDb25maWcge1xuICByZWFkb25seSBsb2dMZXZlbDogc3RyaW5nO1xuICByZWFkb25seSBsb2dGb3JtYXQ6IHN0cmluZztcbiAgcmVhZG9ubHkgc2VydmljZU5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgdHJhY2luZzoge1xuICAgIHJlYWRvbmx5IGVuYWJsZWQ6IGJvb2xlYW47XG4gICAgcmVhZG9ubHkgZW5kcG9pbnQ6IHN0cmluZztcbiAgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb21wbGlhbmNlQ29uZmlnIHtcbiAgcmVhZG9ubHkgc2NhblNjaGVkdWxlckludGVydmFsTXM6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBV1NDb25maWcge1xuICByZWFkb25seSBsYW1iZGE6IHtcbiAgICByZWFkb25seSBydW50aW1lOiBSdW50aW1lO1xuICAgIHJlYWRvbmx5IHRpbWVvdXQ6IER1cmF0aW9uO1xuICAgIHJlYWRvbmx5IG1lbW9yeVNpemU6IG51bWJlcjtcbiAgICByZWFkb25seSBhcmNoaXRlY3R1cmU6IEFyY2hpdGVjdHVyZTtcbiAgICByZWFkb25seSByZXNlcnZlZENvbmN1cnJlbnRFeGVjdXRpb25zPzogbnVtYmVyO1xuICB9O1xuICByZWFkb25seSBsb2dnaW5nOiB7XG4gICAgcmVhZG9ubHkgZ3JvdXBOYW1lOiBzdHJpbmc7XG4gICAgcmVhZG9ubHkgcmV0ZW50aW9uOiBSZXRlbnRpb25EYXlzO1xuICAgIHJlYWRvbmx5IHJlbW92YWxQb2xpY3k6IFJlbW92YWxQb2xpY3k7XG4gIH07XG4gIHJlYWRvbmx5IGNvZGVCdWlsZDoge1xuICAgIHJlYWRvbmx5IGNvbXB1dGVUeXBlOiBDb21wdXRlVHlwZTtcbiAgfTtcbiAgLyoqIFdoZW4gdHJ1ZSwgcmVzb2x2ZSBzeW50aCBwbHVnaW4gdmlhIGN1c3RvbSByZXNvdXJjZSBMYW1iZGEgYXQgZGVwbG95IHRpbWUuXG4gICAqICBXaGVuIGZhbHNlIChkZWZhdWx0KSwgdXNlIGZhbGxiYWNrIHN5bnRoIGNvbW1hbmRzIChwaXBlbGluZS1tYW5hZ2VyIHN5bnRoKS4gKi9cbiAgcmVhZG9ubHkgcmVzb2x2ZWRTeW50aFBsdWdpbjogYm9vbGVhbjtcbn1cblxuLyoqIEV4cHJlc3MgcmF0ZSBsaW1pdGluZyBjb25maWd1cmF0aW9uLiAqL1xuZXhwb3J0IGludGVyZmFjZSBSYXRlTGltaXRDb25maWcge1xuICAvKiogTWF4aW11bSByZXF1ZXN0cyBwZXIgd2luZG93IChlbnY6IGBMSU1JVEVSX01BWGApLiAqL1xuICByZWFkb25seSBtYXg6IG51bWJlcjtcbiAgLyoqIFJhdGUgbGltaXQgd2luZG93IGluIG1pbGxpc2Vjb25kcyAoZW52OiBgTElNSVRFUl9XSU5ET1dNU2ApLiAqL1xuICByZWFkb25seSB3aW5kb3dNczogbnVtYmVyO1xuICAvKiogSW5jbHVkZSBsZWdhY3kgYFgtUmF0ZUxpbWl0LSpgIGhlYWRlcnMuICovXG4gIHJlYWRvbmx5IGxlZ2FjeUhlYWRlcnM6IGJvb2xlYW47XG4gIC8qKiBJbmNsdWRlIHN0YW5kYXJkIGBSYXRlTGltaXQtKmAgaGVhZGVycyAoUkZDIDY1ODUpLiAqL1xuICByZWFkb25seSBzdGFuZGFyZEhlYWRlcnM6IGJvb2xlYW47XG59XG5cbi8qKiBQcmljZSBjb25maWd1cmF0aW9uIGZvciBhIHNpbmdsZSBiaWxsaW5nIHBsYW4gKGluIGNlbnRzKS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQmlsbGluZ1BsYW5QcmljZXMge1xuICByZWFkb25seSBtb250aGx5OiBudW1iZXI7XG4gIHJlYWRvbmx5IGFubnVhbDogbnVtYmVyO1xufVxuXG4vKiogRnVsbCBiaWxsaW5nIHBsYW4gZGVmaW5pdGlvbiB1c2VkIGZvciBzZWVkaW5nIGFuZCBydW50aW1lIGNvbmZpZ3VyYXRpb24uICovXG5leHBvcnQgaW50ZXJmYWNlIEJpbGxpbmdQbGFuQ29uZmlnIHtcbiAgcmVhZG9ubHkgaWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICByZWFkb25seSBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICByZWFkb25seSB0aWVyOiBRdW90YVRpZXI7XG4gIHJlYWRvbmx5IHByaWNlczogQmlsbGluZ1BsYW5QcmljZXM7XG4gIHJlYWRvbmx5IGZlYXR1cmVzOiByZWFkb25seSBzdHJpbmdbXTtcbiAgcmVhZG9ubHkgaXNBY3RpdmU6IGJvb2xlYW47XG4gIHJlYWRvbmx5IGlzRGVmYXVsdDogYm9vbGVhbjtcbiAgcmVhZG9ubHkgc29ydE9yZGVyOiBudW1iZXI7XG59XG5cbi8qKiBCaWxsaW5nIHBsYW5zIGNvbmZpZ3VyYXRpb24uICovXG5leHBvcnQgaW50ZXJmYWNlIEJpbGxpbmdDb25maWcge1xuICByZWFkb25seSBwbGFuczogcmVhZG9ubHkgQmlsbGluZ1BsYW5Db25maWdbXTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { AWSConfig, BuildConfig, ComplianceConfig, DatabaseConfig, ObservabilityConfig, PluginBuildConfig, RedisConfig, RegistryConfig } from './config-types';
|
|
2
|
+
/**
|
|
3
|
+
* Load Docker registry configuration from environment variables.
|
|
4
|
+
*
|
|
5
|
+
* Environment variables:
|
|
6
|
+
* - `IMAGE_REGISTRY_HOST` — Registry hostname (default: `'registry'`)
|
|
7
|
+
* - `IMAGE_REGISTRY_PORT` — Registry port (default: `5000`)
|
|
8
|
+
* - `IMAGE_REGISTRY_USER` — Registry username (default: `'admin'`)
|
|
9
|
+
* - `IMAGE_REGISTRY_TOKEN` — Registry auth token (default: `'password'`)
|
|
10
|
+
* - `DOCKER_NETWORK` — Docker network for build/push (default: `''`)
|
|
11
|
+
* - `DOCKER_REGISTRY_HTTP` — Use plain HTTP (default: `true`). Set `false` for HTTPS.
|
|
12
|
+
* - `DOCKER_REGISTRY_INSECURE` — Skip TLS verification (default: `true`). Set `false` for production.
|
|
13
|
+
*
|
|
14
|
+
* @returns Registry configuration
|
|
15
|
+
*/
|
|
16
|
+
export declare function loadRegistryConfig(): RegistryConfig;
|
|
17
|
+
export declare function loadRedisConfig(): RedisConfig;
|
|
18
|
+
/**
|
|
19
|
+
* Load plugin build queue configuration.
|
|
20
|
+
*
|
|
21
|
+
* Environment variables:
|
|
22
|
+
* - `PLUGIN_BUILD_CONCURRENCY` — Max concurrent plugin builds (default: `1`)
|
|
23
|
+
*/
|
|
24
|
+
export declare function loadPluginBuildConfig(): PluginBuildConfig;
|
|
25
|
+
export declare function loadDatabaseConfig(): DatabaseConfig;
|
|
26
|
+
export declare function loadObservabilityConfig(): ObservabilityConfig;
|
|
27
|
+
export declare function loadComplianceConfig(): ComplianceConfig;
|
|
28
|
+
/**
|
|
29
|
+
* Load Docker/Podman/Kaniko build configuration.
|
|
30
|
+
*
|
|
31
|
+
* Environment variables:
|
|
32
|
+
* - `DOCKER_BUILD_STRATEGY` — Build strategy: `podman`, `docker`, or `kaniko` (default: `podman`)
|
|
33
|
+
* - `DOCKER_BUILD_TEMP_ROOT` — Temp directory for build contexts (default: `<cwd>/tmp`)
|
|
34
|
+
* - `DOCKER_BUILD_TIMEOUT_MS` — Build timeout in milliseconds (default: `900000` / 15 min)
|
|
35
|
+
* - `DOCKER_PUSH_TIMEOUT_MS` — Push timeout in milliseconds (default: `300000` / 5 min)
|
|
36
|
+
* - `KANIKO_EXECUTOR_PATH` — Path to Kaniko executor binary (default: `/kaniko/executor`)
|
|
37
|
+
* - `KANIKO_CACHE_DIR` — Kaniko layer cache directory (default: `/kaniko/cache`)
|
|
38
|
+
*/
|
|
39
|
+
export declare function loadDockerConfig(): BuildConfig;
|
|
40
|
+
/**
|
|
41
|
+
* Load AWS infrastructure configuration from environment variables.
|
|
42
|
+
*
|
|
43
|
+
* Environment variables:
|
|
44
|
+
* - `LAMBDA_RUNTIME` — Lambda runtime (default: `'nodejs24.x'`; supports nodejs22.x, nodejs24.x)
|
|
45
|
+
* - `LAMBDA_TIMEOUT` — Lambda timeout in seconds (default: `900`)
|
|
46
|
+
* - `LAMBDA_MEMORY_SIZE` — Lambda memory in MB (default: `128`)
|
|
47
|
+
* - `LAMBDA_ARCHITECTURE` — `'x86_64'` or ARM (default: ARM_64)
|
|
48
|
+
* - `LOG_GROUP_NAME` — CloudWatch log group (default: `'/pipeline-builder/logs'`)
|
|
49
|
+
* - `LOG_RETENTION` — Log retention in days (default: `7`)
|
|
50
|
+
* - `LOG_REMOVAL_POLICY` — `'RETAIN'` or destroy (default: DESTROY)
|
|
51
|
+
* - `CODEBUILD_COMPUTE_TYPE` — CodeBuild compute type (default: `'SMALL'`)
|
|
52
|
+
*
|
|
53
|
+
* @returns AWS infrastructure configuration
|
|
54
|
+
*/
|
|
55
|
+
export declare function loadAWSConfig(): AWSConfig;
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6
|
+
};
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.loadRegistryConfig = loadRegistryConfig;
|
|
9
|
+
exports.loadRedisConfig = loadRedisConfig;
|
|
10
|
+
exports.loadPluginBuildConfig = loadPluginBuildConfig;
|
|
11
|
+
exports.loadDatabaseConfig = loadDatabaseConfig;
|
|
12
|
+
exports.loadObservabilityConfig = loadObservabilityConfig;
|
|
13
|
+
exports.loadComplianceConfig = loadComplianceConfig;
|
|
14
|
+
exports.loadDockerConfig = loadDockerConfig;
|
|
15
|
+
exports.loadAWSConfig = loadAWSConfig;
|
|
16
|
+
const path_1 = __importDefault(require("path"));
|
|
17
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
18
|
+
const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
|
|
19
|
+
const aws_logs_1 = require("aws-cdk-lib/aws-logs");
|
|
20
|
+
const pipeline_helpers_1 = require("../core/pipeline-helpers");
|
|
21
|
+
function requireInProduction(envVar, devDefault) {
|
|
22
|
+
const value = process.env[envVar];
|
|
23
|
+
if (value)
|
|
24
|
+
return value;
|
|
25
|
+
if (process.env.NODE_ENV === 'production') {
|
|
26
|
+
throw new Error(`${envVar} is required in production`);
|
|
27
|
+
}
|
|
28
|
+
return devDefault;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Load Docker registry configuration from environment variables.
|
|
32
|
+
*
|
|
33
|
+
* Environment variables:
|
|
34
|
+
* - `IMAGE_REGISTRY_HOST` — Registry hostname (default: `'registry'`)
|
|
35
|
+
* - `IMAGE_REGISTRY_PORT` — Registry port (default: `5000`)
|
|
36
|
+
* - `IMAGE_REGISTRY_USER` — Registry username (default: `'admin'`)
|
|
37
|
+
* - `IMAGE_REGISTRY_TOKEN` — Registry auth token (default: `'password'`)
|
|
38
|
+
* - `DOCKER_NETWORK` — Docker network for build/push (default: `''`)
|
|
39
|
+
* - `DOCKER_REGISTRY_HTTP` — Use plain HTTP (default: `true`). Set `false` for HTTPS.
|
|
40
|
+
* - `DOCKER_REGISTRY_INSECURE` — Skip TLS verification (default: `true`). Set `false` for production.
|
|
41
|
+
*
|
|
42
|
+
* @returns Registry configuration
|
|
43
|
+
*/
|
|
44
|
+
function loadRegistryConfig() {
|
|
45
|
+
return {
|
|
46
|
+
host: process.env.IMAGE_REGISTRY_HOST || 'registry',
|
|
47
|
+
port: parseInt(process.env.IMAGE_REGISTRY_PORT || '5000', 10),
|
|
48
|
+
user: requireInProduction('IMAGE_REGISTRY_USER', 'admin'),
|
|
49
|
+
token: requireInProduction('IMAGE_REGISTRY_TOKEN', 'password'),
|
|
50
|
+
network: process.env.DOCKER_NETWORK || '',
|
|
51
|
+
http: process.env.DOCKER_REGISTRY_HTTP !== 'false',
|
|
52
|
+
insecure: process.env.DOCKER_REGISTRY_INSECURE !== 'false',
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function loadRedisConfig() {
|
|
56
|
+
return {
|
|
57
|
+
host: process.env.REDIS_HOST || 'localhost',
|
|
58
|
+
port: parseInt(process.env.REDIS_PORT || '6379', 10),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Load plugin build queue configuration.
|
|
63
|
+
*
|
|
64
|
+
* Environment variables:
|
|
65
|
+
* - `PLUGIN_BUILD_CONCURRENCY` — Max concurrent plugin builds (default: `1`)
|
|
66
|
+
*/
|
|
67
|
+
function loadPluginBuildConfig() {
|
|
68
|
+
return {
|
|
69
|
+
concurrency: parseInt(process.env.PLUGIN_BUILD_CONCURRENCY || '1', 10),
|
|
70
|
+
maxAttempts: parseInt(process.env.PLUGIN_BUILD_MAX_ATTEMPTS || '2', 10),
|
|
71
|
+
backoffDelayMs: parseInt(process.env.PLUGIN_BUILD_BACKOFF_DELAY_MS || '5000', 10),
|
|
72
|
+
workerTimeoutMs: parseInt(process.env.PLUGIN_BUILD_WORKER_TIMEOUT_MS || '10000', 10),
|
|
73
|
+
tempDirMaxAgeMs: parseInt(process.env.TEMP_DIR_MAX_AGE_MS || '14400000', 10),
|
|
74
|
+
dlqMaxAttempts: parseInt(process.env.PLUGIN_DLQ_MAX_ATTEMPTS || '3', 10),
|
|
75
|
+
dlqBackoffBaseMs: parseInt(process.env.PLUGIN_DLQ_BACKOFF_BASE_MS || '300000', 10),
|
|
76
|
+
dlqMaxSize: parseInt(process.env.PLUGIN_DLQ_MAX_SIZE || '20', 10),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function loadDatabaseConfig() {
|
|
80
|
+
return {
|
|
81
|
+
postgres: {
|
|
82
|
+
host: process.env.DB_HOST || 'postgres',
|
|
83
|
+
port: parseInt(process.env.DB_PORT || '5432', 10),
|
|
84
|
+
database: process.env.DATABASE || 'pipeline_builder',
|
|
85
|
+
user: process.env.DB_USER || 'postgres',
|
|
86
|
+
password: process.env.DB_PASSWORD || '',
|
|
87
|
+
},
|
|
88
|
+
drizzle: {
|
|
89
|
+
maxPoolSize: parseInt(process.env.DRIZZLE_MAX_POOL_SIZE || '20', 10),
|
|
90
|
+
idleTimeoutMillis: parseInt(process.env.DRIZZLE_IDLE_TIMEOUT_MILLIS || '30000', 10),
|
|
91
|
+
connectionTimeoutMillis: parseInt(process.env.DRIZZLE_CONNECTION_TIMEOUT_MILLIS || '10000', 10),
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function loadObservabilityConfig() {
|
|
96
|
+
return {
|
|
97
|
+
logLevel: process.env.LOG_LEVEL || 'info',
|
|
98
|
+
logFormat: process.env.LOG_FORMAT || 'json',
|
|
99
|
+
serviceName: process.env.SERVICE_NAME || 'api',
|
|
100
|
+
tracing: {
|
|
101
|
+
enabled: process.env.OTEL_TRACING_ENABLED === 'true',
|
|
102
|
+
endpoint: process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://localhost:4318/v1/traces',
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function loadComplianceConfig() {
|
|
107
|
+
return {
|
|
108
|
+
scanSchedulerIntervalMs: parseInt(process.env.SCAN_SCHEDULER_INTERVAL_MS || '60000', 10),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Load Docker/Podman/Kaniko build configuration.
|
|
113
|
+
*
|
|
114
|
+
* Environment variables:
|
|
115
|
+
* - `DOCKER_BUILD_STRATEGY` — Build strategy: `podman`, `docker`, or `kaniko` (default: `podman`)
|
|
116
|
+
* - `DOCKER_BUILD_TEMP_ROOT` — Temp directory for build contexts (default: `<cwd>/tmp`)
|
|
117
|
+
* - `DOCKER_BUILD_TIMEOUT_MS` — Build timeout in milliseconds (default: `900000` / 15 min)
|
|
118
|
+
* - `DOCKER_PUSH_TIMEOUT_MS` — Push timeout in milliseconds (default: `300000` / 5 min)
|
|
119
|
+
* - `KANIKO_EXECUTOR_PATH` — Path to Kaniko executor binary (default: `/kaniko/executor`)
|
|
120
|
+
* - `KANIKO_CACHE_DIR` — Kaniko layer cache directory (default: `/kaniko/cache`)
|
|
121
|
+
*/
|
|
122
|
+
function loadDockerConfig() {
|
|
123
|
+
const validStrategies = new Set(['docker', 'kaniko', 'podman']);
|
|
124
|
+
const strategyEnv = (process.env.DOCKER_BUILD_STRATEGY || '').toLowerCase();
|
|
125
|
+
return {
|
|
126
|
+
strategy: validStrategies.has(strategyEnv) ? strategyEnv : 'docker',
|
|
127
|
+
tempRoot: process.env.DOCKER_BUILD_TEMP_ROOT || path_1.default.join(process.cwd(), 'tmp'),
|
|
128
|
+
timeoutMs: parseInt(process.env.DOCKER_BUILD_TIMEOUT_MS || '900000', 10),
|
|
129
|
+
pushTimeoutMs: parseInt(process.env.DOCKER_PUSH_TIMEOUT_MS || '300000', 10),
|
|
130
|
+
kanikoExecutor: process.env.KANIKO_EXECUTOR_PATH || '/kaniko/executor',
|
|
131
|
+
kanikoCacheDir: process.env.KANIKO_CACHE_DIR || '/kaniko/cache',
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Load AWS infrastructure configuration from environment variables.
|
|
136
|
+
*
|
|
137
|
+
* Environment variables:
|
|
138
|
+
* - `LAMBDA_RUNTIME` — Lambda runtime (default: `'nodejs24.x'`; supports nodejs22.x, nodejs24.x)
|
|
139
|
+
* - `LAMBDA_TIMEOUT` — Lambda timeout in seconds (default: `900`)
|
|
140
|
+
* - `LAMBDA_MEMORY_SIZE` — Lambda memory in MB (default: `128`)
|
|
141
|
+
* - `LAMBDA_ARCHITECTURE` — `'x86_64'` or ARM (default: ARM_64)
|
|
142
|
+
* - `LOG_GROUP_NAME` — CloudWatch log group (default: `'/pipeline-builder/logs'`)
|
|
143
|
+
* - `LOG_RETENTION` — Log retention in days (default: `7`)
|
|
144
|
+
* - `LOG_REMOVAL_POLICY` — `'RETAIN'` or destroy (default: DESTROY)
|
|
145
|
+
* - `CODEBUILD_COMPUTE_TYPE` — CodeBuild compute type (default: `'SMALL'`)
|
|
146
|
+
*
|
|
147
|
+
* @returns AWS infrastructure configuration
|
|
148
|
+
*/
|
|
149
|
+
function loadAWSConfig() {
|
|
150
|
+
return {
|
|
151
|
+
lambda: {
|
|
152
|
+
runtime: parseRuntime(process.env.LAMBDA_RUNTIME || 'nodejs24.x'),
|
|
153
|
+
timeout: aws_cdk_lib_1.Duration.seconds(parseInt(process.env.LAMBDA_TIMEOUT || '900', 10)),
|
|
154
|
+
memorySize: parseInt(process.env.LAMBDA_MEMORY_SIZE || '512', 10),
|
|
155
|
+
architecture: process.env.LAMBDA_ARCHITECTURE === 'x86_64'
|
|
156
|
+
? aws_lambda_1.Architecture.X86_64
|
|
157
|
+
: aws_lambda_1.Architecture.ARM_64,
|
|
158
|
+
reservedConcurrentExecutions: process.env.LAMBDA_RESERVED_CONCURRENCY
|
|
159
|
+
? parseInt(process.env.LAMBDA_RESERVED_CONCURRENCY, 10)
|
|
160
|
+
: undefined,
|
|
161
|
+
},
|
|
162
|
+
logging: {
|
|
163
|
+
groupName: process.env.LOG_GROUP_NAME || '/pipeline-builder/logs',
|
|
164
|
+
retention: parseRetention(process.env.LOG_RETENTION || '7'),
|
|
165
|
+
removalPolicy: process.env.LOG_REMOVAL_POLICY === 'RETAIN'
|
|
166
|
+
? aws_cdk_lib_1.RemovalPolicy.RETAIN
|
|
167
|
+
: aws_cdk_lib_1.RemovalPolicy.DESTROY,
|
|
168
|
+
},
|
|
169
|
+
codeBuild: {
|
|
170
|
+
computeType: (0, pipeline_helpers_1.getComputeType)(process.env.CODEBUILD_COMPUTE_TYPE || 'SMALL'),
|
|
171
|
+
},
|
|
172
|
+
resolvedSynthPlugin: process.env.RESOLVED_SYNTH_PLUGIN === 'true',
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Parse Lambda runtime string into a CDK Runtime enum value.
|
|
177
|
+
*
|
|
178
|
+
* @param runtime - Runtime string (e.g. `'nodejs24.x'`)
|
|
179
|
+
* @returns CDK Runtime enum; falls back to NODEJS_24_X for unknown values
|
|
180
|
+
*/
|
|
181
|
+
function parseRuntime(runtime) {
|
|
182
|
+
const runtimeMap = {
|
|
183
|
+
'nodejs24.x': aws_lambda_1.Runtime.NODEJS_24_X,
|
|
184
|
+
};
|
|
185
|
+
return runtimeMap[runtime] || aws_lambda_1.Runtime.NODEJS_24_X;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Parse log retention days string into a CDK RetentionDays enum value.
|
|
189
|
+
* RetentionDays enum values are the numeric day counts themselves,
|
|
190
|
+
* so we parse the string and check if it's a valid enum member.
|
|
191
|
+
*
|
|
192
|
+
* @param days - Retention period in days as a string (e.g. `'30'`)
|
|
193
|
+
* @returns CDK RetentionDays enum; falls back to ONE_DAY for unknown values
|
|
194
|
+
*/
|
|
195
|
+
const VALID_RETENTION_DAYS = new Set(Object.values(aws_logs_1.RetentionDays).filter((v) => typeof v === 'number'));
|
|
196
|
+
function parseRetention(days) {
|
|
197
|
+
const parsed = parseInt(days, 10);
|
|
198
|
+
return VALID_RETENTION_DAYS.has(parsed) ? parsed : aws_logs_1.RetentionDays.ONE_DAY;
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5mcmFzdHJ1Y3R1cmUtY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbmZpZy9pbmZyYXN0cnVjdHVyZS1jb25maWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7Ozs7O0FBZ0N0QyxnREFVQztBQUVELDBDQUtDO0FBUUQsc0RBV0M7QUFFRCxnREFlQztBQUVELDBEQVVDO0FBRUQsb0RBSUM7QUFhRCw0Q0FXQztBQWlCRCxzQ0E0QkM7QUExS0QsZ0RBQXdCO0FBQ3hCLDZDQUFzRDtBQUN0RCx1REFBK0Q7QUFDL0QsbURBQXFEO0FBRXJELCtEQUEwRDtBQUUxRCxTQUFTLG1CQUFtQixDQUFDLE1BQWMsRUFBRSxVQUFrQjtJQUM3RCxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ2xDLElBQUksS0FBSztRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQ3hCLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEtBQUssWUFBWSxFQUFFLENBQUM7UUFDMUMsTUFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLE1BQU0sNEJBQTRCLENBQUMsQ0FBQztJQUN6RCxDQUFDO0lBQ0QsT0FBTyxVQUFVLENBQUM7QUFDcEIsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7O0dBYUc7QUFDSCxTQUFnQixrQkFBa0I7SUFDaEMsT0FBTztRQUNMLElBQUksRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixJQUFJLFVBQVU7UUFDbkQsSUFBSSxFQUFFLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixJQUFJLE1BQU0sRUFBRSxFQUFFLENBQUM7UUFDN0QsSUFBSSxFQUFFLG1CQUFtQixDQUFDLHFCQUFxQixFQUFFLE9BQU8sQ0FBQztRQUN6RCxLQUFLLEVBQUUsbUJBQW1CLENBQUMsc0JBQXNCLEVBQUUsVUFBVSxDQUFDO1FBQzlELE9B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QUFhLENBQUMsT0FBTztTQUMxQjtRQUVELFNBQVMsRUFBRTtZQUNULFdBQVcsRUFBRSxJQUFBLGlDQUFjLEVBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsSUFBSSxPQUFPLENBQUM7U0FDM0U7UUFFRCxtQkFBbUIsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLHFCQUFxQixLQUFLLE1BQU07S0FDbEUsQ0FBQztBQUNKLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQVMsWUFBWSxDQUFDLE9BQWU7SUFDbkMsTUFBTSxVQUFVLEdBQTRCO1FBQzFDLFlBQVksRUFBRSxvQkFBTyxDQUFDLFdBQVc7S0FDbEMsQ0FBQztJQUNGLE9BQU8sVUFBVSxDQUFDLE9BQU8sQ0FBQyxJQUFJLG9CQUFPLENBQUMsV0FBVyxDQUFDO0FBQ3BELENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLHdCQUFhLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQWUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUM7QUFFckgsU0FBUyxjQUFjLENBQUMsSUFBWTtJQUNsQyxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ2xDLE9BQU8sb0JBQW9CLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUF1QixDQUFDLENBQUMsQ0FBQyx3QkFBYSxDQUFDLE9BQU8sQ0FBQztBQUM1RixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgRHVyYXRpb24sIFJlbW92YWxQb2xpY3kgfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBBcmNoaXRlY3R1cmUsIFJ1bnRpbWUgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbGFtYmRhJztcbmltcG9ydCB7IFJldGVudGlvbkRheXMgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbG9ncyc7XG5pbXBvcnQgdHlwZSB7IEFXU0NvbmZpZywgQnVpbGRDb25maWcsIENvbXBsaWFuY2VDb25maWcsIERhdGFiYXNlQ29uZmlnLCBPYnNlcnZhYmlsaXR5Q29uZmlnLCBQbHVnaW5CdWlsZENvbmZpZywgUmVkaXNDb25maWcsIFJlZ2lzdHJ5Q29uZmlnIH0gZnJvbSAnLi9jb25maWctdHlwZXMnO1xuaW1wb3J0IHsgZ2V0Q29tcHV0ZVR5cGUgfSBmcm9tICcuLi9jb3JlL3BpcGVsaW5lLWhlbHBlcnMnO1xuXG5mdW5jdGlvbiByZXF1aXJlSW5Qcm9kdWN0aW9uKGVudlZhcjogc3RyaW5nLCBkZXZEZWZhdWx0OiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCB2YWx1ZSA9IHByb2Nlc3MuZW52W2VudlZhcl07XG4gIGlmICh2YWx1ZSkgcmV0dXJuIHZhbHVlO1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdwcm9kdWN0aW9uJykge1xuICAgIHRocm93IG5ldyBFcnJvcihgJHtlbnZWYXJ9IGlzIHJlcXVpcmVkIGluIHByb2R1Y3Rpb25gKTtcbiAgfVxuICByZXR1cm4gZGV2RGVmYXVsdDtcbn1cblxuLyoqXG4gKiBMb2FkIERvY2tlciByZWdpc3RyeSBjb25maWd1cmF0aW9uIGZyb20gZW52aXJvbm1lbnQgdmFyaWFibGVzLlxuICpcbiAqIEVudmlyb25tZW50IHZhcmlhYmxlczpcbiAqIC0gYElNQUdFX1JFR0lTVFJZX0hPU1RgIOKAlCBSZWdpc3RyeSBob3N0bmFtZSAoZGVmYXVsdDogYCdyZWdpc3RyeSdgKVxuICogLSBgSU1BR0VfUkVHSVNUUllfUE9SVGAg4oCUIFJlZ2lzdHJ5IHBvcnQgKGRlZmF1bHQ6IGA1MDAwYClcbiAqIC0gYElNQUdFX1JFR0lTVFJZX1VTRVJgIOKAlCBSZWdpc3RyeSB1c2VybmFtZSAoZGVmYXVsdDogYCdhZG1pbidgKVxuICogLSBgSU1BR0VfUkVHSVNUUllfVE9LRU5gIOKAlCBSZWdpc3RyeSBhdXRoIHRva2VuIChkZWZhdWx0OiBgJ3Bhc3N3b3JkJ2ApXG4gKiAtIGBET0NLRVJfTkVUV09SS2Ag4oCUIERvY2tlciBuZXR3b3JrIGZvciBidWlsZC9wdXNoIChkZWZhdWx0OiBgJydgKVxuICogLSBgRE9DS0VSX1JFR0lTVFJZX0hUVFBgIOKAlCBVc2UgcGxhaW4gSFRUUCAoZGVmYXVsdDogYHRydWVgKS4gU2V0IGBmYWxzZWAgZm9yIEhUVFBTLlxuICogLSBgRE9DS0VSX1JFR0lTVFJZX0lOU0VDVVJFYCDigJQgU2tpcCBUTFMgdmVyaWZpY2F0aW9uIChkZWZhdWx0OiBgdHJ1ZWApLiBTZXQgYGZhbHNlYCBmb3IgcHJvZHVjdGlvbi5cbiAqXG4gKiBAcmV0dXJucyBSZWdpc3RyeSBjb25maWd1cmF0aW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsb2FkUmVnaXN0cnlDb25maWcoKTogUmVnaXN0cnlDb25maWcge1xuICByZXR1cm4ge1xuICAgIGhvc3Q6IHByb2Nlc3MuZW52LklNQUdFX1JFR0lTVFJZX0hPU1QgfHwgJ3JlZ2lzdHJ5JyxcbiAgICBwb3J0OiBwYXJzZUludChwcm9jZXNzLmVudi5JTUFHRV9SRUdJU1RSWV9QT1JUIHx8ICc1MDAwJywgMTApLFxuICAgIHVzZXI6IHJlcXVpcmVJblByb2R1Y3Rpb24oJ0lNQUdFX1JFR0lTVFJZX1VTRVInLCAnYWRtaW4nKSxcbiAgICB0b2tlbjogcmVxdWlyZUluUHJvZHVjdGlvbignSU1BR0VfUkVHSVNUUllfVE9LRU4nLCAncGFzc3dvcmQnKSxcbiAgICBuZXR3b3JrOiBwcm9jZXNzLmVudi5ET0NLRVJfTkVUV09SSyB8fCAnJyxcbiAgICBodHRwOiBwcm9jZXNzLmVudi5ET0NLRVJfUkVHSVNUUllfSFRUUCAhPT0gJ2ZhbHNlJyxcbiAgICBpbnNlY3VyZTogcHJvY2Vzcy5lbnYuRE9DS0VSX1JFR0lTVFJZX0lOU0VDVVJFICE9PSAnZmFsc2UnLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbG9hZFJlZGlzQ29uZmlnKCk6IFJlZGlzQ29uZmlnIHtcbiAgcmV0dXJuIHtcbiAgICBob3N0OiBwcm9jZXNzLmVudi5SRURJU19IT1NUIHx8ICdsb2NhbGhvc3QnLFxuICAgIHBvcnQ6IHBhcnNlSW50KHByb2Nlc3MuZW52LlJFRElTX1BPUlQgfHwgJzYzNzknLCAxMCksXG4gIH07XG59XG5cbi8qKlxuICogTG9hZCBwbHVnaW4gYnVpbGQgcXVldWUgY29uZmlndXJhdGlvbi5cbiAqXG4gKiBFbnZpcm9ubWVudCB2YXJpYWJsZXM6XG4gKiAtIGBQTFVHSU5fQlVJTERfQ09OQ1VSUkVOQ1lgIOKAlCBNYXggY29uY3VycmVudCBwbHVnaW4gYnVpbGRzIChkZWZhdWx0OiBgMWApXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsb2FkUGx1Z2luQnVpbGRDb25maWcoKTogUGx1Z2luQnVpbGRDb25maWcge1xuICByZXR1cm4ge1xuICAgIGNvbmN1cnJlbmN5OiBwYXJzZUludChwcm9jZXNzLmVudi5QTFVHSU5fQlVJTERfQ09OQ1VSUkVOQ1kgfHwgJzEnLCAxMCksXG4gICAgbWF4QXR0ZW1wdHM6IHBhcnNlSW50KHByb2Nlc3MuZW52LlBMVUdJTl9CVUlMRF9NQVhfQVRURU1QVFMgfHwgJzInLCAxMCksXG4gICAgYmFja29mZkRlbGF5TXM6IHBhcnNlSW50KHByb2Nlc3MuZW52LlBMVUdJTl9CVUlMRF9CQUNLT0ZGX0RFTEFZX01TIHx8ICc1MDAwJywgMTApLFxuICAgIHdvcmtlclRpbWVvdXRNczogcGFyc2VJbnQocHJvY2Vzcy5lbnYuUExVR0lOX0JVSUxEX1dPUktFUl9USU1FT1VUX01TIHx8ICcxMDAwMCcsIDEwKSxcbiAgICB0ZW1wRGlyTWF4QWdlTXM6IHBhcnNlSW50KHByb2Nlc3MuZW52LlRFTVBfRElSX01BWF9BR0VfTVMgfHwgJzE0NDAwMDAwJywgMTApLFxuICAgIGRscU1heEF0dGVtcHRzOiBwYXJzZUludChwcm9jZXNzLmVudi5QTFVHSU5fRExRX01BWF9BVFRFTVBUUyB8fCAnMycsIDEwKSxcbiAgICBkbHFCYWNrb2ZmQmFzZU1zOiBwYXJzZUludChwcm9jZXNzLmVudi5QTFVHSU5fRExRX0JBQ0tPRkZfQkFTRV9NUyB8fCAnMzAwMDAwJywgMTApLFxuICAgIGRscU1heFNpemU6IHBhcnNlSW50KHByb2Nlc3MuZW52LlBMVUdJTl9ETFFfTUFYX1NJWkUgfHwgJzIwJywgMTApLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbG9hZERhdGFiYXNlQ29uZmlnKCk6IERhdGFiYXNlQ29uZmlnIHtcbiAgcmV0dXJuIHtcbiAgICBwb3N0Z3Jlczoge1xuICAgICAgaG9zdDogcHJvY2Vzcy5lbnYuREJfSE9TVCB8fCAncG9zdGdyZXMnLFxuICAgICAgcG9ydDogcGFyc2VJbnQocHJvY2Vzcy5lbnYuREJfUE9SVCB8fCAnNTQzMicsIDEwKSxcbiAgICAgIGRhdGFiYXNlOiBwcm9jZXNzLmVudi5EQVRBQkFTRSB8fCAncGlwZWxpbmVfYnVpbGRlcicsXG4gICAgICB1c2VyOiBwcm9jZXNzLmVudi5EQl9VU0VSIHx8ICdwb3N0Z3JlcycsXG4gICAgICBwYXNzd29yZDogcHJvY2Vzcy5lbnYuREJfUEFTU1dPUkQgfHwgJycsXG4gICAgfSxcbiAgICBkcml6emxlOiB7XG4gICAgICBtYXhQb29sU2l6ZTogcGFyc2VJbnQocHJvY2Vzcy5lbnYuRFJJWlpMRV9NQVhfUE9PTF9TSVpFIHx8ICcyMCcsIDEwKSxcbiAgICAgIGlkbGVUaW1lb3V0TWlsbGlzOiBwYXJzZUludChwcm9jZXNzLmVudi5EUklaWkxFX0lETEVfVElNRU9VVF9NSUxMSVMgfHwgJzMwMDAwJywgMTApLFxuICAgICAgY29ubmVjdGlvblRpbWVvdXRNaWxsaXM6IHBhcnNlSW50KHByb2Nlc3MuZW52LkRSSVpaTEVfQ09OTkVDVElPTl9USU1FT1VUX01JTExJUyB8fCAnMTAwMDAnLCAxMCksXG4gICAgfSxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxvYWRPYnNlcnZhYmlsaXR5Q29uZmlnKCk6IE9ic2VydmFiaWxpdHlDb25maWcge1xuICByZXR1cm4ge1xuICAgIGxvZ0xldmVsOiBwcm9jZXNzLmVudi5MT0dfTEVWRUwgfHwgJ2luZm8nLFxuICAgIGxvZ0Zvcm1hdDogcHJvY2Vzcy5lbnYuTE9HX0ZPUk1BVCB8fCAnanNvbicsXG4gICAgc2VydmljZU5hbWU6IHByb2Nlc3MuZW52LlNFUlZJQ0VfTkFNRSB8fCAnYXBpJyxcbiAgICB0cmFjaW5nOiB7XG4gICAgICBlbmFibGVkOiBwcm9jZXNzLmVudi5PVEVMX1RSQUNJTkdfRU5BQkxFRCA9PT0gJ3RydWUnLFxuICAgICAgZW5kcG9pbnQ6IHByb2Nlc3MuZW52Lk9URUxfRVhQT1JURVJfT1RMUF9FTkRQT0lOVCB8fCAnaHR0cDovL2xvY2FsaG9zdDo0MzE4L3YxL3RyYWNlcycsXG4gICAgfSxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxvYWRDb21wbGlhbmNlQ29uZmlnKCk6IENvbXBsaWFuY2VDb25maWcge1xuICByZXR1cm4ge1xuICAgIHNjYW5TY2hlZHVsZXJJbnRlcnZhbE1zOiBwYXJzZUludChwcm9jZXNzLmVudi5TQ0FOX1NDSEVEVUxFUl9JTlRFUlZBTF9NUyB8fCAnNjAwMDAnLCAxMCksXG4gIH07XG59XG5cbi8qKlxuICogTG9hZCBEb2NrZXIvUG9kbWFuL0thbmlrbyBidWlsZCBjb25maWd1cmF0aW9uLlxuICpcbiAqIEVudmlyb25tZW50IHZhcmlhYmxlczpcbiAqIC0gYERPQ0tFUl9CVUlMRF9TVFJBVEVHWWAg4oCUIEJ1aWxkIHN0cmF0ZWd5OiBgcG9kbWFuYCwgYGRvY2tlcmAsIG9yIGBrYW5pa29gIChkZWZhdWx0OiBgcG9kbWFuYClcbiAqIC0gYERPQ0tFUl9CVUlMRF9URU1QX1JPT1RgIOKAlCBUZW1wIGRpcmVjdG9yeSBmb3IgYnVpbGQgY29udGV4dHMgKGRlZmF1bHQ6IGA8Y3dkPi90bXBgKVxuICogLSBgRE9DS0VSX0JVSUxEX1RJTUVPVVRfTVNgIOKAlCBCdWlsZCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcyAoZGVmYXVsdDogYDkwMDAwMGAgLyAxNSBtaW4pXG4gKiAtIGBET0NLRVJfUFVTSF9USU1FT1VUX01TYCDigJQgUHVzaCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcyAoZGVmYXVsdDogYDMwMDAwMGAgLyA1IG1pbilcbiAqIC0gYEtBTklLT19FWEVDVVRPUl9QQVRIYCDigJQgUGF0aCB0byBLYW5pa28gZXhlY3V0b3IgYmluYXJ5IChkZWZhdWx0OiBgL2thbmlrby9leGVjdXRvcmApXG4gKiAtIGBLQU5JS09fQ0FDSEVfRElSYCDigJQgS2FuaWtvIGxheWVyIGNhY2hlIGRpcmVjdG9yeSAoZGVmYXVsdDogYC9rYW5pa28vY2FjaGVgKVxuICovXG5leHBvcnQgZnVuY3Rpb24gbG9hZERvY2tlckNvbmZpZygpOiBCdWlsZENvbmZpZyB7XG4gIGNvbnN0IHZhbGlkU3RyYXRlZ2llcyA9IG5ldyBTZXQoWydkb2NrZXInLCAna2FuaWtvJywgJ3BvZG1hbiddKTtcbiAgY29uc3Qgc3RyYXRlZ3lFbnYgPSAocHJvY2Vzcy5lbnYuRE9DS0VSX0JVSUxEX1NUUkFURUdZIHx8ICcnKS50b0xvd2VyQ2FzZSgpO1xuICByZXR1cm4ge1xuICAgIHN0cmF0ZWd5OiB2YWxpZFN0cmF0ZWdpZXMuaGFzKHN0cmF0ZWd5RW52KSA/IHN0cmF0ZWd5RW52IGFzIEJ1aWxkQ29uZmlnWydzdHJhdGVneSddIDogJ2RvY2tlcicsXG4gICAgdGVtcFJvb3Q6IHByb2Nlc3MuZW52LkRPQ0tFUl9CVUlMRF9URU1QX1JPT1QgfHwgcGF0aC5qb2luKHByb2Nlc3MuY3dkKCksICd0bXAnKSxcbiAgICB0aW1lb3V0TXM6IHBhcnNlSW50KHByb2Nlc3MuZW52LkRPQ0tFUl9CVUlMRF9USU1FT1VUX01TIHx8ICc5MDAwMDAnLCAxMCksXG4gICAgcHVzaFRpbWVvdXRNczogcGFyc2VJbnQocHJvY2Vzcy5lbnYuRE9DS0VSX1BVU0hfVElNRU9VVF9NUyB8fCAnMzAwMDAwJywgMTApLFxuICAgIGthbmlrb0V4ZWN1dG9yOiBwcm9jZXNzLmVudi5LQU5JS09fRVhFQ1VUT1JfUEFUSCB8fCAnL2thbmlrby9leGVjdXRvcicsXG4gICAga2FuaWtvQ2FjaGVEaXI6IHByb2Nlc3MuZW52LktBTklLT19DQUNIRV9ESVIgfHwgJy9rYW5pa28vY2FjaGUnLFxuICB9O1xufVxuXG4vKipcbiAqIExvYWQgQVdTIGluZnJhc3RydWN0dXJlIGNvbmZpZ3VyYXRpb24gZnJvbSBlbnZpcm9ubWVudCB2YXJpYWJsZXMuXG4gKlxuICogRW52aXJvbm1lbnQgdmFyaWFibGVzOlxuICogLSBgTEFNQkRBX1JVTlRJTUVgIOKAlCBMYW1iZGEgcnVudGltZSAoZGVmYXVsdDogYCdub2RlanMyNC54J2A7IHN1cHBvcnRzIG5vZGVqczIyLngsIG5vZGVqczI0LngpXG4gKiAtIGBMQU1CREFfVElNRU9VVGAg4oCUIExhbWJkYSB0aW1lb3V0IGluIHNlY29uZHMgKGRlZmF1bHQ6IGA5MDBgKVxuICogLSBgTEFNQkRBX01FTU9SWV9TSVpFYCDigJQgTGFtYmRhIG1lbW9yeSBpbiBNQiAoZGVmYXVsdDogYDEyOGApXG4gKiAtIGBMQU1CREFfQVJDSElURUNUVVJFYCDigJQgYCd4ODZfNjQnYCBvciBBUk0gKGRlZmF1bHQ6IEFSTV82NClcbiAqIC0gYExPR19HUk9VUF9OQU1FYCDigJQgQ2xvdWRXYXRjaCBsb2cgZ3JvdXAgKGRlZmF1bHQ6IGAnL3BpcGVsaW5lLWJ1aWxkZXIvbG9ncydgKVxuICogLSBgTE9HX1JFVEVOVElPTmAg4oCUIExvZyByZXRlbnRpb24gaW4gZGF5cyAoZGVmYXVsdDogYDdgKVxuICogLSBgTE9HX1JFTU9WQUxfUE9MSUNZYCDigJQgYCdSRVRBSU4nYCBvciBkZXN0cm95IChkZWZhdWx0OiBERVNUUk9ZKVxuICogLSBgQ09ERUJVSUxEX0NPTVBVVEVfVFlQRWAg4oCUIENvZGVCdWlsZCBjb21wdXRlIHR5cGUgKGRlZmF1bHQ6IGAnU01BTEwnYClcbiAqXG4gKiBAcmV0dXJucyBBV1MgaW5mcmFzdHJ1Y3R1cmUgY29uZmlndXJhdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gbG9hZEFXU0NvbmZpZygpOiBBV1NDb25maWcge1xuICByZXR1cm4ge1xuICAgIGxhbWJkYToge1xuICAgICAgcnVudGltZTogcGFyc2VSdW50aW1lKHByb2Nlc3MuZW52LkxBTUJEQV9SVU5USU1FIHx8ICdub2RlanMyNC54JyksXG4gICAgICB0aW1lb3V0OiBEdXJhdGlvbi5zZWNvbmRzKHBhcnNlSW50KHByb2Nlc3MuZW52LkxBTUJEQV9USU1FT1VUIHx8ICc5MDAnLCAxMCkpLFxuICAgICAgbWVtb3J5U2l6ZTogcGFyc2VJbnQocHJvY2Vzcy5lbnYuTEFNQkRBX01FTU9SWV9TSVpFIHx8ICc1MTInLCAxMCksXG4gICAgICBhcmNoaXRlY3R1cmU6IHByb2Nlc3MuZW52LkxBTUJEQV9BUkNISVRFQ1RVUkUgPT09ICd4ODZfNjQnXG4gICAgICAgID8gQXJjaGl0ZWN0dXJlLlg4Nl82NFxuICAgICAgICA6IEFyY2hpdGVjdHVyZS5BUk1fNjQsXG4gICAgICByZXNlcnZlZENvbmN1cnJlbnRFeGVjdXRpb25zOiBwcm9jZXNzLmVudi5MQU1CREFfUkVTRVJWRURfQ09OQ1VSUkVOQ1lcbiAgICAgICAgPyBwYXJzZUludChwcm9jZXNzLmVudi5MQU1CREFfUkVTRVJWRURfQ09OQ1VSUkVOQ1ksIDEwKVxuICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICB9LFxuXG4gICAgbG9nZ2luZzoge1xuICAgICAgZ3JvdXBOYW1lOiBwcm9jZXNzLmVudi5MT0dfR1JPVVBfTkFNRSB8fCAnL3BpcGVsaW5lLWJ1aWxkZXIvbG9ncycsXG4gICAgICByZXRlbnRpb246IHBhcnNlUmV0ZW50aW9uKHByb2Nlc3MuZW52LkxPR19SRVRFTlRJT04gfHwgJzcnKSxcbiAgICAgIHJlbW92YWxQb2xpY3k6IHByb2Nlc3MuZW52LkxPR19SRU1PVkFMX1BPTElDWSA9PT0gJ1JFVEFJTidcbiAgICAgICAgPyBSZW1vdmFsUG9saWN5LlJFVEFJTlxuICAgICAgICA6IFJlbW92YWxQb2xpY3kuREVTVFJPWSxcbiAgICB9LFxuXG4gICAgY29kZUJ1aWxkOiB7XG4gICAgICBjb21wdXRlVHlwZTogZ2V0Q29tcHV0ZVR5cGUocHJvY2Vzcy5lbnYuQ09ERUJVSUxEX0NPTVBVVEVfVFlQRSB8fCAnU01BTEwnKSxcbiAgICB9LFxuXG4gICAgcmVzb2x2ZWRTeW50aFBsdWdpbjogcHJvY2Vzcy5lbnYuUkVTT0xWRURfU1lOVEhfUExVR0lOID09PSAndHJ1ZScsXG4gIH07XG59XG5cbi8qKlxuICogUGFyc2UgTGFtYmRhIHJ1bnRpbWUgc3RyaW5nIGludG8gYSBDREsgUnVudGltZSBlbnVtIHZhbHVlLlxuICpcbiAqIEBwYXJhbSBydW50aW1lIC0gUnVudGltZSBzdHJpbmcgKGUuZy4gYCdub2RlanMyNC54J2ApXG4gKiBAcmV0dXJucyBDREsgUnVudGltZSBlbnVtOyBmYWxscyBiYWNrIHRvIE5PREVKU18yNF9YIGZvciB1bmtub3duIHZhbHVlc1xuICovXG5mdW5jdGlvbiBwYXJzZVJ1bnRpbWUocnVudGltZTogc3RyaW5nKTogUnVudGltZSB7XG4gIGNvbnN0IHJ1bnRpbWVNYXA6IFJlY29yZDxzdHJpbmcsIFJ1bnRpbWU+ID0ge1xuICAgICdub2RlanMyNC54JzogUnVudGltZS5OT0RFSlNfMjRfWCxcbiAgfTtcbiAgcmV0dXJuIHJ1bnRpbWVNYXBbcnVudGltZV0gfHwgUnVudGltZS5OT0RFSlNfMjRfWDtcbn1cblxuLyoqXG4gKiBQYXJzZSBsb2cgcmV0ZW50aW9uIGRheXMgc3RyaW5nIGludG8gYSBDREsgUmV0ZW50aW9uRGF5cyBlbnVtIHZhbHVlLlxuICogUmV0ZW50aW9uRGF5cyBlbnVtIHZhbHVlcyBhcmUgdGhlIG51bWVyaWMgZGF5IGNvdW50cyB0aGVtc2VsdmVzLFxuICogc28gd2UgcGFyc2UgdGhlIHN0cmluZyBhbmQgY2hlY2sgaWYgaXQncyBhIHZhbGlkIGVudW0gbWVtYmVyLlxuICpcbiAqIEBwYXJhbSBkYXlzIC0gUmV0ZW50aW9uIHBlcmlvZCBpbiBkYXlzIGFzIGEgc3RyaW5nIChlLmcuIGAnMzAnYClcbiAqIEByZXR1cm5zIENESyBSZXRlbnRpb25EYXlzIGVudW07IGZhbGxzIGJhY2sgdG8gT05FX0RBWSBmb3IgdW5rbm93biB2YWx1ZXNcbiAqL1xuY29uc3QgVkFMSURfUkVURU5USU9OX0RBWVMgPSBuZXcgU2V0KE9iamVjdC52YWx1ZXMoUmV0ZW50aW9uRGF5cykuZmlsdGVyKCh2KTogdiBpcyBudW1iZXIgPT4gdHlwZW9mIHYgPT09ICdudW1iZXInKSk7XG5cbmZ1bmN0aW9uIHBhcnNlUmV0ZW50aW9uKGRheXM6IHN0cmluZyk6IFJldGVudGlvbkRheXMge1xuICBjb25zdCBwYXJzZWQgPSBwYXJzZUludChkYXlzLCAxMCk7XG4gIHJldHVybiBWQUxJRF9SRVRFTlRJT05fREFZUy5oYXMocGFyc2VkKSA/IHBhcnNlZCBhcyBSZXRlbnRpb25EYXlzIDogUmV0ZW50aW9uRGF5cy5PTkVfREFZO1xufVxuIl19
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { ServerConfig, AuthConfig, RateLimitConfig } from './config-types';
|
|
2
|
+
/**
|
|
3
|
+
* Load server configuration from environment variables.
|
|
4
|
+
*
|
|
5
|
+
* Environment variables:
|
|
6
|
+
* - `PORT` — HTTP listen port (default: `3000`)
|
|
7
|
+
* - `CORS_ORIGIN` — Comma-separated allowed origins (default: `PLATFORM_BASE_URL`)
|
|
8
|
+
* - `CORS_CREDENTIALS` — Allow credentials; set to `'false'` to disable (default: `true`)
|
|
9
|
+
* - `TRUST_PROXY` — Express trust proxy hops (default: `1`)
|
|
10
|
+
* - `PLATFORM_BASE_URL` — Frontend URL used as CORS fallback (default: `'https://localhost:8443'`)
|
|
11
|
+
*
|
|
12
|
+
* @returns Server configuration with port, CORS, trust proxy, and platform URL
|
|
13
|
+
*/
|
|
14
|
+
export declare function loadServerConfig(): ServerConfig;
|
|
15
|
+
/**
|
|
16
|
+
* Load authentication configuration from environment variables.
|
|
17
|
+
*
|
|
18
|
+
* Environment variables:
|
|
19
|
+
* - `JWT_SECRET` — **Required.** Secret key for signing JWTs
|
|
20
|
+
* - `REFRESH_TOKEN_SECRET` — **Required.** Secret key for signing refresh tokens
|
|
21
|
+
* - `JWT_EXPIRES_IN` — JWT lifetime in seconds (default: `7200` = 2 hours)
|
|
22
|
+
* - `JWT_ALGORITHM` — JWT signing algorithm (default: `'HS256'`)
|
|
23
|
+
* - `JWT_SALT_ROUNDS` — bcrypt salt rounds for password hashing (default: `12`)
|
|
24
|
+
* - `REFRESH_TOKEN_EXPIRES_IN` — Refresh token lifetime in seconds (default: `2592000` = 30 days)
|
|
25
|
+
*
|
|
26
|
+
* @returns Authentication configuration with safe defaults (empty strings when env vars are unset).
|
|
27
|
+
* Call {@link validateAuthConfig} at server startup to enforce required secrets.
|
|
28
|
+
*/
|
|
29
|
+
export declare function loadAuthConfig(): AuthConfig;
|
|
30
|
+
/**
|
|
31
|
+
* Load rate limiting configuration from environment variables.
|
|
32
|
+
*
|
|
33
|
+
* Environment variables:
|
|
34
|
+
* - `LIMITER_MAX` — Max requests per window (default: `100`)
|
|
35
|
+
* - `LIMITER_WINDOWMS` — Rate limit window in ms (default: `900000` = 15 minutes)
|
|
36
|
+
*
|
|
37
|
+
* @returns Rate limit configuration
|
|
38
|
+
*/
|
|
39
|
+
export declare function loadRateLimitConfig(): RateLimitConfig;
|
|
40
|
+
/**
|
|
41
|
+
* Validate server configuration and log warnings for insecure settings.
|
|
42
|
+
*
|
|
43
|
+
* @param config - Server configuration to validate
|
|
44
|
+
*/
|
|
45
|
+
export declare function validateServerConfig(config: ServerConfig): void;
|
|
46
|
+
/**
|
|
47
|
+
* Validate authentication configuration (JWT secrets, algorithms, expiration).
|
|
48
|
+
* Call this at server startup, not during CDK synthesis.
|
|
49
|
+
*
|
|
50
|
+
* @param config - Auth configuration to validate
|
|
51
|
+
* @throws {Error} If secrets are insecure, too short (<32 chars), or use disallowed algorithms
|
|
52
|
+
*/
|
|
53
|
+
export declare function validateAuthConfig(config: AuthConfig): void;
|