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.
@@ -1,213 +1,224 @@
1
- import fs from "node:fs";
2
- import os from "node:os";
3
- import path from "node:path";
4
- import dotenv from "dotenv";
5
- import { detectJavaHome } from "../common/java-home.js";
6
-
7
- const cwd = process.cwd();
8
- const userConfigDir = path.resolve(os.homedir(), "maven-proxy");
9
- const defaultUserConfigPath = path.join(userConfigDir, "config");
10
-
11
- function normalizeConfigMode(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 resolveConfigMode() {
42
- const forced = normalizeConfigMode(process.env.MAVEN_PROXY_CONFIG_MODE);
43
- if (forced) {
44
- return forced;
45
- }
46
-
47
- return isProjectWorkspace(cwd) ? "development" : "user";
48
- }
49
-
50
- function resolveConfigFilePath(configMode) {
51
- const envPath = String(process.env.MAVEN_PROXY_CONFIG_FILE || "").trim();
52
- if (envPath) {
53
- return path.isAbsolute(envPath) ? envPath : path.resolve(cwd, envPath);
54
- }
55
-
56
- if (configMode === "development") {
57
- const devCandidates = [
58
- path.resolve(cwd, ".env"),
59
- path.resolve(cwd, ".evn"),
60
- ];
61
-
62
- for (const candidate of devCandidates) {
63
- if (fs.existsSync(candidate)) {
64
- return candidate;
65
- }
66
- }
67
-
68
- return "";
69
- }
70
-
71
- return fs.existsSync(defaultUserConfigPath) ? defaultUserConfigPath : "";
72
- }
73
-
74
- function loadEnvFromFile(filePath) {
75
- if (filePath && fs.existsSync(filePath)) {
76
- dotenv.config({ path: filePath, override: false });
77
- return filePath;
78
- }
79
-
80
- return "";
81
- }
82
-
83
- const configMode = resolveConfigMode();
84
- const resolvedConfigFilePath = resolveConfigFilePath(configMode);
85
- const loadedConfigFile = loadEnvFromFile(resolvedConfigFilePath);
86
- const configBaseDir = configMode === "development"
87
- ? cwd
88
- : (resolvedConfigFilePath ? path.dirname(resolvedConfigFilePath) : userConfigDir);
89
- const javaHomeResolution = detectJavaHome(process.env.JAVA_HOME || "");
90
-
91
- function toBool(value, defaultValue) {
92
- if (value == null || value === "") {
93
- return defaultValue;
94
- }
95
- return ["1", "true", "yes", "on"].includes(String(value).toLowerCase());
96
- }
97
-
98
- function toInt(value, defaultValue) {
99
- const parsed = Number.parseInt(value, 10);
100
- return Number.isFinite(parsed) ? parsed : defaultValue;
101
- }
102
-
103
- function toList(value, defaultValue = []) {
104
- if (!value) {
105
- return defaultValue;
106
- }
107
- return String(value)
108
- .split(",")
109
- .map((item) => item.trim())
110
- .filter(Boolean);
111
- }
112
-
113
- function normalizeRepoList(value, defaultValue = []) {
114
- const raw = toList(value, defaultValue);
115
- return raw
116
- .map((item) => String(item).trim())
117
- .filter((item) => /^https?:\/\//i.test(item))
118
- .map((item) => item.replace(/\/+$/, ""));
119
- }
120
-
121
- function normalizeProxyUrl(value) {
122
- if (!value) {
123
- return "";
124
- }
125
-
126
- const trimmed = String(value).trim();
127
- if (!trimmed) {
128
- return "";
129
- }
130
-
131
- if (/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(trimmed)) {
132
- return trimmed;
133
- }
134
-
135
- return `http://${trimmed}`;
136
- }
137
-
138
- function extractHostsFromUrls(urls) {
139
- const hosts = [];
140
-
141
- for (const rawUrl of urls) {
142
- try {
143
- hosts.push(new URL(rawUrl).hostname.toLowerCase());
144
- } catch {
145
- // ignore invalid URL
146
- }
147
- }
148
-
149
- return [...new Set(hosts)];
150
- }
151
-
152
- const defaultRepoFallbackRepos = [
153
- "https://repo1.maven.org/maven2",
154
- "https://jitpack.io",
155
- "https://plugins.gradle.org/m2",
156
- "https://maven.google.com",
157
- ];
158
-
159
- const repoFallbackRepos = normalizeRepoList(
160
- process.env.REPO_FALLBACK_REPOS,
161
- defaultRepoFallbackRepos,
162
- );
163
-
164
- const defaultMavenRepoDomains = [
165
- "repo1.maven.org",
166
- "repo.maven.apache.org",
167
- "jitpack.io",
168
- "plugins.gradle.org",
169
- "maven.google.com",
170
- ...extractHostsFromUrls(repoFallbackRepos),
171
- ];
172
-
173
- const cacheDir = path.resolve(configBaseDir, process.env.CACHE_DIR || "data/cache");
174
-
175
- export const config = {
176
- configMode,
177
- configBaseDir,
178
- loadedConfigFile,
179
- defaultUserConfigPath,
180
- proxyPort: toInt(process.env.PROXY_PORT, 8080),
181
- repoPort: toInt(process.env.REPO_PORT, 8081),
182
- cacheDir,
183
- mavenCacheDir: path.resolve(cacheDir, "maven"),
184
- npmCacheDir: path.resolve(cacheDir, "npm"),
185
- genericCacheDir: path.resolve(cacheDir, "generic"),
186
- enableHttpsProxy: toBool(process.env.ENABLE_HTTPS_PROXY, true),
187
- httpsMitmDomains: toList(process.env.HTTPS_MITM_DOMAINS, ["repo1.maven.org", "repo.maven.apache.org", "registry.npmjs.org"]),
188
- npmRegistryDomains: toList(process.env.NPM_REGISTRY_DOMAINS, ["registry.npmjs.org", "registry.npmmirror.com", "npm.pkg.github.com"]),
189
- mavenRepoDomains: toList(process.env.MAVEN_REPO_DOMAINS, [...new Set(defaultMavenRepoDomains)]),
190
- multiThreadDomains: toList(process.env.MULTI_THREAD_DOMAINS, ["repo1.maven.org"]),
191
- multiThreadCount: Math.max(1, toInt(process.env.MULTI_THREAD_COUNT, 4)),
192
- multiThreadMinSizeBytes: Math.max(0, toInt(process.env.MULTI_THREAD_MIN_SIZE_BYTES, 1024 * 1024)),
193
- downloadTimeoutMs: Math.max(1000, toInt(process.env.DOWNLOAD_TIMEOUT_MS, 60000)),
194
- downloadLogDir: path.resolve(configBaseDir, process.env.DOWNLOAD_LOG_DIR || "data/logs/downloads"),
195
- logRetentionDays: Math.max(1, toInt(process.env.LOG_RETENTION_DAYS, 7)),
196
- certDir: path.resolve(configBaseDir, process.env.CERT_DIR || "data/certs"),
197
- rootCertPath: path.resolve(configBaseDir, process.env.ROOT_CERT_PATH || "data/certs/root-ca.crt"),
198
- rootKeyPath: path.resolve(configBaseDir, process.env.ROOT_KEY_PATH || "data/certs/root-ca.key.pem"),
199
- leafCertDir: path.resolve(configBaseDir, process.env.LEAF_CERT_DIR || "data/certs/leaf"),
200
- trustStorePath: path.resolve(configBaseDir, process.env.TRUST_STORE_PATH || "data/certs/proxy-truststore.jks"),
201
- trustStoreAlias: process.env.TRUST_STORE_ALIAS || "maven-proxy-root-ca",
202
- trustStorePassword: process.env.TRUST_STORE_PASSWORD || "changeit",
203
- javaHome: javaHomeResolution.javaHome,
204
- javaHomeSource: javaHomeResolution.source,
205
- javaHomeConfigured: javaHomeResolution.configuredJavaHome || "",
206
- httpsPassthroughForUnmatched: toBool(process.env.HTTPS_PASSTHROUGH_FOR_UNMATCHED, true),
207
- upstreamProxyUrl: normalizeProxyUrl(process.env.UPSTREAM_PROXY_URL || process.env.ALL_PROXY || process.env.all_proxy || ""),
208
- upstreamHttpProxyUrl: normalizeProxyUrl(process.env.UPSTREAM_HTTP_PROXY_URL || process.env.HTTP_PROXY || process.env.http_proxy || ""),
209
- upstreamHttpsProxyUrl: normalizeProxyUrl(process.env.UPSTREAM_HTTPS_PROXY_URL || process.env.HTTPS_PROXY || process.env.https_proxy || ""),
210
- upstreamNoProxyDomains: toList(process.env.UPSTREAM_NO_PROXY || process.env.NO_PROXY || process.env.no_proxy || ""),
211
- upstreamIgnoreDomains: toList(process.env.UPSTREAM_IGNORE_DOMAINS || ""),
212
- repoFallbackRepos,
213
- };
1
+ import fs from "node:fs";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import dotenv from "dotenv";
5
+ import { detectJavaHome } from "../common/java-home.js";
6
+
7
+ const cwd = process.cwd();
8
+ const userConfigDir = path.resolve(os.homedir(), "maven-proxy");
9
+ const defaultUserConfigPath = path.join(userConfigDir, "config");
10
+
11
+ function normalizeConfigMode(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 resolveConfigMode() {
42
+ const forced = normalizeConfigMode(process.env.MAVEN_PROXY_CONFIG_MODE);
43
+ if (forced) {
44
+ return forced;
45
+ }
46
+
47
+ return isProjectWorkspace(cwd) ? "development" : "user";
48
+ }
49
+
50
+ function resolveConfigFilePath(configMode) {
51
+ const envPath = String(process.env.MAVEN_PROXY_CONFIG_FILE || "").trim();
52
+ if (envPath) {
53
+ return path.isAbsolute(envPath) ? envPath : path.resolve(cwd, envPath);
54
+ }
55
+
56
+ if (configMode === "development") {
57
+ const devCandidates = [
58
+ path.resolve(cwd, ".env"),
59
+ path.resolve(cwd, ".evn"),
60
+ ];
61
+
62
+ for (const candidate of devCandidates) {
63
+ if (fs.existsSync(candidate)) {
64
+ return candidate;
65
+ }
66
+ }
67
+
68
+ return "";
69
+ }
70
+
71
+ return fs.existsSync(defaultUserConfigPath) ? defaultUserConfigPath : "";
72
+ }
73
+
74
+ function loadEnvFromFile(filePath) {
75
+ if (filePath && fs.existsSync(filePath)) {
76
+ dotenv.config({ path: filePath, override: false });
77
+ return filePath;
78
+ }
79
+
80
+ return "";
81
+ }
82
+
83
+ const configMode = resolveConfigMode();
84
+ const resolvedConfigFilePath = resolveConfigFilePath(configMode);
85
+ const loadedConfigFile = loadEnvFromFile(resolvedConfigFilePath);
86
+ const configBaseDir = configMode === "development"
87
+ ? cwd
88
+ : (resolvedConfigFilePath ? path.dirname(resolvedConfigFilePath) : userConfigDir);
89
+ const javaHomeResolution = detectJavaHome(process.env.JAVA_HOME || "");
90
+
91
+ function toBool(value, defaultValue) {
92
+ if (value == null || value === "") {
93
+ return defaultValue;
94
+ }
95
+ return ["1", "true", "yes", "on"].includes(String(value).toLowerCase());
96
+ }
97
+
98
+ function toInt(value, defaultValue) {
99
+ const parsed = Number.parseInt(value, 10);
100
+ return Number.isFinite(parsed) ? parsed : defaultValue;
101
+ }
102
+
103
+ function toList(value, defaultValue = []) {
104
+ if (!value) {
105
+ return defaultValue;
106
+ }
107
+ return String(value)
108
+ .split(",")
109
+ .map((item) => item.trim())
110
+ .filter(Boolean);
111
+ }
112
+
113
+ function normalizeRepoList(value, defaultValue = []) {
114
+ const raw = toList(value, defaultValue);
115
+ return raw
116
+ .map((item) => String(item).trim())
117
+ .filter((item) => /^https?:\/\//i.test(item))
118
+ .map((item) => item.replace(/\/+$/, ""));
119
+ }
120
+
121
+ function normalizeProxyUrl(value) {
122
+ if (!value) {
123
+ return "";
124
+ }
125
+
126
+ const trimmed = String(value).trim();
127
+ if (!trimmed) {
128
+ return "";
129
+ }
130
+
131
+ if (/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(trimmed)) {
132
+ return trimmed;
133
+ }
134
+
135
+ return `http://${trimmed}`;
136
+ }
137
+
138
+ function resolveOptionalPath(baseDir, value) {
139
+ const raw = String(value || "").trim();
140
+ if (!raw) {
141
+ return "";
142
+ }
143
+
144
+ return path.isAbsolute(raw) ? raw : path.resolve(baseDir, raw);
145
+ }
146
+
147
+ function extractHostsFromUrls(urls) {
148
+ const hosts = [];
149
+
150
+ for (const rawUrl of urls) {
151
+ try {
152
+ hosts.push(new URL(rawUrl).hostname.toLowerCase());
153
+ } catch {
154
+ // ignore invalid URL
155
+ }
156
+ }
157
+
158
+ return [...new Set(hosts)];
159
+ }
160
+
161
+ const defaultRepoFallbackRepos = [
162
+ "https://repo1.maven.org/maven2",
163
+ "https://jitpack.io",
164
+ "https://plugins.gradle.org/m2",
165
+ "https://maven.google.com",
166
+ ];
167
+
168
+ const repoFallbackRepos = normalizeRepoList(
169
+ process.env.REPO_FALLBACK_REPOS,
170
+ defaultRepoFallbackRepos,
171
+ );
172
+
173
+ const defaultMavenRepoDomains = [
174
+ "repo1.maven.org",
175
+ "repo.maven.apache.org",
176
+ "jitpack.io",
177
+ "plugins.gradle.org",
178
+ "maven.google.com",
179
+ ...extractHostsFromUrls(repoFallbackRepos),
180
+ ];
181
+
182
+ const cacheDir = path.resolve(configBaseDir, process.env.CACHE_DIR || "data/cache");
183
+
184
+ export const config = {
185
+ configMode,
186
+ configBaseDir,
187
+ loadedConfigFile,
188
+ defaultUserConfigPath,
189
+ proxyPort: toInt(process.env.PROXY_PORT, 8080),
190
+ repoPort: toInt(process.env.REPO_PORT, 8081),
191
+ cacheDir,
192
+ mavenCacheDir: path.resolve(cacheDir, "maven"),
193
+ npmCacheDir: path.resolve(cacheDir, "npm"),
194
+ genericCacheDir: path.resolve(cacheDir, "generic"),
195
+ enableHttpsProxy: toBool(process.env.ENABLE_HTTPS_PROXY, true),
196
+ httpsMitmDomains: toList(process.env.HTTPS_MITM_DOMAINS, ["repo1.maven.org", "repo.maven.apache.org", "registry.npmjs.org"]),
197
+ npmRegistryDomains: toList(process.env.NPM_REGISTRY_DOMAINS, ["registry.npmjs.org", "registry.npmmirror.com", "npm.pkg.github.com"]),
198
+ mavenRepoDomains: toList(process.env.MAVEN_REPO_DOMAINS, [...new Set(defaultMavenRepoDomains)]),
199
+ multiThreadDomains: toList(process.env.MULTI_THREAD_DOMAINS, ["repo1.maven.org"]),
200
+ multiThreadCount: Math.max(1, toInt(process.env.MULTI_THREAD_COUNT, 4)),
201
+ multiThreadMinSizeBytes: Math.max(0, toInt(process.env.MULTI_THREAD_MIN_SIZE_BYTES, 1024 * 1024)),
202
+ downloadTimeoutMs: Math.max(1000, toInt(process.env.DOWNLOAD_TIMEOUT_MS, 60000)),
203
+ downloadLogDir: path.resolve(configBaseDir, process.env.DOWNLOAD_LOG_DIR || "data/logs/downloads"),
204
+ logRetentionDays: Math.max(1, toInt(process.env.LOG_RETENTION_DAYS, 7)),
205
+ certDir: path.resolve(configBaseDir, process.env.CERT_DIR || "data/certs"),
206
+ rootCertPath: path.resolve(configBaseDir, process.env.ROOT_CERT_PATH || "data/certs/root-ca.crt"),
207
+ rootKeyPath: path.resolve(configBaseDir, process.env.ROOT_KEY_PATH || "data/certs/root-ca.key.pem"),
208
+ leafCertDir: path.resolve(configBaseDir, process.env.LEAF_CERT_DIR || "data/certs/leaf"),
209
+ trustStorePath: path.resolve(configBaseDir, process.env.TRUST_STORE_PATH || "data/certs/proxy-truststore.jks"),
210
+ trustStoreAlias: process.env.TRUST_STORE_ALIAS || "maven-proxy-root-ca",
211
+ trustStorePassword: process.env.TRUST_STORE_PASSWORD || "changeit",
212
+ existingTrustStorePath: resolveOptionalPath(configBaseDir, process.env.EXISTING_TRUST_STORE_PATH || ""),
213
+ existingTrustStorePassword: process.env.EXISTING_TRUST_STORE_PASSWORD || "",
214
+ javaHome: javaHomeResolution.javaHome,
215
+ javaHomeSource: javaHomeResolution.source,
216
+ javaHomeConfigured: javaHomeResolution.configuredJavaHome || "",
217
+ httpsPassthroughForUnmatched: toBool(process.env.HTTPS_PASSTHROUGH_FOR_UNMATCHED, true),
218
+ upstreamProxyUrl: normalizeProxyUrl(process.env.UPSTREAM_PROXY_URL || process.env.ALL_PROXY || process.env.all_proxy || ""),
219
+ upstreamHttpProxyUrl: normalizeProxyUrl(process.env.UPSTREAM_HTTP_PROXY_URL || process.env.HTTP_PROXY || process.env.http_proxy || ""),
220
+ upstreamHttpsProxyUrl: normalizeProxyUrl(process.env.UPSTREAM_HTTPS_PROXY_URL || process.env.HTTPS_PROXY || process.env.https_proxy || ""),
221
+ upstreamNoProxyDomains: toList(process.env.UPSTREAM_NO_PROXY || process.env.NO_PROXY || process.env.no_proxy || ""),
222
+ upstreamIgnoreDomains: toList(process.env.UPSTREAM_IGNORE_DOMAINS || ""),
223
+ repoFallbackRepos,
224
+ };
package/src/index.js CHANGED
@@ -1,93 +1,93 @@
1
- import fs from "node:fs";
2
- import { config } from "./config/config.js";
3
- import { matchesDomain } from "./common/domain-match.js";
4
- import { CertManager } from "./cert/cert-manager.js";
5
- import { Downloader } from "./cache/downloader.js";
6
- import { startProxyServer } from "./proxy/proxy-server.js";
7
- import { startRepoServer } from "./repo/repo-server.js";
8
- import { getTrustStoreCommands } from "./cert/truststore-utils.js";
9
- import { UpstreamProxyManager } from "./proxy/upstream-proxy.js";
10
- import { installConsoleLogFileMirror, installGlobalErrorLogging } from "./common/console-log-file.js";
11
-
12
- installConsoleLogFileMirror({
13
- logDir: config.downloadLogDir,
14
- retentionDays: config.logRetentionDays,
15
- });
16
- installGlobalErrorLogging();
17
-
18
- async function main() {
19
- await fs.promises.mkdir(config.cacheDir, { recursive: true });
20
- await fs.promises.mkdir(config.mavenCacheDir, { recursive: true });
21
- await fs.promises.mkdir(config.npmCacheDir, { recursive: true });
22
- await fs.promises.mkdir(config.genericCacheDir, { recursive: true });
23
- await fs.promises.mkdir(config.downloadLogDir, { recursive: true });
24
- await fs.promises.mkdir(config.certDir, { recursive: true });
25
- await fs.promises.mkdir(config.leafCertDir, { recursive: true });
26
-
27
- const certManager = new CertManager(config);
28
- await certManager.init();
29
-
30
- for (const pattern of config.httpsMitmDomains) {
31
- if (!pattern.includes("*")) {
32
- await certManager.getOrCreateLeaf(pattern);
33
- }
34
- }
35
-
36
- const upstreamProxyManager = new UpstreamProxyManager(config, matchesDomain);
37
-
38
- const downloader = new Downloader(config, matchesDomain, upstreamProxyManager);
39
-
40
- const { proxyServer, mitmHttpServer } = startProxyServer(
41
- config,
42
- certManager,
43
- downloader,
44
- matchesDomain,
45
- upstreamProxyManager,
46
- );
47
- const repoServer = startRepoServer(config, downloader);
48
-
49
- const trustCommands = getTrustStoreCommands(config);
50
-
51
- console.log("[maven-proxy] started");
52
- console.log(`[maven-proxy] config mode: ${config.configMode}`);
53
- console.log(`[maven-proxy] config file: ${config.loadedConfigFile || "(none)"}`);
54
- console.log(`[maven-proxy] config base: ${config.configBaseDir}`);
55
- if (config.configMode === "user") {
56
- console.log(`[maven-proxy] default user config: ${config.defaultUserConfigPath}`);
57
- }
58
- console.log(`[maven-proxy] proxy port: ${config.proxyPort}`);
59
- console.log(`[maven-proxy] repo port: ${config.repoPort}`);
60
- console.log(`[maven-proxy] cache dir : ${config.cacheDir}`);
61
- console.log(`[maven-proxy] cache maven: ${config.mavenCacheDir}`);
62
- console.log(`[maven-proxy] cache npm : ${config.npmCacheDir}`);
63
- console.log(`[maven-proxy] cache other: ${config.genericCacheDir}`);
64
- console.log(`[maven-proxy] download log: ${config.downloadLogDir}`);
65
- console.log(`[maven-proxy] log retention days: ${config.logRetentionDays}`);
66
- console.log(`[maven-proxy] root cert : ${config.rootCertPath}`);
67
- console.log(`[maven-proxy] repo fallback repos: ${(config.repoFallbackRepos || []).join(",") || "(none)"}`);
68
- if (config.upstreamProxyUrl || config.upstreamHttpProxyUrl || config.upstreamHttpsProxyUrl) {
69
- console.log(`[maven-proxy] upstream proxy (generic): ${config.upstreamProxyUrl || "(none)"}`);
70
- console.log(`[maven-proxy] upstream proxy (http) : ${config.upstreamHttpProxyUrl || "(none)"}`);
71
- console.log(`[maven-proxy] upstream proxy (https) : ${config.upstreamHttpsProxyUrl || "(none)"}`);
72
- console.log(`[maven-proxy] upstream no-proxy : ${(config.upstreamNoProxyDomains || []).join(",") || "(none)"}`);
73
- console.log(`[maven-proxy] upstream ignore-domains : ${(config.upstreamIgnoreDomains || []).join(",") || "(none)"}`);
74
- }
75
- console.log("[maven-proxy] trust store command (copy):");
76
- console.log(trustCommands.copyCmd);
77
- console.log("[maven-proxy] trust store command (import):");
78
- console.log(trustCommands.importCmd);
79
-
80
- const shutdown = () => {
81
- proxyServer.close();
82
- mitmHttpServer.close();
83
- repoServer.close();
84
- };
85
-
86
- process.on("SIGINT", shutdown);
87
- process.on("SIGTERM", shutdown);
88
- }
89
-
90
- main().catch((error) => {
91
- console.error("[maven-proxy] fatal error:", error);
92
- process.exit(1);
93
- });
1
+ import fs from "node:fs";
2
+ import { config } from "./config/config.js";
3
+ import { matchesDomain } from "./common/domain-match.js";
4
+ import { CertManager } from "./cert/cert-manager.js";
5
+ import { Downloader } from "./cache/downloader.js";
6
+ import { startProxyServer } from "./proxy/proxy-server.js";
7
+ import { startRepoServer } from "./repo/repo-server.js";
8
+ import { getTrustStoreCommands } from "./cert/truststore-utils.js";
9
+ import { UpstreamProxyManager } from "./proxy/upstream-proxy.js";
10
+ import { installConsoleLogFileMirror, installGlobalErrorLogging } from "./common/console-log-file.js";
11
+
12
+ installConsoleLogFileMirror({
13
+ logDir: config.downloadLogDir,
14
+ retentionDays: config.logRetentionDays,
15
+ });
16
+ installGlobalErrorLogging();
17
+
18
+ async function main() {
19
+ await fs.promises.mkdir(config.cacheDir, { recursive: true });
20
+ await fs.promises.mkdir(config.mavenCacheDir, { recursive: true });
21
+ await fs.promises.mkdir(config.npmCacheDir, { recursive: true });
22
+ await fs.promises.mkdir(config.genericCacheDir, { recursive: true });
23
+ await fs.promises.mkdir(config.downloadLogDir, { recursive: true });
24
+ await fs.promises.mkdir(config.certDir, { recursive: true });
25
+ await fs.promises.mkdir(config.leafCertDir, { recursive: true });
26
+
27
+ const certManager = new CertManager(config);
28
+ await certManager.init();
29
+
30
+ for (const pattern of config.httpsMitmDomains) {
31
+ if (!pattern.includes("*")) {
32
+ await certManager.getOrCreateLeaf(pattern);
33
+ }
34
+ }
35
+
36
+ const upstreamProxyManager = new UpstreamProxyManager(config, matchesDomain);
37
+
38
+ const downloader = new Downloader(config, matchesDomain, upstreamProxyManager);
39
+
40
+ const { proxyServer, mitmHttpServer } = startProxyServer(
41
+ config,
42
+ certManager,
43
+ downloader,
44
+ matchesDomain,
45
+ upstreamProxyManager,
46
+ );
47
+ const repoServer = startRepoServer(config, downloader);
48
+
49
+ const trustCommands = getTrustStoreCommands(config);
50
+
51
+ console.log("[maven-proxy] started");
52
+ console.log(`[maven-proxy] config mode: ${config.configMode}`);
53
+ console.log(`[maven-proxy] config file: ${config.loadedConfigFile || "(none)"}`);
54
+ console.log(`[maven-proxy] config base: ${config.configBaseDir}`);
55
+ if (config.configMode === "user") {
56
+ console.log(`[maven-proxy] default user config: ${config.defaultUserConfigPath}`);
57
+ }
58
+ console.log(`[maven-proxy] proxy port: ${config.proxyPort}`);
59
+ console.log(`[maven-proxy] repo port: ${config.repoPort}`);
60
+ console.log(`[maven-proxy] cache dir : ${config.cacheDir}`);
61
+ console.log(`[maven-proxy] cache maven: ${config.mavenCacheDir}`);
62
+ console.log(`[maven-proxy] cache npm : ${config.npmCacheDir}`);
63
+ console.log(`[maven-proxy] cache other: ${config.genericCacheDir}`);
64
+ console.log(`[maven-proxy] download log: ${config.downloadLogDir}`);
65
+ console.log(`[maven-proxy] log retention days: ${config.logRetentionDays}`);
66
+ console.log(`[maven-proxy] root cert : ${config.rootCertPath}`);
67
+ console.log(`[maven-proxy] repo fallback repos: ${(config.repoFallbackRepos || []).join(",") || "(none)"}`);
68
+ if (config.upstreamProxyUrl || config.upstreamHttpProxyUrl || config.upstreamHttpsProxyUrl) {
69
+ console.log(`[maven-proxy] upstream proxy (generic): ${config.upstreamProxyUrl || "(none)"}`);
70
+ console.log(`[maven-proxy] upstream proxy (http) : ${config.upstreamHttpProxyUrl || "(none)"}`);
71
+ console.log(`[maven-proxy] upstream proxy (https) : ${config.upstreamHttpsProxyUrl || "(none)"}`);
72
+ console.log(`[maven-proxy] upstream no-proxy : ${(config.upstreamNoProxyDomains || []).join(",") || "(none)"}`);
73
+ console.log(`[maven-proxy] upstream ignore-domains : ${(config.upstreamIgnoreDomains || []).join(",") || "(none)"}`);
74
+ }
75
+ console.log("[maven-proxy] trust store command (copy):");
76
+ console.log(trustCommands.copyCmd);
77
+ console.log("[maven-proxy] trust store command (import):");
78
+ console.log(trustCommands.importCmd);
79
+
80
+ const shutdown = () => {
81
+ proxyServer.close();
82
+ mitmHttpServer.close();
83
+ repoServer.close();
84
+ };
85
+
86
+ process.on("SIGINT", shutdown);
87
+ process.on("SIGTERM", shutdown);
88
+ }
89
+
90
+ main().catch((error) => {
91
+ console.error("[maven-proxy] fatal error:", error);
92
+ process.exit(1);
93
+ });