maven-proxy 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +466 -420
- package/bin/maven-proxy.js +585 -573
- package/package.json +54 -54
- package/scripts/truststore.js +96 -96
- package/src/cache/cache-path.js +50 -50
- package/src/cache/downloader.js +350 -350
- package/src/cert/cert-manager.js +194 -194
- package/src/cert/truststore-utils.js +383 -289
- package/src/common/console-log-file.js +61 -61
- package/src/common/daily-log-file.js +78 -78
- package/src/common/domain-match.js +39 -39
- package/src/common/download-log-writer.js +26 -26
- package/src/common/ecosystem.js +63 -63
- package/src/common/java-home.js +327 -327
- package/src/config/config.js +224 -213
- package/src/index.js +93 -93
- package/src/proxy/proxy-connect-handler.js +173 -173
- package/src/proxy/proxy-http-handler.js +187 -187
- package/src/proxy/proxy-server.js +35 -35
- package/src/proxy/upstream-proxy.js +236 -236
- package/src/repo/repo-server.js +120 -120
package/bin/maven-proxy.js
CHANGED
|
@@ -1,573 +1,585 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import fs from "node:fs";
|
|
3
|
-
import os from "node:os";
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
import net from "node:net";
|
|
6
|
-
import { spawnSync } from "node:child_process";
|
|
7
|
-
|
|
8
|
-
const defaultConfigDir = path.resolve(os.homedir(), "maven-proxy");
|
|
9
|
-
const defaultConfigFile = path.join(defaultConfigDir, "config");
|
|
10
|
-
|
|
11
|
-
function normalizeMode(value) {
|
|
12
|
-
const normalized = String(value || "").trim().toLowerCase();
|
|
13
|
-
|
|
14
|
-
if (["dev", "development", "project"].includes(normalized)) {
|
|
15
|
-
return "development";
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
if (["user", "home", "global", "production", "prod"].includes(normalized)) {
|
|
19
|
-
return "user";
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return "";
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function isProjectWorkspace(dirPath) {
|
|
26
|
-
const packageJsonPath = path.resolve(dirPath, "package.json");
|
|
27
|
-
const entryPath = path.resolve(dirPath, "src/index.js");
|
|
28
|
-
|
|
29
|
-
if (!fs.existsSync(packageJsonPath) || !fs.existsSync(entryPath)) {
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
try {
|
|
34
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
35
|
-
return packageJson?.name === "maven-proxy";
|
|
36
|
-
} catch {
|
|
37
|
-
return false;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function resolveEffectiveMode(options) {
|
|
42
|
-
const forced = normalizeMode(options.mode);
|
|
43
|
-
if (forced) {
|
|
44
|
-
return forced;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return isProjectWorkspace(process.cwd()) ? "development" : "user";
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function printHelp() {
|
|
51
|
-
console.log("maven-proxy CLI");
|
|
52
|
-
console.log("");
|
|
53
|
-
console.log("Usage:");
|
|
54
|
-
console.log(" maven-proxy");
|
|
55
|
-
console.log(" maven-proxy start [--mode <development|user>] [--config <file>]");
|
|
56
|
-
console.log(" maven-proxy init-config [--force] [--config <file>]");
|
|
57
|
-
console.log(" maven-proxy truststore <print|init|merge> [options]");
|
|
58
|
-
console.log(" maven-proxy doctor [--mode <development|user>] [--config <file>]");
|
|
59
|
-
console.log("");
|
|
60
|
-
console.log("Examples:");
|
|
61
|
-
console.log(" npx maven-proxy");
|
|
62
|
-
console.log(" maven-proxy init-config");
|
|
63
|
-
console.log(" maven-proxy start --mode development");
|
|
64
|
-
console.log(" maven-proxy --config ~/maven-proxy/config");
|
|
65
|
-
console.log(" maven-proxy truststore print");
|
|
66
|
-
console.log(" maven-proxy truststore merge --source ./a.jks --target ./b.jks");
|
|
67
|
-
console.log(" maven-proxy doctor");
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function parseArgs(args) {
|
|
71
|
-
const options = {
|
|
72
|
-
help: false,
|
|
73
|
-
force: false,
|
|
74
|
-
mode: "",
|
|
75
|
-
configPath: "",
|
|
76
|
-
command: "",
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
const tokens = [];
|
|
80
|
-
|
|
81
|
-
for (let index = 0; index < args.length; index += 1) {
|
|
82
|
-
const token = args[index];
|
|
83
|
-
|
|
84
|
-
if (token === "-h" || token === "--help") {
|
|
85
|
-
options.help = true;
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (token === "--force") {
|
|
90
|
-
options.force = true;
|
|
91
|
-
continue;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (token === "--mode") {
|
|
95
|
-
const value = args[index + 1];
|
|
96
|
-
if (!value || value.startsWith("-")) {
|
|
97
|
-
throw new Error("Missing value for --mode");
|
|
98
|
-
}
|
|
99
|
-
options.mode = value;
|
|
100
|
-
index += 1;
|
|
101
|
-
continue;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
if (token === "--config") {
|
|
105
|
-
const value = args[index + 1];
|
|
106
|
-
if (!value || value.startsWith("-")) {
|
|
107
|
-
throw new Error("Missing value for --config");
|
|
108
|
-
}
|
|
109
|
-
options.configPath = value;
|
|
110
|
-
index += 1;
|
|
111
|
-
continue;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
tokens.push(token);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
options.command = tokens[0] || "";
|
|
118
|
-
options.commandArgs = tokens.slice(1);
|
|
119
|
-
|
|
120
|
-
return options;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
function resolvePath(inputPath) {
|
|
124
|
-
if (!inputPath) {
|
|
125
|
-
return "";
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (inputPath.startsWith("~/")) {
|
|
129
|
-
return path.join(os.homedir(), inputPath.slice(2));
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
return path.isAbsolute(inputPath) ? inputPath : path.resolve(process.cwd(), inputPath);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function getDefaultConfigTemplate() {
|
|
136
|
-
return [
|
|
137
|
-
"# Maven Proxy default user config",
|
|
138
|
-
"# This file is loaded by default in user mode.",
|
|
139
|
-
"",
|
|
140
|
-
"PROXY_PORT=8080",
|
|
141
|
-
"REPO_PORT=8081",
|
|
142
|
-
"CACHE_DIR=data/cache",
|
|
143
|
-
"REPO_FALLBACK_REPOS=https://repo1.maven.org/maven2,https://jitpack.io,https://plugins.gradle.org/m2,https://maven.google.com",
|
|
144
|
-
"ENABLE_HTTPS_PROXY=true",
|
|
145
|
-
"HTTPS_MITM_DOMAINS=repo1.maven.org,repo.maven.apache.org,registry.npmjs.org",
|
|
146
|
-
"HTTPS_PASSTHROUGH_FOR_UNMATCHED=true",
|
|
147
|
-
"NPM_REGISTRY_DOMAINS=registry.npmjs.org,registry.npmmirror.com,npm.pkg.github.com",
|
|
148
|
-
"MAVEN_REPO_DOMAINS=repo1.maven.org,repo.maven.apache.org,jitpack.io,plugins.gradle.org,maven.google.com",
|
|
149
|
-
"MULTI_THREAD_DOMAINS=repo1.maven.org",
|
|
150
|
-
"MULTI_THREAD_COUNT=8",
|
|
151
|
-
"MULTI_THREAD_MIN_SIZE_BYTES=1048576",
|
|
152
|
-
"DOWNLOAD_TIMEOUT_MS=60000",
|
|
153
|
-
"DOWNLOAD_LOG_DIR=data/logs/downloads",
|
|
154
|
-
"LOG_RETENTION_DAYS=7",
|
|
155
|
-
"UPSTREAM_PROXY_URL=",
|
|
156
|
-
"UPSTREAM_HTTP_PROXY_URL=",
|
|
157
|
-
"UPSTREAM_HTTPS_PROXY_URL=",
|
|
158
|
-
"UPSTREAM_NO_PROXY=127.0.0.1,localhost",
|
|
159
|
-
"UPSTREAM_IGNORE_DOMAINS=",
|
|
160
|
-
"CERT_DIR=data/certs",
|
|
161
|
-
"ROOT_CERT_PATH=data/certs/root-ca.crt",
|
|
162
|
-
"ROOT_KEY_PATH=data/certs/root-ca.key.pem",
|
|
163
|
-
"LEAF_CERT_DIR=data/certs/leaf",
|
|
164
|
-
"TRUST_STORE_PATH=data/certs/proxy-truststore.jks",
|
|
165
|
-
"TRUST_STORE_ALIAS=maven-proxy-root-ca",
|
|
166
|
-
"TRUST_STORE_PASSWORD=changeit",
|
|
167
|
-
"
|
|
168
|
-
"",
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
resolve({ ok: false, message:
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
const
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
const
|
|
440
|
-
if (!
|
|
441
|
-
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
const
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import net from "node:net";
|
|
6
|
+
import { spawnSync } from "node:child_process";
|
|
7
|
+
|
|
8
|
+
const defaultConfigDir = path.resolve(os.homedir(), "maven-proxy");
|
|
9
|
+
const defaultConfigFile = path.join(defaultConfigDir, "config");
|
|
10
|
+
|
|
11
|
+
function normalizeMode(value) {
|
|
12
|
+
const normalized = String(value || "").trim().toLowerCase();
|
|
13
|
+
|
|
14
|
+
if (["dev", "development", "project"].includes(normalized)) {
|
|
15
|
+
return "development";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (["user", "home", "global", "production", "prod"].includes(normalized)) {
|
|
19
|
+
return "user";
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return "";
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function isProjectWorkspace(dirPath) {
|
|
26
|
+
const packageJsonPath = path.resolve(dirPath, "package.json");
|
|
27
|
+
const entryPath = path.resolve(dirPath, "src/index.js");
|
|
28
|
+
|
|
29
|
+
if (!fs.existsSync(packageJsonPath) || !fs.existsSync(entryPath)) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
35
|
+
return packageJson?.name === "maven-proxy";
|
|
36
|
+
} catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function resolveEffectiveMode(options) {
|
|
42
|
+
const forced = normalizeMode(options.mode);
|
|
43
|
+
if (forced) {
|
|
44
|
+
return forced;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return isProjectWorkspace(process.cwd()) ? "development" : "user";
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function printHelp() {
|
|
51
|
+
console.log("maven-proxy CLI");
|
|
52
|
+
console.log("");
|
|
53
|
+
console.log("Usage:");
|
|
54
|
+
console.log(" maven-proxy");
|
|
55
|
+
console.log(" maven-proxy start [--mode <development|user>] [--config <file>]");
|
|
56
|
+
console.log(" maven-proxy init-config [--force] [--config <file>]");
|
|
57
|
+
console.log(" maven-proxy truststore <print|init|merge> [options]");
|
|
58
|
+
console.log(" maven-proxy doctor [--mode <development|user>] [--config <file>]");
|
|
59
|
+
console.log("");
|
|
60
|
+
console.log("Examples:");
|
|
61
|
+
console.log(" npx maven-proxy");
|
|
62
|
+
console.log(" maven-proxy init-config");
|
|
63
|
+
console.log(" maven-proxy start --mode development");
|
|
64
|
+
console.log(" maven-proxy --config ~/maven-proxy/config");
|
|
65
|
+
console.log(" maven-proxy truststore print");
|
|
66
|
+
console.log(" maven-proxy truststore merge --source ./a.jks --target ./b.jks");
|
|
67
|
+
console.log(" maven-proxy doctor");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function parseArgs(args) {
|
|
71
|
+
const options = {
|
|
72
|
+
help: false,
|
|
73
|
+
force: false,
|
|
74
|
+
mode: "",
|
|
75
|
+
configPath: "",
|
|
76
|
+
command: "",
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const tokens = [];
|
|
80
|
+
|
|
81
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
82
|
+
const token = args[index];
|
|
83
|
+
|
|
84
|
+
if (token === "-h" || token === "--help") {
|
|
85
|
+
options.help = true;
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (token === "--force") {
|
|
90
|
+
options.force = true;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (token === "--mode") {
|
|
95
|
+
const value = args[index + 1];
|
|
96
|
+
if (!value || value.startsWith("-")) {
|
|
97
|
+
throw new Error("Missing value for --mode");
|
|
98
|
+
}
|
|
99
|
+
options.mode = value;
|
|
100
|
+
index += 1;
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (token === "--config") {
|
|
105
|
+
const value = args[index + 1];
|
|
106
|
+
if (!value || value.startsWith("-")) {
|
|
107
|
+
throw new Error("Missing value for --config");
|
|
108
|
+
}
|
|
109
|
+
options.configPath = value;
|
|
110
|
+
index += 1;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
tokens.push(token);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
options.command = tokens[0] || "";
|
|
118
|
+
options.commandArgs = tokens.slice(1);
|
|
119
|
+
|
|
120
|
+
return options;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function resolvePath(inputPath) {
|
|
124
|
+
if (!inputPath) {
|
|
125
|
+
return "";
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (inputPath.startsWith("~/")) {
|
|
129
|
+
return path.join(os.homedir(), inputPath.slice(2));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return path.isAbsolute(inputPath) ? inputPath : path.resolve(process.cwd(), inputPath);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function getDefaultConfigTemplate() {
|
|
136
|
+
return [
|
|
137
|
+
"# Maven Proxy default user config",
|
|
138
|
+
"# This file is loaded by default in user mode.",
|
|
139
|
+
"",
|
|
140
|
+
"PROXY_PORT=8080",
|
|
141
|
+
"REPO_PORT=8081",
|
|
142
|
+
"CACHE_DIR=data/cache",
|
|
143
|
+
"REPO_FALLBACK_REPOS=https://repo1.maven.org/maven2,https://jitpack.io,https://plugins.gradle.org/m2,https://maven.google.com",
|
|
144
|
+
"ENABLE_HTTPS_PROXY=true",
|
|
145
|
+
"HTTPS_MITM_DOMAINS=repo1.maven.org,repo.maven.apache.org,registry.npmjs.org",
|
|
146
|
+
"HTTPS_PASSTHROUGH_FOR_UNMATCHED=true",
|
|
147
|
+
"NPM_REGISTRY_DOMAINS=registry.npmjs.org,registry.npmmirror.com,npm.pkg.github.com",
|
|
148
|
+
"MAVEN_REPO_DOMAINS=repo1.maven.org,repo.maven.apache.org,jitpack.io,plugins.gradle.org,maven.google.com",
|
|
149
|
+
"MULTI_THREAD_DOMAINS=repo1.maven.org",
|
|
150
|
+
"MULTI_THREAD_COUNT=8",
|
|
151
|
+
"MULTI_THREAD_MIN_SIZE_BYTES=1048576",
|
|
152
|
+
"DOWNLOAD_TIMEOUT_MS=60000",
|
|
153
|
+
"DOWNLOAD_LOG_DIR=data/logs/downloads",
|
|
154
|
+
"LOG_RETENTION_DAYS=7",
|
|
155
|
+
"UPSTREAM_PROXY_URL=",
|
|
156
|
+
"UPSTREAM_HTTP_PROXY_URL=",
|
|
157
|
+
"UPSTREAM_HTTPS_PROXY_URL=",
|
|
158
|
+
"UPSTREAM_NO_PROXY=127.0.0.1,localhost",
|
|
159
|
+
"UPSTREAM_IGNORE_DOMAINS=",
|
|
160
|
+
"CERT_DIR=data/certs",
|
|
161
|
+
"ROOT_CERT_PATH=data/certs/root-ca.crt",
|
|
162
|
+
"ROOT_KEY_PATH=data/certs/root-ca.key.pem",
|
|
163
|
+
"LEAF_CERT_DIR=data/certs/leaf",
|
|
164
|
+
"TRUST_STORE_PATH=data/certs/proxy-truststore.jks",
|
|
165
|
+
"TRUST_STORE_ALIAS=maven-proxy-root-ca",
|
|
166
|
+
"TRUST_STORE_PASSWORD=changeit",
|
|
167
|
+
"EXISTING_TRUST_STORE_PATH=",
|
|
168
|
+
"EXISTING_TRUST_STORE_PASSWORD=",
|
|
169
|
+
"JAVA_HOME=",
|
|
170
|
+
"",
|
|
171
|
+
].join("\n");
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async function initConfigFile(configFile, force = false) {
|
|
175
|
+
await fs.promises.mkdir(path.dirname(configFile), { recursive: true });
|
|
176
|
+
|
|
177
|
+
if (fs.existsSync(configFile) && !force) {
|
|
178
|
+
console.log(`[maven-proxy] config already exists: ${configFile}`);
|
|
179
|
+
console.log("[maven-proxy] use --force to overwrite");
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
await fs.promises.writeFile(configFile, getDefaultConfigTemplate(), "utf8");
|
|
184
|
+
console.log(`[maven-proxy] config written: ${configFile}`);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
async function ensureAutoConfigIfNeeded(options, command) {
|
|
188
|
+
if (!["start", "doctor", "truststore"].includes(command)) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (options.configPath) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const mode = resolveEffectiveMode(options);
|
|
197
|
+
if (mode !== "user") {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (fs.existsSync(defaultConfigFile)) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
console.log(`[maven-proxy] user config not found, auto creating: ${defaultConfigFile}`);
|
|
206
|
+
await initConfigFile(defaultConfigFile, false);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
async function startServer(options) {
|
|
210
|
+
applyConfigOverrides(options);
|
|
211
|
+
|
|
212
|
+
await import("../src/index.js");
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function applyConfigOverrides(options) {
|
|
216
|
+
if (options.mode) {
|
|
217
|
+
process.env.MAVEN_PROXY_CONFIG_MODE = options.mode;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (options.configPath) {
|
|
221
|
+
process.env.MAVEN_PROXY_CONFIG_FILE = resolvePath(options.configPath);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function checkKeytool() {
|
|
226
|
+
const result = spawnSync("keytool", ["-help"], {
|
|
227
|
+
shell: false,
|
|
228
|
+
encoding: "utf8",
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
if (result.error) {
|
|
232
|
+
return {
|
|
233
|
+
ok: false,
|
|
234
|
+
message: result.error.message,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (result.status !== 0) {
|
|
239
|
+
return {
|
|
240
|
+
ok: false,
|
|
241
|
+
message: (result.stderr || "").trim() || "keytool returned non-zero status",
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return {
|
|
246
|
+
ok: true,
|
|
247
|
+
message: "keytool available",
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function checkPathExists(filePath) {
|
|
252
|
+
try {
|
|
253
|
+
const stats = fs.statSync(filePath);
|
|
254
|
+
return {
|
|
255
|
+
ok: true,
|
|
256
|
+
isFile: stats.isFile(),
|
|
257
|
+
isDirectory: stats.isDirectory(),
|
|
258
|
+
};
|
|
259
|
+
} catch {
|
|
260
|
+
return {
|
|
261
|
+
ok: false,
|
|
262
|
+
isFile: false,
|
|
263
|
+
isDirectory: false,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
async function canBindPort(port) {
|
|
269
|
+
return new Promise((resolve) => {
|
|
270
|
+
const server = net.createServer();
|
|
271
|
+
server.once("error", (error) => {
|
|
272
|
+
if (error && error.code === "EADDRINUSE") {
|
|
273
|
+
resolve({ ok: false, message: "in use" });
|
|
274
|
+
} else {
|
|
275
|
+
resolve({ ok: false, message: error?.message || "bind failed" });
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
server.listen(port, "127.0.0.1", () => {
|
|
280
|
+
server.close(() => resolve({ ok: true, message: "available" }));
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
function printDoctorLine(level, title, detail) {
|
|
286
|
+
console.log(`[${level}] ${title}: ${detail}`);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
async function runDoctor(options) {
|
|
290
|
+
applyConfigOverrides(options);
|
|
291
|
+
|
|
292
|
+
const { config } = await import("../src/config/config.js");
|
|
293
|
+
|
|
294
|
+
const failures = [];
|
|
295
|
+
const warnings = [];
|
|
296
|
+
|
|
297
|
+
console.log("[doctor] start");
|
|
298
|
+
printDoctorLine("INFO", "config mode", config.configMode);
|
|
299
|
+
printDoctorLine("INFO", "config base", config.configBaseDir);
|
|
300
|
+
|
|
301
|
+
if (config.loadedConfigFile) {
|
|
302
|
+
printDoctorLine("PASS", "config file", config.loadedConfigFile);
|
|
303
|
+
} else if (config.configMode === "user") {
|
|
304
|
+
warnings.push("user config file missing");
|
|
305
|
+
printDoctorLine("WARN", "config file", `not found, expected ${config.defaultUserConfigPath}`);
|
|
306
|
+
} else {
|
|
307
|
+
warnings.push("development config file missing");
|
|
308
|
+
printDoctorLine("WARN", "config file", "no .env/.evn loaded, using defaults");
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
const keytool = checkKeytool();
|
|
312
|
+
if (keytool.ok) {
|
|
313
|
+
printDoctorLine("PASS", "keytool", keytool.message);
|
|
314
|
+
} else {
|
|
315
|
+
failures.push("keytool unavailable");
|
|
316
|
+
printDoctorLine("FAIL", "keytool", keytool.message);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
printDoctorLine("INFO", "JAVA_HOME source", config.javaHomeSource || "unknown");
|
|
320
|
+
if (config.javaHomeSource === "auto-fallback" && config.javaHomeConfigured) {
|
|
321
|
+
warnings.push("configured JAVA_HOME invalid, auto fallback used");
|
|
322
|
+
printDoctorLine("WARN", "JAVA_HOME configured", `invalid: ${config.javaHomeConfigured}`);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if (config.javaHome) {
|
|
326
|
+
const javaHomeExists = checkPathExists(config.javaHome).ok;
|
|
327
|
+
if (javaHomeExists) {
|
|
328
|
+
printDoctorLine("PASS", "JAVA_HOME", config.javaHome);
|
|
329
|
+
const cacertsPath = path.join(config.javaHome, "lib", "security", "cacerts");
|
|
330
|
+
const cacerts = checkPathExists(cacertsPath);
|
|
331
|
+
if (cacerts.ok && cacerts.isFile) {
|
|
332
|
+
printDoctorLine("PASS", "cacerts", cacertsPath);
|
|
333
|
+
} else {
|
|
334
|
+
warnings.push("cacerts missing");
|
|
335
|
+
printDoctorLine("WARN", "cacerts", `not found: ${cacertsPath}`);
|
|
336
|
+
}
|
|
337
|
+
} else {
|
|
338
|
+
warnings.push("JAVA_HOME path missing");
|
|
339
|
+
printDoctorLine("WARN", "JAVA_HOME", `path not found: ${config.javaHome}`);
|
|
340
|
+
}
|
|
341
|
+
} else {
|
|
342
|
+
warnings.push("JAVA_HOME not configured");
|
|
343
|
+
printDoctorLine("WARN", "JAVA_HOME", "not configured");
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
const rootCert = checkPathExists(config.rootCertPath);
|
|
347
|
+
if (rootCert.ok && rootCert.isFile) {
|
|
348
|
+
printDoctorLine("PASS", "root cert", config.rootCertPath);
|
|
349
|
+
} else {
|
|
350
|
+
warnings.push("root cert missing");
|
|
351
|
+
printDoctorLine("WARN", "root cert", `not found: ${config.rootCertPath}`);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const rootKey = checkPathExists(config.rootKeyPath);
|
|
355
|
+
if (rootKey.ok && rootKey.isFile) {
|
|
356
|
+
printDoctorLine("PASS", "root key", config.rootKeyPath);
|
|
357
|
+
} else {
|
|
358
|
+
warnings.push("root key missing");
|
|
359
|
+
printDoctorLine("WARN", "root key", `not found: ${config.rootKeyPath}`);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const trustStore = checkPathExists(config.trustStorePath);
|
|
363
|
+
if (trustStore.ok && trustStore.isFile) {
|
|
364
|
+
printDoctorLine("PASS", "trust store", config.trustStorePath);
|
|
365
|
+
} else {
|
|
366
|
+
warnings.push("trust store missing");
|
|
367
|
+
printDoctorLine("WARN", "trust store", `not found: ${config.trustStorePath}`);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
if (config.existingTrustStorePath) {
|
|
371
|
+
const existingTrustStore = checkPathExists(config.existingTrustStorePath);
|
|
372
|
+
if (existingTrustStore.ok && existingTrustStore.isFile) {
|
|
373
|
+
printDoctorLine("PASS", "existing trust store source", config.existingTrustStorePath);
|
|
374
|
+
} else {
|
|
375
|
+
warnings.push("existing trust store source missing");
|
|
376
|
+
printDoctorLine("WARN", "existing trust store source", `not found: ${config.existingTrustStorePath}`);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const dirs = [
|
|
381
|
+
["cache dir", config.cacheDir],
|
|
382
|
+
["cert dir", config.certDir],
|
|
383
|
+
["log dir", config.downloadLogDir],
|
|
384
|
+
];
|
|
385
|
+
|
|
386
|
+
for (const [name, dirPath] of dirs) {
|
|
387
|
+
try {
|
|
388
|
+
await fs.promises.mkdir(dirPath, { recursive: true });
|
|
389
|
+
printDoctorLine("PASS", name, dirPath);
|
|
390
|
+
} catch (error) {
|
|
391
|
+
failures.push(`${name} create failed`);
|
|
392
|
+
printDoctorLine("FAIL", name, error.message);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const proxyPort = await canBindPort(config.proxyPort);
|
|
397
|
+
if (proxyPort.ok) {
|
|
398
|
+
printDoctorLine("PASS", "proxy port", `${config.proxyPort} available`);
|
|
399
|
+
} else {
|
|
400
|
+
failures.push("proxy port unavailable");
|
|
401
|
+
printDoctorLine("FAIL", "proxy port", `${config.proxyPort} ${proxyPort.message}`);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const repoPort = await canBindPort(config.repoPort);
|
|
405
|
+
if (repoPort.ok) {
|
|
406
|
+
printDoctorLine("PASS", "repo port", `${config.repoPort} available`);
|
|
407
|
+
} else {
|
|
408
|
+
failures.push("repo port unavailable");
|
|
409
|
+
printDoctorLine("FAIL", "repo port", `${config.repoPort} ${repoPort.message}`);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
if (failures.length > 0) {
|
|
413
|
+
console.log(`[doctor] done with failures=${failures.length} warnings=${warnings.length}`);
|
|
414
|
+
process.exitCode = 2;
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
if (warnings.length > 0) {
|
|
419
|
+
console.log(`[doctor] done with warnings=${warnings.length}`);
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
console.log("[doctor] all checks passed");
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
function printTruststoreUsage() {
|
|
427
|
+
console.log("Usage:");
|
|
428
|
+
console.log(" maven-proxy truststore print");
|
|
429
|
+
console.log(" maven-proxy truststore init");
|
|
430
|
+
console.log(
|
|
431
|
+
" maven-proxy truststore merge --source <path> --target <path> [--source-pass <pwd>] [--target-pass <pwd>] [--source-type <JKS|PKCS12>] [--target-type <JKS|PKCS12>] [--on-conflict <fail|overwrite>] [--dry-run]",
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
function parseCliOptions(args) {
|
|
436
|
+
const parsed = {};
|
|
437
|
+
|
|
438
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
439
|
+
const token = args[i];
|
|
440
|
+
if (!token.startsWith("--")) {
|
|
441
|
+
continue;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
const key = token.slice(2);
|
|
445
|
+
|
|
446
|
+
if (key === "dry-run") {
|
|
447
|
+
parsed[key] = true;
|
|
448
|
+
continue;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
const value = args[i + 1];
|
|
452
|
+
if (!value || value.startsWith("--")) {
|
|
453
|
+
throw new Error(`Missing value for option: --${key}`);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
parsed[key] = value;
|
|
457
|
+
i += 1;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
return parsed;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
async function runTruststore(options) {
|
|
464
|
+
const action = options.commandArgs[0] || "print";
|
|
465
|
+
const args = options.commandArgs.slice(1);
|
|
466
|
+
|
|
467
|
+
if (action === "--help" || action === "-h") {
|
|
468
|
+
printTruststoreUsage();
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
473
|
+
printTruststoreUsage();
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
applyConfigOverrides(options);
|
|
478
|
+
|
|
479
|
+
const [{ config }, trustUtils] = await Promise.all([
|
|
480
|
+
import("../src/config/config.js"),
|
|
481
|
+
import("../src/cert/truststore-utils.js"),
|
|
482
|
+
]);
|
|
483
|
+
|
|
484
|
+
const {
|
|
485
|
+
getTrustStoreCommands,
|
|
486
|
+
initTrustStore,
|
|
487
|
+
mergeTrustStores,
|
|
488
|
+
} = trustUtils;
|
|
489
|
+
|
|
490
|
+
if (action === "init") {
|
|
491
|
+
initTrustStore(config);
|
|
492
|
+
console.log("Trust store initialized.");
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
if (action === "merge") {
|
|
497
|
+
const parsed = parseCliOptions(args);
|
|
498
|
+
if (!parsed.source || !parsed.target) {
|
|
499
|
+
throw new Error("truststore merge requires --source and --target");
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
const mergeResult = mergeTrustStores({
|
|
503
|
+
sourcePath: parsed.source,
|
|
504
|
+
targetPath: parsed.target,
|
|
505
|
+
sourcePassword: parsed["source-pass"] || config.trustStorePassword,
|
|
506
|
+
targetPassword: parsed["target-pass"] || config.trustStorePassword,
|
|
507
|
+
sourceType: (parsed["source-type"] || "JKS").toUpperCase(),
|
|
508
|
+
targetType: (parsed["target-type"] || "JKS").toUpperCase(),
|
|
509
|
+
onConflict: (parsed["on-conflict"] || "fail").toLowerCase(),
|
|
510
|
+
dryRun: Boolean(parsed["dry-run"]),
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
if (mergeResult?.dryRun) {
|
|
514
|
+
console.log("Dry run passed: merge validation completed, no changes were made.");
|
|
515
|
+
} else {
|
|
516
|
+
console.log("Trust stores merged successfully.");
|
|
517
|
+
}
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
if (action !== "print") {
|
|
522
|
+
printTruststoreUsage();
|
|
523
|
+
throw new Error(`Unknown truststore action: ${action}`);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
const commands = getTrustStoreCommands(config);
|
|
527
|
+
console.log("Trust store commands:");
|
|
528
|
+
console.log(commands.copyCmd);
|
|
529
|
+
console.log(commands.importCmd);
|
|
530
|
+
console.log(commands.listCmd);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
async function main() {
|
|
534
|
+
const options = parseArgs(process.argv.slice(2));
|
|
535
|
+
|
|
536
|
+
if (options.help) {
|
|
537
|
+
if (options.command === "truststore") {
|
|
538
|
+
printTruststoreUsage();
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
printHelp();
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
const command = options.command || "start";
|
|
546
|
+
const configFile = resolvePath(options.configPath) || defaultConfigFile;
|
|
547
|
+
|
|
548
|
+
await ensureAutoConfigIfNeeded(options, command);
|
|
549
|
+
|
|
550
|
+
if (command === "init-config") {
|
|
551
|
+
if (options.commandArgs.length > 0) {
|
|
552
|
+
throw new Error(`Unknown argument for init-config: ${options.commandArgs[0]}`);
|
|
553
|
+
}
|
|
554
|
+
await initConfigFile(configFile, options.force);
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
if (command === "truststore") {
|
|
559
|
+
await runTruststore(options);
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
if (command === "doctor") {
|
|
564
|
+
if (options.commandArgs.length > 0) {
|
|
565
|
+
throw new Error(`Unknown argument for doctor: ${options.commandArgs[0]}`);
|
|
566
|
+
}
|
|
567
|
+
await runDoctor(options);
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
if (command === "start") {
|
|
572
|
+
if (options.commandArgs.length > 0) {
|
|
573
|
+
throw new Error(`Unknown argument for start: ${options.commandArgs[0]}`);
|
|
574
|
+
}
|
|
575
|
+
await startServer(options);
|
|
576
|
+
return;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
throw new Error(`Unknown command: ${command}`);
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
main().catch((error) => {
|
|
583
|
+
console.error(`[maven-proxy] ${error.message}`);
|
|
584
|
+
process.exit(1);
|
|
585
|
+
});
|