com.jimuwd.xian.registry-proxy 1.0.0 → 1.0.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/dist/index.js +46 -26
- package/package.json +1 -1
- package/src/index.ts +50 -26
package/dist/index.js
CHANGED
|
@@ -5,44 +5,63 @@ import { load } from 'js-yaml';
|
|
|
5
5
|
import fetch from 'node-fetch';
|
|
6
6
|
import { homedir } from 'os';
|
|
7
7
|
import { join } from 'path';
|
|
8
|
-
async function loadRegistries(
|
|
9
|
-
|
|
8
|
+
async function loadRegistries(proxyConfigPath = './.registry-proxy.yml', localYarnConfigPath = './.yarnrc.yml', globalYarnConfigPath = join(homedir(), '.yarnrc.yml')) {
|
|
9
|
+
// 读取独立的 .registry-proxy.yml
|
|
10
|
+
let proxyConfig = { registries: {} };
|
|
10
11
|
try {
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
console.log(`Loaded
|
|
12
|
+
const proxyYamlContent = await readFile(proxyConfigPath, 'utf8');
|
|
13
|
+
proxyConfig = load(proxyYamlContent);
|
|
14
|
+
console.log(`Loaded proxy config from ${proxyConfigPath}`);
|
|
14
15
|
}
|
|
15
16
|
catch (e) {
|
|
16
|
-
console.error(`Failed to load ${
|
|
17
|
-
process.exit(1);
|
|
17
|
+
console.error(`Failed to load ${proxyConfigPath}: ${e.message}`);
|
|
18
|
+
process.exit(1); // 代理配置文件是必须的
|
|
18
19
|
}
|
|
19
|
-
if (!
|
|
20
|
-
console.error(`No
|
|
20
|
+
if (!proxyConfig.registries || !Object.keys(proxyConfig.registries).length) {
|
|
21
|
+
console.error(`No registries found in ${proxyConfigPath}`);
|
|
21
22
|
process.exit(1);
|
|
22
23
|
}
|
|
23
|
-
|
|
24
|
+
// 读取本地 .yarnrc.yml(用于 token 回退)
|
|
25
|
+
let localYarnConfig = {};
|
|
26
|
+
try {
|
|
27
|
+
const localYamlContent = await readFile(localYarnConfigPath, 'utf8');
|
|
28
|
+
localYarnConfig = load(localYamlContent);
|
|
29
|
+
console.log(`Loaded local Yarn config from ${localYarnConfigPath}`);
|
|
30
|
+
}
|
|
31
|
+
catch (e) {
|
|
32
|
+
console.warn(`Failed to load ${localYarnConfigPath}: ${e.message}`);
|
|
33
|
+
}
|
|
34
|
+
// 读取全局 ~/.yarnrc.yml(用于 token 回退)
|
|
35
|
+
let globalYarnConfig = {};
|
|
24
36
|
try {
|
|
25
|
-
const globalYamlContent = await readFile(
|
|
26
|
-
|
|
27
|
-
console.log(`Loaded global config from ${
|
|
37
|
+
const globalYamlContent = await readFile(globalYarnConfigPath, 'utf8');
|
|
38
|
+
globalYarnConfig = load(globalYamlContent);
|
|
39
|
+
console.log(`Loaded global Yarn config from ${globalYarnConfigPath}`);
|
|
28
40
|
}
|
|
29
41
|
catch (e) {
|
|
30
|
-
console.warn(`Failed to load ${
|
|
42
|
+
console.warn(`Failed to load ${globalYarnConfigPath}: ${e.message}`);
|
|
31
43
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
44
|
+
// 从 .registry-proxy.yml 获取 registries,并回退读取 token
|
|
45
|
+
const registries = Object.entries(proxyConfig.registries).map(([url, regConfig]) => {
|
|
46
|
+
let token = regConfig.npmAuthToken?.replace(/\${(.+)}/, (_, key) => process.env[key] || '') || regConfig.npmAuthToken;
|
|
47
|
+
// 如果 .registry-proxy.yml 未提供 token,从本地 .yarnrc.yml 回退
|
|
48
|
+
if (!token && localYarnConfig.npmRegistries && localYarnConfig.npmRegistries[url]) {
|
|
49
|
+
token = localYarnConfig.npmRegistries[url].npmAuthToken?.replace(/\${(.+)}/, (_, key) => process.env[key] || '') || localYarnConfig.npmRegistries[url].npmAuthToken;
|
|
50
|
+
console.log(`Token for ${url} not found in ${proxyConfigPath}, using local Yarn config`);
|
|
51
|
+
}
|
|
52
|
+
// 如果本地 .yarnrc.yml 仍无 token,从全局 ~/.yarnrc.yml 回退
|
|
53
|
+
if (!token && globalYarnConfig.npmRegistries && globalYarnConfig.npmRegistries[url]) {
|
|
54
|
+
token = globalYarnConfig.npmRegistries[url].npmAuthToken?.replace(/\${(.+)}/, (_, key) => process.env[key] || '') || globalYarnConfig.npmRegistries[url].npmAuthToken;
|
|
55
|
+
console.log(`Token for ${url} not found in local Yarn config, using global Yarn config`);
|
|
37
56
|
}
|
|
38
57
|
console.log(`Registry ${url}: token=${token ? 'present' : 'missing'}`);
|
|
39
58
|
return { url, token };
|
|
40
59
|
});
|
|
41
60
|
return registries;
|
|
42
61
|
}
|
|
43
|
-
export async function startProxyServer(
|
|
62
|
+
export async function startProxyServer(proxyConfigPath, localYarnConfigPath, globalYarnConfigPath, port = 4873) {
|
|
44
63
|
console.log('Starting proxy server...');
|
|
45
|
-
const registries = await loadRegistries(
|
|
64
|
+
const registries = await loadRegistries(proxyConfigPath, localYarnConfigPath, globalYarnConfigPath);
|
|
46
65
|
const server = createServer(async (req, res) => {
|
|
47
66
|
if (!req.url || req.method !== 'GET') {
|
|
48
67
|
res.writeHead(400);
|
|
@@ -86,11 +105,12 @@ export async function startProxyServer(localConfigPath, globalConfigPath, port =
|
|
|
86
105
|
return server;
|
|
87
106
|
}
|
|
88
107
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
89
|
-
const
|
|
90
|
-
const
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
108
|
+
const proxyConfigPath = process.argv[2];
|
|
109
|
+
const localYarnConfigPath = process.argv[3];
|
|
110
|
+
const globalYarnConfigPath = process.argv[4];
|
|
111
|
+
const port = parseInt(process.argv[5], 10) || 4873;
|
|
112
|
+
console.log(`CLI: proxyConfigPath=${proxyConfigPath || './.registry-proxy.yml'}, localYarnConfigPath=${localYarnConfigPath || './.yarnrc.yml'}, globalYarnConfigPath=${globalYarnConfigPath || join(homedir(), '.yarnrc.yml')}, port=${port}`);
|
|
113
|
+
startProxyServer(proxyConfigPath, localYarnConfigPath, globalYarnConfigPath, port).catch(err => {
|
|
94
114
|
console.error('Startup failed:', err.message);
|
|
95
115
|
process.exit(1);
|
|
96
116
|
});
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -7,39 +7,62 @@ import { homedir } from 'os';
|
|
|
7
7
|
import { join } from 'path';
|
|
8
8
|
|
|
9
9
|
interface RegistryConfig { npmAuthToken?: string; }
|
|
10
|
+
interface ProxyConfig { registries: Record<string, RegistryConfig>; }
|
|
10
11
|
interface YarnConfig { npmRegistries?: Record<string, RegistryConfig>; }
|
|
11
12
|
|
|
12
|
-
async function loadRegistries(
|
|
13
|
-
|
|
13
|
+
async function loadRegistries(proxyConfigPath = './.registry-proxy.yml', localYarnConfigPath = './.yarnrc.yml', globalYarnConfigPath = join(homedir(), '.yarnrc.yml')): Promise<{ url: string; token?: string }[]> {
|
|
14
|
+
// 读取独立的 .registry-proxy.yml
|
|
15
|
+
let proxyConfig: ProxyConfig = { registries: {} };
|
|
14
16
|
try {
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
console.log(`Loaded
|
|
17
|
+
const proxyYamlContent = await readFile(proxyConfigPath, 'utf8');
|
|
18
|
+
proxyConfig = load(proxyYamlContent) as ProxyConfig;
|
|
19
|
+
console.log(`Loaded proxy config from ${proxyConfigPath}`);
|
|
18
20
|
} catch (e) {
|
|
19
|
-
console.error(`Failed to load ${
|
|
20
|
-
process.exit(1);
|
|
21
|
+
console.error(`Failed to load ${proxyConfigPath}: ${(e as Error).message}`);
|
|
22
|
+
process.exit(1); // 代理配置文件是必须的
|
|
21
23
|
}
|
|
22
24
|
|
|
23
|
-
if (!
|
|
24
|
-
console.error(`No
|
|
25
|
+
if (!proxyConfig.registries || !Object.keys(proxyConfig.registries).length) {
|
|
26
|
+
console.error(`No registries found in ${proxyConfigPath}`);
|
|
25
27
|
process.exit(1);
|
|
26
28
|
}
|
|
27
29
|
|
|
28
|
-
|
|
30
|
+
// 读取本地 .yarnrc.yml(用于 token 回退)
|
|
31
|
+
let localYarnConfig: YarnConfig = {};
|
|
32
|
+
try {
|
|
33
|
+
const localYamlContent = await readFile(localYarnConfigPath, 'utf8');
|
|
34
|
+
localYarnConfig = load(localYamlContent) as YarnConfig;
|
|
35
|
+
console.log(`Loaded local Yarn config from ${localYarnConfigPath}`);
|
|
36
|
+
} catch (e) {
|
|
37
|
+
console.warn(`Failed to load ${localYarnConfigPath}: ${(e as Error).message}`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// 读取全局 ~/.yarnrc.yml(用于 token 回退)
|
|
41
|
+
let globalYarnConfig: YarnConfig = {};
|
|
29
42
|
try {
|
|
30
|
-
const globalYamlContent = await readFile(
|
|
31
|
-
|
|
32
|
-
console.log(`Loaded global config from ${
|
|
43
|
+
const globalYamlContent = await readFile(globalYarnConfigPath, 'utf8');
|
|
44
|
+
globalYarnConfig = load(globalYamlContent) as YarnConfig;
|
|
45
|
+
console.log(`Loaded global Yarn config from ${globalYarnConfigPath}`);
|
|
33
46
|
} catch (e) {
|
|
34
|
-
console.warn(`Failed to load ${
|
|
47
|
+
console.warn(`Failed to load ${globalYarnConfigPath}: ${(e as Error).message}`);
|
|
35
48
|
}
|
|
36
49
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
50
|
+
// 从 .registry-proxy.yml 获取 registries,并回退读取 token
|
|
51
|
+
const registries = Object.entries(proxyConfig.registries).map(([url, regConfig]) => {
|
|
52
|
+
let token = regConfig.npmAuthToken?.replace(/\${(.+)}/, (_, key) => process.env[key] || '') || regConfig.npmAuthToken;
|
|
53
|
+
|
|
54
|
+
// 如果 .registry-proxy.yml 未提供 token,从本地 .yarnrc.yml 回退
|
|
55
|
+
if (!token && localYarnConfig.npmRegistries && localYarnConfig.npmRegistries[url]) {
|
|
56
|
+
token = localYarnConfig.npmRegistries[url].npmAuthToken?.replace(/\${(.+)}/, (_, key) => process.env[key] || '') || localYarnConfig.npmRegistries[url].npmAuthToken;
|
|
57
|
+
console.log(`Token for ${url} not found in ${proxyConfigPath}, using local Yarn config`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 如果本地 .yarnrc.yml 仍无 token,从全局 ~/.yarnrc.yml 回退
|
|
61
|
+
if (!token && globalYarnConfig.npmRegistries && globalYarnConfig.npmRegistries[url]) {
|
|
62
|
+
token = globalYarnConfig.npmRegistries[url].npmAuthToken?.replace(/\${(.+)}/, (_, key) => process.env[key] || '') || globalYarnConfig.npmRegistries[url].npmAuthToken;
|
|
63
|
+
console.log(`Token for ${url} not found in local Yarn config, using global Yarn config`);
|
|
42
64
|
}
|
|
65
|
+
|
|
43
66
|
console.log(`Registry ${url}: token=${token ? 'present' : 'missing'}`);
|
|
44
67
|
return { url, token };
|
|
45
68
|
});
|
|
@@ -47,9 +70,9 @@ async function loadRegistries(localConfigPath = './.yarnrc.yml', globalConfigPat
|
|
|
47
70
|
return registries;
|
|
48
71
|
}
|
|
49
72
|
|
|
50
|
-
export async function startProxyServer(
|
|
73
|
+
export async function startProxyServer(proxyConfigPath?: string, localYarnConfigPath?: string, globalYarnConfigPath?: string, port: number = 4873): Promise<Server> {
|
|
51
74
|
console.log('Starting proxy server...');
|
|
52
|
-
const registries = await loadRegistries(
|
|
75
|
+
const registries = await loadRegistries(proxyConfigPath, localYarnConfigPath, globalYarnConfigPath);
|
|
53
76
|
|
|
54
77
|
const server = createServer(async (req, res) => {
|
|
55
78
|
if (!req.url || req.method !== 'GET') {
|
|
@@ -99,11 +122,12 @@ export async function startProxyServer(localConfigPath?: string, globalConfigPat
|
|
|
99
122
|
}
|
|
100
123
|
|
|
101
124
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
102
|
-
const
|
|
103
|
-
const
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
125
|
+
const proxyConfigPath = process.argv[2];
|
|
126
|
+
const localYarnConfigPath = process.argv[3];
|
|
127
|
+
const globalYarnConfigPath = process.argv[4];
|
|
128
|
+
const port = parseInt(process.argv[5], 10) || 4873;
|
|
129
|
+
console.log(`CLI: proxyConfigPath=${proxyConfigPath || './.registry-proxy.yml'}, localYarnConfigPath=${localYarnConfigPath || './.yarnrc.yml'}, globalYarnConfigPath=${globalYarnConfigPath || join(homedir(), '.yarnrc.yml')}, port=${port}`);
|
|
130
|
+
startProxyServer(proxyConfigPath, localYarnConfigPath, globalYarnConfigPath, port).catch(err => {
|
|
107
131
|
console.error('Startup failed:', (err as Error).message);
|
|
108
132
|
process.exit(1);
|
|
109
133
|
});
|