meocli 0.1.7 → 0.1.9
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 +627 -116
- package/dist/commands/js/clash.d.ts +1 -0
- package/dist/commands/js/clash.js +118 -449
- package/dist/commands/prettier/index.js +1 -1
- package/dist/consts/prettierrc.d.ts +1 -0
- package/dist/consts/prettierrc.js +6 -9
- package/dist/lib/ast.js +7 -1
- package/oclif.manifest.json +8 -3
- package/package.json +2 -1
|
@@ -2,6 +2,7 @@ import { Command } from "@oclif/core";
|
|
|
2
2
|
export default class ClashModify extends Command {
|
|
3
3
|
static args: {
|
|
4
4
|
filePath: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
+
templatePath: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
6
|
};
|
|
6
7
|
static description: string;
|
|
7
8
|
static examples: string[];
|
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
import traverse from "@babel/traverse";
|
|
2
|
+
import * as t from "@babel/types";
|
|
2
3
|
import { Args, Command, Flags } from "@oclif/core";
|
|
3
|
-
import { existsSync } from "node:fs";
|
|
4
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
4
5
|
import { extname } from "node:path";
|
|
5
6
|
import { objToAst, readJsAst, writeAst } from "../../lib/ast.js";
|
|
6
7
|
import { require } from "../../lib/commonjs.js";
|
|
7
8
|
export default class ClashModify extends Command {
|
|
8
9
|
static args = {
|
|
9
|
-
filePath: Args.string({
|
|
10
|
-
|
|
10
|
+
filePath: Args.string({ description: "目标js文件路径", required: true }),
|
|
11
|
+
templatePath: Args.string({
|
|
12
|
+
description: "template.json配置文件路径",
|
|
11
13
|
required: true,
|
|
12
14
|
}),
|
|
13
15
|
};
|
|
14
16
|
static description = "修改Clash脚本";
|
|
15
|
-
static examples = [
|
|
17
|
+
static examples = [
|
|
18
|
+
"<%= config.bin %> <%= command.id %> ./test.js ./template.json",
|
|
19
|
+
];
|
|
16
20
|
static flags = {
|
|
17
21
|
verbose: Flags.boolean({
|
|
18
22
|
char: "v",
|
|
@@ -20,472 +24,137 @@ export default class ClashModify extends Command {
|
|
|
20
24
|
description: "Show verbose output",
|
|
21
25
|
}),
|
|
22
26
|
};
|
|
23
|
-
// https://github.com/IvanSolis1989/Smart-Config-Kit/tree/main/Clash%20Party
|
|
24
27
|
async run() {
|
|
25
|
-
// 目标 myCustomRules
|
|
26
|
-
const customRules = [
|
|
27
|
-
"RULE-SET,my-direct,DIRECT",
|
|
28
|
-
"RULE-SET,my-reject,REJECT",
|
|
29
|
-
"RULE-SET,my-proxy,🌍 全球节点",
|
|
30
|
-
];
|
|
31
|
-
// 目标 rule-providers 配置
|
|
32
|
-
const ruleProviders = {
|
|
33
|
-
"my-direct": {
|
|
34
|
-
behavior: "classical",
|
|
35
|
-
format: "yaml",
|
|
36
|
-
interval: 3600,
|
|
37
|
-
path: "./ruleset/my-direct.yaml",
|
|
38
|
-
type: "http",
|
|
39
|
-
url: "https://raw.githubusercontent.com/meme2046/data/main/clash/direct.yaml?_t={{timestamp}}",
|
|
40
|
-
},
|
|
41
|
-
"my-proxy": {
|
|
42
|
-
behavior: "classical",
|
|
43
|
-
format: "yaml",
|
|
44
|
-
interval: 3600,
|
|
45
|
-
path: "./ruleset/my-proxy.yaml",
|
|
46
|
-
type: "http",
|
|
47
|
-
url: "https://raw.githubusercontent.com/meme2046/data/main/clash/proxy.yaml?_t={{timestamp}}",
|
|
48
|
-
},
|
|
49
|
-
"my-reject": {
|
|
50
|
-
behavior: "classical",
|
|
51
|
-
format: "yaml",
|
|
52
|
-
interval: 3600,
|
|
53
|
-
path: "./ruleset/my-reject.yaml",
|
|
54
|
-
type: "http",
|
|
55
|
-
url: "https://raw.githubusercontent.com/meme2046/data/main/clash/reject.yaml?_t={{timestamp}}",
|
|
56
|
-
},
|
|
57
|
-
};
|
|
58
28
|
const { args, flags } = await this.parse(ClashModify);
|
|
59
|
-
const { filePath } = args;
|
|
29
|
+
const { filePath, templatePath } = args;
|
|
60
30
|
const { verbose } = flags;
|
|
61
31
|
if (verbose) {
|
|
62
32
|
process.env.DEBUG = "oclif:me:js";
|
|
63
33
|
require("debug").enable(process.env.DEBUG);
|
|
64
34
|
}
|
|
65
|
-
// 检查文件是否存在
|
|
66
35
|
if (!existsSync(filePath)) {
|
|
67
36
|
this.error(`file『${filePath}』not found`);
|
|
68
37
|
return;
|
|
69
38
|
}
|
|
70
|
-
|
|
39
|
+
if (!existsSync(templatePath)) {
|
|
40
|
+
this.error(`template file『${templatePath}』not found`);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const templateContent = readFileSync(templatePath, "utf8");
|
|
44
|
+
const template = JSON.parse(templateContent);
|
|
45
|
+
const { ruleProviders, ruleSet, v6Domains } = template;
|
|
46
|
+
this.log("✔ 已读取 template.json 配置:");
|
|
47
|
+
this.log(` - ruleSet: ${JSON.stringify(ruleSet)}`);
|
|
48
|
+
this.log(` - ruleProviders: ${Object.keys(ruleProviders || {}).join(", ")}`);
|
|
49
|
+
this.log(` - v6Domains: ${JSON.stringify(v6Domains)}`);
|
|
50
|
+
this.log("");
|
|
71
51
|
const ast = await readJsAst(filePath);
|
|
72
52
|
traverse(ast, {
|
|
73
|
-
// 修改 injectRuleProviders、injectRules 和 overwriteGeneral 函数
|
|
74
53
|
FunctionDeclaration: (path) => {
|
|
75
|
-
|
|
76
|
-
if (path.node.id?.name === "injectRuleProviders") {
|
|
77
|
-
// 找到 if (!config["rule-providers"]) config["rule-providers"] = {}; 的位置
|
|
78
|
-
let insertIndex = 0;
|
|
79
|
-
for (let i = 0; i < path.node.body.body.length; i++) {
|
|
80
|
-
const stmt = path.node.body.body[i];
|
|
81
|
-
// 匹配 if 语句
|
|
82
|
-
if (stmt.type === "IfStatement" &&
|
|
83
|
-
stmt.test.type === "UnaryExpression" &&
|
|
84
|
-
stmt.test.operator === "!" &&
|
|
85
|
-
stmt.test.argument.type === "MemberExpression" &&
|
|
86
|
-
stmt.test.argument.object.type === "Identifier" &&
|
|
87
|
-
stmt.test.argument.object.name === "config" &&
|
|
88
|
-
stmt.test.argument.property.type === "StringLiteral" &&
|
|
89
|
-
stmt.test.argument.property.value === "rule-providers") {
|
|
90
|
-
insertIndex = i + 1; // 在 if 语句之后插入
|
|
91
|
-
break;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
// 在找到的位置之后插入新的赋值语句
|
|
95
|
-
for (const [name, cfg] of Object.entries(ruleProviders)) {
|
|
96
|
-
const newAssignment = {
|
|
97
|
-
expression: {
|
|
98
|
-
left: {
|
|
99
|
-
computed: true,
|
|
100
|
-
object: {
|
|
101
|
-
computed: true,
|
|
102
|
-
object: { name: "config", type: "Identifier" },
|
|
103
|
-
property: {
|
|
104
|
-
type: "StringLiteral",
|
|
105
|
-
value: "rule-providers",
|
|
106
|
-
},
|
|
107
|
-
type: "MemberExpression",
|
|
108
|
-
},
|
|
109
|
-
property: { type: "StringLiteral", value: name },
|
|
110
|
-
type: "MemberExpression",
|
|
111
|
-
},
|
|
112
|
-
operator: "=",
|
|
113
|
-
right: objToAst(cfg),
|
|
114
|
-
type: "AssignmentExpression",
|
|
115
|
-
},
|
|
116
|
-
type: "ExpressionStatement",
|
|
117
|
-
};
|
|
118
|
-
// 使用 splice 在指定位置插入
|
|
119
|
-
path.node.body.body.splice(insertIndex, 0, newAssignment);
|
|
120
|
-
insertIndex++; // 下一个插入位置后移
|
|
121
|
-
this.log(`✔ rule-provider '${name}' 已添加/更新:`);
|
|
122
|
-
this.log(`${JSON.stringify(cfg, null, 2)}\n`);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
// 修改 injectRules 函数
|
|
126
|
-
if (path.node.id?.name === "injectRules") {
|
|
127
|
-
// 第一遍:删除已存在的 myCustomRules 声明
|
|
54
|
+
if (path.node.id?.name === "main") {
|
|
128
55
|
path.traverse({
|
|
129
|
-
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
56
|
+
TryStatement: (tryPath) => {
|
|
57
|
+
const tryBody = tryPath.node.block.body;
|
|
58
|
+
for (let i = tryBody.length - 1; i >= 0; i--) {
|
|
59
|
+
const stmt = tryBody[i];
|
|
60
|
+
if (t.isReturnStatement(stmt) &&
|
|
61
|
+
t.isIdentifier(stmt.argument) &&
|
|
62
|
+
stmt.argument.name === "config") {
|
|
63
|
+
const insertStatements = [];
|
|
64
|
+
// 1. ruleSet
|
|
65
|
+
if (ruleSet && Array.isArray(ruleSet)) {
|
|
66
|
+
const ruleSetVar = t.variableDeclaration("const", [
|
|
67
|
+
t.variableDeclarator(t.identifier("ruleSet"), objToAst(ruleSet)),
|
|
68
|
+
]);
|
|
69
|
+
insertStatements.push(ruleSetVar);
|
|
70
|
+
const rulesAssign = t.expressionStatement(t.assignmentExpression("=", t.memberExpression(t.identifier("config"), t.identifier("rules")), t.arrayExpression([
|
|
71
|
+
t.spreadElement(t.identifier("ruleSet")),
|
|
72
|
+
t.spreadElement(t.memberExpression(t.identifier("config"), t.identifier("rules"))),
|
|
73
|
+
])));
|
|
74
|
+
insertStatements.push(rulesAssign);
|
|
75
|
+
this.log("✔ 已添加 ruleSet 到 config.rules 开头");
|
|
76
|
+
}
|
|
77
|
+
// 2. ruleProviders
|
|
78
|
+
if (ruleProviders && typeof ruleProviders === "object") {
|
|
79
|
+
const ruleProvidersVar = t.variableDeclaration("const", [
|
|
80
|
+
t.variableDeclarator(t.identifier("ruleProviders"), objToAst(ruleProviders)),
|
|
81
|
+
]);
|
|
82
|
+
insertStatements.push(ruleProvidersVar);
|
|
83
|
+
// 使用 forEach 方式合并 ruleProviders
|
|
84
|
+
const forEachRuleProviders = t.expressionStatement(t.callExpression(t.memberExpression(t.callExpression(t.memberExpression(t.identifier("Object"), t.identifier("keys")), [t.identifier("ruleProviders")]), t.identifier("forEach")), [
|
|
85
|
+
t.functionExpression(null, [t.identifier("key")], t.blockStatement([
|
|
86
|
+
t.expressionStatement(t.assignmentExpression("=", t.memberExpression(t.memberExpression(t.identifier("config"), t.stringLiteral("rule-providers"), true), t.identifier("key"), true), t.memberExpression(t.identifier("ruleProviders"), t.identifier("key"), true))),
|
|
87
|
+
])),
|
|
88
|
+
]));
|
|
89
|
+
insertStatements.push(forEachRuleProviders);
|
|
90
|
+
this.log(`✔ 已合并 ruleProviders: ${Object.keys(ruleProviders).join(", ")}`);
|
|
91
|
+
}
|
|
92
|
+
// 3. IPv6 配置
|
|
93
|
+
if (v6Domains && Array.isArray(v6Domains)) {
|
|
94
|
+
const v6DomainsVar = t.variableDeclaration("const", [
|
|
95
|
+
t.variableDeclarator(t.identifier("v6Domains"), objToAst(v6Domains)),
|
|
96
|
+
]);
|
|
97
|
+
insertStatements.push(v6DomainsVar, t.expressionStatement(t.assignmentExpression("=", t.memberExpression(t.identifier("config"), t.identifier("ipv6")), t.booleanLiteral(true))), t.expressionStatement(t.assignmentExpression("=", t.memberExpression(t.memberExpression(t.identifier("config"), t.identifier("dns")), t.identifier("ipv6")), t.booleanLiteral(true))));
|
|
98
|
+
// domesticDoH
|
|
99
|
+
const domesticDoHDecl = t.variableDeclaration("const", [
|
|
100
|
+
t.variableDeclarator(t.identifier("domesticDoH"), t.arrayExpression([
|
|
101
|
+
t.stringLiteral("https://dns.alidns.com/dns-query"),
|
|
102
|
+
t.stringLiteral("https://doh.pub/dns-query"),
|
|
103
|
+
])),
|
|
104
|
+
]);
|
|
105
|
+
insertStatements.push(domesticDoHDecl);
|
|
106
|
+
// ipv6Doh
|
|
107
|
+
const ipv6DohDecl = t.variableDeclaration("const", [
|
|
108
|
+
t.variableDeclarator(t.identifier("ipv6Doh"), t.arrayExpression([
|
|
109
|
+
t.stringLiteral("https://[2402:4e00::]/dns-query"),
|
|
110
|
+
t.stringLiteral("https://[2400:3200::1]/dns-query"),
|
|
111
|
+
])),
|
|
112
|
+
]);
|
|
113
|
+
insertStatements.push(ipv6DohDecl);
|
|
114
|
+
// mixedDns
|
|
115
|
+
const mixedDnsDecl = t.variableDeclaration("const", [
|
|
116
|
+
t.variableDeclarator(t.identifier("mixedDns"), t.arrayExpression([
|
|
117
|
+
t.spreadElement(t.identifier("domesticDoH")),
|
|
118
|
+
t.spreadElement(t.identifier("ipv6Doh")),
|
|
119
|
+
])),
|
|
120
|
+
]);
|
|
121
|
+
insertStatements.push(mixedDnsDecl);
|
|
122
|
+
// v6Domains.forEach nameserver-policy
|
|
123
|
+
const forEachDnsPolicy = t.expressionStatement(t.callExpression(t.memberExpression(t.identifier("v6Domains"), t.identifier("forEach")), [
|
|
124
|
+
t.functionExpression(null, [t.identifier("host")], t.blockStatement([
|
|
125
|
+
t.ifStatement(t.unaryExpression("!", t.memberExpression(t.memberExpression(t.memberExpression(t.identifier("config"), t.identifier("dns")), t.stringLiteral("nameserver-policy"), true), t.identifier("host"), true)), t.blockStatement([
|
|
126
|
+
t.expressionStatement(t.assignmentExpression("=", t.memberExpression(t.memberExpression(t.memberExpression(t.identifier("config"), t.identifier("dns")), t.stringLiteral("nameserver-policy"), true), t.identifier("host"), true), t.callExpression(t.memberExpression(t.identifier("mixedDns"), t.identifier("slice")), []))),
|
|
127
|
+
])),
|
|
128
|
+
])),
|
|
129
|
+
]));
|
|
130
|
+
insertStatements.push(forEachDnsPolicy);
|
|
131
|
+
// v6Domains.forEach fake-ip-filter
|
|
132
|
+
const forEachFakeIpFilter = t.expressionStatement(t.callExpression(t.memberExpression(t.identifier("v6Domains"), t.identifier("forEach")), [
|
|
133
|
+
t.functionExpression(null, [t.identifier("domain")], t.blockStatement([
|
|
134
|
+
t.ifStatement(t.unaryExpression("!", t.callExpression(t.memberExpression(t.memberExpression(t.memberExpression(t.identifier("config"), t.identifier("dns")), t.stringLiteral("fake-ip-filter"), true), t.identifier("includes")), [t.identifier("domain")])), t.blockStatement([
|
|
135
|
+
t.expressionStatement(t.callExpression(t.memberExpression(t.memberExpression(t.memberExpression(t.identifier("config"), t.identifier("dns")), t.stringLiteral("fake-ip-filter"), true), t.identifier("push")), [t.identifier("domain")])),
|
|
136
|
+
])),
|
|
137
|
+
])),
|
|
138
|
+
]));
|
|
139
|
+
insertStatements.push(forEachFakeIpFilter);
|
|
140
|
+
this.log(`✔ 已添加 IPv6 配置,目标域名: ${v6Domains.join(", ")}`);
|
|
141
|
+
}
|
|
142
|
+
if (insertStatements.length > 0) {
|
|
143
|
+
tryBody.splice(i, 0, ...insertStatements);
|
|
144
|
+
this.log("");
|
|
145
|
+
}
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
134
148
|
}
|
|
135
149
|
},
|
|
136
150
|
});
|
|
137
|
-
// 添加新的 myCustomRules 到函数开头
|
|
138
|
-
const varDecl = {
|
|
139
|
-
declarations: [
|
|
140
|
-
{
|
|
141
|
-
id: { name: "myCustomRules", type: "Identifier" },
|
|
142
|
-
init: objToAst(customRules),
|
|
143
|
-
type: "VariableDeclarator",
|
|
144
|
-
},
|
|
145
|
-
],
|
|
146
|
-
kind: "const",
|
|
147
|
-
type: "VariableDeclaration",
|
|
148
|
-
};
|
|
149
|
-
path.node.body.body.unshift(varDecl);
|
|
150
|
-
this.log("✔ 已添加 myCustomRules:");
|
|
151
|
-
this.log(`${JSON.stringify(customRules, null, 2)}\n`);
|
|
152
|
-
// 在 config.rules 数组前面添加 ...myCustomRules
|
|
153
|
-
path.traverse({
|
|
154
|
-
AssignmentExpression: (innerPath) => {
|
|
155
|
-
const { left } = innerPath.node;
|
|
156
|
-
// 匹配 config.rules = [...] 赋值
|
|
157
|
-
if (left.type === "MemberExpression" &&
|
|
158
|
-
left.object.type === "Identifier" &&
|
|
159
|
-
left.object.name === "config" &&
|
|
160
|
-
left.property.type === "Identifier" &&
|
|
161
|
-
left.property.name === "rules" &&
|
|
162
|
-
innerPath.node.right.type === "ArrayExpression") {
|
|
163
|
-
const arrayExp = innerPath.node.right;
|
|
164
|
-
// 在数组开头插入展开表达式 ...myCustomRules
|
|
165
|
-
arrayExp.elements.unshift({
|
|
166
|
-
argument: { name: "myCustomRules", type: "Identifier" },
|
|
167
|
-
type: "SpreadElement",
|
|
168
|
-
});
|
|
169
|
-
this.log("✔ 已在 config.rules 前面添加 ...myCustomRules\n");
|
|
170
|
-
}
|
|
171
|
-
},
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
// 修改 overwriteGeneral 函数
|
|
175
|
-
if (path.node.id?.name === "overwriteGeneral") {
|
|
176
|
-
const targetDomains = ["api.memeniu.xyz", "meme.us.kg"];
|
|
177
|
-
// 1. 声明 targetDomains 变量
|
|
178
|
-
const targetDomainsDecl = {
|
|
179
|
-
declarations: [
|
|
180
|
-
{
|
|
181
|
-
id: { name: "targetDomains", type: "Identifier" },
|
|
182
|
-
init: objToAst(targetDomains),
|
|
183
|
-
type: "VariableDeclarator",
|
|
184
|
-
},
|
|
185
|
-
],
|
|
186
|
-
kind: "const",
|
|
187
|
-
type: "VariableDeclaration",
|
|
188
|
-
};
|
|
189
|
-
// 2. 设置 config.ipv6 = true
|
|
190
|
-
const ipv6Assign1 = {
|
|
191
|
-
expression: {
|
|
192
|
-
left: {
|
|
193
|
-
object: { name: "config", type: "Identifier" },
|
|
194
|
-
property: { name: "ipv6", type: "Identifier" },
|
|
195
|
-
type: "MemberExpression",
|
|
196
|
-
},
|
|
197
|
-
operator: "=",
|
|
198
|
-
right: { type: "BooleanLiteral", value: true },
|
|
199
|
-
type: "AssignmentExpression",
|
|
200
|
-
},
|
|
201
|
-
type: "ExpressionStatement",
|
|
202
|
-
};
|
|
203
|
-
// 3. 设置 config.dns.ipv6 = true
|
|
204
|
-
const ipv6Assign2 = {
|
|
205
|
-
expression: {
|
|
206
|
-
left: {
|
|
207
|
-
object: {
|
|
208
|
-
object: { name: "config", type: "Identifier" },
|
|
209
|
-
property: { name: "dns", type: "Identifier" },
|
|
210
|
-
type: "MemberExpression",
|
|
211
|
-
},
|
|
212
|
-
property: { name: "ipv6", type: "Identifier" },
|
|
213
|
-
type: "MemberExpression",
|
|
214
|
-
},
|
|
215
|
-
operator: "=",
|
|
216
|
-
right: { type: "BooleanLiteral", value: true },
|
|
217
|
-
type: "AssignmentExpression",
|
|
218
|
-
},
|
|
219
|
-
type: "ExpressionStatement",
|
|
220
|
-
};
|
|
221
|
-
// 4. 声明 ipv6Doh 数组
|
|
222
|
-
const ipv6DohDecl = {
|
|
223
|
-
declarations: [
|
|
224
|
-
{
|
|
225
|
-
id: { name: "ipv6Doh", type: "Identifier" },
|
|
226
|
-
init: {
|
|
227
|
-
elements: [
|
|
228
|
-
{
|
|
229
|
-
type: "StringLiteral",
|
|
230
|
-
value: "https://[2402:4e00::]/dns-query",
|
|
231
|
-
},
|
|
232
|
-
{
|
|
233
|
-
type: "StringLiteral",
|
|
234
|
-
value: "https://[2400:3200::1]/dns-query",
|
|
235
|
-
},
|
|
236
|
-
],
|
|
237
|
-
type: "ArrayExpression",
|
|
238
|
-
},
|
|
239
|
-
type: "VariableDeclarator",
|
|
240
|
-
},
|
|
241
|
-
],
|
|
242
|
-
kind: "const",
|
|
243
|
-
type: "VariableDeclaration",
|
|
244
|
-
};
|
|
245
|
-
// 5. 声明 mixedDns 数组
|
|
246
|
-
const mixedDnsDecl = {
|
|
247
|
-
declarations: [
|
|
248
|
-
{
|
|
249
|
-
id: { name: "mixedDns", type: "Identifier" },
|
|
250
|
-
init: {
|
|
251
|
-
elements: [
|
|
252
|
-
{
|
|
253
|
-
argument: { name: "domesticDoH", type: "Identifier" },
|
|
254
|
-
type: "SpreadElement",
|
|
255
|
-
},
|
|
256
|
-
{
|
|
257
|
-
argument: { name: "ipv6Doh", type: "Identifier" },
|
|
258
|
-
type: "SpreadElement",
|
|
259
|
-
},
|
|
260
|
-
],
|
|
261
|
-
type: "ArrayExpression",
|
|
262
|
-
},
|
|
263
|
-
type: "VariableDeclarator",
|
|
264
|
-
},
|
|
265
|
-
],
|
|
266
|
-
kind: "const",
|
|
267
|
-
type: "VariableDeclaration",
|
|
268
|
-
};
|
|
269
|
-
// 6. 循环给每个域名绑定混合DNS池
|
|
270
|
-
const forEachDnsPolicy = {
|
|
271
|
-
expression: {
|
|
272
|
-
arguments: [
|
|
273
|
-
{
|
|
274
|
-
body: {
|
|
275
|
-
body: [
|
|
276
|
-
{
|
|
277
|
-
consequent: {
|
|
278
|
-
body: [
|
|
279
|
-
{
|
|
280
|
-
expression: {
|
|
281
|
-
left: {
|
|
282
|
-
computed: true,
|
|
283
|
-
object: {
|
|
284
|
-
computed: true,
|
|
285
|
-
object: {
|
|
286
|
-
object: {
|
|
287
|
-
name: "config",
|
|
288
|
-
type: "Identifier",
|
|
289
|
-
},
|
|
290
|
-
property: {
|
|
291
|
-
name: "dns",
|
|
292
|
-
type: "Identifier",
|
|
293
|
-
},
|
|
294
|
-
type: "MemberExpression",
|
|
295
|
-
},
|
|
296
|
-
property: {
|
|
297
|
-
type: "StringLiteral",
|
|
298
|
-
value: "nameserver-policy",
|
|
299
|
-
},
|
|
300
|
-
type: "MemberExpression",
|
|
301
|
-
},
|
|
302
|
-
property: {
|
|
303
|
-
name: "host",
|
|
304
|
-
type: "Identifier",
|
|
305
|
-
},
|
|
306
|
-
type: "MemberExpression",
|
|
307
|
-
},
|
|
308
|
-
operator: "=",
|
|
309
|
-
right: {
|
|
310
|
-
arguments: [],
|
|
311
|
-
callee: {
|
|
312
|
-
object: {
|
|
313
|
-
name: "mixedDns",
|
|
314
|
-
type: "Identifier",
|
|
315
|
-
},
|
|
316
|
-
property: {
|
|
317
|
-
name: "slice",
|
|
318
|
-
type: "Identifier",
|
|
319
|
-
},
|
|
320
|
-
type: "MemberExpression",
|
|
321
|
-
},
|
|
322
|
-
type: "CallExpression",
|
|
323
|
-
},
|
|
324
|
-
type: "AssignmentExpression",
|
|
325
|
-
},
|
|
326
|
-
type: "ExpressionStatement",
|
|
327
|
-
},
|
|
328
|
-
],
|
|
329
|
-
type: "BlockStatement",
|
|
330
|
-
},
|
|
331
|
-
test: {
|
|
332
|
-
argument: {
|
|
333
|
-
computed: true,
|
|
334
|
-
object: {
|
|
335
|
-
computed: true,
|
|
336
|
-
object: {
|
|
337
|
-
object: { name: "config", type: "Identifier" },
|
|
338
|
-
property: { name: "dns", type: "Identifier" },
|
|
339
|
-
type: "MemberExpression",
|
|
340
|
-
},
|
|
341
|
-
property: {
|
|
342
|
-
type: "StringLiteral",
|
|
343
|
-
value: "nameserver-policy",
|
|
344
|
-
},
|
|
345
|
-
type: "MemberExpression",
|
|
346
|
-
},
|
|
347
|
-
property: { name: "host", type: "Identifier" },
|
|
348
|
-
type: "MemberExpression",
|
|
349
|
-
},
|
|
350
|
-
operator: "!",
|
|
351
|
-
type: "UnaryExpression",
|
|
352
|
-
},
|
|
353
|
-
type: "IfStatement",
|
|
354
|
-
},
|
|
355
|
-
],
|
|
356
|
-
type: "BlockStatement",
|
|
357
|
-
},
|
|
358
|
-
params: [{ name: "host", type: "Identifier" }],
|
|
359
|
-
type: "FunctionExpression",
|
|
360
|
-
},
|
|
361
|
-
],
|
|
362
|
-
callee: {
|
|
363
|
-
object: { name: "targetDomains", type: "Identifier" },
|
|
364
|
-
property: { name: "forEach", type: "Identifier" },
|
|
365
|
-
type: "MemberExpression",
|
|
366
|
-
},
|
|
367
|
-
type: "CallExpression",
|
|
368
|
-
},
|
|
369
|
-
type: "ExpressionStatement",
|
|
370
|
-
};
|
|
371
|
-
// 7. 加入fake-ip白名单
|
|
372
|
-
const forEachFakeIpFilter = {
|
|
373
|
-
expression: {
|
|
374
|
-
arguments: [
|
|
375
|
-
{
|
|
376
|
-
body: {
|
|
377
|
-
body: [
|
|
378
|
-
{
|
|
379
|
-
consequent: {
|
|
380
|
-
body: [
|
|
381
|
-
{
|
|
382
|
-
expression: {
|
|
383
|
-
arguments: [
|
|
384
|
-
{ name: "domain", type: "Identifier" },
|
|
385
|
-
],
|
|
386
|
-
callee: {
|
|
387
|
-
object: {
|
|
388
|
-
computed: true,
|
|
389
|
-
object: {
|
|
390
|
-
object: {
|
|
391
|
-
name: "config",
|
|
392
|
-
type: "Identifier",
|
|
393
|
-
},
|
|
394
|
-
property: {
|
|
395
|
-
name: "dns",
|
|
396
|
-
type: "Identifier",
|
|
397
|
-
},
|
|
398
|
-
type: "MemberExpression",
|
|
399
|
-
},
|
|
400
|
-
property: {
|
|
401
|
-
type: "StringLiteral",
|
|
402
|
-
value: "fake-ip-filter",
|
|
403
|
-
},
|
|
404
|
-
type: "MemberExpression",
|
|
405
|
-
},
|
|
406
|
-
property: {
|
|
407
|
-
name: "push",
|
|
408
|
-
type: "Identifier",
|
|
409
|
-
},
|
|
410
|
-
type: "MemberExpression",
|
|
411
|
-
},
|
|
412
|
-
type: "CallExpression",
|
|
413
|
-
},
|
|
414
|
-
type: "ExpressionStatement",
|
|
415
|
-
},
|
|
416
|
-
],
|
|
417
|
-
type: "BlockStatement",
|
|
418
|
-
},
|
|
419
|
-
test: {
|
|
420
|
-
argument: {
|
|
421
|
-
arguments: [{ name: "domain", type: "Identifier" }],
|
|
422
|
-
callee: {
|
|
423
|
-
object: {
|
|
424
|
-
computed: true,
|
|
425
|
-
object: {
|
|
426
|
-
object: {
|
|
427
|
-
name: "config",
|
|
428
|
-
type: "Identifier",
|
|
429
|
-
},
|
|
430
|
-
property: { name: "dns", type: "Identifier" },
|
|
431
|
-
type: "MemberExpression",
|
|
432
|
-
},
|
|
433
|
-
property: {
|
|
434
|
-
type: "StringLiteral",
|
|
435
|
-
value: "fake-ip-filter",
|
|
436
|
-
},
|
|
437
|
-
type: "MemberExpression",
|
|
438
|
-
},
|
|
439
|
-
property: {
|
|
440
|
-
name: "includes",
|
|
441
|
-
type: "Identifier",
|
|
442
|
-
},
|
|
443
|
-
type: "MemberExpression",
|
|
444
|
-
},
|
|
445
|
-
type: "CallExpression",
|
|
446
|
-
},
|
|
447
|
-
operator: "!",
|
|
448
|
-
type: "UnaryExpression",
|
|
449
|
-
},
|
|
450
|
-
type: "IfStatement",
|
|
451
|
-
},
|
|
452
|
-
],
|
|
453
|
-
type: "BlockStatement",
|
|
454
|
-
},
|
|
455
|
-
params: [{ name: "domain", type: "Identifier" }],
|
|
456
|
-
type: "FunctionExpression",
|
|
457
|
-
},
|
|
458
|
-
],
|
|
459
|
-
callee: {
|
|
460
|
-
object: { name: "targetDomains", type: "Identifier" },
|
|
461
|
-
property: { name: "forEach", type: "Identifier" },
|
|
462
|
-
type: "MemberExpression",
|
|
463
|
-
},
|
|
464
|
-
type: "CallExpression",
|
|
465
|
-
},
|
|
466
|
-
type: "ExpressionStatement",
|
|
467
|
-
};
|
|
468
|
-
// 将所有新语句插入到函数末尾
|
|
469
|
-
const newStatements = [
|
|
470
|
-
targetDomainsDecl,
|
|
471
|
-
ipv6Assign1,
|
|
472
|
-
ipv6Assign2,
|
|
473
|
-
ipv6DohDecl,
|
|
474
|
-
mixedDnsDecl,
|
|
475
|
-
forEachDnsPolicy,
|
|
476
|
-
forEachFakeIpFilter,
|
|
477
|
-
];
|
|
478
|
-
path.node.body.body.push(...newStatements);
|
|
479
|
-
this.log("✔ 已在 overwriteGeneral 函数末尾添加 IPv6 配置代码\n");
|
|
480
151
|
}
|
|
481
152
|
},
|
|
482
153
|
});
|
|
483
|
-
|
|
484
|
-
const
|
|
485
|
-
const
|
|
486
|
-
|
|
487
|
-
await writeAst(ast, outputPath); // 保存到新文件
|
|
488
|
-
// 3. 写回文件
|
|
154
|
+
const ext = extname(filePath);
|
|
155
|
+
const baseName = filePath.slice(0, -ext.length);
|
|
156
|
+
const outputPath = `${baseName}_update${ext}`;
|
|
157
|
+
await writeAst(ast, outputPath);
|
|
489
158
|
this.log("✔ 自定义clash配置添加完成");
|
|
490
159
|
}
|
|
491
160
|
}
|
|
@@ -14,7 +14,7 @@ export default class Prettier extends Command {
|
|
|
14
14
|
required: true,
|
|
15
15
|
}),
|
|
16
16
|
};
|
|
17
|
-
static description = "Use Prettier to format file,集成:『@prettier/plugin-xml、prettier-plugin-toml、prettier-plugin-sh
|
|
17
|
+
static description = "Use Prettier to format file,集成:『@prettier/plugin-xml、prettier-plugin-toml、prettier-plugin-sh、prettier-plugin-nginx、prettier-plugin-ini』";
|
|
18
18
|
static examples = [
|
|
19
19
|
"<%= config.bin %> <%= command.id %> ./tests/test.svg",
|
|
20
20
|
"<%= config.bin %> <%= command.id %> ./src/file.ts --config ./.prettierrc.yaml",
|