aicodeswitch 1.4.0 → 1.5.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/CLAUDE.md +1 -0
- package/README.md +2 -0
- package/dist/server/version-check.js +1 -2
- package/dist/ui/assets/{index-s2lL7OMJ.js → index-DJ5R6Vso.js} +2 -0
- package/dist/ui/index.html +1 -1
- package/package.json +2 -2
- package/src/server/auth.ts +79 -0
- package/src/server/database.ts +809 -0
- package/src/server/main.ts +514 -0
- package/src/server/proxy-server.ts +1301 -0
- package/src/server/transformers/chunk-collector.ts +202 -0
- package/src/server/transformers/claude-openai.ts +261 -0
- package/src/server/transformers/openai-responses.ts +440 -0
- package/src/server/transformers/streaming.ts +775 -0
- package/src/server/version-check.ts +108 -0
- package/src/types/index.ts +217 -0
- package/src/ui/App.tsx +342 -0
- package/src/ui/api/client.ts +179 -0
- package/src/ui/components/JSONViewer.tsx +89 -0
- package/src/ui/constants/index.ts +4 -0
- package/src/ui/docs/vendors-recommand.md +13 -0
- package/src/ui/main.tsx +10 -0
- package/src/ui/pages/LogsPage.tsx +702 -0
- package/src/ui/pages/RoutesPage.tsx +552 -0
- package/src/ui/pages/SettingsPage.tsx +206 -0
- package/src/ui/pages/StatisticsPage.tsx +620 -0
- package/src/ui/pages/UsagePage.tsx +13 -0
- package/src/ui/pages/VendorsPage.tsx +490 -0
- package/src/ui/pages/WriteConfigPage.tsx +198 -0
- package/src/ui/styles/App.css +831 -0
- package/src/ui/styles/index.css +137 -0
package/CLAUDE.md
CHANGED
package/README.md
CHANGED
|
@@ -34,8 +34,7 @@ exports.compareVersions = compareVersions;
|
|
|
34
34
|
// 获取当前版本
|
|
35
35
|
const getCurrentVersion = () => {
|
|
36
36
|
try {
|
|
37
|
-
|
|
38
|
-
const packageJsonPath = path_1.default.resolve(process.cwd(), 'package.json');
|
|
37
|
+
const packageJsonPath = path_1.default.resolve(__dirname, '../../package.json');
|
|
39
38
|
const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf-8'));
|
|
40
39
|
return packageJson.version;
|
|
41
40
|
}
|
package/dist/ui/index.html
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>AI Code Switch</title>
|
|
7
|
-
<script type="module" crossorigin src="./assets/index-
|
|
7
|
+
<script type="module" crossorigin src="./assets/index-DJ5R6Vso.js"></script>
|
|
8
8
|
<link rel="stylesheet" crossorigin href="./assets/index-dcQX0zYo.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aicodeswitch",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "A tool to help you manage AI programming tools to access large language models locally. It allows your Claude Code, Codex and other tools to no longer be limited to official models.",
|
|
5
5
|
"author": "tangshuang",
|
|
6
6
|
"license": "GPL-3.0",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"scripts": {
|
|
37
37
|
"dev": "concurrently \"npm run dev:server\" \"npm run dev:ui\"",
|
|
38
38
|
"dev:ui": "vite",
|
|
39
|
-
"dev:server": "tsx watch --env-file=.env --tsconfig=tsconfig.server.json server/main.ts",
|
|
39
|
+
"dev:server": "tsx watch --env-file=.env --tsconfig=tsconfig.server.json src/server/main.ts",
|
|
40
40
|
"build": "npm run build:ui && npm run build:server",
|
|
41
41
|
"build:ui": "vite build",
|
|
42
42
|
"build:server": "tsc -p tsconfig.server.json",
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { Request, Response, NextFunction } from 'express';
|
|
2
|
+
import jwt from 'jsonwebtoken';
|
|
3
|
+
import crypto from 'crypto';
|
|
4
|
+
|
|
5
|
+
const AUTH_CODE = process.env.AUTH || '';
|
|
6
|
+
const JWT_SECRET = process.env.JWT_SECRET || (AUTH_CODE ? crypto.createHash('sha256').update(AUTH_CODE).digest('hex') : '');
|
|
7
|
+
const TOKEN_EXPIRY = '7d'; // 7天有效期
|
|
8
|
+
|
|
9
|
+
interface JWTPayload {
|
|
10
|
+
authenticated: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 检查是否启用鉴权
|
|
15
|
+
*/
|
|
16
|
+
export function isAuthEnabled(): boolean {
|
|
17
|
+
return AUTH_CODE.trim().length > 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 验证鉴权码
|
|
22
|
+
*/
|
|
23
|
+
export function verifyAuthCode(authCode: string): boolean {
|
|
24
|
+
if (!isAuthEnabled()) {
|
|
25
|
+
return true; // 未启用鉴权,直接通过
|
|
26
|
+
}
|
|
27
|
+
return authCode === AUTH_CODE;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* 生成 JWT Token
|
|
32
|
+
*/
|
|
33
|
+
export function generateToken(): string {
|
|
34
|
+
const payload: JWTPayload = {
|
|
35
|
+
authenticated: true,
|
|
36
|
+
};
|
|
37
|
+
return jwt.sign(payload, JWT_SECRET, { expiresIn: TOKEN_EXPIRY });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* 验证 JWT Token
|
|
42
|
+
*/
|
|
43
|
+
export function verifyToken(token: string): boolean {
|
|
44
|
+
try {
|
|
45
|
+
jwt.verify(token, JWT_SECRET) as JWTPayload;
|
|
46
|
+
return true;
|
|
47
|
+
} catch (error) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Express 中间件: 验证 JWT Token
|
|
54
|
+
*
|
|
55
|
+
* 如果未启用鉴权,直接放行
|
|
56
|
+
* 如果启用鉴权但 token 无效,返回 401
|
|
57
|
+
*/
|
|
58
|
+
export function authMiddleware(req: Request, res: Response, next: NextFunction): void {
|
|
59
|
+
// 如果未启用鉴权,直接放行
|
|
60
|
+
if (!isAuthEnabled()) {
|
|
61
|
+
next();
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// 从 Authorization header 中提取 token
|
|
66
|
+
const authHeader = req.headers.authorization;
|
|
67
|
+
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
|
68
|
+
res.status(401).json({ error: 'Unauthorized: Missing or invalid token' });
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const token = authHeader.substring(7); // 移除 "Bearer " 前缀
|
|
73
|
+
|
|
74
|
+
if (verifyToken(token)) {
|
|
75
|
+
next();
|
|
76
|
+
} else {
|
|
77
|
+
res.status(401).json({ error: 'Unauthorized: Invalid or expired token' });
|
|
78
|
+
}
|
|
79
|
+
}
|