@so1ve/eslint-plugin 4.0.1 → 4.1.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/index.d.mts +44 -30
- package/dist/index.mjs +688 -92
- package/package.json +3 -2
package/dist/index.d.mts
CHANGED
|
@@ -1,53 +1,65 @@
|
|
|
1
1
|
import { ESLintUtils } from "@typescript-eslint/utils";
|
|
2
2
|
|
|
3
3
|
//#region src/rules/function-style.d.ts
|
|
4
|
-
type MessageIds$
|
|
4
|
+
type MessageIds$12 = "arrow" | "declaration";
|
|
5
|
+
type Options$12 = [];
|
|
6
|
+
declare const rule$12: ESLintUtils.RuleModule<MessageIds$12, Options$12>;
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region src/rules/html-spaced-comment.d.ts
|
|
9
|
+
type MessageIds$11 = "expectedSpaceBefore" | "expectedSpaceAfter";
|
|
10
|
+
type Options$11 = [];
|
|
11
|
+
declare const rule$11: ESLintUtils.RuleModule<MessageIds$11, Options$11>;
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/rules/import-dedupe.d.ts
|
|
14
|
+
type MessageIds$10 = "importDedupe";
|
|
5
15
|
type Options$10 = [];
|
|
6
16
|
declare const rule$10: ESLintUtils.RuleModule<MessageIds$10, Options$10>;
|
|
7
17
|
//#endregion
|
|
8
|
-
//#region src/rules/
|
|
9
|
-
type MessageIds$9 = "
|
|
18
|
+
//#region src/rules/import-export-newline.d.ts
|
|
19
|
+
type MessageIds$9 = "newlineAfterLastImport" | "newlineBeforeExport" | "newlineAfterExport";
|
|
10
20
|
type Options$9 = [];
|
|
11
21
|
declare const rule$9: ESLintUtils.RuleModule<MessageIds$9, Options$9>;
|
|
12
22
|
//#endregion
|
|
13
|
-
//#region src/rules/import-
|
|
14
|
-
type MessageIds$8 = "
|
|
23
|
+
//#region src/rules/no-import-promises-as.d.ts
|
|
24
|
+
type MessageIds$8 = "noImportPromisesAs";
|
|
15
25
|
type Options$8 = [];
|
|
16
26
|
declare const rule$8: ESLintUtils.RuleModule<MessageIds$8, Options$8>;
|
|
17
27
|
//#endregion
|
|
18
|
-
//#region src/rules/
|
|
19
|
-
type MessageIds$7 = "
|
|
28
|
+
//#region src/rules/no-inline-type-modifier.d.ts
|
|
29
|
+
type MessageIds$7 = "noInlineTypeModifier";
|
|
20
30
|
type Options$7 = [];
|
|
21
31
|
declare const rule$7: ESLintUtils.RuleModule<MessageIds$7, Options$7>;
|
|
22
32
|
//#endregion
|
|
23
|
-
//#region src/rules/no-
|
|
24
|
-
type MessageIds$6 = "
|
|
33
|
+
//#region src/rules/no-negated-comparison.d.ts
|
|
34
|
+
type MessageIds$6 = "noNegatedComparison";
|
|
25
35
|
type Options$6 = [];
|
|
26
36
|
declare const rule$6: ESLintUtils.RuleModule<MessageIds$6, Options$6>;
|
|
27
37
|
//#endregion
|
|
28
|
-
//#region src/rules/no-
|
|
29
|
-
type MessageIds$5 = "
|
|
38
|
+
//#region src/rules/no-useless-template-string.d.ts
|
|
39
|
+
type MessageIds$5 = "noUselessTemplateString";
|
|
30
40
|
type Options$5 = [];
|
|
31
41
|
declare const rule$5: ESLintUtils.RuleModule<MessageIds$5, Options$5>;
|
|
32
42
|
//#endregion
|
|
33
|
-
//#region src/rules/
|
|
34
|
-
type MessageIds$4 = "
|
|
43
|
+
//#region src/rules/prefer-ts-expect-error.d.ts
|
|
44
|
+
type MessageIds$4 = "preferExpectErrorComment";
|
|
35
45
|
type Options$4 = [];
|
|
36
46
|
declare const rule$4: ESLintUtils.RuleModule<MessageIds$4, Options$4>;
|
|
37
47
|
//#endregion
|
|
38
|
-
//#region src/rules/
|
|
39
|
-
type MessageIds$3 = "
|
|
48
|
+
//#region src/rules/require-async-with-await.d.ts
|
|
49
|
+
type MessageIds$3 = "requireAsyncWithAwait";
|
|
40
50
|
type Options$3 = [];
|
|
41
51
|
declare const rule$3: ESLintUtils.RuleModule<MessageIds$3, Options$3>;
|
|
42
52
|
//#endregion
|
|
43
|
-
//#region src/rules/
|
|
44
|
-
type MessageIds$2 = "
|
|
53
|
+
//#region src/rules/sort-exports.d.ts
|
|
54
|
+
type MessageIds$2 = "sort";
|
|
45
55
|
type Options$2 = [];
|
|
46
56
|
declare const rule$2: ESLintUtils.RuleModule<MessageIds$2, Options$2>;
|
|
47
57
|
//#endregion
|
|
48
|
-
//#region src/rules/
|
|
49
|
-
type MessageIds$1 = "
|
|
50
|
-
type Options$1 = [
|
|
58
|
+
//#region src/rules/sort-imports.d.ts
|
|
59
|
+
type MessageIds$1 = "sort";
|
|
60
|
+
type Options$1 = [{
|
|
61
|
+
groups?: string[][];
|
|
62
|
+
}];
|
|
51
63
|
declare const rule$1: ESLintUtils.RuleModule<MessageIds$1, Options$1>;
|
|
52
64
|
//#endregion
|
|
53
65
|
//#region src/rules/vue-root-element-sort-attributes.d.ts
|
|
@@ -61,16 +73,18 @@ declare const rule: ESLintUtils.RuleModule<MessageIds, Options>;
|
|
|
61
73
|
//#region src/index.d.ts
|
|
62
74
|
declare const _default: {
|
|
63
75
|
rules: {
|
|
64
|
-
"function-style": typeof rule$
|
|
65
|
-
"html-spaced-comment": typeof rule$
|
|
66
|
-
"import-dedupe": typeof rule$
|
|
67
|
-
"import-export-newline": typeof rule$
|
|
68
|
-
"no-import-promises-as": typeof rule$
|
|
69
|
-
"no-inline-type-
|
|
70
|
-
"no-negated-comparison": typeof rule$
|
|
71
|
-
"no-useless-template-string": typeof rule$
|
|
72
|
-
"prefer-ts-expect-error": typeof rule$
|
|
73
|
-
"require-async-with-await": typeof rule$
|
|
76
|
+
"function-style": typeof rule$12;
|
|
77
|
+
"html-spaced-comment": typeof rule$11;
|
|
78
|
+
"import-dedupe": typeof rule$10;
|
|
79
|
+
"import-export-newline": typeof rule$9;
|
|
80
|
+
"no-import-promises-as": typeof rule$8;
|
|
81
|
+
"no-inline-type-modifier": typeof rule$7;
|
|
82
|
+
"no-negated-comparison": typeof rule$6;
|
|
83
|
+
"no-useless-template-string": typeof rule$5;
|
|
84
|
+
"prefer-ts-expect-error": typeof rule$4;
|
|
85
|
+
"require-async-with-await": typeof rule$3;
|
|
86
|
+
"sort-exports": typeof rule$2;
|
|
87
|
+
"sort-imports": typeof rule$1;
|
|
74
88
|
"vue-root-element-sort-attributes": typeof rule;
|
|
75
89
|
};
|
|
76
90
|
};
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AST_NODE_TYPES, TSESTree } from "@typescript-eslint/types";
|
|
2
2
|
import { AST_TOKEN_TYPES, ESLintUtils } from "@typescript-eslint/utils";
|
|
3
|
+
import natsort from "natsort";
|
|
3
4
|
|
|
4
5
|
//#region src/utils/index.ts
|
|
5
6
|
const createEslintRule = ESLintUtils.RuleCreator((ruleName) => ruleName);
|
|
@@ -18,9 +19,9 @@ const getNextNode = (node) => getSiblingNode(node, 1);
|
|
|
18
19
|
|
|
19
20
|
//#endregion
|
|
20
21
|
//#region src/rules/function-style.ts
|
|
21
|
-
const RULE_NAME$
|
|
22
|
-
const rule$
|
|
23
|
-
name: RULE_NAME$
|
|
22
|
+
const RULE_NAME$11 = "function-style";
|
|
23
|
+
const rule$12 = createEslintRule({
|
|
24
|
+
name: RULE_NAME$11,
|
|
24
25
|
meta: {
|
|
25
26
|
type: "problem",
|
|
26
27
|
docs: { description: "Enforce function style." },
|
|
@@ -155,13 +156,13 @@ const rule$10 = createEslintRule({
|
|
|
155
156
|
};
|
|
156
157
|
}
|
|
157
158
|
});
|
|
158
|
-
var function_style_default = rule$
|
|
159
|
+
var function_style_default = rule$12;
|
|
159
160
|
|
|
160
161
|
//#endregion
|
|
161
162
|
//#region src/rules/html-spaced-comment.ts
|
|
162
|
-
const RULE_NAME$
|
|
163
|
-
const rule$
|
|
164
|
-
name: RULE_NAME$
|
|
163
|
+
const RULE_NAME$10 = "html-spaced-comment";
|
|
164
|
+
const rule$11 = createEslintRule({
|
|
165
|
+
name: RULE_NAME$10,
|
|
165
166
|
meta: {
|
|
166
167
|
type: "layout",
|
|
167
168
|
docs: { description: "Enforce consistent spacing in HTML comments" },
|
|
@@ -193,13 +194,13 @@ const rule$9 = createEslintRule({
|
|
|
193
194
|
});
|
|
194
195
|
} })
|
|
195
196
|
});
|
|
196
|
-
var html_spaced_comment_default = rule$
|
|
197
|
+
var html_spaced_comment_default = rule$11;
|
|
197
198
|
|
|
198
199
|
//#endregion
|
|
199
200
|
//#region src/rules/import-dedupe.ts
|
|
200
|
-
const RULE_NAME$
|
|
201
|
-
const rule$
|
|
202
|
-
name: RULE_NAME$
|
|
201
|
+
const RULE_NAME$9 = "import-dedupe";
|
|
202
|
+
const rule$10 = createEslintRule({
|
|
203
|
+
name: RULE_NAME$9,
|
|
203
204
|
meta: {
|
|
204
205
|
type: "problem",
|
|
205
206
|
docs: { description: "Fix duplication in imports." },
|
|
@@ -232,14 +233,14 @@ const rule$8 = createEslintRule({
|
|
|
232
233
|
}
|
|
233
234
|
} })
|
|
234
235
|
});
|
|
235
|
-
var import_dedupe_default = rule$
|
|
236
|
+
var import_dedupe_default = rule$10;
|
|
236
237
|
|
|
237
238
|
//#endregion
|
|
238
239
|
//#region src/rules/import-export-newline.ts
|
|
239
|
-
const RULE_NAME$
|
|
240
|
+
const RULE_NAME$8 = "import-export-newline";
|
|
240
241
|
const isExportDeclaration = (node) => node.type === "ExportNamedDeclaration" || node.type === "ExportDefaultDeclaration" || node.type === "ExportAllDeclaration";
|
|
241
|
-
const rule$
|
|
242
|
-
name: RULE_NAME$
|
|
242
|
+
const rule$9 = createEslintRule({
|
|
243
|
+
name: RULE_NAME$8,
|
|
243
244
|
meta: {
|
|
244
245
|
type: "problem",
|
|
245
246
|
docs: { description: "Enforce spacing between imports and exports." },
|
|
@@ -327,19 +328,19 @@ const rule$7 = createEslintRule({
|
|
|
327
328
|
};
|
|
328
329
|
}
|
|
329
330
|
});
|
|
330
|
-
var import_export_newline_default = rule$
|
|
331
|
+
var import_export_newline_default = rule$9;
|
|
331
332
|
|
|
332
333
|
//#endregion
|
|
333
334
|
//#region src/rules/no-import-promises-as.ts
|
|
334
|
-
const RULE_NAME$
|
|
335
|
+
const RULE_NAME$7 = "no-import-promises-as";
|
|
335
336
|
const POSSIBLE_IMPORT_SOURCES = [
|
|
336
337
|
"dns",
|
|
337
338
|
"fs",
|
|
338
339
|
"readline",
|
|
339
340
|
"stream"
|
|
340
341
|
].flatMap((s) => [s, `node:${s}`]);
|
|
341
|
-
const rule$
|
|
342
|
-
name: RULE_NAME$
|
|
342
|
+
const rule$8 = createEslintRule({
|
|
343
|
+
name: RULE_NAME$7,
|
|
343
344
|
meta: {
|
|
344
345
|
type: "problem",
|
|
345
346
|
docs: { description: "Disallow import promises as." },
|
|
@@ -369,74 +370,93 @@ const rule$6 = createEslintRule({
|
|
|
369
370
|
} };
|
|
370
371
|
}
|
|
371
372
|
});
|
|
372
|
-
var no_import_promises_as_default = rule$
|
|
373
|
+
var no_import_promises_as_default = rule$8;
|
|
373
374
|
|
|
374
375
|
//#endregion
|
|
375
|
-
//#region src/rules/no-inline-type-
|
|
376
|
-
const RULE_NAME$
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
const
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
}
|
|
384
|
-
text += texts.join(", ");
|
|
385
|
-
text += " }";
|
|
386
|
-
return text;
|
|
387
|
-
}
|
|
388
|
-
function generateTypeImportText(typeSpecifiers) {
|
|
389
|
-
let text = "type ";
|
|
390
|
-
text += generateImportsText(typeSpecifiers);
|
|
391
|
-
return text;
|
|
392
|
-
}
|
|
393
|
-
function generateValueImportText(defaultImportSpecifier, valueSpecifiers) {
|
|
394
|
-
const hasValueImport = valueSpecifiers.length > 0;
|
|
395
|
-
let text = "";
|
|
396
|
-
if (defaultImportSpecifier) {
|
|
397
|
-
text += defaultImportSpecifier.local.name;
|
|
398
|
-
if (hasValueImport) text += ", ";
|
|
399
|
-
}
|
|
400
|
-
if (hasValueImport) text += generateImportsText(valueSpecifiers);
|
|
401
|
-
return text;
|
|
376
|
+
//#region src/rules/no-inline-type-modifier.ts
|
|
377
|
+
const RULE_NAME$6 = "no-inline-type-modifier";
|
|
378
|
+
const getName = (node) => node.type === AST_NODE_TYPES.Identifier ? node.name : node.raw;
|
|
379
|
+
function getSpecifierText(s) {
|
|
380
|
+
const isExport = s.type === AST_NODE_TYPES.ExportSpecifier;
|
|
381
|
+
const name1 = getName(isExport ? s.local : s.imported);
|
|
382
|
+
const name2 = getName(isExport ? s.exported : s.local);
|
|
383
|
+
return name1 === name2 ? name1 : `${name1} as ${name2}`;
|
|
402
384
|
}
|
|
403
|
-
|
|
404
|
-
|
|
385
|
+
function generateSpecifiersText(specifiers) {
|
|
386
|
+
return `{ ${specifiers.map(getSpecifierText).join(", ")} }`;
|
|
387
|
+
}
|
|
388
|
+
const generateTypeText = (specifiers) => `type ${generateSpecifiersText(specifiers)}`;
|
|
389
|
+
function generateValueText(valueSpecifiers, defaultSpecifier) {
|
|
390
|
+
const parts = [];
|
|
391
|
+
if (defaultSpecifier) parts.push(defaultSpecifier.local.name);
|
|
392
|
+
if (valueSpecifiers.length > 0) parts.push(generateSpecifiersText(valueSpecifiers));
|
|
393
|
+
return parts.join(", ");
|
|
394
|
+
}
|
|
395
|
+
function classifySpecifiers(specifiers) {
|
|
396
|
+
const typeSpecifiers = [];
|
|
397
|
+
const valueSpecifiers = [];
|
|
398
|
+
let defaultSpecifier;
|
|
399
|
+
for (const s of specifiers) if (s.type === AST_NODE_TYPES.ImportDefaultSpecifier) defaultSpecifier = s;
|
|
400
|
+
else if (s.type === AST_NODE_TYPES.ImportSpecifier) if (s.importKind === "type") typeSpecifiers.push(s);
|
|
401
|
+
else valueSpecifiers.push(s);
|
|
402
|
+
else if (s.type === AST_NODE_TYPES.ExportSpecifier) if (s.exportKind === "type") typeSpecifiers.push(s);
|
|
403
|
+
else valueSpecifiers.push(s);
|
|
404
|
+
return {
|
|
405
|
+
typeSpecifiers,
|
|
406
|
+
valueSpecifiers,
|
|
407
|
+
defaultSpecifier
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
const rule$7 = createEslintRule({
|
|
411
|
+
name: RULE_NAME$6,
|
|
405
412
|
meta: {
|
|
406
413
|
type: "layout",
|
|
407
|
-
docs: { description: "Disallow inline type import." },
|
|
414
|
+
docs: { description: "Disallow inline type modifiers in import/export." },
|
|
408
415
|
fixable: "code",
|
|
409
416
|
schema: [],
|
|
410
|
-
messages: {
|
|
417
|
+
messages: { noInlineTypeModifier: "Expected no inline type modifier." }
|
|
411
418
|
},
|
|
412
419
|
defaultOptions: [],
|
|
413
|
-
create: (context) => ({
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
|
|
420
|
+
create: (context) => ({
|
|
421
|
+
ImportDeclaration: (node) => {
|
|
422
|
+
const { typeSpecifiers, valueSpecifiers, defaultSpecifier } = classifySpecifiers(node.specifiers);
|
|
423
|
+
if (typeSpecifiers.length === 0) return;
|
|
424
|
+
const texts = [];
|
|
425
|
+
texts.push(generateTypeText(typeSpecifiers));
|
|
426
|
+
if (defaultSpecifier || valueSpecifiers.length > 0) texts.push(generateValueText(valueSpecifiers, defaultSpecifier));
|
|
427
|
+
const textToReport = texts.map((text) => `import ${text} from "${node.source.value}";`).join("\n");
|
|
428
|
+
context.report({
|
|
429
|
+
node,
|
|
430
|
+
messageId: "noInlineTypeModifier",
|
|
431
|
+
fix(fixer) {
|
|
432
|
+
return fixer.replaceText(node, textToReport);
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
},
|
|
436
|
+
ExportNamedDeclaration: (node) => {
|
|
437
|
+
if (node.declaration || node.exportKind === "type") return;
|
|
438
|
+
const { typeSpecifiers, valueSpecifiers } = classifySpecifiers(node.specifiers);
|
|
439
|
+
if (typeSpecifiers.length === 0) return;
|
|
440
|
+
const fromText = node.source ? ` from "${node.source.value}"` : "";
|
|
441
|
+
const texts = [];
|
|
442
|
+
texts.push(generateTypeText(typeSpecifiers));
|
|
443
|
+
if (valueSpecifiers.length > 0) texts.push(generateValueText(valueSpecifiers));
|
|
444
|
+
const textToReport = texts.map((text) => `export ${text}${fromText};`).join("\n");
|
|
445
|
+
context.report({
|
|
446
|
+
node,
|
|
447
|
+
messageId: "noInlineTypeModifier",
|
|
448
|
+
fix(fixer) {
|
|
449
|
+
return fixer.replaceText(node, textToReport);
|
|
450
|
+
}
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
})
|
|
434
454
|
});
|
|
435
|
-
var
|
|
455
|
+
var no_inline_type_modifier_default = rule$7;
|
|
436
456
|
|
|
437
457
|
//#endregion
|
|
438
458
|
//#region src/rules/no-negated-comparison.ts
|
|
439
|
-
const RULE_NAME$
|
|
459
|
+
const RULE_NAME$5 = "no-negated-comparison";
|
|
440
460
|
const negatedToPositive = {
|
|
441
461
|
"==": "!=",
|
|
442
462
|
"===": "!==",
|
|
@@ -448,8 +468,8 @@ const negatedToPositive = {
|
|
|
448
468
|
">=": "<"
|
|
449
469
|
};
|
|
450
470
|
const negatives = Object.keys(negatedToPositive);
|
|
451
|
-
const rule$
|
|
452
|
-
name: RULE_NAME$
|
|
471
|
+
const rule$6 = createEslintRule({
|
|
472
|
+
name: RULE_NAME$5,
|
|
453
473
|
meta: {
|
|
454
474
|
type: "problem",
|
|
455
475
|
docs: { description: "Disallow negated comparison." },
|
|
@@ -473,13 +493,13 @@ const rule$4 = createEslintRule({
|
|
|
473
493
|
});
|
|
474
494
|
} })
|
|
475
495
|
});
|
|
476
|
-
var no_negated_comparison_default = rule$
|
|
496
|
+
var no_negated_comparison_default = rule$6;
|
|
477
497
|
|
|
478
498
|
//#endregion
|
|
479
499
|
//#region src/rules/no-useless-template-string.ts
|
|
480
|
-
const RULE_NAME$
|
|
481
|
-
const rule$
|
|
482
|
-
name: RULE_NAME$
|
|
500
|
+
const RULE_NAME$4 = "no-useless-template-string";
|
|
501
|
+
const rule$5 = createEslintRule({
|
|
502
|
+
name: RULE_NAME$4,
|
|
483
503
|
meta: {
|
|
484
504
|
type: "problem",
|
|
485
505
|
docs: { description: "No useless template string." },
|
|
@@ -500,11 +520,11 @@ const rule$3 = createEslintRule({
|
|
|
500
520
|
});
|
|
501
521
|
} })
|
|
502
522
|
});
|
|
503
|
-
var no_useless_template_string_default = rule$
|
|
523
|
+
var no_useless_template_string_default = rule$5;
|
|
504
524
|
|
|
505
525
|
//#endregion
|
|
506
526
|
//#region src/rules/prefer-ts-expect-error.ts
|
|
507
|
-
const rule$
|
|
527
|
+
const rule$4 = createEslintRule({
|
|
508
528
|
name: "prefer-ts-expect-error",
|
|
509
529
|
meta: {
|
|
510
530
|
type: "problem",
|
|
@@ -518,15 +538,15 @@ const rule$2 = createEslintRule({
|
|
|
518
538
|
create(context) {
|
|
519
539
|
const tsIgnoreRegExpSingleLine = /^\s*(?:\/\s*)?@ts-ignore/;
|
|
520
540
|
const tsIgnoreRegExpMultiLine = /^\s*(?:(?:\/|\*)+\s*)?@ts-ignore/;
|
|
521
|
-
const isLineComment = (comment) => comment.type === AST_TOKEN_TYPES.Line;
|
|
541
|
+
const isLineComment$1 = (comment) => comment.type === AST_TOKEN_TYPES.Line;
|
|
522
542
|
function getLastCommentLine(comment) {
|
|
523
|
-
if (isLineComment(comment)) return comment.value;
|
|
543
|
+
if (isLineComment$1(comment)) return comment.value;
|
|
524
544
|
const commentlines = comment.value.split("\n");
|
|
525
545
|
return commentlines[commentlines.length - 1];
|
|
526
546
|
}
|
|
527
547
|
function isValidTsIgnorePresent(comment) {
|
|
528
548
|
const line = getLastCommentLine(comment);
|
|
529
|
-
return isLineComment(comment) ? tsIgnoreRegExpSingleLine.test(line) : tsIgnoreRegExpMultiLine.test(line);
|
|
549
|
+
return isLineComment$1(comment) ? tsIgnoreRegExpSingleLine.test(line) : tsIgnoreRegExpMultiLine.test(line);
|
|
530
550
|
}
|
|
531
551
|
return { Program() {
|
|
532
552
|
const comments = context.sourceCode.getAllComments();
|
|
@@ -536,19 +556,19 @@ const rule$2 = createEslintRule({
|
|
|
536
556
|
context.report({
|
|
537
557
|
node: comment,
|
|
538
558
|
messageId: "preferExpectErrorComment",
|
|
539
|
-
fix: isLineComment(comment) ? lineCommentRuleFixer : blockCommentRuleFixer
|
|
559
|
+
fix: isLineComment$1(comment) ? lineCommentRuleFixer : blockCommentRuleFixer
|
|
540
560
|
});
|
|
541
561
|
}
|
|
542
562
|
} };
|
|
543
563
|
}
|
|
544
564
|
});
|
|
545
|
-
var prefer_ts_expect_error_default = rule$
|
|
565
|
+
var prefer_ts_expect_error_default = rule$4;
|
|
546
566
|
|
|
547
567
|
//#endregion
|
|
548
568
|
//#region src/rules/require-async-with-await.ts
|
|
549
|
-
const RULE_NAME$
|
|
550
|
-
const rule$
|
|
551
|
-
name: RULE_NAME$
|
|
569
|
+
const RULE_NAME$3 = "require-async-with-await";
|
|
570
|
+
const rule$3 = createEslintRule({
|
|
571
|
+
name: RULE_NAME$3,
|
|
552
572
|
meta: {
|
|
553
573
|
type: "problem",
|
|
554
574
|
docs: { description: "Require using async keyword with await." },
|
|
@@ -589,7 +609,581 @@ const rule$1 = createEslintRule({
|
|
|
589
609
|
};
|
|
590
610
|
}
|
|
591
611
|
});
|
|
592
|
-
var require_async_with_await_default = rule$
|
|
612
|
+
var require_async_with_await_default = rule$3;
|
|
613
|
+
|
|
614
|
+
//#endregion
|
|
615
|
+
//#region src/utils/sort-imports.ts
|
|
616
|
+
const NEWLINE = /(\r?\n)/;
|
|
617
|
+
const hasNewline = (text) => NEWLINE.test(text);
|
|
618
|
+
function guessNewline(sourceCode) {
|
|
619
|
+
const match = NEWLINE.exec(sourceCode.text);
|
|
620
|
+
return match == null ? "\n" : match[0];
|
|
621
|
+
}
|
|
622
|
+
const withCode = (token, sourceCode) => ({
|
|
623
|
+
...token,
|
|
624
|
+
code: sourceCode.getText(token)
|
|
625
|
+
});
|
|
626
|
+
function parseWhitespace(whitespace) {
|
|
627
|
+
const allItems = whitespace.split(NEWLINE);
|
|
628
|
+
return (allItems.length >= 5 ? [...allItems.slice(0, 2), ...allItems.slice(-1)] : allItems).map((spacesOrNewline, index) => index % 2 === 0 ? {
|
|
629
|
+
type: "Spaces",
|
|
630
|
+
code: spacesOrNewline
|
|
631
|
+
} : {
|
|
632
|
+
type: "Newline",
|
|
633
|
+
code: spacesOrNewline
|
|
634
|
+
}).filter((token) => token.code !== "");
|
|
635
|
+
}
|
|
636
|
+
const naturalSort = ("default" in natsort ? natsort.default : natsort)();
|
|
637
|
+
function compare(path1, path2) {
|
|
638
|
+
const path1Depth = path1.split("-").filter((p) => p === "__").length;
|
|
639
|
+
const path2Depth = path2.split("-").filter((p) => p === "__").length;
|
|
640
|
+
const path1IsDot = path1 === "_-,";
|
|
641
|
+
const path2IsDot = path2 === "_-,";
|
|
642
|
+
if (path1IsDot && !path2IsDot) return 1;
|
|
643
|
+
if (path2IsDot && !path1IsDot) return -1;
|
|
644
|
+
return path1Depth === path2Depth ? naturalSort(path1, path2) : path2Depth - path1Depth;
|
|
645
|
+
}
|
|
646
|
+
const isIdentifier = (node) => node.type === "Identifier";
|
|
647
|
+
const isKeyword = (node) => node.type === "Keyword";
|
|
648
|
+
const isPunctuator = (node, value) => node.type === "Punctuator" && typeof node.value === "string" && node.value === value;
|
|
649
|
+
const isBlockComment = (node) => node.type === "Block";
|
|
650
|
+
const isLineComment = (node) => node.type === "Line";
|
|
651
|
+
const isSpaces = (node) => node.type === "Spaces";
|
|
652
|
+
const isNewline = (node) => node.type === "Newline";
|
|
653
|
+
const getImportExportKind = (node) => node.importKind ?? node.exportKind ?? "value";
|
|
654
|
+
function getSource(node) {
|
|
655
|
+
const source = String(node.source.value);
|
|
656
|
+
return {
|
|
657
|
+
source: source.replace(/^[./]*\.$/, "$&/").replace(/^[./]*\/$/, "$&,").replace(/[./_-]/g, (char) => {
|
|
658
|
+
switch (char) {
|
|
659
|
+
case ".": return "_";
|
|
660
|
+
case "/": return "-";
|
|
661
|
+
case "_": return ".";
|
|
662
|
+
case "-": return "/";
|
|
663
|
+
default: throw new Error(`Unknown source substitution character: ${char}`);
|
|
664
|
+
}
|
|
665
|
+
}),
|
|
666
|
+
originalSource: source,
|
|
667
|
+
kind: getImportExportKind(node)
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
function findLastIndex(array, fn) {
|
|
671
|
+
for (let index = array.length - 1; index >= 0; index--) if (fn(array[index], index, array)) return index;
|
|
672
|
+
return -1;
|
|
673
|
+
}
|
|
674
|
+
const flatMap = (array, fn) => array.flatMap((item, index) => fn(item, index));
|
|
675
|
+
function getAllTokens(node, sourceCode) {
|
|
676
|
+
const tokens = sourceCode.getTokens(node);
|
|
677
|
+
const lastTokenIndex = tokens.length - 1;
|
|
678
|
+
return flatMap(tokens, (token, tokenIndex) => {
|
|
679
|
+
const newToken = withCode(token, sourceCode);
|
|
680
|
+
if (tokenIndex === lastTokenIndex) return [newToken];
|
|
681
|
+
const comments = sourceCode.getCommentsAfter(token);
|
|
682
|
+
const last = comments.length > 0 ? comments[comments.length - 1] : token;
|
|
683
|
+
const nextToken = tokens[tokenIndex + 1];
|
|
684
|
+
return [
|
|
685
|
+
newToken,
|
|
686
|
+
...flatMap(comments, (comment, commentIndex) => {
|
|
687
|
+
const previous = commentIndex === 0 ? token : comments[commentIndex - 1];
|
|
688
|
+
return [...parseWhitespace(sourceCode.text.slice(previous.range[1], comment.range[0])), withCode(comment, sourceCode)];
|
|
689
|
+
}),
|
|
690
|
+
...parseWhitespace(sourceCode.text.slice(last.range[1], nextToken.range[0]))
|
|
691
|
+
];
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
const printTokens = (tokens) => tokens.map((token) => token.code).join("");
|
|
695
|
+
const removeBlankLines = (whitespace) => printTokens(parseWhitespace(whitespace));
|
|
696
|
+
function printCommentsBefore(node, comments, sourceCode) {
|
|
697
|
+
const lastIndex = comments.length - 1;
|
|
698
|
+
return comments.map((comment, index) => {
|
|
699
|
+
const next = index === lastIndex ? node : comments[index + 1];
|
|
700
|
+
return sourceCode.getText(comment) + removeBlankLines(sourceCode.text.slice(comment.range[1], next.range[0]));
|
|
701
|
+
}).join("");
|
|
702
|
+
}
|
|
703
|
+
const printCommentsAfter = (node, comments, sourceCode) => comments.map((comment, index) => {
|
|
704
|
+
const previous = index === 0 ? node : comments[index - 1];
|
|
705
|
+
return removeBlankLines(sourceCode.text.slice(previous.range[1], comment.range[0])) + sourceCode.getText(comment);
|
|
706
|
+
}).join("");
|
|
707
|
+
function getIndentationAt(index, sourceCode) {
|
|
708
|
+
const lines = sourceCode.text.slice(0, index).split(NEWLINE);
|
|
709
|
+
return lines[lines.length - 1];
|
|
710
|
+
}
|
|
711
|
+
function getTrailingSpacesAt(index, sourceCode) {
|
|
712
|
+
const { text } = sourceCode;
|
|
713
|
+
let end = index;
|
|
714
|
+
while (end < text.length) {
|
|
715
|
+
const char = text[end];
|
|
716
|
+
if (char === " " || char === " ") {
|
|
717
|
+
end++;
|
|
718
|
+
continue;
|
|
719
|
+
}
|
|
720
|
+
break;
|
|
721
|
+
}
|
|
722
|
+
return text.slice(index, end);
|
|
723
|
+
}
|
|
724
|
+
const sortImportExportItems = (items) => [...items].sort((itemA, itemB) => itemA.isSideEffectImport && itemB.isSideEffectImport ? itemA.index - itemB.index : itemA.isSideEffectImport ? -1 : itemB.isSideEffectImport ? 1 : compare(itemA.source.source, itemB.source.source) || compare(itemA.source.originalSource, itemB.source.originalSource) || compare(itemA.source.kind, itemB.source.kind) || itemA.index - itemB.index);
|
|
725
|
+
const getSpecifierName = (node) => node.type === "Identifier" ? node.name : node.value;
|
|
726
|
+
const getExternalName = (node) => getSpecifierName("imported" in node ? node.imported : node.exported);
|
|
727
|
+
const getLocalName = (node) => getSpecifierName(node.local);
|
|
728
|
+
function compareImportExportKind(kindA, kindB) {
|
|
729
|
+
if (kindA === kindB) return 0;
|
|
730
|
+
return kindA === "type" ? -1 : 1;
|
|
731
|
+
}
|
|
732
|
+
const sortSpecifierItems = (items) => [...items].sort((itemA, itemB) => compareImportExportKind(getImportExportKind(itemA.node), getImportExportKind(itemB.node)) || compare(getExternalName(itemA.node), getExternalName(itemB.node)) || compare(getLocalName(itemA.node), getLocalName(itemB.node)) || itemA.index - itemB.index);
|
|
733
|
+
function extractChunks(parentNode, isPartOfChunk$1) {
|
|
734
|
+
const chunks = [];
|
|
735
|
+
let chunk = [];
|
|
736
|
+
let lastNode;
|
|
737
|
+
for (const node of parentNode.body) {
|
|
738
|
+
const result = isPartOfChunk$1(node, lastNode);
|
|
739
|
+
switch (result) {
|
|
740
|
+
case "PartOfChunk":
|
|
741
|
+
chunk.push(node);
|
|
742
|
+
break;
|
|
743
|
+
case "PartOfNewChunk":
|
|
744
|
+
if (chunk.length > 0) chunks.push(chunk);
|
|
745
|
+
chunk = [node];
|
|
746
|
+
break;
|
|
747
|
+
case "NotPartOfChunk":
|
|
748
|
+
if (chunk.length > 0) {
|
|
749
|
+
chunks.push(chunk);
|
|
750
|
+
chunk = [];
|
|
751
|
+
}
|
|
752
|
+
break;
|
|
753
|
+
default: {
|
|
754
|
+
const _never = result;
|
|
755
|
+
throw new Error(`Unknown chunk result: ${String(_never)}`);
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
lastNode = node;
|
|
759
|
+
}
|
|
760
|
+
if (chunk.length > 0) chunks.push(chunk);
|
|
761
|
+
return chunks;
|
|
762
|
+
}
|
|
763
|
+
function maybeReportSorting(context, sorted, start, end) {
|
|
764
|
+
const sourceCode = context.sourceCode;
|
|
765
|
+
if (sourceCode.getText().slice(start, end) !== sorted) context.report({
|
|
766
|
+
messageId: "sort",
|
|
767
|
+
loc: {
|
|
768
|
+
start: sourceCode.getLocFromIndex(start),
|
|
769
|
+
end: sourceCode.getLocFromIndex(end)
|
|
770
|
+
},
|
|
771
|
+
fix: (fixer) => fixer.replaceTextRange([start, end], sorted)
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
function printSortedItems(sortedItems, originalItems, sourceCode) {
|
|
775
|
+
const newline = guessNewline(sourceCode);
|
|
776
|
+
const sorted = sortedItems.map((groups) => groups.map((groupItems) => groupItems.map((item) => item.code).join(newline)).join(newline)).join(newline + newline);
|
|
777
|
+
const flattened = flatMap(sortedItems, (groups) => flatMap(groups, (g) => g));
|
|
778
|
+
const lastSortedItem = flattened[flattened.length - 1];
|
|
779
|
+
const lastOriginalItem = originalItems[originalItems.length - 1];
|
|
780
|
+
const nextToken = lastSortedItem.needsNewline ? sourceCode.getTokenAfter(lastOriginalItem.node, {
|
|
781
|
+
includeComments: true,
|
|
782
|
+
filter: (token) => token.type !== "Line" && (token.type !== "Block" || token.loc.end.line !== lastOriginalItem.node.loc.end.line)
|
|
783
|
+
}) : void 0;
|
|
784
|
+
return sorted + (nextToken != null && nextToken.loc.start.line === lastOriginalItem.node.loc.end.line ? newline : "");
|
|
785
|
+
}
|
|
786
|
+
const makeEmptyItem = () => ({
|
|
787
|
+
state: "before",
|
|
788
|
+
before: [],
|
|
789
|
+
after: [],
|
|
790
|
+
specifier: [],
|
|
791
|
+
hadComma: false
|
|
792
|
+
});
|
|
793
|
+
function getSpecifierItems(tokens) {
|
|
794
|
+
const result = {
|
|
795
|
+
before: [],
|
|
796
|
+
after: [],
|
|
797
|
+
items: []
|
|
798
|
+
};
|
|
799
|
+
let current = makeEmptyItem();
|
|
800
|
+
for (const token of tokens) switch (current.state) {
|
|
801
|
+
case "before":
|
|
802
|
+
switch (token.type) {
|
|
803
|
+
case "Newline":
|
|
804
|
+
current.before.push(token);
|
|
805
|
+
if (result.before.length === 0 && result.items.length === 0) {
|
|
806
|
+
result.before = current.before;
|
|
807
|
+
current = makeEmptyItem();
|
|
808
|
+
}
|
|
809
|
+
break;
|
|
810
|
+
case "Spaces":
|
|
811
|
+
case "Block":
|
|
812
|
+
case "Line":
|
|
813
|
+
current.before.push(token);
|
|
814
|
+
break;
|
|
815
|
+
default:
|
|
816
|
+
if (result.before.length === 0 && result.items.length === 0) {
|
|
817
|
+
result.before = current.before;
|
|
818
|
+
current = makeEmptyItem();
|
|
819
|
+
}
|
|
820
|
+
current.state = "specifier";
|
|
821
|
+
current.specifier.push(token);
|
|
822
|
+
}
|
|
823
|
+
break;
|
|
824
|
+
case "specifier":
|
|
825
|
+
switch (token.type) {
|
|
826
|
+
case "Punctuator":
|
|
827
|
+
if (isPunctuator(token, ",")) {
|
|
828
|
+
current.hadComma = true;
|
|
829
|
+
current.state = "after";
|
|
830
|
+
} else current.specifier.push(token);
|
|
831
|
+
break;
|
|
832
|
+
default: current.specifier.push(token);
|
|
833
|
+
}
|
|
834
|
+
break;
|
|
835
|
+
case "after":
|
|
836
|
+
switch (token.type) {
|
|
837
|
+
case "Newline":
|
|
838
|
+
current.after.push(token);
|
|
839
|
+
result.items.push(current);
|
|
840
|
+
current = makeEmptyItem();
|
|
841
|
+
break;
|
|
842
|
+
case "Spaces":
|
|
843
|
+
case "Line":
|
|
844
|
+
current.after.push(token);
|
|
845
|
+
break;
|
|
846
|
+
case "Block":
|
|
847
|
+
if (hasNewline(token.code)) {
|
|
848
|
+
result.items.push(current);
|
|
849
|
+
current = makeEmptyItem();
|
|
850
|
+
current.before.push(token);
|
|
851
|
+
} else current.after.push(token);
|
|
852
|
+
break;
|
|
853
|
+
default:
|
|
854
|
+
result.items.push(current);
|
|
855
|
+
current = makeEmptyItem();
|
|
856
|
+
current.state = "specifier";
|
|
857
|
+
current.specifier.push(token);
|
|
858
|
+
}
|
|
859
|
+
break;
|
|
860
|
+
default: {
|
|
861
|
+
const _never = current.state;
|
|
862
|
+
throw new Error(`Unknown state: ${String(_never)}`);
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
switch (current.state) {
|
|
866
|
+
case "before":
|
|
867
|
+
result.after = current.before;
|
|
868
|
+
break;
|
|
869
|
+
case "specifier": {
|
|
870
|
+
const lastIdentifierIndex = findLastIndex(current.specifier, (t) => isIdentifier(t) || isKeyword(t));
|
|
871
|
+
const specifier = current.specifier.slice(0, lastIdentifierIndex + 1);
|
|
872
|
+
const after = current.specifier.slice(lastIdentifierIndex + 1);
|
|
873
|
+
const newlineIndexRaw = after.findIndex((t) => isNewline(t));
|
|
874
|
+
const newlineIndex = newlineIndexRaw === -1 ? -1 : newlineIndexRaw + 1;
|
|
875
|
+
const multilineBlockCommentIndex = after.findIndex((t) => isBlockComment(t) && hasNewline(t.code));
|
|
876
|
+
const sliceIndex = newlineIndex >= 0 && multilineBlockCommentIndex !== -1 ? Math.min(newlineIndex, multilineBlockCommentIndex) : newlineIndex >= 0 ? newlineIndex : multilineBlockCommentIndex === -1 ? endsWithSpaces(after) ? after.length - 1 : -1 : multilineBlockCommentIndex;
|
|
877
|
+
current.specifier = specifier;
|
|
878
|
+
current.after = sliceIndex === -1 ? after : after.slice(0, sliceIndex);
|
|
879
|
+
result.items.push(current);
|
|
880
|
+
result.after = sliceIndex === -1 ? [] : after.slice(sliceIndex);
|
|
881
|
+
break;
|
|
882
|
+
}
|
|
883
|
+
case "after":
|
|
884
|
+
if (endsWithSpaces(current.after)) {
|
|
885
|
+
const last = current.after.pop();
|
|
886
|
+
if (last) result.after = [last];
|
|
887
|
+
}
|
|
888
|
+
result.items.push(current);
|
|
889
|
+
break;
|
|
890
|
+
default: {
|
|
891
|
+
const _never = current.state;
|
|
892
|
+
throw new Error(`Unknown state: ${String(_never)}`);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
return {
|
|
896
|
+
before: result.before,
|
|
897
|
+
after: result.after,
|
|
898
|
+
items: result.items.map((item) => ({
|
|
899
|
+
before: item.before,
|
|
900
|
+
after: item.after,
|
|
901
|
+
specifier: item.specifier,
|
|
902
|
+
hadComma: item.hadComma
|
|
903
|
+
}))
|
|
904
|
+
};
|
|
905
|
+
}
|
|
906
|
+
function needsStartingNewline(tokens) {
|
|
907
|
+
const before = tokens.filter((token) => !isSpaces(token));
|
|
908
|
+
if (before.length === 0) return false;
|
|
909
|
+
const firstToken = before[0];
|
|
910
|
+
return isLineComment(firstToken) || isBlockComment(firstToken) && !hasNewline(firstToken.code);
|
|
911
|
+
}
|
|
912
|
+
function endsWithSpaces(tokens) {
|
|
913
|
+
const last = tokens.length > 0 ? tokens[tokens.length - 1] : void 0;
|
|
914
|
+
return last == null ? false : isSpaces(last);
|
|
915
|
+
}
|
|
916
|
+
function printWithSortedSpecifiers(node, sourceCode, getSpecifiers$2) {
|
|
917
|
+
const allTokens = getAllTokens(node, sourceCode);
|
|
918
|
+
const openBraceIndex = allTokens.findIndex((token) => isPunctuator(token, "{"));
|
|
919
|
+
const closeBraceIndex = allTokens.findIndex((token) => isPunctuator(token, "}"));
|
|
920
|
+
const specifiers = getSpecifiers$2(node);
|
|
921
|
+
if (openBraceIndex === -1 || closeBraceIndex === -1 || specifiers.length <= 1) return printTokens(allTokens);
|
|
922
|
+
const itemsResult = getSpecifierItems(allTokens.slice(openBraceIndex + 1, closeBraceIndex));
|
|
923
|
+
const sortedItems = sortSpecifierItems(itemsResult.items.map((originalItem, index) => ({
|
|
924
|
+
...originalItem,
|
|
925
|
+
node: specifiers[index],
|
|
926
|
+
index
|
|
927
|
+
})));
|
|
928
|
+
const newline = guessNewline(sourceCode);
|
|
929
|
+
const hasTrailingComma = (() => {
|
|
930
|
+
for (let index = closeBraceIndex - 1; index > openBraceIndex; index--) {
|
|
931
|
+
const token = allTokens[index];
|
|
932
|
+
if (token.type === "Spaces" || token.type === "Newline" || token.type === "Block" || token.type === "Line") continue;
|
|
933
|
+
return isPunctuator(token, ",");
|
|
934
|
+
}
|
|
935
|
+
return false;
|
|
936
|
+
})();
|
|
937
|
+
const lastIndex = sortedItems.length - 1;
|
|
938
|
+
const sorted = flatMap(sortedItems, (item, index) => {
|
|
939
|
+
const previous = index === 0 ? void 0 : sortedItems[index - 1];
|
|
940
|
+
const maybeNewline$1 = previous != null && needsStartingNewline(item.before) && (previous.after.length <= 0 || !isNewline(previous.after[previous.after.length - 1])) ? [{
|
|
941
|
+
type: "Newline",
|
|
942
|
+
code: newline
|
|
943
|
+
}] : [];
|
|
944
|
+
if (index < lastIndex || hasTrailingComma) return [
|
|
945
|
+
...maybeNewline$1,
|
|
946
|
+
...item.before,
|
|
947
|
+
...item.specifier,
|
|
948
|
+
{
|
|
949
|
+
type: "Comma",
|
|
950
|
+
code: ","
|
|
951
|
+
},
|
|
952
|
+
...item.after
|
|
953
|
+
];
|
|
954
|
+
const nonBlankIndex = item.after.findIndex((token) => !isNewline(token) && !isSpaces(token));
|
|
955
|
+
const after = item.hadComma ? nonBlankIndex === -1 ? [] : item.after.slice(nonBlankIndex) : item.after;
|
|
956
|
+
return [
|
|
957
|
+
...maybeNewline$1,
|
|
958
|
+
...item.before,
|
|
959
|
+
...item.specifier,
|
|
960
|
+
...after
|
|
961
|
+
];
|
|
962
|
+
});
|
|
963
|
+
const maybeNewline = needsStartingNewline(itemsResult.after) && !isNewline(sorted[sorted.length - 1]) ? [{
|
|
964
|
+
type: "Newline",
|
|
965
|
+
code: newline
|
|
966
|
+
}] : [];
|
|
967
|
+
return printTokens([
|
|
968
|
+
...allTokens.slice(0, openBraceIndex + 1),
|
|
969
|
+
...itemsResult.before,
|
|
970
|
+
...sorted,
|
|
971
|
+
...maybeNewline,
|
|
972
|
+
...itemsResult.after,
|
|
973
|
+
...allTokens.slice(closeBraceIndex)
|
|
974
|
+
]);
|
|
975
|
+
}
|
|
976
|
+
function handleLastSemicolon(chunk, sourceCode) {
|
|
977
|
+
const lastIndex = chunk.length - 1;
|
|
978
|
+
const lastNode = chunk[lastIndex];
|
|
979
|
+
const tokens = sourceCode.getLastTokens(lastNode, { count: 2 });
|
|
980
|
+
if (tokens.length < 2) return [...chunk];
|
|
981
|
+
const [nextToLastToken, lastToken] = tokens;
|
|
982
|
+
if (!(lastToken.type === "Punctuator" && lastToken.value === ";")) return [...chunk];
|
|
983
|
+
if (nextToLastToken.loc.end.line === lastToken.loc.start.line || sourceCode.getTokenAfter(lastToken) == null) return [...chunk];
|
|
984
|
+
const newLastNode = {
|
|
985
|
+
...lastNode,
|
|
986
|
+
range: [lastNode.range[0], nextToLastToken.range[1]],
|
|
987
|
+
loc: {
|
|
988
|
+
start: lastNode.loc.start,
|
|
989
|
+
end: nextToLastToken.loc.end
|
|
990
|
+
}
|
|
991
|
+
};
|
|
992
|
+
return [...chunk.slice(0, lastIndex), newLastNode];
|
|
993
|
+
}
|
|
994
|
+
function getImportExportItems(passedChunk, sourceCode, isSideEffectImport$1, getSpecifiers$2) {
|
|
995
|
+
const chunk = handleLastSemicolon(passedChunk, sourceCode);
|
|
996
|
+
return chunk.map((node, nodeIndex) => {
|
|
997
|
+
const lastLine = nodeIndex === 0 ? node.loc.start.line - 1 : chunk[nodeIndex - 1].loc.end.line;
|
|
998
|
+
const commentsBefore = sourceCode.getCommentsBefore(node).filter((comment) => comment.loc.start.line <= node.loc.start.line && comment.loc.end.line > lastLine && (nodeIndex > 0 || comment.loc.start.line > lastLine));
|
|
999
|
+
const commentsAfter = sourceCode.getCommentsAfter(node).filter((comment) => comment.loc.end.line === node.loc.end.line);
|
|
1000
|
+
const before = printCommentsBefore(node, commentsBefore, sourceCode);
|
|
1001
|
+
const after = printCommentsAfter(node, commentsAfter, sourceCode);
|
|
1002
|
+
const indentation = getIndentationAt((commentsBefore.length > 0 ? commentsBefore[0] : node).range[0], sourceCode);
|
|
1003
|
+
const trailingSpaces = getTrailingSpacesAt((commentsAfter.length > 0 ? commentsAfter[commentsAfter.length - 1] : node).range[1], sourceCode);
|
|
1004
|
+
const code = indentation + before + printWithSortedSpecifiers(node, sourceCode, getSpecifiers$2) + after + trailingSpaces;
|
|
1005
|
+
const all = [
|
|
1006
|
+
...commentsBefore,
|
|
1007
|
+
node,
|
|
1008
|
+
...commentsAfter
|
|
1009
|
+
];
|
|
1010
|
+
const [start] = all[0].range;
|
|
1011
|
+
const [, end] = all[all.length - 1].range;
|
|
1012
|
+
const source = getSource(node);
|
|
1013
|
+
const lastAfter = commentsAfter.length > 0 ? commentsAfter[commentsAfter.length - 1] : void 0;
|
|
1014
|
+
return {
|
|
1015
|
+
node,
|
|
1016
|
+
code,
|
|
1017
|
+
start: start - indentation.length,
|
|
1018
|
+
end: end + trailingSpaces.length,
|
|
1019
|
+
isSideEffectImport: isSideEffectImport$1(node, sourceCode),
|
|
1020
|
+
source,
|
|
1021
|
+
index: nodeIndex,
|
|
1022
|
+
needsNewline: lastAfter?.type === "Line"
|
|
1023
|
+
};
|
|
1024
|
+
});
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
//#endregion
|
|
1028
|
+
//#region src/rules/sort-exports.ts
|
|
1029
|
+
const RULE_NAME$2 = "sort-exports";
|
|
1030
|
+
function isParentWithBody$1(node) {
|
|
1031
|
+
if (!node) return false;
|
|
1032
|
+
if (!("body" in node)) return false;
|
|
1033
|
+
const maybe = node;
|
|
1034
|
+
return Array.isArray(maybe.body);
|
|
1035
|
+
}
|
|
1036
|
+
const isExportFrom = (node) => node.type === "ExportNamedDeclaration" && node.source != null || node.type === "ExportAllDeclaration" && node.source != null;
|
|
1037
|
+
function isPartOfChunk(node, lastNode, sourceCode) {
|
|
1038
|
+
if (!isExportFrom(node)) return "NotPartOfChunk";
|
|
1039
|
+
return sourceCode.getCommentsBefore(node).some((comment) => (lastNode == null || comment.loc.start.line > lastNode.loc.end.line) && comment.loc.end.line < node.loc.start.line) ? "PartOfNewChunk" : "PartOfChunk";
|
|
1040
|
+
}
|
|
1041
|
+
const getSpecifiers$1 = (exportNode) => exportNode.type === "ExportNamedDeclaration" ? exportNode.specifiers : [];
|
|
1042
|
+
function maybeReportChunkSorting$1(chunk, context) {
|
|
1043
|
+
const sourceCode = context.sourceCode;
|
|
1044
|
+
const items = getImportExportItems(chunk.filter(isExportFrom), sourceCode, () => false, getSpecifiers$1);
|
|
1045
|
+
const sorted = printSortedItems([[sortImportExportItems(items)]], items, sourceCode);
|
|
1046
|
+
const start = items[0].start;
|
|
1047
|
+
const end = items[items.length - 1].end;
|
|
1048
|
+
maybeReportSorting(context, sorted, start, end);
|
|
1049
|
+
}
|
|
1050
|
+
function maybeReportExportSpecifierSorting(node, context) {
|
|
1051
|
+
const sorted = printWithSortedSpecifiers(node, context.sourceCode, (n) => n.specifiers);
|
|
1052
|
+
const [start, end] = node.range;
|
|
1053
|
+
maybeReportSorting(context, sorted, start, end);
|
|
1054
|
+
}
|
|
1055
|
+
const rule$2 = createEslintRule({
|
|
1056
|
+
name: RULE_NAME$2,
|
|
1057
|
+
meta: {
|
|
1058
|
+
type: "layout",
|
|
1059
|
+
docs: {
|
|
1060
|
+
description: "Sort export declarations.",
|
|
1061
|
+
url: "https://github.com/lydell/eslint-plugin-simple-import-sort#sort-order"
|
|
1062
|
+
},
|
|
1063
|
+
fixable: "code",
|
|
1064
|
+
schema: [],
|
|
1065
|
+
messages: { sort: "Run autofix to sort these exports!" }
|
|
1066
|
+
},
|
|
1067
|
+
defaultOptions: [],
|
|
1068
|
+
create: (context) => {
|
|
1069
|
+
const parents = /* @__PURE__ */ new Set();
|
|
1070
|
+
function addParent(node) {
|
|
1071
|
+
if (isExportFrom(node) && isParentWithBody$1(node.parent)) parents.add(node.parent);
|
|
1072
|
+
}
|
|
1073
|
+
return {
|
|
1074
|
+
ExportNamedDeclaration(node) {
|
|
1075
|
+
if (node.source == null && node.declaration == null) maybeReportExportSpecifierSorting(node, context);
|
|
1076
|
+
else addParent(node);
|
|
1077
|
+
},
|
|
1078
|
+
ExportAllDeclaration(node) {
|
|
1079
|
+
addParent(node);
|
|
1080
|
+
},
|
|
1081
|
+
"Program:exit"() {
|
|
1082
|
+
const sourceCode = context.sourceCode;
|
|
1083
|
+
for (const parent of parents) for (const chunk of extractChunks(parent, (node, lastNode) => isPartOfChunk(node, lastNode, sourceCode))) maybeReportChunkSorting$1(chunk, context);
|
|
1084
|
+
parents.clear();
|
|
1085
|
+
}
|
|
1086
|
+
};
|
|
1087
|
+
}
|
|
1088
|
+
});
|
|
1089
|
+
var sort_exports_default = rule$2;
|
|
1090
|
+
|
|
1091
|
+
//#endregion
|
|
1092
|
+
//#region src/rules/sort-imports.ts
|
|
1093
|
+
const RULE_NAME$1 = "sort-imports";
|
|
1094
|
+
function isParentWithBody(node) {
|
|
1095
|
+
if (!node) return false;
|
|
1096
|
+
if (!("body" in node)) return false;
|
|
1097
|
+
const maybe = node;
|
|
1098
|
+
return Array.isArray(maybe.body);
|
|
1099
|
+
}
|
|
1100
|
+
const defaultGroups = [
|
|
1101
|
+
["^node:"],
|
|
1102
|
+
["^@?\\w"],
|
|
1103
|
+
["^"],
|
|
1104
|
+
["^\\."],
|
|
1105
|
+
["^\\u0000"]
|
|
1106
|
+
];
|
|
1107
|
+
const isImportSpecifier = (node) => node.type === "ImportSpecifier";
|
|
1108
|
+
const getSpecifiers = (importNode) => importNode.specifiers.filter(isImportSpecifier);
|
|
1109
|
+
const isImport = (node) => node.type === "ImportDeclaration";
|
|
1110
|
+
function isSideEffectImport(importNode, sourceCode) {
|
|
1111
|
+
const token = sourceCode.getFirstToken(importNode, { skip: 1 });
|
|
1112
|
+
const startsWithBrace = token != null && isPunctuator(token, "{");
|
|
1113
|
+
return importNode.specifiers.length === 0 && (!importNode.importKind || importNode.importKind === "value") && !startsWithBrace;
|
|
1114
|
+
}
|
|
1115
|
+
const rule$1 = createEslintRule({
|
|
1116
|
+
name: RULE_NAME$1,
|
|
1117
|
+
meta: {
|
|
1118
|
+
type: "layout",
|
|
1119
|
+
docs: {
|
|
1120
|
+
description: "Sort import declarations.",
|
|
1121
|
+
url: "https://github.com/lydell/eslint-plugin-simple-import-sort#sort-order"
|
|
1122
|
+
},
|
|
1123
|
+
fixable: "code",
|
|
1124
|
+
schema: [{
|
|
1125
|
+
type: "object",
|
|
1126
|
+
properties: { groups: {
|
|
1127
|
+
type: "array",
|
|
1128
|
+
items: {
|
|
1129
|
+
type: "array",
|
|
1130
|
+
items: { type: "string" }
|
|
1131
|
+
}
|
|
1132
|
+
} },
|
|
1133
|
+
additionalProperties: false
|
|
1134
|
+
}],
|
|
1135
|
+
messages: { sort: "Run autofix to sort these imports!" }
|
|
1136
|
+
},
|
|
1137
|
+
defaultOptions: [{ groups: defaultGroups }],
|
|
1138
|
+
create: (context) => {
|
|
1139
|
+
const outerGroups = (context.options[0]?.groups ?? defaultGroups).map((groups) => groups.map((item) => new RegExp(item, "u")));
|
|
1140
|
+
const parents = /* @__PURE__ */ new Set();
|
|
1141
|
+
return {
|
|
1142
|
+
ImportDeclaration(node) {
|
|
1143
|
+
if (isParentWithBody(node.parent)) parents.add(node.parent);
|
|
1144
|
+
},
|
|
1145
|
+
"Program:exit"() {
|
|
1146
|
+
const sourceCode = context.sourceCode;
|
|
1147
|
+
for (const parent of parents) for (const chunk of extractChunks(parent, (node) => isImport(node) ? "PartOfChunk" : "NotPartOfChunk")) maybeReportChunkSorting(chunk, context, outerGroups, sourceCode);
|
|
1148
|
+
parents.clear();
|
|
1149
|
+
}
|
|
1150
|
+
};
|
|
1151
|
+
}
|
|
1152
|
+
});
|
|
1153
|
+
var sort_imports_default = rule$1;
|
|
1154
|
+
function maybeReportChunkSorting(chunk, context, outerGroups, sourceCode) {
|
|
1155
|
+
const items = getImportExportItems(chunk.filter(isImport), sourceCode, isSideEffectImport, getSpecifiers);
|
|
1156
|
+
const sorted = printSortedItems(makeSortedItems(items, outerGroups), items, sourceCode);
|
|
1157
|
+
const start = items[0].start;
|
|
1158
|
+
const end = items[items.length - 1].end;
|
|
1159
|
+
maybeReportSorting(context, sorted, start, end);
|
|
1160
|
+
}
|
|
1161
|
+
function makeSortedItems(items, outerGroups) {
|
|
1162
|
+
const itemGroups = outerGroups.map((groups) => groups.map((regex) => ({
|
|
1163
|
+
regex,
|
|
1164
|
+
items: []
|
|
1165
|
+
})));
|
|
1166
|
+
const rest = [];
|
|
1167
|
+
for (const item of items) {
|
|
1168
|
+
const { originalSource } = item.source;
|
|
1169
|
+
const source = item.isSideEffectImport ? `\0${originalSource}` : item.source.kind === "value" ? originalSource : `${originalSource}\0`;
|
|
1170
|
+
let matchedGroup;
|
|
1171
|
+
let longestMatchLength = -1;
|
|
1172
|
+
for (const groups of itemGroups) for (const group of groups) {
|
|
1173
|
+
const match = group.regex.exec(source);
|
|
1174
|
+
if (match != null && match[0].length > longestMatchLength) {
|
|
1175
|
+
matchedGroup = group;
|
|
1176
|
+
longestMatchLength = match[0].length;
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
if (matchedGroup == null) rest.push(item);
|
|
1180
|
+
else matchedGroup.items.push(item);
|
|
1181
|
+
}
|
|
1182
|
+
return [...itemGroups, [{
|
|
1183
|
+
regex: /^/,
|
|
1184
|
+
items: rest
|
|
1185
|
+
}]].map((groups) => groups.filter((group) => group.items.length > 0)).filter((groups) => groups.length > 0).map((groups) => groups.map((group) => sortImportExportItems(group.items)));
|
|
1186
|
+
}
|
|
593
1187
|
|
|
594
1188
|
//#endregion
|
|
595
1189
|
//#region src/rules/vue-root-element-sort-attributes.ts
|
|
@@ -662,11 +1256,13 @@ var src_default = { rules: {
|
|
|
662
1256
|
"import-dedupe": import_dedupe_default,
|
|
663
1257
|
"import-export-newline": import_export_newline_default,
|
|
664
1258
|
"no-import-promises-as": no_import_promises_as_default,
|
|
665
|
-
"no-inline-type-
|
|
1259
|
+
"no-inline-type-modifier": no_inline_type_modifier_default,
|
|
666
1260
|
"no-negated-comparison": no_negated_comparison_default,
|
|
667
1261
|
"no-useless-template-string": no_useless_template_string_default,
|
|
668
1262
|
"prefer-ts-expect-error": prefer_ts_expect_error_default,
|
|
669
1263
|
"require-async-with-await": require_async_with_await_default,
|
|
1264
|
+
"sort-exports": sort_exports_default,
|
|
1265
|
+
"sort-imports": sort_imports_default,
|
|
670
1266
|
"vue-root-element-sort-attributes": vue_root_element_sort_attributes_default
|
|
671
1267
|
} };
|
|
672
1268
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@so1ve/eslint-plugin",
|
|
3
|
-
"version": "4.0
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"author": "Ray <i@mk1.io> (https://github.com/so1ve/)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -32,7 +32,8 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@typescript-eslint/types": "^8.50.1",
|
|
35
|
-
"@typescript-eslint/utils": "^8.50.1"
|
|
35
|
+
"@typescript-eslint/utils": "^8.50.1",
|
|
36
|
+
"natsort": "^2.0.3"
|
|
36
37
|
},
|
|
37
38
|
"devDependencies": {
|
|
38
39
|
"@html-eslint/parser": "^0.52.0",
|