@shigen/eslint-plugin 0.3.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.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/rules/experimental/no-commented-code.js +142 -0
- package/dist/rules/experimental/no-commented-code.js.map +1 -0
- package/dist/rules/group-imports.js +211 -0
- package/dist/rules/group-imports.js.map +1 -0
- package/dist/rules/sort-imports.js +184 -0
- package/dist/rules/sort-imports.js.map +1 -0
- package/dist/tools/ast.js +36 -0
- package/dist/tools/ast.js.map +1 -0
- package/dist/tools/rule.js +18 -0
- package/dist/tools/rule.js.map +1 -0
- package/dist/tools/sort.js +65 -0
- package/dist/tools/sort.js.map +1 -0
- package/package.json +81 -0
- package/readme.md +171 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rules = void 0;
|
|
4
|
+
const no_commented_code_1 = require("./rules/experimental/no-commented-code");
|
|
5
|
+
const group_imports_1 = require("./rules/group-imports");
|
|
6
|
+
const sort_imports_1 = require("./rules/sort-imports");
|
|
7
|
+
exports.rules = {
|
|
8
|
+
'group-imports': group_imports_1.rule,
|
|
9
|
+
'sort-imports': sort_imports_1.rule,
|
|
10
|
+
'experimental/no-commented-code': no_commented_code_1.rule,
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAGA,8EAAiF;AACjF,yDAA6D;AAC7D,uDAA2D;AAY9C,QAAA,KAAK,GAAoC;IACrD,eAAe,EAAE,oBAAY;IAC7B,cAAc,EAAE,mBAAW;IAC3B,gCAAgC,EAAE,wBAAe;CACjD,CAAC"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rule = void 0;
|
|
4
|
+
const defaultConfiguration = {
|
|
5
|
+
ignorePatterns: ['^eslint-', '^@ts-'],
|
|
6
|
+
extendDefaultIgnorePatterns: false,
|
|
7
|
+
};
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
9
|
+
function mapPatternReducer(result, pattern) {
|
|
10
|
+
try {
|
|
11
|
+
result.push(new RegExp(pattern, 'u'));
|
|
12
|
+
}
|
|
13
|
+
catch { }
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
16
|
+
function parseIgnorePatterns(config) {
|
|
17
|
+
if (!config?.ignorePatterns) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const ignorePatterns = new Set(config.ignorePatterns);
|
|
21
|
+
if (config.extendDefaultIgnorePatterns) {
|
|
22
|
+
defaultConfiguration.ignorePatterns.forEach((pattern) => ignorePatterns.add(pattern));
|
|
23
|
+
}
|
|
24
|
+
return [...ignorePatterns].reduce(mapPatternReducer, []);
|
|
25
|
+
}
|
|
26
|
+
exports.rule = {
|
|
27
|
+
meta: {
|
|
28
|
+
schema: [
|
|
29
|
+
{
|
|
30
|
+
type: 'object',
|
|
31
|
+
properties: {
|
|
32
|
+
ignorePatterns: {
|
|
33
|
+
type: 'array',
|
|
34
|
+
items: {
|
|
35
|
+
type: 'string',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
extendDefaultIgnorePatterns: {
|
|
39
|
+
type: 'boolean',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
create(context) {
|
|
46
|
+
function isNonSyntaxError(error) {
|
|
47
|
+
if (error instanceof SyntaxError) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
return (context.parserPath.includes('@typescript-eslint') &&
|
|
51
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-var-requires
|
|
52
|
+
!(error instanceof require('@typescript-eslint/typescript-estree').TSError));
|
|
53
|
+
}
|
|
54
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
|
|
55
|
+
const parser = require(context.parserPath);
|
|
56
|
+
const source = context.getSourceCode();
|
|
57
|
+
const ignorePatterns = parseIgnorePatterns(context.options[0]) ?? defaultConfiguration.ignorePatterns.reduce(mapPatternReducer, []);
|
|
58
|
+
// generate power set of all comments to process and sort sets by size descending
|
|
59
|
+
const commentSets = source
|
|
60
|
+
.getAllComments()
|
|
61
|
+
.filter((comment) => {
|
|
62
|
+
if (!comment.loc) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
if (comment.type === 'Block' && comment.value.startsWith('*')) {
|
|
66
|
+
// ignore doc comments
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
return ignorePatterns.every((pattern) => !pattern.test(comment.value.trim()));
|
|
70
|
+
})
|
|
71
|
+
.reduce((sets, comment) => [...sets, ...sets.map((set) => [...set, comment])], [[]])
|
|
72
|
+
.sort((a, b) => b.length - a.length);
|
|
73
|
+
const reportedComments = new Set();
|
|
74
|
+
for (const set of commentSets) {
|
|
75
|
+
if (set.some((comment) => reportedComments.has(comment))) {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
// we modify the lines in place so make a copy for each test
|
|
79
|
+
const lines = [...source.getLines()];
|
|
80
|
+
// uncomment locations in source
|
|
81
|
+
for (const comment of set) {
|
|
82
|
+
const startIndex = comment.loc.start.line - 1;
|
|
83
|
+
const start = [...(lines[startIndex] ?? '')];
|
|
84
|
+
// replace comment delimiters with spaces to not move locations for multiple comments on same line
|
|
85
|
+
start.splice(comment.loc.start.column, 2, ' ', ' ');
|
|
86
|
+
if (comment.type === 'Block') {
|
|
87
|
+
const endIndex = comment.loc.end.line - 1;
|
|
88
|
+
if (startIndex === endIndex) {
|
|
89
|
+
start.splice(comment.loc.end.column - 2, 2, ' ', ' ');
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
const end = [...(lines[endIndex] ?? '')];
|
|
93
|
+
end.splice(comment.loc.end.column - 2, 2, ' ', ' ');
|
|
94
|
+
lines[endIndex] = end.join('');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
lines[startIndex] = start.join('');
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
const parse = parser.parse ?? parser.parseForESLint;
|
|
101
|
+
if (!parse) {
|
|
102
|
+
throw new Error(`unexpected error: no 'parse' method found`);
|
|
103
|
+
}
|
|
104
|
+
parse(lines.join('\n'), {
|
|
105
|
+
...context.parserOptions,
|
|
106
|
+
// provide same parser defaults as eslint (https://github.com/eslint/eslint/blob/82669fa66670a00988db5b1d10fe8f3bf30be84e/lib/linter/linter.js#L636-L645)
|
|
107
|
+
// the typescript parser would potentially error without the 'filePath' or 'range' options (https://github.com/typescript-eslint/typescript-eslint/issues/2742)
|
|
108
|
+
loc: true,
|
|
109
|
+
range: true,
|
|
110
|
+
raw: true,
|
|
111
|
+
tokens: true,
|
|
112
|
+
comment: true,
|
|
113
|
+
eslintVisitorKeys: true,
|
|
114
|
+
eslintScopeManager: true,
|
|
115
|
+
filePath: context.getFilename(),
|
|
116
|
+
// don't parse a typescript source in a project context
|
|
117
|
+
// it'd be much slower and is not necessary for simple syntax validation
|
|
118
|
+
project: undefined,
|
|
119
|
+
projects: undefined,
|
|
120
|
+
});
|
|
121
|
+
for (const comment of set) {
|
|
122
|
+
reportedComments.add(comment);
|
|
123
|
+
context.report({
|
|
124
|
+
loc: comment.loc,
|
|
125
|
+
message: 'comment contains code',
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
if (isNonSyntaxError(error)) {
|
|
131
|
+
const position = { line: 1, column: 0 };
|
|
132
|
+
context.report({
|
|
133
|
+
loc: { start: position, end: position },
|
|
134
|
+
message: error.message,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return {};
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
//# sourceMappingURL=no-commented-code.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-commented-code.js","sourceRoot":"","sources":["../../../src/rules/experimental/no-commented-code.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rule = exports.TypeImportConfiguration = exports.ModuleClass = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const builtin_modules_1 = tslib_1.__importDefault(require("builtin-modules"));
|
|
7
|
+
const ast_1 = require("../tools/ast");
|
|
8
|
+
const rule_1 = require("../tools/rule");
|
|
9
|
+
const sort_1 = require("../tools/sort");
|
|
10
|
+
var ModuleClass;
|
|
11
|
+
(function (ModuleClass) {
|
|
12
|
+
ModuleClass["Node"] = "node";
|
|
13
|
+
ModuleClass["External"] = "external";
|
|
14
|
+
ModuleClass["Absolute"] = "absolute";
|
|
15
|
+
ModuleClass["Relative"] = "relative";
|
|
16
|
+
})(ModuleClass = exports.ModuleClass || (exports.ModuleClass = {}));
|
|
17
|
+
var TypeImportConfiguration;
|
|
18
|
+
(function (TypeImportConfiguration) {
|
|
19
|
+
TypeImportConfiguration["Include"] = "include";
|
|
20
|
+
TypeImportConfiguration["Exclude"] = "exclude";
|
|
21
|
+
TypeImportConfiguration["Only"] = "only";
|
|
22
|
+
})(TypeImportConfiguration = exports.TypeImportConfiguration || (exports.TypeImportConfiguration = {}));
|
|
23
|
+
const defaultConfiguration = [
|
|
24
|
+
{ class: ModuleClass.Node },
|
|
25
|
+
{ class: ModuleClass.External },
|
|
26
|
+
{ class: ModuleClass.Absolute },
|
|
27
|
+
{ class: ModuleClass.Relative },
|
|
28
|
+
];
|
|
29
|
+
function groupIndex(node, groups) {
|
|
30
|
+
if (typeof node.source.value !== 'string') {
|
|
31
|
+
return groups.length;
|
|
32
|
+
}
|
|
33
|
+
const importPath = node.source.value;
|
|
34
|
+
const findIndex = (callback) => groups.findIndex((group) => {
|
|
35
|
+
if (group instanceof Array) {
|
|
36
|
+
return group.find((configuration) => callback(configuration));
|
|
37
|
+
}
|
|
38
|
+
return callback(group);
|
|
39
|
+
});
|
|
40
|
+
const isTypeImport = (0, ast_1.isTypeImportOrExport)(node);
|
|
41
|
+
const hardCodedIndex = findIndex((group) => {
|
|
42
|
+
if (typeof group === 'string') {
|
|
43
|
+
return importPath.startsWith(group);
|
|
44
|
+
}
|
|
45
|
+
if (!Reflect.has(group, 'path')) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
if (isTypeImport) {
|
|
49
|
+
return importPath.startsWith(group.path) && group.types !== TypeImportConfiguration.Exclude;
|
|
50
|
+
}
|
|
51
|
+
return importPath.startsWith(group.path) && group.types !== TypeImportConfiguration.Only;
|
|
52
|
+
});
|
|
53
|
+
if (hardCodedIndex >= 0) {
|
|
54
|
+
return hardCodedIndex;
|
|
55
|
+
}
|
|
56
|
+
// split path at / delimiter but keep first / for absolute paths
|
|
57
|
+
const [module] = importPath.split(/(?=^\/)|\//u);
|
|
58
|
+
if (!module) {
|
|
59
|
+
throw new Error(`group-imports: unexpected undefined module name for path '${importPath}'`);
|
|
60
|
+
}
|
|
61
|
+
let moduleClass = ModuleClass.External;
|
|
62
|
+
if (builtin_modules_1.default.includes(module.replace(/^node:/u, ''))) {
|
|
63
|
+
moduleClass = ModuleClass.Node;
|
|
64
|
+
}
|
|
65
|
+
else if (/^(?:\/|\.)/u.exec(module)) {
|
|
66
|
+
moduleClass = (0, path_1.isAbsolute)(module) ? ModuleClass.Absolute : ModuleClass.Relative;
|
|
67
|
+
}
|
|
68
|
+
const classIndex = findIndex((group) => {
|
|
69
|
+
if (typeof group !== 'object' || !Reflect.has(group, 'class')) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
if (isTypeImport) {
|
|
73
|
+
return group.class === moduleClass && group.types !== TypeImportConfiguration.Exclude;
|
|
74
|
+
}
|
|
75
|
+
return group.class === moduleClass && group.types !== TypeImportConfiguration.Only;
|
|
76
|
+
});
|
|
77
|
+
return classIndex >= 0 ? classIndex : groups.length;
|
|
78
|
+
}
|
|
79
|
+
function checkLines(context, previous, next, lineCount) {
|
|
80
|
+
if (!previous || !next) {
|
|
81
|
+
throw new Error(`group-imports: unexpected undefined node`);
|
|
82
|
+
}
|
|
83
|
+
if ((0, ast_1.linesBetween)(previous, next) === lineCount) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
context.report({
|
|
87
|
+
node: previous,
|
|
88
|
+
message: `Expected ${lineCount} empty line${lineCount === 1 ? '' : 's'} after import`,
|
|
89
|
+
fix(fixer) {
|
|
90
|
+
if (!previous.range || !next.range || !(0, ast_1.onlyWhiteSpaceBetween)(previous, next, context.getSourceCode())) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
return fixer.replaceTextRange([previous.range[1], next.range[0]], ''.padEnd(lineCount + 1, '\n'));
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
function groupLabels(groups) {
|
|
98
|
+
return groups.map((group) => {
|
|
99
|
+
if (group instanceof Array || typeof group === 'string' || Reflect.has(group, 'path')) {
|
|
100
|
+
return 'custom';
|
|
101
|
+
}
|
|
102
|
+
return group.class.toUpperCase();
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
exports.rule = {
|
|
106
|
+
meta: {
|
|
107
|
+
fixable: 'code',
|
|
108
|
+
schema: {
|
|
109
|
+
definitions: {
|
|
110
|
+
typeImportConfiguration: {
|
|
111
|
+
enum: ['include', 'exclude', 'only'],
|
|
112
|
+
},
|
|
113
|
+
moduleConfiguration: {
|
|
114
|
+
oneOf: [
|
|
115
|
+
{ type: 'string' },
|
|
116
|
+
{
|
|
117
|
+
type: 'object',
|
|
118
|
+
properties: {
|
|
119
|
+
class: {
|
|
120
|
+
enum: ['node', 'external', 'absolute', 'relative'],
|
|
121
|
+
},
|
|
122
|
+
types: {
|
|
123
|
+
$ref: '#/definitions/typeImportConfiguration',
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
required: ['class'],
|
|
127
|
+
additionalProperties: false,
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
type: 'object',
|
|
131
|
+
properties: {
|
|
132
|
+
path: {
|
|
133
|
+
type: 'string',
|
|
134
|
+
},
|
|
135
|
+
types: {
|
|
136
|
+
$ref: '#/definitions/typeImportConfiguration',
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
required: ['path'],
|
|
140
|
+
additionalProperties: false,
|
|
141
|
+
},
|
|
142
|
+
],
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
type: 'array',
|
|
146
|
+
items: {
|
|
147
|
+
anyOf: [
|
|
148
|
+
{
|
|
149
|
+
$ref: '#/definitions/moduleConfiguration',
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
type: 'array',
|
|
153
|
+
items: {
|
|
154
|
+
$ref: '#/definitions/moduleConfiguration',
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
create(context) {
|
|
162
|
+
const groupConfigurations = context.options.length ? context.options : defaultConfiguration;
|
|
163
|
+
const source = context.getSourceCode();
|
|
164
|
+
const imports = (0, ast_1.importModules)(source).map((node) => {
|
|
165
|
+
return {
|
|
166
|
+
index: groupIndex(node, groupConfigurations),
|
|
167
|
+
node,
|
|
168
|
+
};
|
|
169
|
+
});
|
|
170
|
+
if (imports.length === 0) {
|
|
171
|
+
return {};
|
|
172
|
+
}
|
|
173
|
+
const sorted = (0, sort_1.sortByPath)(imports, ['index']);
|
|
174
|
+
let previousIndex = sorted[0]?.index;
|
|
175
|
+
const groups = sorted.reduce((result, value) => {
|
|
176
|
+
const current = result.at(-1);
|
|
177
|
+
if (current && previousIndex === value.index) {
|
|
178
|
+
current.push(value.node);
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
result.push([value.node]);
|
|
182
|
+
}
|
|
183
|
+
previousIndex = value.index;
|
|
184
|
+
return result;
|
|
185
|
+
}, [[]]);
|
|
186
|
+
if (sorted.some((node, i) => node !== imports[i])) {
|
|
187
|
+
(0, rule_1.fixRange)(context, {
|
|
188
|
+
range: (0, ast_1.extrema)(imports.map(({ node }) => node)),
|
|
189
|
+
message: `Expected import groups: ${groupLabels(groupConfigurations).join(', ')}`,
|
|
190
|
+
code: groups.map((nodes) => nodes.map((node) => source.getText(node)).join('\n')).join('\n\n'),
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
groups.forEach((group, i) => {
|
|
195
|
+
for (let j = 1; j < group.length; j++) {
|
|
196
|
+
const previous = group[j - 1];
|
|
197
|
+
const current = group[j];
|
|
198
|
+
checkLines(context, previous, current, 0);
|
|
199
|
+
}
|
|
200
|
+
if (i === 0) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
const previous = groups[i - 1]?.at(-1);
|
|
204
|
+
const [current] = group;
|
|
205
|
+
checkLines(context, previous, current, 1);
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
return {};
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
//# sourceMappingURL=group-imports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"group-imports.js","sourceRoot":"","sources":["../../src/rules/group-imports.ts"],"names":[],"mappings":";;;;AAAA,+BAAkC;AAElC,8EAA6C;AAI7C,sCAAiH;AACjH,wCAAyC;AACzC,wCAA2C;AAE3C,IAAY,WAKX;AALD,WAAY,WAAW;IACtB,4BAAa,CAAA;IACb,oCAAqB,CAAA;IACrB,oCAAqB,CAAA;IACrB,oCAAqB,CAAA;AACtB,CAAC,EALW,WAAW,GAAX,mBAAW,KAAX,mBAAW,QAKtB;AAED,IAAY,uBAIX;AAJD,WAAY,uBAAuB;IAClC,8CAAmB,CAAA;IACnB,8CAAmB,CAAA;IACnB,wCAAa,CAAA;AACd,CAAC,EAJW,uBAAuB,GAAvB,+BAAuB,KAAvB,+BAAuB,QAIlC;AAgBD,MAAM,oBAAoB,GAAyB;IAClD,EAAE,KAAK,EAAE,WAAW,CAAC,IAAI,EAAE;IAC3B,EAAE,KAAK,EAAE,WAAW,CAAC,QAAQ,EAAE;IAC/B,EAAE,KAAK,EAAE,WAAW,CAAC,QAAQ,EAAE;IAC/B,EAAE,KAAK,EAAE,WAAW,CAAC,QAAQ,EAAE;CAC/B,CAAC;AAEF,SAAS,UAAU,CAAC,IAA6B,EAAE,MAA4B;IAC9E,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,QAAQ,EAAE;QAC1C,OAAO,MAAM,CAAC,MAAM,CAAC;KACrB;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;IAErC,MAAM,SAAS,GAAG,CAAC,QAAiD,EAAE,EAAE,CACvE,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;QAC1B,IAAI,KAAK,YAAY,KAAK,EAAE;YAC3B,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;SAC9D;QAED,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;IAEJ,MAAM,YAAY,GAAG,IAAA,0BAAoB,EAAC,IAAI,CAAC,CAAC;IAEhD,MAAM,cAAc,GAAG,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;QAC1C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;YAC9B,OAAO,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;SACpC;QAED,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE;YAChC,OAAO,KAAK,CAAC;SACb;QAED,IAAI,YAAY,EAAE;YACjB,OAAO,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,KAAK,KAAK,uBAAuB,CAAC,OAAO,CAAC;SAC5F;QAED,OAAO,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,KAAK,KAAK,uBAAuB,CAAC,IAAI,CAAC;IAC1F,CAAC,CAAC,CAAC;IAEH,IAAI,cAAc,IAAI,CAAC,EAAE;QACxB,OAAO,cAAc,CAAC;KACtB;IAED,gEAAgE;IAChE,MAAM,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IAEjD,IAAI,CAAC,MAAM,EAAE;QACZ,MAAM,IAAI,KAAK,CAAC,6DAA6D,UAAU,GAAG,CAAC,CAAC;KAC5F;IAED,IAAI,WAAW,GAAG,WAAW,CAAC,QAAQ,CAAC;IAEvC,IAAI,yBAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,EAAE;QAC3D,WAAW,GAAG,WAAW,CAAC,IAAI,CAAC;KAC/B;SAAM,IAAI,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;QACtC,WAAW,GAAG,IAAA,iBAAU,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC;KAC/E;IAED,MAAM,UAAU,GAAG,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;QACtC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE;YAC9D,OAAO,KAAK,CAAC;SACb;QAED,IAAI,YAAY,EAAE;YACjB,OAAO,KAAK,CAAC,KAAK,KAAK,WAAW,IAAI,KAAK,CAAC,KAAK,KAAK,uBAAuB,CAAC,OAAO,CAAC;SACtF;QAED,OAAO,KAAK,CAAC,KAAK,KAAK,WAAW,IAAI,KAAK,CAAC,KAAK,KAAK,uBAAuB,CAAC,IAAI,CAAC;IACpF,CAAC,CAAC,CAAC;IAEH,OAAO,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;AACrD,CAAC;AAED,SAAS,UAAU,CAClB,OAA0C,EAC1C,QAA6C,EAC7C,IAAyC,EACzC,SAAiB;IAEjB,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,EAAE;QACvB,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;KAC5D;IAED,IAAI,IAAA,kBAAY,EAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,SAAS,EAAE;QAC/C,OAAO;KACP;IAED,OAAO,CAAC,MAAM,CAAC;QACd,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,YAAY,SAAS,cAAc,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,eAAe;QACrF,GAAG,CAAC,KAAK;YACR,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAA,2BAAqB,EAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,EAAE;gBACtG,OAAO,IAAI,CAAC;aACZ;YAED,OAAO,KAAK,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;QACnG,CAAC;KACD,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,MAA4B;IAChD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAC3B,IAAI,KAAK,YAAY,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE;YACtF,OAAO,QAAQ,CAAC;SAChB;QAED,OAAO,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;IAClC,CAAC,CAAC,CAAC;AACJ,CAAC;AAEY,QAAA,IAAI,GAAqC;IACrD,IAAI,EAAE;QACL,OAAO,EAAE,MAAM;QACf,MAAM,EAAE;YACP,WAAW,EAAE;gBACZ,uBAAuB,EAAE;oBACxB,IAAI,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC;iBACpC;gBACD,mBAAmB,EAAE;oBACpB,KAAK,EAAE;wBACN,EAAE,IAAI,EAAE,QAAQ,EAAE;wBAClB;4BACC,IAAI,EAAE,QAAQ;4BACd,UAAU,EAAE;gCACX,KAAK,EAAE;oCACN,IAAI,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC;iCAClD;gCACD,KAAK,EAAE;oCACN,IAAI,EAAE,uCAAuC;iCAC7C;6BACD;4BACD,QAAQ,EAAE,CAAC,OAAO,CAAC;4BACnB,oBAAoB,EAAE,KAAK;yBAC3B;wBACD;4BACC,IAAI,EAAE,QAAQ;4BACd,UAAU,EAAE;gCACX,IAAI,EAAE;oCACL,IAAI,EAAE,QAAQ;iCACd;gCACD,KAAK,EAAE;oCACN,IAAI,EAAE,uCAAuC;iCAC7C;6BACD;4BACD,QAAQ,EAAE,CAAC,MAAM,CAAC;4BAClB,oBAAoB,EAAE,KAAK;yBAC3B;qBACD;iBACD;aACD;YACD,IAAI,EAAE,OAAO;YACb,KAAK,EAAE;gBACN,KAAK,EAAE;oBACN;wBACC,IAAI,EAAE,mCAAmC;qBACzC;oBACD;wBACC,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE;4BACN,IAAI,EAAE,mCAAmC;yBACzC;qBACD;iBACD;aACD;SACD;KACD;IACD,MAAM,CAAC,OAAO;QACb,MAAM,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC;QAE5F,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;QAEvC,MAAM,OAAO,GAAG,IAAA,mBAAa,EAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YAClD,OAAO;gBACN,KAAK,EAAE,UAAU,CAAC,IAAI,EAAE,mBAAmB,CAAC;gBAC5C,IAAI;aACJ,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;YACzB,OAAO,EAAE,CAAC;SACV;QAED,MAAM,MAAM,GAAG,IAAA,iBAAU,EAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAE9C,IAAI,aAAa,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;QAErC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAC3B,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;YACjB,MAAM,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAE9B,IAAI,OAAO,IAAI,aAAa,KAAK,KAAK,CAAC,KAAK,EAAE;gBAC7C,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;aACzB;iBAAM;gBACN,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;aAC1B;YAED,aAAa,GAAG,KAAK,CAAC,KAAK,CAAC;YAE5B,OAAO,MAAM,CAAC;QACf,CAAC,EACD,CAAC,EAAE,CAAC,CACJ,CAAC;QAEF,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;YAClD,IAAA,eAAQ,EAAC,OAAO,EAAE;gBACjB,KAAK,EAAE,IAAA,aAAO,EAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;gBAC/C,OAAO,EAAE,2BAA2B,WAAW,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;gBACjF,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;aAC9F,CAAC,CAAC;SACH;aAAM;YACN,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;gBAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;oBACtC,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;oBAC9B,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;oBACzB,UAAU,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;iBAC1C;gBAED,IAAI,CAAC,KAAK,CAAC,EAAE;oBACZ,OAAO;iBACP;gBAED,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;gBACvC,MAAM,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC;gBACxB,UAAU,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;YAC3C,CAAC,CAAC,CAAC;SACH;QAED,OAAO,EAAE,CAAC;IACX,CAAC;CACD,CAAC"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rule = exports.TypeImportInlinePosition = exports.TypeImportGroupPosition = void 0;
|
|
4
|
+
const ast_1 = require("../tools/ast");
|
|
5
|
+
const rule_1 = require("../tools/rule");
|
|
6
|
+
const sort_1 = require("../tools/sort");
|
|
7
|
+
var TypeImportGroupPosition;
|
|
8
|
+
(function (TypeImportGroupPosition) {
|
|
9
|
+
TypeImportGroupPosition["Ignore"] = "ignore";
|
|
10
|
+
TypeImportGroupPosition["Top"] = "top";
|
|
11
|
+
TypeImportGroupPosition["Bottom"] = "bottom";
|
|
12
|
+
TypeImportGroupPosition["AboveValue"] = "above-value";
|
|
13
|
+
TypeImportGroupPosition["BelowValue"] = "below-value";
|
|
14
|
+
})(TypeImportGroupPosition = exports.TypeImportGroupPosition || (exports.TypeImportGroupPosition = {}));
|
|
15
|
+
var TypeImportInlinePosition;
|
|
16
|
+
(function (TypeImportInlinePosition) {
|
|
17
|
+
TypeImportInlinePosition["Ignore"] = "ignore";
|
|
18
|
+
TypeImportInlinePosition["Start"] = "start";
|
|
19
|
+
TypeImportInlinePosition["End"] = "End";
|
|
20
|
+
})(TypeImportInlinePosition = exports.TypeImportInlinePosition || (exports.TypeImportInlinePosition = {}));
|
|
21
|
+
const defaultConfiguration = {
|
|
22
|
+
specifier: 'source',
|
|
23
|
+
locales: ['en-US'],
|
|
24
|
+
numeric: true,
|
|
25
|
+
caseFirst: 'lower',
|
|
26
|
+
sortExports: true,
|
|
27
|
+
typesInGroup: TypeImportGroupPosition.Ignore,
|
|
28
|
+
inlineTypes: TypeImportInlinePosition.Ignore,
|
|
29
|
+
};
|
|
30
|
+
exports.rule = {
|
|
31
|
+
meta: {
|
|
32
|
+
fixable: 'code',
|
|
33
|
+
schema: [
|
|
34
|
+
{
|
|
35
|
+
type: 'object',
|
|
36
|
+
properties: {
|
|
37
|
+
locales: {
|
|
38
|
+
type: 'array',
|
|
39
|
+
items: {
|
|
40
|
+
type: 'string',
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
sensitivity: {
|
|
44
|
+
enum: ['base', 'accent', 'case', 'variant'],
|
|
45
|
+
},
|
|
46
|
+
ignorePunctuation: {
|
|
47
|
+
type: 'boolean',
|
|
48
|
+
},
|
|
49
|
+
numeric: {
|
|
50
|
+
type: 'boolean',
|
|
51
|
+
},
|
|
52
|
+
caseFirst: {
|
|
53
|
+
enum: ['upper', 'lower', 'false'],
|
|
54
|
+
},
|
|
55
|
+
caseGroups: {
|
|
56
|
+
type: 'boolean',
|
|
57
|
+
},
|
|
58
|
+
specifier: {
|
|
59
|
+
enum: ['source', 'rename'],
|
|
60
|
+
},
|
|
61
|
+
sortExports: {
|
|
62
|
+
type: 'boolean',
|
|
63
|
+
},
|
|
64
|
+
typesInGroup: {
|
|
65
|
+
enum: ['ignore', 'top', 'bottom', 'above-value', 'below-value'],
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
create(context) {
|
|
72
|
+
const configuration = { ...defaultConfiguration, ...context.options[0] };
|
|
73
|
+
const source = context.getSourceCode();
|
|
74
|
+
const partition = (result, node, index, from) => {
|
|
75
|
+
if (index > 0 && (0, ast_1.linesBetween)(from[index - 1], node) > 0) {
|
|
76
|
+
result.push([]);
|
|
77
|
+
}
|
|
78
|
+
result.at(-1)?.push(node);
|
|
79
|
+
return result;
|
|
80
|
+
};
|
|
81
|
+
const sortModules = (group) => {
|
|
82
|
+
const sorted = (0, sort_1.sortByPath)(group, ['source', 'value'], configuration);
|
|
83
|
+
if (configuration.typesInGroup !== TypeImportGroupPosition.Ignore) {
|
|
84
|
+
sorted.sort((a, b) => {
|
|
85
|
+
const aIsType = (0, ast_1.isTypeImportOrExport)(a);
|
|
86
|
+
const bIsType = (0, ast_1.isTypeImportOrExport)(b);
|
|
87
|
+
if (aIsType === bIsType) {
|
|
88
|
+
return 0;
|
|
89
|
+
}
|
|
90
|
+
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
|
91
|
+
switch (configuration.typesInGroup) {
|
|
92
|
+
case TypeImportGroupPosition.Top:
|
|
93
|
+
return aIsType ? -1 : 1;
|
|
94
|
+
case TypeImportGroupPosition.Bottom:
|
|
95
|
+
return aIsType ? 1 : -1;
|
|
96
|
+
}
|
|
97
|
+
if (a.source.value === b.source.value) {
|
|
98
|
+
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
|
99
|
+
switch (configuration.typesInGroup) {
|
|
100
|
+
case TypeImportGroupPosition.AboveValue:
|
|
101
|
+
return aIsType ? -1 : 1;
|
|
102
|
+
case TypeImportGroupPosition.BelowValue:
|
|
103
|
+
return aIsType ? 1 : -1;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return 0;
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
if (sorted.some((node, i) => node !== group[i])) {
|
|
110
|
+
(0, rule_1.fixRange)(context, {
|
|
111
|
+
range: (0, ast_1.extrema)(group),
|
|
112
|
+
message: 'Expected modules in group to be sorted',
|
|
113
|
+
code: sorted.map((node) => source.getText(node)).join('\n'),
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
const sortSpecifiers = (specifiers) => {
|
|
118
|
+
if (!specifiers.length) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const sorted = (() => {
|
|
122
|
+
if (specifiers[0]?.type === 'ImportSpecifier') {
|
|
123
|
+
const from = configuration.specifier === 'source' ? 'imported' : 'local';
|
|
124
|
+
return (0, sort_1.sortByPath)(specifiers, [from, 'name'], configuration);
|
|
125
|
+
}
|
|
126
|
+
const from = configuration.specifier === 'source' ? 'local' : 'exported';
|
|
127
|
+
return (0, sort_1.sortByPath)(specifiers, [from, 'name'], configuration);
|
|
128
|
+
})();
|
|
129
|
+
if (configuration.inlineTypes !== TypeImportInlinePosition.Ignore) {
|
|
130
|
+
sorted.sort((a, b) => {
|
|
131
|
+
const aIsType = (0, ast_1.isTypeImportOrExport)(a);
|
|
132
|
+
const bIsType = (0, ast_1.isTypeImportOrExport)(b);
|
|
133
|
+
if (aIsType === bIsType) {
|
|
134
|
+
return 0;
|
|
135
|
+
}
|
|
136
|
+
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
|
137
|
+
switch (configuration.inlineTypes) {
|
|
138
|
+
case TypeImportInlinePosition.Start:
|
|
139
|
+
return aIsType ? -1 : 1;
|
|
140
|
+
case TypeImportInlinePosition.End:
|
|
141
|
+
return aIsType ? 1 : -1;
|
|
142
|
+
}
|
|
143
|
+
return 0;
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
if (sorted.some((node, i) => node !== specifiers[i])) {
|
|
147
|
+
(0, rule_1.fixRange)(context, {
|
|
148
|
+
range: (0, ast_1.extrema)(specifiers),
|
|
149
|
+
message: 'Expected specifiers to be sorted',
|
|
150
|
+
code: sorted.map((node) => source.getText(node)).join(', '),
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
(0, ast_1.importModules)(source)
|
|
155
|
+
.reduce(partition, [[]])
|
|
156
|
+
.forEach((group) => {
|
|
157
|
+
sortModules(group);
|
|
158
|
+
group.forEach((node) => {
|
|
159
|
+
sortSpecifiers(node.specifiers.filter(($) => $.type === 'ImportSpecifier'));
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
if (configuration.sortExports) {
|
|
163
|
+
const sortExportSpecifiers = (specifiers) => {
|
|
164
|
+
const from = configuration.specifier === 'source' ? 'local' : 'exported';
|
|
165
|
+
const sorted = (0, sort_1.sortByPath)(specifiers, [from, 'name'], configuration);
|
|
166
|
+
if (sorted.some((node, i) => node !== specifiers[i])) {
|
|
167
|
+
(0, rule_1.fixRange)(context, {
|
|
168
|
+
range: (0, ast_1.extrema)(specifiers),
|
|
169
|
+
message: 'Expected specifiers to be sorted',
|
|
170
|
+
code: sorted.map((node) => source.getText(node)).join(', '),
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
(0, ast_1.exportModules)(source)
|
|
175
|
+
.reduce(partition, [[]])
|
|
176
|
+
.forEach((group) => {
|
|
177
|
+
sortModules(group);
|
|
178
|
+
group.forEach((node) => sortExportSpecifiers(node.specifiers ?? []));
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
return {};
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
//# sourceMappingURL=sort-imports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sort-imports.js","sourceRoot":"","sources":["../../src/rules/sort-imports.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.onlyWhiteSpaceBetween = exports.linesBetween = exports.extrema = exports.isTypeImportOrExport = exports.exportModules = exports.importModules = void 0;
|
|
4
|
+
function importModules(source) {
|
|
5
|
+
return source.ast.body.filter((node) => node.type === 'ImportDeclaration');
|
|
6
|
+
}
|
|
7
|
+
exports.importModules = importModules;
|
|
8
|
+
function exportModules(source) {
|
|
9
|
+
return source.ast.body.filter((node) => (node.type === 'ExportNamedDeclaration' || node.type === 'ExportAllDeclaration') && Boolean(node.source));
|
|
10
|
+
}
|
|
11
|
+
exports.exportModules = exportModules;
|
|
12
|
+
function isTypeImportOrExport(node) {
|
|
13
|
+
return ((Reflect.has(node, 'importKind') && node.importKind === 'type') ||
|
|
14
|
+
(Reflect.has(node, 'exportKind') && node.exportKind === 'type'));
|
|
15
|
+
}
|
|
16
|
+
exports.isTypeImportOrExport = isTypeImportOrExport;
|
|
17
|
+
function extrema(source) {
|
|
18
|
+
const [a, b] = [source.at(0), source.at(-1)];
|
|
19
|
+
if (!a || !b) {
|
|
20
|
+
throw new Error(`extrema: invalid input`);
|
|
21
|
+
}
|
|
22
|
+
return [a, b];
|
|
23
|
+
}
|
|
24
|
+
exports.extrema = extrema;
|
|
25
|
+
function linesBetween(a, b) {
|
|
26
|
+
if (!a?.loc || !b?.loc) {
|
|
27
|
+
throw new Error(`error: AST was generated without node location information`);
|
|
28
|
+
}
|
|
29
|
+
return b.loc.start.line - a.loc.end.line - 1;
|
|
30
|
+
}
|
|
31
|
+
exports.linesBetween = linesBetween;
|
|
32
|
+
function onlyWhiteSpaceBetween(a, b, source) {
|
|
33
|
+
return !source.getFirstTokenBetween(a, b, { includeComments: true });
|
|
34
|
+
}
|
|
35
|
+
exports.onlyWhiteSpaceBetween = onlyWhiteSpaceBetween;
|
|
36
|
+
//# sourceMappingURL=ast.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast.js","sourceRoot":"","sources":["../../src/tools/ast.ts"],"names":[],"mappings":";;;AAeA,SAAgB,aAAa,CAAC,MAAkB;IAC/C,OAAO,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAmC,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,mBAAmB,CAAC,CAAC;AAC7G,CAAC;AAFD,sCAEC;AAED,SAAgB,aAAa,CAAC,MAAkB;IAC/C,OAAO,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAC5B,CAAC,IAAI,EAAmC,EAAE,CACzC,CAAC,IAAI,CAAC,IAAI,KAAK,wBAAwB,IAAI,IAAI,CAAC,IAAI,KAAK,sBAAsB,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CACzG,CAAC;AACH,CAAC;AALD,sCAKC;AAED,SAAgB,oBAAoB,CAAC,IAA2D;IAC/F,OAAO,CACN,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC,IAAI,IAAI,CAAC,UAAU,KAAK,MAAM,CAAC;QAC/D,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC,IAAI,IAAI,CAAC,UAAU,KAAK,MAAM,CAAC,CAC/D,CAAC;AACH,CAAC;AALD,oDAKC;AAED,SAAgB,OAAO,CAAwB,MAAoB;IAClE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE7C,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE;QACb,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;KAC1C;IAED,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACf,CAAC;AARD,0BAQC;AAED,SAAgB,YAAY,CAAC,CAA0B,EAAE,CAA0B;IAClF,IAAI,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE;QACvB,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;KAC9E;IAED,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;AAC9C,CAAC;AAND,oCAMC;AAED,SAAgB,qBAAqB,CAAC,CAAc,EAAE,CAAc,EAAE,MAAkB;IACvF,OAAO,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC;AACtE,CAAC;AAFD,sDAEC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fixRange = void 0;
|
|
4
|
+
function fixRange(context, data) {
|
|
5
|
+
const [first, last] = data.range;
|
|
6
|
+
context.report({
|
|
7
|
+
node: last,
|
|
8
|
+
message: data.message,
|
|
9
|
+
fix(fixer) {
|
|
10
|
+
if (!first.range || !last.range) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
return fixer.replaceTextRange([first.range[0], last.range[1]], data.code);
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
exports.fixRange = fixRange;
|
|
18
|
+
//# sourceMappingURL=rule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule.js","sourceRoot":"","sources":["../../src/tools/rule.ts"],"names":[],"mappings":";;;AAWA,SAAgB,QAAQ,CACvB,OAAyB,EACzB,IAIC;IAED,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;IAEjC,OAAO,CAAC,MAAM,CAAC;QACd,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,GAAG,CAAC,KAAK;YACR,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;gBAChC,OAAO,IAAI,CAAC;aACZ;YAED,OAAO,KAAK,CAAC,gBAAgB,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3E,CAAC;KACD,CAAC,CAAC;AACJ,CAAC;AArBD,4BAqBC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sortByPath = void 0;
|
|
4
|
+
function isIndexable(value) {
|
|
5
|
+
return typeof value === 'object' && value !== null;
|
|
6
|
+
}
|
|
7
|
+
function readPath(from, path) {
|
|
8
|
+
if (!isIndexable(from)) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
const [head, ...rest] = path;
|
|
12
|
+
if (!head) {
|
|
13
|
+
throw new Error(`readPath: invalid input`);
|
|
14
|
+
}
|
|
15
|
+
if (path.length === 1) {
|
|
16
|
+
return from[head];
|
|
17
|
+
}
|
|
18
|
+
return readPath(from[head], rest);
|
|
19
|
+
}
|
|
20
|
+
function sort(options) {
|
|
21
|
+
return (a, b) => {
|
|
22
|
+
if (typeof a.sortValue === 'number' && typeof b.sortValue === 'number') {
|
|
23
|
+
return a.sortValue - b.sortValue;
|
|
24
|
+
}
|
|
25
|
+
if (typeof a.sortValue === 'string' && typeof b.sortValue === 'string') {
|
|
26
|
+
return a.sortValue.localeCompare(b.sortValue, options?.locales, options);
|
|
27
|
+
}
|
|
28
|
+
return 0;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
32
|
+
function sortByPath(sources, path, options) {
|
|
33
|
+
const caseGroups = sources.reduce((groups, source) => {
|
|
34
|
+
const sortValue = readPath(source, path);
|
|
35
|
+
const sortable = {
|
|
36
|
+
source,
|
|
37
|
+
sortValue,
|
|
38
|
+
};
|
|
39
|
+
let target = groups.lower;
|
|
40
|
+
if (options?.caseGroups && typeof sortValue === 'string' && sortValue.length) {
|
|
41
|
+
if (/^[@$_]/u.test(sortValue)) {
|
|
42
|
+
target = groups.punctuation;
|
|
43
|
+
}
|
|
44
|
+
else if (sortValue[0]?.toLocaleUpperCase(options.locales) === sortValue[0]) {
|
|
45
|
+
target = groups.upper;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
target.push(sortable);
|
|
49
|
+
return groups;
|
|
50
|
+
}, {
|
|
51
|
+
punctuation: [],
|
|
52
|
+
upper: [],
|
|
53
|
+
lower: [],
|
|
54
|
+
});
|
|
55
|
+
caseGroups.punctuation.sort(sort(options));
|
|
56
|
+
caseGroups.upper.sort(sort(options));
|
|
57
|
+
caseGroups.lower.sort(sort(options));
|
|
58
|
+
return [
|
|
59
|
+
...caseGroups.punctuation.map(({ source }) => source),
|
|
60
|
+
...(options?.caseFirst === 'upper' ? caseGroups.upper : caseGroups.lower).map(({ source }) => source),
|
|
61
|
+
...(options?.caseFirst === 'upper' ? caseGroups.lower : caseGroups.upper).map(({ source }) => source),
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
exports.sortByPath = sortByPath;
|
|
65
|
+
//# sourceMappingURL=sort.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sort.js","sourceRoot":"","sources":["../../src/tools/sort.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@shigen/eslint-plugin",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "General purpose plugin for ESLint",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"eslint",
|
|
7
|
+
"lint",
|
|
8
|
+
"js",
|
|
9
|
+
"javascript",
|
|
10
|
+
"ts",
|
|
11
|
+
"typescript",
|
|
12
|
+
"es6"
|
|
13
|
+
],
|
|
14
|
+
"license": "ISC",
|
|
15
|
+
"author": "Tao Cumplido",
|
|
16
|
+
"repository": "https://github.com/tao-cumplido/shigen/tree/main/packages/eslint-plugin",
|
|
17
|
+
"bugs": "https://github.com/tao-cumplido/shigen/issues",
|
|
18
|
+
"files": [
|
|
19
|
+
"readme.md",
|
|
20
|
+
"dist/**/*"
|
|
21
|
+
],
|
|
22
|
+
"main": "dist/index.js",
|
|
23
|
+
"scripts": {
|
|
24
|
+
"prepublishOnly": "wireit",
|
|
25
|
+
"test": "wireit",
|
|
26
|
+
"build": "wireit"
|
|
27
|
+
},
|
|
28
|
+
"wireit": {
|
|
29
|
+
"prepublishOnly": {
|
|
30
|
+
"dependencies": [
|
|
31
|
+
"test",
|
|
32
|
+
"build"
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
"test": {
|
|
36
|
+
"command": "npx -c 'tsx --tsconfig tsconfig.test.json --test src/**/*.test.ts'",
|
|
37
|
+
"files": [
|
|
38
|
+
"src/**/*.ts"
|
|
39
|
+
],
|
|
40
|
+
"output": []
|
|
41
|
+
},
|
|
42
|
+
"build": {
|
|
43
|
+
"command": "tsc --build tsconfig.build.json",
|
|
44
|
+
"clean": "if-file-deleted",
|
|
45
|
+
"files": [
|
|
46
|
+
"src/**/*.ts",
|
|
47
|
+
"!src/**/*.test.ts",
|
|
48
|
+
"!src/tools/test.ts",
|
|
49
|
+
"../../tsconfig.base.json",
|
|
50
|
+
"tsconfig.build.json"
|
|
51
|
+
],
|
|
52
|
+
"output": [
|
|
53
|
+
"dist/**",
|
|
54
|
+
"*.tsbuildinfo"
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"engines": {
|
|
59
|
+
"node": "^16.7.0 || >=18.6.0"
|
|
60
|
+
},
|
|
61
|
+
"dependencies": {
|
|
62
|
+
"tslib": "~2.6.1"
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"@types/eslint": "8.44.2",
|
|
66
|
+
"@typescript-eslint/parser": "6.4.0",
|
|
67
|
+
"@typescript-eslint/types": "6.4.0",
|
|
68
|
+
"ajv": "8.12.0",
|
|
69
|
+
"eslint": "8.47.0",
|
|
70
|
+
"dedent": "1.5.1"
|
|
71
|
+
},
|
|
72
|
+
"peerDependencies": {
|
|
73
|
+
"@typescript-eslint/parser": "^6.0.0",
|
|
74
|
+
"eslint": "^8.0.0"
|
|
75
|
+
},
|
|
76
|
+
"peerDependenciesMeta": {
|
|
77
|
+
"@typescript-eslint/parser": {
|
|
78
|
+
"optional": true
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# @shigen/eslint-plugin
|
|
2
|
+
|
|
3
|
+
> General purpose ESLint plugin
|
|
4
|
+
|
|
5
|
+
[![NPM Version][npm-image]][npm-url]
|
|
6
|
+
|
|
7
|
+
Configurable ESLint rules for issues not -- or not sufficiently -- covered by ESLint core rules.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install --save-dev @shigen/eslint-plugin
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
[npm-image]: https://img.shields.io/npm/v/@shigen/eslint-plugin.svg
|
|
16
|
+
[npm-url]: https://npmjs.org/package/@shigen/eslint-plugin
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
In your `.eslintrc`:
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
{
|
|
24
|
+
"plugins": ["@shigen"],
|
|
25
|
+
"rules": {
|
|
26
|
+
"@shigen/group-imports": "error"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Rules
|
|
32
|
+
|
|
33
|
+
### `@shigen/group-imports`
|
|
34
|
+
|
|
35
|
+
Requires imports to be grouped and groups to be separated by a new line. This rule is partially auto-fixable.
|
|
36
|
+
It is currently not capable to move an import that is preceded by non-import statements, including comments.
|
|
37
|
+
|
|
38
|
+
The following configuration options can be set:
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
interface ModuleClassConfiguration {
|
|
42
|
+
class: 'node' | 'external' | 'relative' | 'absolute';
|
|
43
|
+
types?: 'include' | 'exclude' | 'only';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
interface ModulePathConfiguration {
|
|
47
|
+
path: string;
|
|
48
|
+
types?: 'include' | 'exclude' | 'only';
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
type ModuleConfiguration = string | ModulePathConfiguration | ModuleClassConfiguration;
|
|
52
|
+
|
|
53
|
+
type Configuration = Array<ModuleConfiguration | ModuleConfiguration[]>;
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
where `ModuleConfiguration` can be a path or an object.
|
|
57
|
+
If it's an object, `path` can be a path and `class` can be one of the following:
|
|
58
|
+
|
|
59
|
+
- `node`: All node builtin packages like `fs` and `path`, with or without the `node:` protocol prefix.
|
|
60
|
+
- `external`: All other declared dependencies, e.g. `lodash`, `react`, etc.
|
|
61
|
+
- `relative`: All relative imports.
|
|
62
|
+
- `absolute`: All absolute imports, never seen a project use these, but it's possible.
|
|
63
|
+
|
|
64
|
+
Paths are matched from the start of the actual import path. This makes it possible for subpaths of the same module or scope to be in different groups.
|
|
65
|
+
The property `types` is only relevant for TypeScript's type imports and defaults to `'include'`.
|
|
66
|
+
If you want type and value imports to be in separate groups you need to explicitly declare them with `'only'` and `'exclude'`.
|
|
67
|
+
|
|
68
|
+
Nested arrays allow packages to be treated as a single group, e.g.
|
|
69
|
+
|
|
70
|
+
<!-- prettier-ignore -->
|
|
71
|
+
```json
|
|
72
|
+
[
|
|
73
|
+
[{ "class": "node" }, { "class": "external" }],
|
|
74
|
+
["@my-scope", "my-package"],
|
|
75
|
+
{ "class": "relative" }
|
|
76
|
+
]
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Explicitly declared packages and scopes have precedence over the predefined `class` tokens. Unused tokens are in an implicit additional group.
|
|
80
|
+
|
|
81
|
+
The default configuration is:
|
|
82
|
+
|
|
83
|
+
<!-- prettier-ignore -->
|
|
84
|
+
```json
|
|
85
|
+
[
|
|
86
|
+
{ "class": "node" },
|
|
87
|
+
{ "class": "external" },
|
|
88
|
+
{ "class": "absolute" },
|
|
89
|
+
{ "class": "relative" }
|
|
90
|
+
]
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### `@shigen/sort-imports`
|
|
94
|
+
|
|
95
|
+
Requires import groups to be sorted by module first and then by specifier. Auto-fixable!
|
|
96
|
+
|
|
97
|
+
The following configuration options can be set:
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
interface Configuration {
|
|
101
|
+
specifier?: 'source' | 'rename';
|
|
102
|
+
locales?: string[];
|
|
103
|
+
sensitivity?: 'base' | 'accent' | 'case' | 'variant';
|
|
104
|
+
ignorePunctuation?: boolean;
|
|
105
|
+
numeric?: boolean;
|
|
106
|
+
caseFirst?: 'upper' | 'lower' | 'false';
|
|
107
|
+
caseGroups?: boolean;
|
|
108
|
+
sortExports?: boolean;
|
|
109
|
+
typesInGroup?: 'ignore' | 'top' | 'bottom' | 'above-value' | 'below-value';
|
|
110
|
+
inlineTypes?: 'ignore' | 'start' | 'end';
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
- `specifier`: Determines specifier priority, e.g. in `import { foo as bar } from 'baz'` `foo` is `'source'` and `bar` is `'rename'`.
|
|
115
|
+
- `caseGroups`: When `true`, import names need to be grouped by case before sorting.
|
|
116
|
+
- `sortExports`: Whether to sort deferred export groups, i.e. all statements that export from another module.
|
|
117
|
+
- `typesInGroup`: Where to place type imports/exports in groups with mixed type and value imports/exports. TypeScript only!
|
|
118
|
+
- `inlineTypes`: Where to place inline type imports/exports with mixed type and value imports/exports. TypeScript only!
|
|
119
|
+
|
|
120
|
+
For all other possible settings, see [String#localeCompare](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare).
|
|
121
|
+
|
|
122
|
+
The default configuration is:
|
|
123
|
+
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"specifier": "source",
|
|
127
|
+
"locales": ["en-US"],
|
|
128
|
+
"sensitivity": "variant",
|
|
129
|
+
"ignorePunctuation": false,
|
|
130
|
+
"numeric": true,
|
|
131
|
+
"caseFirst": "lower",
|
|
132
|
+
"caseGroups": false,
|
|
133
|
+
"sortExports": true,
|
|
134
|
+
"typesInGroup": "ignore",
|
|
135
|
+
"inlineTypes": "ignore"
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Experimental rules
|
|
140
|
+
|
|
141
|
+
:warning: These rules are experimental and may produce unexpected behavior. :warning:
|
|
142
|
+
|
|
143
|
+
- These rules are not auto-fixable!
|
|
144
|
+
- Consider setting the level to `"warn"` instead of `"error"`.
|
|
145
|
+
|
|
146
|
+
### `@shigen/experimental/no-commented-code`
|
|
147
|
+
|
|
148
|
+
This rule is meant to detect commented code. It does so by uncommenting comment nodes and run the whole file with the uncommented part through the parser. If the parser produces a valid AST the comment is marked as commented code. Generally it should work with any parser but has only been tested with the default parser `espree` and `@typescript-eslint/parser`. For example, `// type A = 0;` is not commented code with `espree` but it is with `@typescript-eslint/parser`.
|
|
149
|
+
|
|
150
|
+
False positives will probably happen, single words for example, are valid identifiers in many positions and `eslint-disable-next-line` is parsed as a `BinaryExpression`. Common patterns can be ignored and `^eslint-` is ignored by default. Additionally, doc comments are ignored as well, this cannot be turned off.
|
|
151
|
+
|
|
152
|
+
The following configuration options can be set:
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
interface Configuration {
|
|
156
|
+
ignorePatterns?: string[];
|
|
157
|
+
extendDefaultIgnorePatterns?: boolean;
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
- `ignorePatterns`: When a comment matches one of the specified patterns it will be ignored. The expressions are tested against the trimmed text content of the comment. Invalid regular expressions will be ignored.
|
|
162
|
+
- `extendDefaultIgnorePatterns`: Whether to keep the default ignore patterns without explicitly redefining them.
|
|
163
|
+
|
|
164
|
+
The default configuration is:
|
|
165
|
+
|
|
166
|
+
```json
|
|
167
|
+
{
|
|
168
|
+
"ignorePatterns": ["^eslint-", "^@ts-"],
|
|
169
|
+
"extendDefaultIgnorePatterns": false
|
|
170
|
+
}
|
|
171
|
+
```
|