@engjts/nexus 0.1.8 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/advanced/playground/playground.js.map +1 -1
- package/dist/advanced/static/generateDirectoryListing.d.ts +1 -1
- package/dist/advanced/static/generateDirectoryListing.d.ts.map +1 -1
- package/dist/advanced/static/generateDirectoryListing.js +12 -6
- package/dist/advanced/static/generateDirectoryListing.js.map +1 -1
- package/dist/advanced/static/index.d.ts +2 -0
- package/dist/advanced/static/index.d.ts.map +1 -1
- package/dist/advanced/static/index.js +4 -1
- package/dist/advanced/static/index.js.map +1 -1
- package/dist/advanced/static/serveStatic.d.ts.map +1 -1
- package/dist/advanced/static/serveStatic.js +7 -1
- package/dist/advanced/static/serveStatic.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/BENCHMARK_REPORT.md +0 -343
- package/documentation/01-getting-started.md +0 -240
- package/documentation/02-context.md +0 -335
- package/documentation/03-routing.md +0 -397
- package/documentation/04-middleware.md +0 -483
- package/documentation/05-validation.md +0 -514
- package/documentation/06-error-handling.md +0 -465
- package/documentation/07-performance.md +0 -364
- package/documentation/08-adapters.md +0 -470
- package/documentation/09-api-reference.md +0 -548
- package/documentation/10-examples.md +0 -582
- package/documentation/11-deployment.md +0 -477
- package/documentation/12-sentry.md +0 -620
- package/documentation/13-sentry-data-storage.md +0 -996
- package/documentation/14-sentry-data-reference.md +0 -457
- package/documentation/15-sentry-summary.md +0 -409
- package/documentation/16-alerts-system.md +0 -745
- package/documentation/17-alert-adapters.md +0 -696
- package/documentation/18-alerts-implementation-summary.md +0 -385
- package/documentation/19-class-based-routing.md +0 -840
- package/documentation/20-websocket-realtime.md +0 -813
- package/documentation/21-cache-system.md +0 -510
- package/documentation/22-job-queue.md +0 -772
- package/documentation/23-sentry-plugin.md +0 -551
- package/documentation/24-testing-utilities.md +0 -1287
- package/documentation/25-api-versioning.md +0 -533
- package/documentation/26-context-store.md +0 -607
- package/documentation/27-dependency-injection.md +0 -329
- package/documentation/28-lifecycle-hooks.md +0 -521
- package/documentation/29-package-structure.md +0 -196
- package/documentation/30-plugin-system.md +0 -414
- package/documentation/31-jwt-authentication.md +0 -597
- package/documentation/32-cli.md +0 -268
- package/documentation/ALERTS-COMPLETE-SUMMARY.md +0 -429
- package/documentation/ALERTS-INDEX.md +0 -330
- package/documentation/ALERTS-QUICK-REFERENCE.md +0 -286
- package/documentation/README.md +0 -178
- package/documentation/index.html +0 -34
- package/modern_framework_paper.md +0 -1870
- package/public/css/style.css +0 -87
- package/public/index.html +0 -34
- package/public/js/app.js +0 -27
- package/src/advanced/cache/InMemoryCacheStore.ts +0 -68
- package/src/advanced/cache/MultiTierCache.ts +0 -194
- package/src/advanced/cache/RedisCacheStore.ts +0 -341
- package/src/advanced/cache/index.ts +0 -5
- package/src/advanced/cache/types.ts +0 -40
- package/src/advanced/graphql/SimpleDataLoader.ts +0 -42
- package/src/advanced/graphql/index.ts +0 -22
- package/src/advanced/graphql/server.ts +0 -252
- package/src/advanced/graphql/types.ts +0 -42
- package/src/advanced/jobs/InMemoryQueueStore.ts +0 -68
- package/src/advanced/jobs/JobQueue.ts +0 -556
- package/src/advanced/jobs/RedisQueueStore.ts +0 -367
- package/src/advanced/jobs/index.ts +0 -5
- package/src/advanced/jobs/types.ts +0 -70
- package/src/advanced/observability/APMManager.ts +0 -163
- package/src/advanced/observability/AlertManager.ts +0 -109
- package/src/advanced/observability/MetricRegistry.ts +0 -151
- package/src/advanced/observability/ObservabilityCenter.ts +0 -304
- package/src/advanced/observability/StructuredLogger.ts +0 -154
- package/src/advanced/observability/TracingManager.ts +0 -117
- package/src/advanced/observability/adapters.ts +0 -304
- package/src/advanced/observability/createObservabilityMiddleware.ts +0 -63
- package/src/advanced/observability/index.ts +0 -11
- package/src/advanced/observability/types.ts +0 -174
- package/src/advanced/playground/extractPathParams.ts +0 -6
- package/src/advanced/playground/generateFieldExample.ts +0 -31
- package/src/advanced/playground/generatePlaygroundHTML.ts +0 -1956
- package/src/advanced/playground/generateSummary.ts +0 -19
- package/src/advanced/playground/getTagFromPath.ts +0 -9
- package/src/advanced/playground/index.ts +0 -8
- package/src/advanced/playground/playground.ts +0 -250
- package/src/advanced/playground/types.ts +0 -49
- package/src/advanced/playground/zodToExample.ts +0 -16
- package/src/advanced/playground/zodToParams.ts +0 -15
- package/src/advanced/postman/buildAuth.ts +0 -31
- package/src/advanced/postman/buildBody.ts +0 -15
- package/src/advanced/postman/buildQueryParams.ts +0 -27
- package/src/advanced/postman/buildRequestItem.ts +0 -36
- package/src/advanced/postman/buildResponses.ts +0 -11
- package/src/advanced/postman/buildUrl.ts +0 -33
- package/src/advanced/postman/capitalize.ts +0 -4
- package/src/advanced/postman/generateCollection.ts +0 -59
- package/src/advanced/postman/generateEnvironment.ts +0 -34
- package/src/advanced/postman/generateExampleFromZod.ts +0 -21
- package/src/advanced/postman/generateFieldExample.ts +0 -45
- package/src/advanced/postman/generateName.ts +0 -20
- package/src/advanced/postman/generateUUID.ts +0 -11
- package/src/advanced/postman/getTagFromPath.ts +0 -10
- package/src/advanced/postman/index.ts +0 -28
- package/src/advanced/postman/postman.ts +0 -156
- package/src/advanced/postman/slugify.ts +0 -7
- package/src/advanced/postman/types.ts +0 -140
- package/src/advanced/realtime/index.ts +0 -18
- package/src/advanced/realtime/websocket.ts +0 -231
- package/src/advanced/sentry/index.ts +0 -1236
- package/src/advanced/sentry/types.ts +0 -355
- package/src/advanced/static/generateDirectoryListing.ts +0 -47
- package/src/advanced/static/generateETag.ts +0 -7
- package/src/advanced/static/getMimeType.ts +0 -9
- package/src/advanced/static/index.ts +0 -32
- package/src/advanced/static/isSafePath.ts +0 -13
- package/src/advanced/static/publicDir.ts +0 -21
- package/src/advanced/static/serveStatic.ts +0 -225
- package/src/advanced/static/spa.ts +0 -24
- package/src/advanced/static/types.ts +0 -159
- package/src/advanced/swagger/SwaggerGenerator.ts +0 -66
- package/src/advanced/swagger/buildOperation.ts +0 -61
- package/src/advanced/swagger/buildParameters.ts +0 -61
- package/src/advanced/swagger/buildRequestBody.ts +0 -21
- package/src/advanced/swagger/buildResponses.ts +0 -54
- package/src/advanced/swagger/capitalize.ts +0 -5
- package/src/advanced/swagger/convertPath.ts +0 -9
- package/src/advanced/swagger/createSwagger.ts +0 -12
- package/src/advanced/swagger/generateOperationId.ts +0 -21
- package/src/advanced/swagger/generateSpec.ts +0 -105
- package/src/advanced/swagger/generateSummary.ts +0 -24
- package/src/advanced/swagger/generateSwaggerUI.ts +0 -70
- package/src/advanced/swagger/generateThemeCss.ts +0 -53
- package/src/advanced/swagger/index.ts +0 -25
- package/src/advanced/swagger/swagger.ts +0 -237
- package/src/advanced/swagger/types.ts +0 -206
- package/src/advanced/swagger/zodFieldToOpenAPI.ts +0 -94
- package/src/advanced/swagger/zodSchemaToOpenAPI.ts +0 -50
- package/src/advanced/swagger/zodToOpenAPI.ts +0 -22
- package/src/advanced/testing/factory.ts +0 -509
- package/src/advanced/testing/harness.ts +0 -612
- package/src/advanced/testing/index.ts +0 -430
- package/src/advanced/testing/load-test.ts +0 -618
- package/src/advanced/testing/mock-server.ts +0 -498
- package/src/advanced/testing/mock.ts +0 -670
- package/src/cli/bin.ts +0 -9
- package/src/cli/cli.ts +0 -158
- package/src/cli/commands/add.ts +0 -178
- package/src/cli/commands/build.ts +0 -73
- package/src/cli/commands/create.ts +0 -166
- package/src/cli/commands/dev.ts +0 -85
- package/src/cli/commands/generate.ts +0 -99
- package/src/cli/commands/help.ts +0 -95
- package/src/cli/commands/init.ts +0 -91
- package/src/cli/commands/version.ts +0 -38
- package/src/cli/index.ts +0 -6
- package/src/cli/templates/generators.ts +0 -359
- package/src/cli/templates/index.ts +0 -680
- package/src/cli/utils/exec.ts +0 -52
- package/src/cli/utils/file-system.ts +0 -78
- package/src/cli/utils/logger.ts +0 -111
- package/src/core/adapter.ts +0 -88
- package/src/core/application.ts +0 -1453
- package/src/core/context-pool.ts +0 -79
- package/src/core/context.ts +0 -856
- package/src/core/index.ts +0 -94
- package/src/core/middleware.ts +0 -272
- package/src/core/performance/buffer-pool.ts +0 -108
- package/src/core/performance/middleware-optimizer.ts +0 -162
- package/src/core/plugin/PluginManager.ts +0 -435
- package/src/core/plugin/builder.ts +0 -358
- package/src/core/plugin/index.ts +0 -50
- package/src/core/plugin/types.ts +0 -214
- package/src/core/router/file-router.ts +0 -623
- package/src/core/router/index.ts +0 -260
- package/src/core/router/radix-tree.ts +0 -242
- package/src/core/serializer.ts +0 -397
- package/src/core/store/index.ts +0 -30
- package/src/core/store/registry.ts +0 -178
- package/src/core/store/request-store.ts +0 -240
- package/src/core/store/types.ts +0 -233
- package/src/core/types.ts +0 -616
- package/src/database/adapter.ts +0 -35
- package/src/database/adapters/index.ts +0 -1
- package/src/database/adapters/mysql.ts +0 -669
- package/src/database/database.ts +0 -70
- package/src/database/dialect.ts +0 -388
- package/src/database/index.ts +0 -12
- package/src/database/migrations.ts +0 -86
- package/src/database/optimizer.ts +0 -125
- package/src/database/query-builder.ts +0 -404
- package/src/database/realtime.ts +0 -53
- package/src/database/schema.ts +0 -71
- package/src/database/transactions.ts +0 -56
- package/src/database/types.ts +0 -87
- package/src/deployment/cluster.ts +0 -471
- package/src/deployment/config.ts +0 -454
- package/src/deployment/docker.ts +0 -599
- package/src/deployment/graceful-shutdown.ts +0 -373
- package/src/deployment/index.ts +0 -56
- package/src/index.ts +0 -281
- package/src/security/adapter.ts +0 -318
- package/src/security/auth/JWTPlugin.ts +0 -234
- package/src/security/auth/JWTProvider.ts +0 -316
- package/src/security/auth/adapter.ts +0 -12
- package/src/security/auth/jwt.ts +0 -234
- package/src/security/auth/middleware.ts +0 -188
- package/src/security/csrf.ts +0 -220
- package/src/security/headers.ts +0 -108
- package/src/security/index.ts +0 -60
- package/src/security/rate-limit/adapter.ts +0 -7
- package/src/security/rate-limit/memory.ts +0 -108
- package/src/security/rate-limit/middleware.ts +0 -181
- package/src/security/sanitization.ts +0 -75
- package/src/security/types.ts +0 -240
- package/src/security/utils.ts +0 -52
- package/tsconfig.json +0 -39
package/src/deployment/docker.ts
DELETED
|
@@ -1,599 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Docker Support
|
|
3
|
-
* Generates optimized Dockerfile and docker-compose configurations
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { writeFileSync } from 'fs';
|
|
7
|
-
import { resolve } from 'path';
|
|
8
|
-
|
|
9
|
-
export interface DockerOptions {
|
|
10
|
-
/**
|
|
11
|
-
* Base Node.js image
|
|
12
|
-
* @default 'node:20-alpine'
|
|
13
|
-
*/
|
|
14
|
-
baseImage?: string;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Application port
|
|
18
|
-
* @default 3000
|
|
19
|
-
*/
|
|
20
|
-
port?: number;
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Working directory in container
|
|
24
|
-
* @default '/app'
|
|
25
|
-
*/
|
|
26
|
-
workdir?: string;
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Entry point file
|
|
30
|
-
* @default 'dist/index.js'
|
|
31
|
-
*/
|
|
32
|
-
entrypoint?: string;
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Use multi-stage build
|
|
36
|
-
* @default true
|
|
37
|
-
*/
|
|
38
|
-
multiStage?: boolean;
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Include health check
|
|
42
|
-
* @default true
|
|
43
|
-
*/
|
|
44
|
-
healthCheck?: boolean;
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Health check endpoint
|
|
48
|
-
* @default '/health'
|
|
49
|
-
*/
|
|
50
|
-
healthEndpoint?: string;
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Add security user
|
|
54
|
-
* @default true
|
|
55
|
-
*/
|
|
56
|
-
nonRootUser?: boolean;
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Additional environment variables
|
|
60
|
-
*/
|
|
61
|
-
env?: Record<string, string>;
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Additional labels
|
|
65
|
-
*/
|
|
66
|
-
labels?: Record<string, string>;
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Files to copy before npm install (for better caching)
|
|
70
|
-
*/
|
|
71
|
-
copyBeforeInstall?: string[];
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Files/directories to ignore
|
|
75
|
-
*/
|
|
76
|
-
ignore?: string[];
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Use npm ci instead of npm install
|
|
80
|
-
* @default true
|
|
81
|
-
*/
|
|
82
|
-
useNpmCi?: boolean;
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Prune dev dependencies in production
|
|
86
|
-
* @default true
|
|
87
|
-
*/
|
|
88
|
-
pruneDevDeps?: boolean;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export interface ComposeService {
|
|
92
|
-
build?: {
|
|
93
|
-
context?: string;
|
|
94
|
-
dockerfile?: string;
|
|
95
|
-
};
|
|
96
|
-
image?: string;
|
|
97
|
-
ports?: string[];
|
|
98
|
-
environment?: Record<string, string>;
|
|
99
|
-
env_file?: string[];
|
|
100
|
-
depends_on?: string[];
|
|
101
|
-
volumes?: string[];
|
|
102
|
-
networks?: string[];
|
|
103
|
-
healthcheck?: {
|
|
104
|
-
test: string[];
|
|
105
|
-
interval?: string;
|
|
106
|
-
timeout?: string;
|
|
107
|
-
retries?: number;
|
|
108
|
-
start_period?: string;
|
|
109
|
-
};
|
|
110
|
-
restart?: 'no' | 'always' | 'on-failure' | 'unless-stopped';
|
|
111
|
-
deploy?: {
|
|
112
|
-
replicas?: number;
|
|
113
|
-
resources?: {
|
|
114
|
-
limits?: { cpus?: string; memory?: string };
|
|
115
|
-
reservations?: { cpus?: string; memory?: string };
|
|
116
|
-
};
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export interface ComposeConfig {
|
|
121
|
-
version?: string;
|
|
122
|
-
services?: Record<string, ComposeService>;
|
|
123
|
-
networks?: Record<string, any>;
|
|
124
|
-
volumes?: Record<string, any>;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Docker Generator
|
|
129
|
-
*/
|
|
130
|
-
export class DockerGenerator {
|
|
131
|
-
private options: Required<DockerOptions>;
|
|
132
|
-
|
|
133
|
-
constructor(options: DockerOptions = {}) {
|
|
134
|
-
this.options = {
|
|
135
|
-
baseImage: options.baseImage ?? 'node:20-alpine',
|
|
136
|
-
port: options.port ?? 3000,
|
|
137
|
-
workdir: options.workdir ?? '/app',
|
|
138
|
-
entrypoint: options.entrypoint ?? 'dist/index.js',
|
|
139
|
-
multiStage: options.multiStage ?? true,
|
|
140
|
-
healthCheck: options.healthCheck ?? true,
|
|
141
|
-
healthEndpoint: options.healthEndpoint ?? '/health',
|
|
142
|
-
nonRootUser: options.nonRootUser ?? true,
|
|
143
|
-
env: options.env ?? {},
|
|
144
|
-
labels: options.labels ?? {},
|
|
145
|
-
copyBeforeInstall: options.copyBeforeInstall ?? ['package*.json'],
|
|
146
|
-
ignore: options.ignore ?? [
|
|
147
|
-
'node_modules',
|
|
148
|
-
'.git',
|
|
149
|
-
'.env*',
|
|
150
|
-
'*.log',
|
|
151
|
-
'.DS_Store',
|
|
152
|
-
'coverage',
|
|
153
|
-
'.nyc_output',
|
|
154
|
-
'test',
|
|
155
|
-
'tests',
|
|
156
|
-
'__tests__',
|
|
157
|
-
'*.test.ts',
|
|
158
|
-
'*.spec.ts'
|
|
159
|
-
],
|
|
160
|
-
useNpmCi: options.useNpmCi ?? true,
|
|
161
|
-
pruneDevDeps: options.pruneDevDeps ?? true
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Generate Dockerfile content
|
|
167
|
-
*/
|
|
168
|
-
generateDockerfile(): string {
|
|
169
|
-
if (this.options.multiStage) {
|
|
170
|
-
return this.generateMultiStageDockerfile();
|
|
171
|
-
}
|
|
172
|
-
return this.generateSimpleDockerfile();
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Generate multi-stage Dockerfile for optimized builds
|
|
177
|
-
*/
|
|
178
|
-
private generateMultiStageDockerfile(): string {
|
|
179
|
-
const lines: string[] = [];
|
|
180
|
-
const { baseImage, workdir, port, entrypoint } = this.options;
|
|
181
|
-
|
|
182
|
-
// Base stage
|
|
183
|
-
lines.push(`# ============================================`);
|
|
184
|
-
lines.push(`# Base Stage`);
|
|
185
|
-
lines.push(`# ============================================`);
|
|
186
|
-
lines.push(`FROM ${baseImage} AS base`);
|
|
187
|
-
lines.push(`WORKDIR ${workdir}`);
|
|
188
|
-
lines.push('');
|
|
189
|
-
|
|
190
|
-
// Dependencies stage
|
|
191
|
-
lines.push(`# ============================================`);
|
|
192
|
-
lines.push(`# Dependencies Stage`);
|
|
193
|
-
lines.push(`# ============================================`);
|
|
194
|
-
lines.push(`FROM base AS deps`);
|
|
195
|
-
lines.push('');
|
|
196
|
-
|
|
197
|
-
// Copy package files
|
|
198
|
-
for (const file of this.options.copyBeforeInstall) {
|
|
199
|
-
lines.push(`COPY ${file} ./`);
|
|
200
|
-
}
|
|
201
|
-
lines.push('');
|
|
202
|
-
|
|
203
|
-
// Install production dependencies only
|
|
204
|
-
const installCmd = this.options.useNpmCi ? 'npm ci --only=production' : 'npm install --only=production';
|
|
205
|
-
lines.push(`# Install production dependencies only`);
|
|
206
|
-
lines.push(`RUN ${installCmd}`);
|
|
207
|
-
lines.push('');
|
|
208
|
-
|
|
209
|
-
// Build stage
|
|
210
|
-
lines.push(`# ============================================`);
|
|
211
|
-
lines.push(`# Build Stage`);
|
|
212
|
-
lines.push(`# ============================================`);
|
|
213
|
-
lines.push(`FROM base AS build`);
|
|
214
|
-
lines.push('');
|
|
215
|
-
|
|
216
|
-
// Copy package files
|
|
217
|
-
for (const file of this.options.copyBeforeInstall) {
|
|
218
|
-
lines.push(`COPY ${file} ./`);
|
|
219
|
-
}
|
|
220
|
-
lines.push('');
|
|
221
|
-
|
|
222
|
-
// Install all dependencies
|
|
223
|
-
const devInstallCmd = this.options.useNpmCi ? 'npm ci' : 'npm install';
|
|
224
|
-
lines.push(`# Install all dependencies (including dev)`);
|
|
225
|
-
lines.push(`RUN ${devInstallCmd}`);
|
|
226
|
-
lines.push('');
|
|
227
|
-
|
|
228
|
-
// Copy source code
|
|
229
|
-
lines.push(`# Copy source code`);
|
|
230
|
-
lines.push(`COPY . .`);
|
|
231
|
-
lines.push('');
|
|
232
|
-
|
|
233
|
-
// Build
|
|
234
|
-
lines.push(`# Build application`);
|
|
235
|
-
lines.push(`RUN npm run build`);
|
|
236
|
-
lines.push('');
|
|
237
|
-
|
|
238
|
-
// Production stage
|
|
239
|
-
lines.push(`# ============================================`);
|
|
240
|
-
lines.push(`# Production Stage`);
|
|
241
|
-
lines.push(`# ============================================`);
|
|
242
|
-
lines.push(`FROM base AS production`);
|
|
243
|
-
lines.push('');
|
|
244
|
-
|
|
245
|
-
// Security: non-root user
|
|
246
|
-
if (this.options.nonRootUser) {
|
|
247
|
-
lines.push(`# Create non-root user for security`);
|
|
248
|
-
lines.push(`RUN addgroup --system --gid 1001 nodejs`);
|
|
249
|
-
lines.push(`RUN adduser --system --uid 1001 nexus`);
|
|
250
|
-
lines.push('');
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
// Set NODE_ENV
|
|
254
|
-
lines.push(`# Set environment`);
|
|
255
|
-
lines.push(`ENV NODE_ENV=production`);
|
|
256
|
-
|
|
257
|
-
// Additional environment variables
|
|
258
|
-
for (const [key, value] of Object.entries(this.options.env)) {
|
|
259
|
-
lines.push(`ENV ${key}=${value}`);
|
|
260
|
-
}
|
|
261
|
-
lines.push('');
|
|
262
|
-
|
|
263
|
-
// Labels
|
|
264
|
-
if (Object.keys(this.options.labels).length > 0) {
|
|
265
|
-
lines.push(`# Labels`);
|
|
266
|
-
for (const [key, value] of Object.entries(this.options.labels)) {
|
|
267
|
-
lines.push(`LABEL ${key}="${value}"`);
|
|
268
|
-
}
|
|
269
|
-
lines.push('');
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// Copy dependencies and build output
|
|
273
|
-
if (this.options.nonRootUser) {
|
|
274
|
-
lines.push(`# Copy dependencies from deps stage`);
|
|
275
|
-
lines.push(`COPY --from=deps --chown=nexus:nodejs ${workdir}/node_modules ./node_modules`);
|
|
276
|
-
lines.push('');
|
|
277
|
-
lines.push(`# Copy built application from build stage`);
|
|
278
|
-
lines.push(`COPY --from=build --chown=nexus:nodejs ${workdir}/dist ./dist`);
|
|
279
|
-
lines.push(`COPY --from=build --chown=nexus:nodejs ${workdir}/package.json ./`);
|
|
280
|
-
lines.push('');
|
|
281
|
-
lines.push(`# Switch to non-root user`);
|
|
282
|
-
lines.push(`USER nexus`);
|
|
283
|
-
} else {
|
|
284
|
-
lines.push(`# Copy dependencies from deps stage`);
|
|
285
|
-
lines.push(`COPY --from=deps ${workdir}/node_modules ./node_modules`);
|
|
286
|
-
lines.push('');
|
|
287
|
-
lines.push(`# Copy built application from build stage`);
|
|
288
|
-
lines.push(`COPY --from=build ${workdir}/dist ./dist`);
|
|
289
|
-
lines.push(`COPY --from=build ${workdir}/package.json ./`);
|
|
290
|
-
}
|
|
291
|
-
lines.push('');
|
|
292
|
-
|
|
293
|
-
// Expose port
|
|
294
|
-
lines.push(`# Expose port`);
|
|
295
|
-
lines.push(`EXPOSE ${port}`);
|
|
296
|
-
lines.push('');
|
|
297
|
-
|
|
298
|
-
// Health check
|
|
299
|
-
if (this.options.healthCheck) {
|
|
300
|
-
lines.push(`# Health check`);
|
|
301
|
-
lines.push(`HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \\`);
|
|
302
|
-
lines.push(` CMD wget --no-verbose --tries=1 --spider http://localhost:${port}${this.options.healthEndpoint} || exit 1`);
|
|
303
|
-
lines.push('');
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
// Start command
|
|
307
|
-
lines.push(`# Start the application`);
|
|
308
|
-
lines.push(`CMD ["node", "${entrypoint}"]`);
|
|
309
|
-
|
|
310
|
-
return lines.join('\n');
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* Generate simple single-stage Dockerfile
|
|
315
|
-
*/
|
|
316
|
-
private generateSimpleDockerfile(): string {
|
|
317
|
-
const lines: string[] = [];
|
|
318
|
-
const { baseImage, workdir, port, entrypoint } = this.options;
|
|
319
|
-
|
|
320
|
-
lines.push(`FROM ${baseImage}`);
|
|
321
|
-
lines.push(`WORKDIR ${workdir}`);
|
|
322
|
-
lines.push('');
|
|
323
|
-
|
|
324
|
-
// Copy package files
|
|
325
|
-
for (const file of this.options.copyBeforeInstall) {
|
|
326
|
-
lines.push(`COPY ${file} ./`);
|
|
327
|
-
}
|
|
328
|
-
lines.push('');
|
|
329
|
-
|
|
330
|
-
const installCmd = this.options.useNpmCi ? 'npm ci' : 'npm install';
|
|
331
|
-
lines.push(`RUN ${installCmd}`);
|
|
332
|
-
lines.push('');
|
|
333
|
-
|
|
334
|
-
lines.push(`COPY . .`);
|
|
335
|
-
lines.push(`RUN npm run build`);
|
|
336
|
-
lines.push('');
|
|
337
|
-
|
|
338
|
-
if (this.options.pruneDevDeps) {
|
|
339
|
-
lines.push(`RUN npm prune --production`);
|
|
340
|
-
lines.push('');
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
lines.push(`ENV NODE_ENV=production`);
|
|
344
|
-
for (const [key, value] of Object.entries(this.options.env)) {
|
|
345
|
-
lines.push(`ENV ${key}=${value}`);
|
|
346
|
-
}
|
|
347
|
-
lines.push('');
|
|
348
|
-
|
|
349
|
-
lines.push(`EXPOSE ${port}`);
|
|
350
|
-
lines.push(`CMD ["node", "${entrypoint}"]`);
|
|
351
|
-
|
|
352
|
-
return lines.join('\n');
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
/**
|
|
356
|
-
* Generate .dockerignore content
|
|
357
|
-
*/
|
|
358
|
-
generateDockerignore(): string {
|
|
359
|
-
const lines = [
|
|
360
|
-
'# Dependencies',
|
|
361
|
-
'node_modules',
|
|
362
|
-
'',
|
|
363
|
-
'# Build output',
|
|
364
|
-
'dist',
|
|
365
|
-
'',
|
|
366
|
-
'# Git',
|
|
367
|
-
'.git',
|
|
368
|
-
'.gitignore',
|
|
369
|
-
'',
|
|
370
|
-
'# Environment files',
|
|
371
|
-
'.env',
|
|
372
|
-
'.env.*',
|
|
373
|
-
'!.env.example',
|
|
374
|
-
'',
|
|
375
|
-
'# Logs',
|
|
376
|
-
'*.log',
|
|
377
|
-
'logs',
|
|
378
|
-
'',
|
|
379
|
-
'# Test files',
|
|
380
|
-
'test',
|
|
381
|
-
'tests',
|
|
382
|
-
'__tests__',
|
|
383
|
-
'coverage',
|
|
384
|
-
'.nyc_output',
|
|
385
|
-
'*.test.ts',
|
|
386
|
-
'*.test.js',
|
|
387
|
-
'*.spec.ts',
|
|
388
|
-
'*.spec.js',
|
|
389
|
-
'',
|
|
390
|
-
'# IDE',
|
|
391
|
-
'.vscode',
|
|
392
|
-
'.idea',
|
|
393
|
-
'*.swp',
|
|
394
|
-
'*.swo',
|
|
395
|
-
'',
|
|
396
|
-
'# OS',
|
|
397
|
-
'.DS_Store',
|
|
398
|
-
'Thumbs.db',
|
|
399
|
-
'',
|
|
400
|
-
'# Docker',
|
|
401
|
-
'Dockerfile*',
|
|
402
|
-
'docker-compose*',
|
|
403
|
-
'.docker',
|
|
404
|
-
'',
|
|
405
|
-
'# Documentation',
|
|
406
|
-
'docs',
|
|
407
|
-
'*.md',
|
|
408
|
-
'!README.md',
|
|
409
|
-
'',
|
|
410
|
-
'# Misc',
|
|
411
|
-
'.editorconfig',
|
|
412
|
-
'.eslintrc*',
|
|
413
|
-
'.prettierrc*',
|
|
414
|
-
'tsconfig*.json',
|
|
415
|
-
'jest.config.*'
|
|
416
|
-
];
|
|
417
|
-
|
|
418
|
-
// Add custom ignore patterns
|
|
419
|
-
for (const pattern of this.options.ignore) {
|
|
420
|
-
if (!lines.includes(pattern)) {
|
|
421
|
-
lines.push(pattern);
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
return lines.join('\n');
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
/**
|
|
429
|
-
* Generate docker-compose.yml for development
|
|
430
|
-
*/
|
|
431
|
-
generateComposeFile(config: ComposeConfig = {}): string {
|
|
432
|
-
const defaultConfig: ComposeConfig = {
|
|
433
|
-
version: '3.8',
|
|
434
|
-
services: {
|
|
435
|
-
app: {
|
|
436
|
-
build: {
|
|
437
|
-
context: '.',
|
|
438
|
-
dockerfile: 'Dockerfile'
|
|
439
|
-
},
|
|
440
|
-
ports: [`${this.options.port}:${this.options.port}`],
|
|
441
|
-
environment: {
|
|
442
|
-
NODE_ENV: 'production',
|
|
443
|
-
...this.options.env
|
|
444
|
-
},
|
|
445
|
-
restart: 'unless-stopped',
|
|
446
|
-
healthcheck: this.options.healthCheck
|
|
447
|
-
? {
|
|
448
|
-
test: ['CMD', 'wget', '--no-verbose', '--tries=1', '--spider', `http://localhost:${this.options.port}${this.options.healthEndpoint}`],
|
|
449
|
-
interval: '30s',
|
|
450
|
-
timeout: '10s',
|
|
451
|
-
retries: 3,
|
|
452
|
-
start_period: '10s'
|
|
453
|
-
}
|
|
454
|
-
: undefined
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
};
|
|
458
|
-
|
|
459
|
-
// Merge with provided config
|
|
460
|
-
const finalConfig = this.mergeComposeConfig(defaultConfig, config);
|
|
461
|
-
|
|
462
|
-
return this.serializeYaml(finalConfig);
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
/**
|
|
466
|
-
* Generate docker-compose.dev.yml for development
|
|
467
|
-
*/
|
|
468
|
-
generateDevComposeFile(): string {
|
|
469
|
-
const config: ComposeConfig = {
|
|
470
|
-
version: '3.8',
|
|
471
|
-
services: {
|
|
472
|
-
app: {
|
|
473
|
-
build: {
|
|
474
|
-
context: '.',
|
|
475
|
-
dockerfile: 'Dockerfile'
|
|
476
|
-
},
|
|
477
|
-
ports: [`${this.options.port}:${this.options.port}`],
|
|
478
|
-
environment: {
|
|
479
|
-
NODE_ENV: 'development'
|
|
480
|
-
},
|
|
481
|
-
volumes: [
|
|
482
|
-
'.:/app',
|
|
483
|
-
'/app/node_modules'
|
|
484
|
-
],
|
|
485
|
-
restart: 'unless-stopped'
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
};
|
|
489
|
-
|
|
490
|
-
return this.serializeYaml(config);
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
/**
|
|
494
|
-
* Write all Docker files to disk
|
|
495
|
-
*/
|
|
496
|
-
writeFiles(outputDir: string = '.'): { files: string[] } {
|
|
497
|
-
const files: string[] = [];
|
|
498
|
-
const basePath = resolve(process.cwd(), outputDir);
|
|
499
|
-
|
|
500
|
-
// Dockerfile
|
|
501
|
-
const dockerfilePath = resolve(basePath, 'Dockerfile');
|
|
502
|
-
writeFileSync(dockerfilePath, this.generateDockerfile());
|
|
503
|
-
files.push(dockerfilePath);
|
|
504
|
-
|
|
505
|
-
// .dockerignore
|
|
506
|
-
const dockerignorePath = resolve(basePath, '.dockerignore');
|
|
507
|
-
writeFileSync(dockerignorePath, this.generateDockerignore());
|
|
508
|
-
files.push(dockerignorePath);
|
|
509
|
-
|
|
510
|
-
// docker-compose.yml
|
|
511
|
-
const composePath = resolve(basePath, 'docker-compose.yml');
|
|
512
|
-
writeFileSync(composePath, this.generateComposeFile());
|
|
513
|
-
files.push(composePath);
|
|
514
|
-
|
|
515
|
-
// docker-compose.dev.yml
|
|
516
|
-
const devComposePath = resolve(basePath, 'docker-compose.dev.yml');
|
|
517
|
-
writeFileSync(devComposePath, this.generateDevComposeFile());
|
|
518
|
-
files.push(devComposePath);
|
|
519
|
-
|
|
520
|
-
return { files };
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
/**
|
|
524
|
-
* Merge compose configs
|
|
525
|
-
*/
|
|
526
|
-
private mergeComposeConfig(base: ComposeConfig, override: ComposeConfig): ComposeConfig {
|
|
527
|
-
return {
|
|
528
|
-
version: override.version ?? base.version,
|
|
529
|
-
services: {
|
|
530
|
-
...base.services,
|
|
531
|
-
...override.services
|
|
532
|
-
},
|
|
533
|
-
networks: {
|
|
534
|
-
...base.networks,
|
|
535
|
-
...override.networks
|
|
536
|
-
},
|
|
537
|
-
volumes: {
|
|
538
|
-
...base.volumes,
|
|
539
|
-
...override.volumes
|
|
540
|
-
}
|
|
541
|
-
};
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
/**
|
|
545
|
-
* Simple YAML serializer
|
|
546
|
-
*/
|
|
547
|
-
private serializeYaml(obj: any, indent: number = 0): string {
|
|
548
|
-
const lines: string[] = [];
|
|
549
|
-
const prefix = ' '.repeat(indent);
|
|
550
|
-
|
|
551
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
552
|
-
if (value === undefined || value === null) continue;
|
|
553
|
-
|
|
554
|
-
if (Array.isArray(value)) {
|
|
555
|
-
lines.push(`${prefix}${key}:`);
|
|
556
|
-
for (const item of value) {
|
|
557
|
-
if (typeof item === 'object') {
|
|
558
|
-
const itemLines = this.serializeYaml(item, indent + 2).split('\n');
|
|
559
|
-
lines.push(`${prefix} - ${itemLines[0].trim()}`);
|
|
560
|
-
for (let i = 1; i < itemLines.length; i++) {
|
|
561
|
-
if (itemLines[i].trim()) {
|
|
562
|
-
lines.push(`${prefix} ${itemLines[i].trim()}`);
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
} else {
|
|
566
|
-
lines.push(`${prefix} - ${item}`);
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
} else if (typeof value === 'object') {
|
|
570
|
-
lines.push(`${prefix}${key}:`);
|
|
571
|
-
lines.push(this.serializeYaml(value, indent + 1));
|
|
572
|
-
} else if (typeof value === 'string' && value.includes(':')) {
|
|
573
|
-
lines.push(`${prefix}${key}: "${value}"`);
|
|
574
|
-
} else {
|
|
575
|
-
lines.push(`${prefix}${key}: ${value}`);
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
return lines.join('\n');
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
/**
|
|
584
|
-
* Create Docker generator
|
|
585
|
-
*/
|
|
586
|
-
export function createDocker(options?: DockerOptions): DockerGenerator {
|
|
587
|
-
return new DockerGenerator(options);
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
/**
|
|
591
|
-
* Generate Docker files with default options
|
|
592
|
-
*/
|
|
593
|
-
export function generateDockerFiles(
|
|
594
|
-
outputDir: string = '.',
|
|
595
|
-
options?: DockerOptions
|
|
596
|
-
): { files: string[] } {
|
|
597
|
-
const generator = createDocker(options);
|
|
598
|
-
return generator.writeFiles(outputDir);
|
|
599
|
-
}
|