@hotmanxp/opencode-qwen-login-plugin 1.1.0 → 1.2.0
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/cli.js +0 -0
- package/dist/config-merge.test.js +188 -0
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/plugin.d.ts +14 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +83 -0
- package/dist/plugin.js.map +1 -0
- package/dist/qwen-oauth.js +2 -2
- package/dist/qwen-oauth.js.map +1 -1
- package/dist/qwen-oauth.test.js +123 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 配置合并测试 - 集成测试
|
|
3
|
+
*
|
|
4
|
+
* 测试 saveToOpencodeConfig 函数的合并行为
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, beforeEach, afterEach } from 'node:test';
|
|
7
|
+
import { writeFile, mkdir, rm, readFile } from 'node:fs/promises';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
import assert from 'node:assert';
|
|
10
|
+
import { saveToOpencodeConfig } from './qwen-oauth.js';
|
|
11
|
+
describe('saveToOpencodeConfig - 配置合并', () => {
|
|
12
|
+
let testConfigDir;
|
|
13
|
+
let testConfigPath;
|
|
14
|
+
let originalHOME;
|
|
15
|
+
beforeEach(async () => {
|
|
16
|
+
originalHOME = process.env.HOME;
|
|
17
|
+
testConfigDir = await mkdtemp('opencode-config-test-');
|
|
18
|
+
testConfigPath = join(testConfigDir, '.config', 'opencode');
|
|
19
|
+
await mkdir(testConfigPath, { recursive: true });
|
|
20
|
+
process.env.HOME = testConfigDir;
|
|
21
|
+
});
|
|
22
|
+
afterEach(async () => {
|
|
23
|
+
process.env.HOME = originalHOME;
|
|
24
|
+
await rm(testConfigDir, { recursive: true, force: true }).catch(() => { });
|
|
25
|
+
});
|
|
26
|
+
it('应该保留现有的 plugin 数组', async () => {
|
|
27
|
+
// 创建初始配置
|
|
28
|
+
const initialConfig = {
|
|
29
|
+
plugin: ['oh-my-opencode', 'another-plugin'],
|
|
30
|
+
agent: {
|
|
31
|
+
build: {
|
|
32
|
+
max_steps: 10
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
const configPath = join(testConfigPath, 'opencode.json');
|
|
37
|
+
await writeFile(configPath, JSON.stringify(initialConfig, null, 2));
|
|
38
|
+
// 调用 saveToOpencodeConfig
|
|
39
|
+
await saveToOpencodeConfig({
|
|
40
|
+
apiKey: 'Bearer test-token',
|
|
41
|
+
baseURL: 'https://portal.qwen.ai/v1',
|
|
42
|
+
headers: {
|
|
43
|
+
'user-agent': 'QwenCode/test'
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
// 读取更新后的配置
|
|
47
|
+
const updatedConfig = JSON.parse(await readFile(configPath, 'utf-8'));
|
|
48
|
+
// 验证 plugin 数组被保留
|
|
49
|
+
assert.ok(updatedConfig.plugin.includes('oh-my-opencode'), 'Should contain oh-my-opencode');
|
|
50
|
+
assert.ok(updatedConfig.plugin.includes('another-plugin'), 'Should contain another-plugin');
|
|
51
|
+
// 验证 agent 配置被保留
|
|
52
|
+
assert.ok(updatedConfig.agent, 'Should have agent config');
|
|
53
|
+
assert.ok(updatedConfig.agent.build, 'Should have build agent');
|
|
54
|
+
assert.strictEqual(updatedConfig.agent.build.max_steps, 10);
|
|
55
|
+
// 验证 qwen provider 被添加
|
|
56
|
+
assert.ok(updatedConfig.provider, 'Should have provider config');
|
|
57
|
+
assert.ok(updatedConfig.provider.qwen, 'Should have qwen provider');
|
|
58
|
+
});
|
|
59
|
+
it('应该保留现有的其他 provider', async () => {
|
|
60
|
+
// 创建初始配置,包含其他 provider
|
|
61
|
+
const initialConfig = {
|
|
62
|
+
provider: {
|
|
63
|
+
anthropic: {
|
|
64
|
+
options: {
|
|
65
|
+
apiKey: 'sk-ant-xxx'
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
openai: {
|
|
69
|
+
options: {
|
|
70
|
+
apiKey: 'sk-openai-xxx'
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
model: 'anthropic/claude-sonnet-4-20250514'
|
|
75
|
+
};
|
|
76
|
+
const configPath = join(testConfigPath, 'opencode.json');
|
|
77
|
+
await writeFile(configPath, JSON.stringify(initialConfig, null, 2));
|
|
78
|
+
// 调用 saveToOpencodeConfig
|
|
79
|
+
await saveToOpencodeConfig({
|
|
80
|
+
apiKey: 'Bearer test-token',
|
|
81
|
+
baseURL: 'https://portal.qwen.ai/v1',
|
|
82
|
+
headers: {}
|
|
83
|
+
});
|
|
84
|
+
// 读取更新后的配置
|
|
85
|
+
const updatedConfig = JSON.parse(await readFile(configPath, 'utf-8'));
|
|
86
|
+
// 验证其他 provider 被保留
|
|
87
|
+
assert.ok(updatedConfig.provider.anthropic, "should be defined");
|
|
88
|
+
assert.strictEqual(updatedConfig.provider.anthropic.options.apiKey, 'sk-ant-xxx');
|
|
89
|
+
assert.ok(updatedConfig.provider.openai, "should be defined");
|
|
90
|
+
assert.strictEqual(updatedConfig.provider.openai.options.apiKey, 'sk-openai-xxx');
|
|
91
|
+
// 验证 qwen provider 被添加
|
|
92
|
+
assert.ok(updatedConfig.provider.qwen, "should be defined");
|
|
93
|
+
assert.strictEqual(updatedConfig.provider.qwen.options.apiKey, 'Bearer test-token');
|
|
94
|
+
});
|
|
95
|
+
it('不应该覆盖现有的 model 配置', async () => {
|
|
96
|
+
// 创建初始配置,包含自定义 model
|
|
97
|
+
const initialConfig = {
|
|
98
|
+
provider: {
|
|
99
|
+
anthropic: {
|
|
100
|
+
options: {
|
|
101
|
+
apiKey: 'sk-ant-xxx'
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
model: 'anthropic/claude-sonnet-4-20250514'
|
|
106
|
+
};
|
|
107
|
+
const configPath = join(testConfigPath, 'opencode.json');
|
|
108
|
+
await writeFile(configPath, JSON.stringify(initialConfig, null, 2));
|
|
109
|
+
// 调用 saveToOpencodeConfig
|
|
110
|
+
await saveToOpencodeConfig({
|
|
111
|
+
apiKey: 'Bearer test-token',
|
|
112
|
+
baseURL: 'https://portal.qwen.ai/v1',
|
|
113
|
+
headers: {}
|
|
114
|
+
});
|
|
115
|
+
// 读取更新后的配置
|
|
116
|
+
const updatedConfig = JSON.parse(await readFile(configPath, 'utf-8'));
|
|
117
|
+
// 验证原有 model 被保留(不覆盖)
|
|
118
|
+
assert.strictEqual(updatedConfig.model, 'anthropic/claude-sonnet-4-20250514');
|
|
119
|
+
});
|
|
120
|
+
it('不应该设置默认 model', async () => {
|
|
121
|
+
// 创建初始配置,没有 model
|
|
122
|
+
const initialConfig = {
|
|
123
|
+
plugin: ['test-plugin']
|
|
124
|
+
};
|
|
125
|
+
const configPath = join(testConfigPath, 'opencode.json');
|
|
126
|
+
await writeFile(configPath, JSON.stringify(initialConfig, null, 2));
|
|
127
|
+
// 调用 saveToOpencodeConfig
|
|
128
|
+
await saveToOpencodeConfig({
|
|
129
|
+
apiKey: 'Bearer test-token',
|
|
130
|
+
baseURL: 'https://portal.qwen.ai/v1',
|
|
131
|
+
headers: {}
|
|
132
|
+
});
|
|
133
|
+
// 读取更新后的配置
|
|
134
|
+
const updatedConfig = JSON.parse(await readFile(configPath, 'utf-8'));
|
|
135
|
+
// 验证不设置默认 model(让用户自己配置)
|
|
136
|
+
assert.strictEqual(updatedConfig.model, undefined, 'Should not set default model');
|
|
137
|
+
// 验证 plugin 被保留
|
|
138
|
+
assert.ok(updatedConfig.plugin.includes('test-plugin'), 'Should include test-plugin');
|
|
139
|
+
});
|
|
140
|
+
it('应该保留其他顶层配置', async () => {
|
|
141
|
+
// 创建初始配置,包含各种配置
|
|
142
|
+
const initialConfig = {
|
|
143
|
+
$schema: 'https://opencode.ai/config.json',
|
|
144
|
+
agent: {
|
|
145
|
+
build: { max_steps: 10 },
|
|
146
|
+
plan: { read_only: true }
|
|
147
|
+
},
|
|
148
|
+
mode: {
|
|
149
|
+
default: 'build'
|
|
150
|
+
},
|
|
151
|
+
instructions: ['./instructions.md'],
|
|
152
|
+
plugin: ['plugin-a', 'plugin-b'],
|
|
153
|
+
provider: {
|
|
154
|
+
anthropic: { options: { apiKey: 'sk-ant' } }
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
const configPath = join(testConfigPath, 'opencode.json');
|
|
158
|
+
await writeFile(configPath, JSON.stringify(initialConfig, null, 2));
|
|
159
|
+
// 调用 saveToOpencodeConfig
|
|
160
|
+
await saveToOpencodeConfig({
|
|
161
|
+
apiKey: 'Bearer test-token',
|
|
162
|
+
baseURL: 'https://portal.qwen.ai/v1',
|
|
163
|
+
headers: {}
|
|
164
|
+
});
|
|
165
|
+
// 读取更新后的配置
|
|
166
|
+
const updatedConfig = JSON.parse(await readFile(configPath, 'utf-8'));
|
|
167
|
+
// 验证所有配置都被保留
|
|
168
|
+
assert.strictEqual(updatedConfig.$schema, 'https://opencode.ai/config.json');
|
|
169
|
+
assert.strictEqual(updatedConfig.agent.build.max_steps, 10);
|
|
170
|
+
assert.strictEqual(updatedConfig.agent.plan.read_only, true);
|
|
171
|
+
assert.strictEqual(updatedConfig.mode.default, 'build');
|
|
172
|
+
assert.ok(updatedConfig.instructions.includes('./instructions.md'), "should include");
|
|
173
|
+
assert.ok(updatedConfig.plugin.includes('plugin-a'), "should include");
|
|
174
|
+
assert.ok(updatedConfig.plugin.includes('plugin-b'), "should include");
|
|
175
|
+
assert.strictEqual(updatedConfig.provider.anthropic.options.apiKey, 'sk-ant');
|
|
176
|
+
// 验证 qwen 被添加
|
|
177
|
+
assert.ok(updatedConfig.provider.qwen, "should be defined");
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
// 辅助函数
|
|
181
|
+
async function mkdtemp(template) {
|
|
182
|
+
const fs = await import('node:fs/promises');
|
|
183
|
+
const path = await import('node:path');
|
|
184
|
+
const os = await import('node:os');
|
|
185
|
+
const dir = path.join(os.tmpdir(), `${template}${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
186
|
+
await fs.mkdir(dir, { recursive: true });
|
|
187
|
+
return dir;
|
|
188
|
+
}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,8BAA8B,EAAE,oBAAoB,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AAE3H;;GAEG;AACH,KAAK,UAAU,MAAM,CAAC,WAAgB;IACpC,gBAAgB;IAChB,IAAI,CAAC;QACH,MAAM,8BAA8B,EAAE,CAAA;IACxC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,gBAAgB;IAClB,CAAC;IAED,OAAO;QACL,iBAAiB;QACjB,MAAM,EAAE,KAAK,EAAE,MAAW,EAAE,EAAE;YAC5B,IAAI,CAAC;gBACH,iBAAiB;gBACjB,MAAM,KAAK,GAAG,MAAM,oBAAoB,EAAE,CAAA;gBAE1C,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,OAAM;gBACR,CAAC;gBAED,mBAAmB;gBACnB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;oBACzB,OAAM;gBACR,CAAC;gBAED,eAAe;gBACf,MAAM,SAAS,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAA;gBAE9C,oCAAoC;gBACpC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;oBACrB,MAAM,CAAC,QAAQ,GAAG,EAAE,CAAA;gBACtB,CAAC;gBAED,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG;oBACrB,IAAI,EAAE,aAAa;oBACnB,GAAG,EAAE,2BAA2B;oBAChC,GAAG,EAAE,EAAE;oBACP,MAAM,EAAE;wBACN,aAAa,EAAE;4BACb,IAAI,EAAE,kBAAkB;4BACxB,SAAS,EAAE,IAAI;4BACf,SAAS,EAAE,KAAK;4BAChB,UAAU,EAAE,IAAI;4BAChB,WAAW,EAAE,IAAI;4BACjB,WAAW,EAAE,IAAI;4BACjB,KAAK,EAAE;gCACL,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,8BAA8B,EAAE,oBAAoB,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AAE3H;;GAEG;AACH,KAAK,UAAU,MAAM,CAAC,WAAgB;IACpC,gBAAgB;IAChB,IAAI,CAAC;QACH,MAAM,8BAA8B,EAAE,CAAA;IACxC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,gBAAgB;IAClB,CAAC;IAED,OAAO;QACL,iBAAiB;QACjB,MAAM,EAAE,KAAK,EAAE,MAAW,EAAE,EAAE;YAC5B,IAAI,CAAC;gBACH,iBAAiB;gBACjB,MAAM,KAAK,GAAG,MAAM,oBAAoB,EAAE,CAAA;gBAE1C,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,OAAM;gBACR,CAAC;gBAED,mBAAmB;gBACnB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;oBACzB,OAAM;gBACR,CAAC;gBAED,eAAe;gBACf,MAAM,SAAS,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAA;gBAE9C,oCAAoC;gBACpC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;oBACrB,MAAM,CAAC,QAAQ,GAAG,EAAE,CAAA;gBACtB,CAAC;gBAED,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG;oBACrB,IAAI,EAAE,aAAa;oBACnB,GAAG,EAAE,2BAA2B;oBAChC,GAAG,EAAE,EAAE;oBACP,MAAM,EAAE;wBACN,aAAa,EAAE;4BACb,IAAI,EAAE,kBAAkB;4BACxB,SAAS,EAAE,IAAI;4BACf,SAAS,EAAE,KAAK;4BAChB,UAAU,EAAE,IAAI;4BAChB,WAAW,EAAE,IAAI;4BACjB,WAAW,EAAE,IAAI;4BACjB,KAAK,EAAE;gCACL,OAAO,EAAE,OAAO;gCAChB,MAAM,EAAE,MAAM;6BACf;yBACF;wBACD,WAAW,EAAE;4BACX,IAAI,EAAE,WAAW;4BACjB,SAAS,EAAE,IAAI;4BACf,SAAS,EAAE,KAAK;4BAChB,UAAU,EAAE,IAAI;4BAChB,WAAW,EAAE,IAAI;4BACjB,WAAW,EAAE,IAAI;4BACjB,KAAK,EAAE;gCACL,OAAO,EAAE,MAAM;gCACf,MAAM,EAAE,IAAI;6BACb;yBACF;qBACF;oBACD,OAAO,EAAE;wBACP,MAAM,EAAE,SAAS,CAAC,MAAM;wBACxB,OAAO,EAAE,SAAS,CAAC,OAAO;wBAC1B,OAAO,EAAE,SAAS,CAAC,OAAO;qBAC3B;iBACF,CAAA;YAEH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO;YACT,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC;AAED,UAAU;AACV,eAAe,MAAM,CAAA"}
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Qwen Login Plugin - 通义千问认证插件
|
|
3
|
+
*
|
|
4
|
+
* 为 opencode 提供 Qwen 模型认证支持
|
|
5
|
+
* 自动从 qwen-code OAuth 配置导入认证信息
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Qwen 认证插件主函数
|
|
9
|
+
*/
|
|
10
|
+
declare function plugin(pluginInput: any): Promise<{
|
|
11
|
+
config: (config: any) => Promise<void>;
|
|
12
|
+
}>;
|
|
13
|
+
export default plugin;
|
|
14
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;GAEG;AACH,iBAAe,MAAM,CAAC,WAAW,EAAE,GAAG;qBAUX,GAAG;GAgE7B;AAGD,eAAe,MAAM,CAAA"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Qwen Login Plugin - 通义千问认证插件
|
|
3
|
+
*
|
|
4
|
+
* 为 opencode 提供 Qwen 模型认证支持
|
|
5
|
+
* 自动从 qwen-code OAuth 配置导入认证信息
|
|
6
|
+
*/
|
|
7
|
+
import { configureOpencodeFromQwenOAuth, readOAuthCredentials, isTokenValid, getApiConfigFromOAuth } from "./qwen-oauth.js";
|
|
8
|
+
/**
|
|
9
|
+
* Qwen 认证插件主函数
|
|
10
|
+
*/
|
|
11
|
+
async function plugin(pluginInput) {
|
|
12
|
+
// 插件加载时立即写入配置文件
|
|
13
|
+
try {
|
|
14
|
+
await configureOpencodeFromQwenOAuth();
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
// 静默失败,使用其他认证方式
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
// 配置钩子 - 修改运行时配置
|
|
21
|
+
config: async (config) => {
|
|
22
|
+
try {
|
|
23
|
+
// 1. 读取 OAuth 凭证
|
|
24
|
+
const creds = await readOAuthCredentials();
|
|
25
|
+
if (!creds) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
// 2. 检查 token 是否有效
|
|
29
|
+
if (!isTokenValid(creds)) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
// 3. 生成 API 配置
|
|
33
|
+
const apiConfig = getApiConfigFromOAuth(creds);
|
|
34
|
+
// 4. 按照 opencode provider schema 配置
|
|
35
|
+
if (!config.provider) {
|
|
36
|
+
config.provider = {};
|
|
37
|
+
}
|
|
38
|
+
config.provider.qwen = {
|
|
39
|
+
name: "Qwen (通义千问)",
|
|
40
|
+
npm: "@ai-sdk/openai-compatible",
|
|
41
|
+
env: [],
|
|
42
|
+
models: {
|
|
43
|
+
"coder-model": {
|
|
44
|
+
name: "Qwen Coder Model",
|
|
45
|
+
tool_call: true,
|
|
46
|
+
reasoning: false,
|
|
47
|
+
attachment: true,
|
|
48
|
+
temperature: true,
|
|
49
|
+
interleaved: true,
|
|
50
|
+
limit: {
|
|
51
|
+
context: 256000,
|
|
52
|
+
output: 8192
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"qwen-plus": {
|
|
56
|
+
name: "Qwen Plus",
|
|
57
|
+
tool_call: true,
|
|
58
|
+
reasoning: false,
|
|
59
|
+
attachment: true,
|
|
60
|
+
temperature: true,
|
|
61
|
+
interleaved: true,
|
|
62
|
+
limit: {
|
|
63
|
+
context: 131072,
|
|
64
|
+
output: 8192
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
options: {
|
|
69
|
+
apiKey: apiConfig.apiKey,
|
|
70
|
+
baseURL: apiConfig.baseURL,
|
|
71
|
+
headers: apiConfig.headers
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
// 静默失败
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
// 只导出默认函数
|
|
82
|
+
export default plugin;
|
|
83
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,8BAA8B,EAAE,oBAAoB,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AAE3H;;GAEG;AACH,KAAK,UAAU,MAAM,CAAC,WAAgB;IACpC,gBAAgB;IAChB,IAAI,CAAC;QACH,MAAM,8BAA8B,EAAE,CAAA;IACxC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,gBAAgB;IAClB,CAAC;IAED,OAAO;QACL,iBAAiB;QACjB,MAAM,EAAE,KAAK,EAAE,MAAW,EAAE,EAAE;YAC5B,IAAI,CAAC;gBACH,iBAAiB;gBACjB,MAAM,KAAK,GAAG,MAAM,oBAAoB,EAAE,CAAA;gBAE1C,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,OAAM;gBACR,CAAC;gBAED,mBAAmB;gBACnB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;oBACzB,OAAM;gBACR,CAAC;gBAED,eAAe;gBACf,MAAM,SAAS,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAA;gBAE9C,oCAAoC;gBACpC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;oBACrB,MAAM,CAAC,QAAQ,GAAG,EAAE,CAAA;gBACtB,CAAC;gBAED,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG;oBACrB,IAAI,EAAE,aAAa;oBACnB,GAAG,EAAE,2BAA2B;oBAChC,GAAG,EAAE,EAAE;oBACP,MAAM,EAAE;wBACN,aAAa,EAAE;4BACb,IAAI,EAAE,kBAAkB;4BACxB,SAAS,EAAE,IAAI;4BACf,SAAS,EAAE,KAAK;4BAChB,UAAU,EAAE,IAAI;4BAChB,WAAW,EAAE,IAAI;4BACjB,WAAW,EAAE,IAAI;4BACjB,KAAK,EAAE;gCACL,OAAO,EAAE,MAAM;gCACf,MAAM,EAAE,IAAI;6BACb;yBACF;wBACD,WAAW,EAAE;4BACX,IAAI,EAAE,WAAW;4BACjB,SAAS,EAAE,IAAI;4BACf,SAAS,EAAE,KAAK;4BAChB,UAAU,EAAE,IAAI;4BAChB,WAAW,EAAE,IAAI;4BACjB,WAAW,EAAE,IAAI;4BACjB,KAAK,EAAE;gCACL,OAAO,EAAE,MAAM;gCACf,MAAM,EAAE,IAAI;6BACb;yBACF;qBACF;oBACD,OAAO,EAAE;wBACP,MAAM,EAAE,SAAS,CAAC,MAAM;wBACxB,OAAO,EAAE,SAAS,CAAC,OAAO;wBAC1B,OAAO,EAAE,SAAS,CAAC,OAAO;qBAC3B;iBACF,CAAA;YAEH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO;YACT,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC;AAED,UAAU;AACV,eAAe,MAAM,CAAA"}
|
package/dist/qwen-oauth.js
CHANGED
package/dist/qwen-oauth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qwen-oauth.js","sourceRoot":"","sources":["../src/qwen-oauth.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAsBjC;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,mDAAmD,CAAA;AAEnF;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAA;AAE1C;;GAEG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO;QACL,QAAQ,EAAE,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ;QACrE,IAAI,EAAE,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI;QACvD,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC;KAC9C,CAAA;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,YAAY,GAAG,eAAe,EAAE,CAAA;IACtC,OAAO,YAAY,iBAAiB,KAAK,YAAY,CAAC,QAAQ,KAAK,YAAY,CAAC,IAAI,GAAG,CAAA;AACzF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,MAAM,SAAS,GAAG,cAAc,EAAE,CAAA;IAClC,MAAM,YAAY,GAAG,eAAe,EAAE,CAAA;IAEtC,OAAO;QACL,QAAQ,EAAE,kBAAkB;QAC5B,cAAc,EAAE,kBAAkB;QAClC,YAAY,EAAE,SAAS;QACvB,kBAAkB,EAAE,IAAI;QACxB,6BAA6B,EAAE,SAAS;QACxC,gBAAgB,EAAE,OAAO;QACzB,kBAAkB,EAAE,YAAY,CAAC,IAAI;QACrC,qBAAqB,EAAE,MAAM;QAC7B,6BAA6B,EAAE,YAAY,CAAC,WAAW;QACvD,eAAe,EAAE,UAAU,KAAK,EAAE;QAClC,0BAA0B,EAAE,QAAQ;QACpC,uBAAuB,EAAE,SAAS;QAClC,sBAAsB,EAAE,YAAY;QACpC,yBAAyB,EAAE,GAAG;QAC9B,qBAAqB,EAAE,KAAK;KAC7B,CAAA;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,WAAmB;IAC9C,6BAA6B;IAC7B,gEAAgE;IAChE,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,WAAW,WAAW,KAAK,CAAA;IACpC,CAAC;IACD,OAAO,gBAAgB,CAAA;AACzB,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB;IACxB,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,kBAAkB,CAAC,CAAA;AACrD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,iBAAiB,EAAE,CAAA;QACrC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;QAClD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAqB,CAAA;IAChD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,aAAa;QACb,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,KAAuB;IAClD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IACtB,OAAO,KAAK,CAAC,WAAW,GAAG,GAAG,CAAA;AAChC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAuB;IAC3D,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IAChD,MAAM,OAAO,GAAG,mBAAmB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IAEvD,OAAO;QACL,MAAM,EAAE,GAAG,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,YAAY,EAAE;QACnD,OAAO,EAAE,OAAO;QAChB,OAAO,EAAE,OAAO;KACjB,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB;IAC1C,MAAM,KAAK,GAAG,MAAM,oBAAoB,EAAE,CAAA;IAE1C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,qBAAqB,CAAC,KAAK,CAAC,CAAA;AACrC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,MAAqB;IAC9D,mDAAmD;IACnD,IAAI,kBAAkB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,eAAe,CAAC,CAAA;IAEhF,6BAA6B;IAC7B,IAAI,CAAC;QACH,MAAM,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAA;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,wBAAwB;QACxB,kBAAkB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,qBAAqB,EAAE,UAAU,EAAE,eAAe,CAAC,CAAA;IACrG,CAAC;IAED,MAAM,gBAAgB,CAAC,kBAAkB,EAAE,MAAM,EAAE,UAAU,CAAC,CAAA;AAChE,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,MAAqB;IAC9D,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,eAAe,CAAC,CAAA;IACtE,MAAM,gBAAgB,CAAC,kBAAkB,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAA;AAC9D,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,gBAAgB,CAC7B,UAAkB,EAClB,MAAqB,EACrB,UAAiC;IAEjC,IAAI,CAAC;QACH,SAAS;QACT,MAAM,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAExD,SAAS;QACT,IAAI,cAAc,GAAQ,EAAE,CAAA;QAC5B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;YACnD,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,eAAe;QACjB,CAAC;QAED,OAAO;QACP,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC;YAC7B,cAAc,CAAC,QAAQ,GAAG,EAAE,CAAA;QAC9B,CAAC;QAED,cAAc,CAAC,QAAQ,CAAC,IAAI,GAAG;YAC7B,IAAI,EAAE,aAAa;YACnB,GAAG,EAAE,2BAA2B;YAChC,GAAG,EAAE,EAAE;YACP,MAAM,EAAE;gBACN,aAAa,EAAE;oBACb,IAAI,EAAE,kBAAkB;oBACxB,SAAS,EAAE,IAAI;oBACf,SAAS,EAAE,KAAK;oBAChB,UAAU,EAAE,IAAI;oBAChB,WAAW,EAAE,IAAI;oBACjB,WAAW,EAAE,IAAI;oBACjB,KAAK,EAAE;wBACL,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"qwen-oauth.js","sourceRoot":"","sources":["../src/qwen-oauth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Qwen Login Plugin - 单元测试
|
|
3
|
+
*
|
|
4
|
+
* 测试配置合并、OAuth 读取等功能
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, beforeEach, afterEach } from 'node:test';
|
|
7
|
+
import { writeFile, mkdir, rm } from 'node:fs/promises';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
import { tmpdir } from 'node:os';
|
|
10
|
+
import assert from 'node:assert';
|
|
11
|
+
import { readOAuthCredentials, isTokenValid, getApiConfigFromOAuth, buildBaseUrl, buildDefaultHeaders } from './qwen-oauth.js';
|
|
12
|
+
// 测试用的临时目录
|
|
13
|
+
let testDir;
|
|
14
|
+
let testQwenDir;
|
|
15
|
+
describe('Qwen Login Plugin', () => {
|
|
16
|
+
beforeEach(async () => {
|
|
17
|
+
// 创建临时测试目录
|
|
18
|
+
testDir = await mkdtemp('qwen-login-plugin-test-');
|
|
19
|
+
testQwenDir = join(testDir, '.qwen');
|
|
20
|
+
await mkdir(testQwenDir, { recursive: true });
|
|
21
|
+
});
|
|
22
|
+
afterEach(async () => {
|
|
23
|
+
// 清理临时目录
|
|
24
|
+
await rm(testDir, { recursive: true, force: true }).catch(() => { });
|
|
25
|
+
});
|
|
26
|
+
describe('buildBaseUrl', () => {
|
|
27
|
+
it('应该从 resource_url 构建正确的 endpoint', () => {
|
|
28
|
+
assert.strictEqual(buildBaseUrl('portal.qwen.ai'), 'https://portal.qwen.ai/v1');
|
|
29
|
+
});
|
|
30
|
+
it('应该在没有 resource_url 时使用默认值', () => {
|
|
31
|
+
assert.strictEqual(buildBaseUrl(''), 'https://dashscope.aliyuncs.com/compatible-mode/v1');
|
|
32
|
+
assert.strictEqual(buildBaseUrl(undefined), 'https://dashscope.aliyuncs.com/compatible-mode/v1');
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
describe('buildDefaultHeaders', () => {
|
|
36
|
+
it('应该生成完整的请求头', () => {
|
|
37
|
+
const headers = buildDefaultHeaders('test-token-123');
|
|
38
|
+
assert.ok(headers.authorization, 'Should have authorization header');
|
|
39
|
+
assert.strictEqual(headers.authorization, 'Bearer test-token-123');
|
|
40
|
+
assert.ok(headers['user-agent'], 'Should have user-agent header');
|
|
41
|
+
assert.match(headers['user-agent'], /QwenCode\/.*\(.*;.*\)/);
|
|
42
|
+
assert.ok(headers['x-dashscope-authtype'], 'Should have x-dashscope-authtype header');
|
|
43
|
+
assert.strictEqual(headers['x-dashscope-authtype'], 'qwen-oauth');
|
|
44
|
+
assert.ok(headers['content-type'], 'Should have content-type header');
|
|
45
|
+
assert.strictEqual(headers['content-type'], 'application/json');
|
|
46
|
+
assert.ok(headers['accept'], 'Should have accept header');
|
|
47
|
+
assert.strictEqual(headers['accept'], 'application/json');
|
|
48
|
+
});
|
|
49
|
+
it('应该包含所有 stainless 相关 headers', () => {
|
|
50
|
+
const headers = buildDefaultHeaders('test-token');
|
|
51
|
+
assert.strictEqual(headers['x-stainless-lang'], 'js');
|
|
52
|
+
assert.strictEqual(headers['x-stainless-package-version'], '4.104.0');
|
|
53
|
+
assert.strictEqual(headers['x-stainless-os'], 'MacOS');
|
|
54
|
+
assert.strictEqual(headers['x-stainless-runtime'], 'node');
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
describe('isTokenValid', () => {
|
|
58
|
+
it('应该返回 true 当 token 未过期', () => {
|
|
59
|
+
const futureDate = Date.now() + 1000 * 60 * 60 * 24; // 1 天后
|
|
60
|
+
assert.strictEqual(isTokenValid({ expiry_date: futureDate }), true);
|
|
61
|
+
});
|
|
62
|
+
it('应该返回 false 当 token 已过期', () => {
|
|
63
|
+
const pastDate = Date.now() - 1000 * 60 * 60; // 1 小时前
|
|
64
|
+
assert.strictEqual(isTokenValid({ expiry_date: pastDate }), false);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
describe('readOAuthCredentials', () => {
|
|
68
|
+
it('应该成功读取 OAuth 凭证', async () => {
|
|
69
|
+
// 模拟 OAuth 凭证文件
|
|
70
|
+
const mockCreds = {
|
|
71
|
+
access_token: 'test-access-token',
|
|
72
|
+
token_type: 'Bearer',
|
|
73
|
+
refresh_token: 'test-refresh-token',
|
|
74
|
+
resource_url: 'portal.qwen.ai',
|
|
75
|
+
expiry_date: Date.now() + 1000000
|
|
76
|
+
};
|
|
77
|
+
await writeFile(join(testQwenDir, 'oauth_creds.json'), JSON.stringify(mockCreds));
|
|
78
|
+
// 临时修改 home 目录
|
|
79
|
+
const originalHome = process.env.HOME;
|
|
80
|
+
process.env.HOME = testDir;
|
|
81
|
+
try {
|
|
82
|
+
const creds = await readOAuthCredentials();
|
|
83
|
+
assert.deepStrictEqual(creds, mockCreds);
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
process.env.HOME = originalHome;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
it('应该在文件不存在时返回 null', async () => {
|
|
90
|
+
const originalHome = process.env.HOME;
|
|
91
|
+
process.env.HOME = testDir;
|
|
92
|
+
try {
|
|
93
|
+
const creds = await readOAuthCredentials();
|
|
94
|
+
assert.strictEqual(creds, null);
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
process.env.HOME = originalHome;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
describe('getApiConfigFromOAuth', () => {
|
|
102
|
+
it('应该从 OAuth 凭证生成正确的 API 配置', () => {
|
|
103
|
+
const mockCreds = {
|
|
104
|
+
access_token: 'test-token',
|
|
105
|
+
token_type: 'Bearer',
|
|
106
|
+
refresh_token: 'test-refresh',
|
|
107
|
+
resource_url: 'portal.qwen.ai',
|
|
108
|
+
expiry_date: Date.now() + 1000000
|
|
109
|
+
};
|
|
110
|
+
const config = getApiConfigFromOAuth(mockCreds);
|
|
111
|
+
assert.strictEqual(config.apiKey, 'Bearer test-token');
|
|
112
|
+
assert.strictEqual(config.baseURL, 'https://portal.qwen.ai/v1');
|
|
113
|
+
assert.ok(config.headers);
|
|
114
|
+
assert.strictEqual(config.headers?.authorization, 'Bearer test-token');
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
// 辅助函数
|
|
119
|
+
async function mkdtemp(template) {
|
|
120
|
+
const dir = join(tmpdir(), `${template}${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
121
|
+
await mkdir(dir, { recursive: true });
|
|
122
|
+
return dir;
|
|
123
|
+
}
|