protocol-proxy 2.0.1 → 2.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.
@@ -21,6 +21,50 @@ migrateOldConfig();
21
21
 
22
22
  let configCache = null;
23
23
 
24
+ // 迁移旧格式:target → providerId
25
+ function migrateTargetToProvider(config) {
26
+ if (!Array.isArray(config.proxies)) return config;
27
+ let changed = false;
28
+
29
+ for (const proxy of config.proxies) {
30
+ if (!proxy.target) continue;
31
+
32
+ // 有 target 但没有 providerId → 从 target 创建供应商
33
+ if (!proxy.providerId) {
34
+ const t = proxy.target;
35
+ const provider = {
36
+ id: 'provider-' + Date.now(),
37
+ name: t.providerName || t.providerUrl,
38
+ url: t.providerUrl,
39
+ protocol: t.protocol || 'openai',
40
+ apiKey: t.apiKey || '',
41
+ models: Array.isArray(t.models) ? t.models : [],
42
+ };
43
+ config.providers = config.providers || [];
44
+ config.providers.push(provider);
45
+ proxy.providerId = provider.id;
46
+ proxy.defaultModel = t.defaultModel || '';
47
+ delete proxy.target;
48
+ changed = true;
49
+ } else {
50
+ // 有 target 也有 providerId → 迁移 apiKey 到供应商,删除 target
51
+ const provider = (config.providers || []).find(p => p.id === proxy.providerId);
52
+ if (provider && proxy.target.apiKey && !provider.apiKey) {
53
+ provider.apiKey = proxy.target.apiKey;
54
+ changed = true;
55
+ }
56
+ delete proxy.target;
57
+ changed = true;
58
+ }
59
+ }
60
+
61
+ if (changed) {
62
+ configCache = config;
63
+ saveConfig(config);
64
+ }
65
+ return config;
66
+ }
67
+
24
68
  function normalizeModels(models) {
25
69
  if (!Array.isArray(models)) return [];
26
70
  return Array.from(new Set(
@@ -58,7 +102,9 @@ function loadConfig() {
58
102
  return configCache;
59
103
  }
60
104
  const raw = fs.readFileSync(CONFIG_PATH, 'utf-8');
61
- configCache = normalizeConfig(JSON.parse(raw));
105
+ let config = normalizeConfig(JSON.parse(raw));
106
+ config = migrateTargetToProvider(config);
107
+ configCache = config;
62
108
  return configCache;
63
109
  } catch (err) {
64
110
  console.error('加载配置失败:', err.message);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "protocol-proxy",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "description": "OpenAI / Anthropic 协议转换透明代理",
5
5
  "main": "server.js",
6
6
  "bin": {
package/public/app.js CHANGED
@@ -40,6 +40,7 @@ function initProviderDropdown() {
40
40
  const dropdown = document.getElementById('provider-dropdown');
41
41
  const addNameInput = document.getElementById('provider-add-name');
42
42
  const addUrlInput = document.getElementById('provider-add-url');
43
+ const addKeyInput = document.getElementById('provider-add-key');
43
44
  const addBtn = document.getElementById('provider-add-btn');
44
45
 
45
46
  trigger.addEventListener('click', (e) => {
@@ -48,6 +49,7 @@ function initProviderDropdown() {
48
49
  if (dropdown.classList.contains('open')) {
49
50
  addNameInput.value = '';
50
51
  addUrlInput.value = '';
52
+ addKeyInput.value = '';
51
53
  renderProviderOptions();
52
54
  addNameInput.focus();
53
55
  }
@@ -62,6 +64,7 @@ function initProviderDropdown() {
62
64
  addBtn.addEventListener('click', async () => {
63
65
  const name = addNameInput.value.trim();
64
66
  const url = addUrlInput.value.trim();
67
+ const apiKey = addKeyInput.value.trim();
65
68
  if (!name || !url) {
66
69
  showToast('请填写供应商名称和地址', true);
67
70
  return;
@@ -70,7 +73,7 @@ function initProviderDropdown() {
70
73
  const res = await fetch('/api/providers', {
71
74
  method: 'POST',
72
75
  headers: { 'Content-Type': 'application/json' },
73
- body: JSON.stringify({ name, url }),
76
+ body: JSON.stringify({ name, url, apiKey }),
74
77
  });
75
78
  if (!res.ok) {
76
79
  const err = await res.json();
package/public/index.html CHANGED
@@ -85,6 +85,7 @@
85
85
  <div class="model-add-section">
86
86
  <input type="text" class="model-add-input" id="provider-add-name" placeholder="供应商名称">
87
87
  <input type="url" class="model-add-input" id="provider-add-url" placeholder="https://api.example.com">
88
+ <input type="password" class="model-add-input" id="provider-add-key" placeholder="API Key">
88
89
  <button type="button" class="btn btn-primary btn-sm" id="provider-add-btn">添加</button>
89
90
  </div>
90
91
  </div>
package/server.js CHANGED
@@ -235,7 +235,12 @@ async function init() {
235
235
  const proxies = configStore.getProxies().map(p => {
236
236
  const provider = configStore.getProviderById(p.providerId);
237
237
  return {
238
- ...p,
238
+ id: p.id,
239
+ name: p.name,
240
+ port: p.port,
241
+ requireAuth: p.requireAuth,
242
+ authToken: p.authToken,
243
+ providerId: p.providerId,
239
244
  providerName: provider?.name || '',
240
245
  providerUrl: provider?.url || '',
241
246
  protocol: provider?.protocol || '',