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.
@@ -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
- description: "目标js文件路径",
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 = ["<%= config.bin %> <%= command.id %> ./tests/test.js"];
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
- // 1. 读取并解析AST
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
- // 修改 injectRuleProviders 函数内的 rule-providers
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
- VariableDeclarator: (innerPath) => {
130
- const { id } = innerPath.node;
131
- if (id.type === "Identifier" && id.name === "myCustomRules") {
132
- innerPath.remove();
133
- this.log("✔ 已删除原有的 myCustomRules\n");
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 ext = extname(filePath); // 获取扩展名(如 .js)
485
- const baseName = filePath.slice(0, -ext.length); // 获取去掉扩展名的文件名
486
- const outputPath = `${baseName}_update${ext}`; // 拼接新文件名
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』、prettier-plugin-nginx";
17
+ static description = "Use Prettier to format file,集成:『@prettier/plugin-xml、prettier-plugin-toml、prettier-plugin-shprettier-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",
@@ -10,6 +10,7 @@ export declare const DEFAULT_CONFIG: {
10
10
  experimentalTernaries: boolean;
11
11
  htmlWhitespaceSensitivity: string;
12
12
  indentEntries: boolean;
13
+ iniSpaceAroundEquals: boolean;
13
14
  insertPragma: boolean;
14
15
  jsxSingleQuote: boolean;
15
16
  objectWrap: string;