clash-kit 1.0.3 → 1.0.4

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/README.md CHANGED
@@ -1,9 +1,11 @@
1
1
  # Clash Kit
2
2
 
3
- <img width="800" alt="clash-kit" src="https://github.com/user-attachments/assets/dd7dfd29-f59a-418b-8623-6ab08ece9ddb" />
4
-
5
3
  一个基于 Node.js 的 Clash 命令行管理工具,旨在简化 Clash 的配置管理、订阅切换和节点测速等操作。
6
4
 
5
+ ## 截图
6
+
7
+ <img width="1920" alt="image" src="https://github.com/user-attachments/assets/1183f778-62b0-4ac7-ab55-b821b66161f0" />
8
+
7
9
  ## 特性
8
10
 
9
11
  - 🔄 **订阅管理**:支持添加、切换多个订阅源。
@@ -95,9 +97,6 @@ sudo ck tun on
95
97
  | `ck sysproxy` (`sys`) | 设置系统代理 (on/off) | `ck sys on` |
96
98
  | `ck tun` | 设置 TUN 模式 (on/off) | `sudo ck tun on` |
97
99
 
98
- ## 截图
99
-
100
- <img width="2742" height="1994" alt="image" src="https://github.com/user-attachments/assets/1183f778-62b0-4ac7-ab55-b821b66161f0" />
101
100
 
102
101
  ## License
103
102
 
@@ -4,6 +4,7 @@ import axios from 'axios'
4
4
  import { fileURLToPath } from 'url'
5
5
  import ora from 'ora'
6
6
  import { reloadConfig, isClashRunning } from './api.js'
7
+ import YAML from 'yaml'
7
8
 
8
9
  const __filename = fileURLToPath(import.meta.url)
9
10
  const __dirname = path.dirname(__filename)
@@ -20,9 +21,46 @@ if (!fs.existsSync(PROFILES_DIR)) {
20
21
  export async function downloadSubscription(url, name) {
21
22
  const spinner = ora(`正在下载订阅 ${name}...`).start()
22
23
  try {
23
- const res = await axios.get(url, { responseType: 'text' })
24
+ const res = await axios.get(url, {
25
+ responseType: 'text',
26
+ headers: {
27
+ 'User-Agent': 'Clash/1.0.0', // 伪装成 Clash 客户端,通常能直接获取 YAML 格式
28
+ },
29
+ })
30
+
31
+ let content = res.data
32
+
33
+ // 尝试解析 YAML,如果不是对象或者看起来不像配置,尝试 Base64 解码
34
+ let isConfig = false
35
+ try {
36
+ const parsed = YAML.parse(content)
37
+ if (parsed && typeof parsed === 'object' && (parsed.proxies || parsed.Proxy || parsed.port)) {
38
+ isConfig = true
39
+ }
40
+ } catch (e) {
41
+ console.warn('订阅服务商返回的不是有效 YAML,尝试 Base64 解码...')
42
+ }
43
+
44
+ if (!isConfig) {
45
+ try {
46
+ // 尝试 Base64 解码
47
+ const decoded = Buffer.from(content, 'base64').toString('utf-8')
48
+ // 再次检查解码后是否为有效 YAML 配置
49
+ const parsedDecoded = YAML.parse(decoded)
50
+ if (
51
+ parsedDecoded &&
52
+ typeof parsedDecoded === 'object' &&
53
+ (parsedDecoded.proxies || parsedDecoded.Proxy || parsedDecoded.port)
54
+ ) {
55
+ content = decoded
56
+ }
57
+ } catch (e) {
58
+ console.warn('Base64 解码失败,保留原始内容')
59
+ }
60
+ }
61
+
24
62
  const filePath = path.join(PROFILES_DIR, `${name}.yaml`)
25
- fs.writeFileSync(filePath, res.data)
63
+ fs.writeFileSync(filePath, content)
26
64
  spinner.succeed(`订阅 ${name} 下载成功`)
27
65
  return filePath
28
66
  } catch (err) {
@@ -51,9 +89,27 @@ export async function useProfile(name) {
51
89
 
52
90
  const spinner = ora(`正在切换到配置 ${name}...`).start()
53
91
 
54
- // 直接复制配置文件,保持原样
55
- fs.copyFileSync(source, CONFIG_PATH)
56
- fs.writeFileSync(CURRENT_PROFILE_PATH, name)
92
+ // 读取订阅配置
93
+ const subscriptionConfig = YAML.parse(fs.readFileSync(source, 'utf8'))
94
+
95
+ // 读取现有配置(如果存在)
96
+ let existingConfig = {}
97
+ if (fs.existsSync(CONFIG_PATH)) {
98
+ existingConfig = YAML.parse(fs.readFileSync(CONFIG_PATH, 'utf8'))
99
+ }
100
+
101
+ // 合并配置:保留用户自定义字段,更新订阅字段
102
+ const mergedConfig = {
103
+ ...subscriptionConfig,
104
+ port: existingConfig['port'],
105
+ 'bind-address': existingConfig['bind-address'],
106
+ 'socks-port': existingConfig['socks-port'],
107
+ 'allow-lan': existingConfig['allow-lan'],
108
+ // 其他需要保留的自定义字段...
109
+ }
110
+
111
+ // 写入合并后的配置
112
+ fs.writeFileSync(CONFIG_PATH, YAML.stringify(mergedConfig))
57
113
 
58
114
  // 尝试热重载
59
115
  if (await isClashRunning()) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clash-kit",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "type": "module",
5
5
  "description": "A command-line interface for managing Clash configurations, subscriptions, and proxies.",
6
6
  "bin": {