@borela-tech/eslint-config 2.2.2 → 2.4.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/README.md +308 -19
- package/dist/index.d.ts +5 -0
- package/dist/index.mjs +3864 -811
- package/dist/index.mjs.map +1 -1
- package/jest.config.ts +19 -0
- package/package.json +15 -9
- package/vite.config.ts +41 -0
- package/bin/build +0 -9
- package/bin/lint +0 -14
- package/bin/publish +0 -12
- package/bin/test +0 -12
- package/bin/typecheck +0 -8
- package/dist/index.d.mts +0 -7
- package/src/index.ts +0 -149
- package/src/lib/ReExportDeclaration.ts +0 -5
- package/src/lib/ReplacementRange.ts +0 -4
- package/src/lib/compare.ts +0 -3
- package/src/rules/__tests__/dedent/countLeadingSpaces.ts +0 -4
- package/src/rules/__tests__/dedent/findMinIndent.ts +0 -7
- package/src/rules/__tests__/dedent/index.ts +0 -17
- package/src/rules/__tests__/dedent/interpolate.ts +0 -11
- package/src/rules/__tests__/dedent/removeEmptyPrefix.ts +0 -6
- package/src/rules/__tests__/dedent/removeEmptySuffix.ts +0 -6
- package/src/rules/__tests__/dedent/removeIndent.ts +0 -3
- package/src/rules/__tests__/importsAndReExportsAtTop.test.ts +0 -88
- package/src/rules/__tests__/individualImports.test.ts +0 -44
- package/src/rules/__tests__/individualReExports.test.ts +0 -64
- package/src/rules/__tests__/multilineUnionTypes.test.ts +0 -75
- package/src/rules/__tests__/singleLineImports.test.ts +0 -129
- package/src/rules/__tests__/singleLineReExports.test.ts +0 -100
- package/src/rules/__tests__/sortedImports.test.ts +0 -227
- package/src/rules/__tests__/sortedReExports.test.ts +0 -220
- package/src/rules/importsAndReExportsAtTop/CategorizedStatements.ts +0 -8
- package/src/rules/importsAndReExportsAtTop/StatementIndices.ts +0 -5
- package/src/rules/importsAndReExportsAtTop/categorizeStatements.ts +0 -28
- package/src/rules/importsAndReExportsAtTop/findStatementIndices.ts +0 -25
- package/src/rules/importsAndReExportsAtTop/generateSortedText.ts +0 -16
- package/src/rules/importsAndReExportsAtTop/getStatementType.ts +0 -17
- package/src/rules/importsAndReExportsAtTop/hasViolation.ts +0 -25
- package/src/rules/importsAndReExportsAtTop/index.ts +0 -45
- package/src/rules/importsAndReExportsAtTop/isImportDeclaration.ts +0 -7
- package/src/rules/importsAndReExportsAtTop/isReExport.ts +0 -12
- package/src/rules/importsAndReExportsAtTop/statementType.ts +0 -4
- package/src/rules/individualImports.ts +0 -38
- package/src/rules/individualReExports.ts +0 -51
- package/src/rules/multilineUnionTypes/createFix.ts +0 -13
- package/src/rules/multilineUnionTypes/index.ts +0 -52
- package/src/rules/multilineUnionTypes/isMultiline.ts +0 -6
- package/src/rules/singleLineImports/createFix.ts +0 -23
- package/src/rules/singleLineImports/formatAttributes.ts +0 -20
- package/src/rules/singleLineImports/formatNamed.ts +0 -9
- package/src/rules/singleLineImports/formatSpecifiers.ts +0 -32
- package/src/rules/singleLineImports/index.ts +0 -34
- package/src/rules/singleLineImports/isMultiline.ts +0 -6
- package/src/rules/singleLineReExports/createFix.ts +0 -29
- package/src/rules/singleLineReExports/index.ts +0 -48
- package/src/rules/singleLineReExports/isMultiline.ts +0 -6
- package/src/rules/sortedImports/CategorizedImport.ts +0 -8
- package/src/rules/sortedImports/ImportError.ts +0 -9
- package/src/rules/sortedImports/ImportGroup.ts +0 -6
- package/src/rules/sortedImports/ImportGroupOrder.ts +0 -9
- package/src/rules/sortedImports/areSpecifiersSorted.ts +0 -9
- package/src/rules/sortedImports/categorizeImport.ts +0 -23
- package/src/rules/sortedImports/categorizeImports.ts +0 -12
- package/src/rules/sortedImports/checkAlphabeticalSorting.ts +0 -23
- package/src/rules/sortedImports/checkGroupOrdering.ts +0 -21
- package/src/rules/sortedImports/checkSpecifiersSorting.ts +0 -21
- package/src/rules/sortedImports/createFix/buildSortedCode.ts +0 -23
- package/src/rules/sortedImports/createFix/findLastImportIndex.ts +0 -12
- package/src/rules/sortedImports/createFix/formatNamedImport.ts +0 -21
- package/src/rules/sortedImports/createFix/getReplacementRange.ts +0 -14
- package/src/rules/sortedImports/createFix/groupImportsByType.ts +0 -19
- package/src/rules/sortedImports/createFix/index.ts +0 -47
- package/src/rules/sortedImports/createFix/sortImportGroups.ts +0 -13
- package/src/rules/sortedImports/getImportGroups.ts +0 -23
- package/src/rules/sortedImports/getNamedSpecifiers.ts +0 -7
- package/src/rules/sortedImports/getSortKey.ts +0 -26
- package/src/rules/sortedImports/getSpecifierName.ts +0 -7
- package/src/rules/sortedImports/index.ts +0 -63
- package/src/rules/sortedImports/sortSpecifiersText.ts +0 -16
- package/src/rules/sortedReExports/CategorizedNamedReExport.ts +0 -6
- package/src/rules/sortedReExports/CategorizedReExport.ts +0 -26
- package/src/rules/sortedReExports/ReExportError.ts +0 -9
- package/src/rules/sortedReExports/ReExportGroup.ts +0 -5
- package/src/rules/sortedReExports/ReExportGroupOrder.ts +0 -8
- package/src/rules/sortedReExports/areSpecifiersSorted.ts +0 -9
- package/src/rules/sortedReExports/categorizeReExport.ts +0 -21
- package/src/rules/sortedReExports/categorizeReExports.ts +0 -14
- package/src/rules/sortedReExports/checkAlphabeticalSorting.ts +0 -25
- package/src/rules/sortedReExports/checkGroupOrdering.ts +0 -21
- package/src/rules/sortedReExports/checkSpecifiersSorting.ts +0 -23
- package/src/rules/sortedReExports/createFix/buildSortedCode.ts +0 -29
- package/src/rules/sortedReExports/createFix/findFirstExportIndex.ts +0 -11
- package/src/rules/sortedReExports/createFix/findLastExportIndex.ts +0 -12
- package/src/rules/sortedReExports/createFix/formatNamedReExport.ts +0 -21
- package/src/rules/sortedReExports/createFix/getReplacementRange.ts +0 -22
- package/src/rules/sortedReExports/createFix/groupReExportsByType.ts +0 -18
- package/src/rules/sortedReExports/createFix/index.ts +0 -47
- package/src/rules/sortedReExports/createFix/sortExportGroups.ts +0 -12
- package/src/rules/sortedReExports/getNamedSpecifiers.ts +0 -9
- package/src/rules/sortedReExports/getReExportGroups.ts +0 -33
- package/src/rules/sortedReExports/getSortKey.ts +0 -22
- package/src/rules/sortedReExports/getSpecifierName.ts +0 -7
- package/src/rules/sortedReExports/index.ts +0 -63
- package/src/rules/sortedReExports/isNamedReExport.ts +0 -6
- package/src/rules/sortedReExports/sortSpecifiersText.ts +0 -16
- package/tsdown.config.ts +0 -22
package/dist/index.mjs
CHANGED
|
@@ -1,872 +1,3925 @@
|
|
|
1
1
|
import eslint from "@eslint/js";
|
|
2
2
|
import react from "eslint-plugin-react";
|
|
3
|
-
import reactHooks from "eslint-plugin-react-hooks";
|
|
4
3
|
import stylistic from "@stylistic/eslint-plugin";
|
|
5
4
|
import typescript from "typescript-eslint";
|
|
6
|
-
|
|
5
|
+
import * as path from "path";
|
|
6
|
+
import perfectionist from "eslint-plugin-perfectionist";
|
|
7
|
+
import rule from "eslint-plugin-react-hooks";
|
|
8
|
+
import eslintPluginUnicorn from "eslint-plugin-unicorn";
|
|
9
|
+
function getLineIndent$1(sourceCode, line) {
|
|
10
|
+
const text = sourceCode.getText();
|
|
11
|
+
const lines = text.split("\n");
|
|
12
|
+
const lineText = lines[line - 1] ?? "";
|
|
13
|
+
const match = lineText.match(/^(\s*)/);
|
|
14
|
+
return match?.[1] ?? "";
|
|
15
|
+
}
|
|
16
|
+
function buildMultilineFix$1(fixer, brackets, elements, sourceCode) {
|
|
17
|
+
const openingLine = brackets.openingBracket.loc.start.line;
|
|
18
|
+
const baseIndent = getLineIndent$1(sourceCode, openingLine);
|
|
19
|
+
const itemIndent = baseIndent + " ";
|
|
20
|
+
const nonNullElements = elements.filter((el) => el !== null);
|
|
21
|
+
const formattedItems = nonNullElements.map((element) => {
|
|
22
|
+
const text = sourceCode.getText(element);
|
|
23
|
+
return `${itemIndent}${text}`;
|
|
24
|
+
}).join(",\n");
|
|
25
|
+
const newText = `
|
|
26
|
+
${formattedItems},
|
|
27
|
+
${baseIndent}`;
|
|
28
|
+
return fixer.replaceTextRange(
|
|
29
|
+
[brackets.openingBracket.range[1], brackets.closingBracket.range[0]],
|
|
30
|
+
newText
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
const defaultOptions$6 = {
|
|
34
|
+
maxLength: 80
|
|
35
|
+
};
|
|
36
|
+
function getBrackets(sourceCode, node2) {
|
|
37
|
+
const elements = node2.elements;
|
|
38
|
+
if (elements.length === 0)
|
|
39
|
+
return null;
|
|
40
|
+
const firstElement = elements.find((el) => el !== null);
|
|
41
|
+
if (!firstElement)
|
|
42
|
+
return null;
|
|
43
|
+
const lastElement = [...elements].reverse().find((el) => el !== null);
|
|
44
|
+
if (!lastElement)
|
|
45
|
+
return null;
|
|
46
|
+
const openingBracket = sourceCode.getTokenBefore(firstElement);
|
|
47
|
+
const closingBracket = sourceCode.getTokenAfter(lastElement);
|
|
48
|
+
if (!openingBracket || !closingBracket)
|
|
49
|
+
return null;
|
|
50
|
+
if (openingBracket.value !== "[" || closingBracket.value !== "]")
|
|
51
|
+
return null;
|
|
52
|
+
return { closingBracket, openingBracket };
|
|
53
|
+
}
|
|
54
|
+
function getLineLength(sourceCode, lineNumber) {
|
|
55
|
+
const line = sourceCode.getLines()[lineNumber - 1];
|
|
56
|
+
return line?.length ?? 0;
|
|
57
|
+
}
|
|
58
|
+
function checkArray(sourceCode, context, node2) {
|
|
59
|
+
const options = context.options[0] ?? {};
|
|
60
|
+
const maxLength = options.maxLength ?? defaultOptions$6.maxLength;
|
|
61
|
+
const elements = node2.elements;
|
|
62
|
+
if (elements.length <= 1)
|
|
63
|
+
return;
|
|
64
|
+
const brackets = getBrackets(sourceCode, node2);
|
|
65
|
+
if (!brackets)
|
|
66
|
+
return;
|
|
67
|
+
const firstLine = brackets.openingBracket.loc.start.line;
|
|
68
|
+
const lastLine = brackets.closingBracket.loc.end.line;
|
|
69
|
+
if (firstLine !== lastLine)
|
|
70
|
+
return;
|
|
71
|
+
const lineLength = getLineLength(sourceCode, firstLine);
|
|
72
|
+
if (lineLength <= maxLength)
|
|
73
|
+
return;
|
|
74
|
+
context.report({
|
|
75
|
+
fix: (fixer) => buildMultilineFix$1(
|
|
76
|
+
fixer,
|
|
77
|
+
brackets,
|
|
78
|
+
elements,
|
|
79
|
+
sourceCode
|
|
80
|
+
),
|
|
81
|
+
messageId: "arrayItemsOnNewLine",
|
|
82
|
+
node: elements[0]
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
const messageIds$d = {
|
|
86
|
+
arrayItemsOnNewLine: "arrayItemsOnNewLine"
|
|
87
|
+
};
|
|
88
|
+
const arrayItemsLineBreak = {
|
|
89
|
+
create(context) {
|
|
90
|
+
const sourceCode = context.sourceCode ?? context.getSourceCode();
|
|
91
|
+
return {
|
|
92
|
+
ArrayExpression(node2) {
|
|
93
|
+
checkArray(sourceCode, context, node2);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
},
|
|
97
|
+
meta: {
|
|
98
|
+
docs: {
|
|
99
|
+
description: "Enforce each array item to be on its own line when the array expression exceeds a configurable maximum line length."
|
|
100
|
+
},
|
|
101
|
+
fixable: "code",
|
|
102
|
+
messages: messageIds$d,
|
|
103
|
+
schema: [{
|
|
104
|
+
additionalProperties: false,
|
|
105
|
+
properties: {
|
|
106
|
+
maxLength: {
|
|
107
|
+
type: "number"
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
type: "object"
|
|
111
|
+
}],
|
|
112
|
+
type: "layout"
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
function getIndentation(node2, sourceCode) {
|
|
116
|
+
const tokenBeforeBody = sourceCode.getTokenBefore(node2);
|
|
117
|
+
if (!tokenBeforeBody)
|
|
118
|
+
return "";
|
|
119
|
+
const line = sourceCode.getText().split("\n")[tokenBeforeBody.loc.start.line - 1];
|
|
120
|
+
if (!line)
|
|
121
|
+
return "";
|
|
122
|
+
const match = line.match(/^(\s*)/);
|
|
123
|
+
return match?.[1] ?? "";
|
|
124
|
+
}
|
|
125
|
+
function createBraceStyleFix(fixer, body, sourceCode) {
|
|
126
|
+
if (body.type === "BlockStatement") {
|
|
127
|
+
const firstToken = sourceCode.getFirstToken(body);
|
|
128
|
+
if (!firstToken)
|
|
129
|
+
return null;
|
|
130
|
+
return fixer.insertTextBefore(firstToken, "\n");
|
|
131
|
+
}
|
|
132
|
+
const bodyText = sourceCode.getText(body);
|
|
133
|
+
const indentation = getIndentation(body, sourceCode);
|
|
134
|
+
const fixedText = `{
|
|
135
|
+
${indentation} ${bodyText}
|
|
136
|
+
${indentation}}`;
|
|
137
|
+
return fixer.replaceText(body, fixedText);
|
|
138
|
+
}
|
|
139
|
+
function isOnSameLineAsCondition(node2, sourceCode) {
|
|
140
|
+
const tokenBeforeBody = sourceCode.getTokenBefore(node2);
|
|
141
|
+
if (!tokenBeforeBody)
|
|
142
|
+
return false;
|
|
143
|
+
const firstToken = sourceCode.getFirstToken(node2);
|
|
144
|
+
if (!firstToken)
|
|
145
|
+
return false;
|
|
146
|
+
return tokenBeforeBody.loc.end.line === firstToken.loc.start.line;
|
|
147
|
+
}
|
|
148
|
+
function isSingleLineStatement$1(node2, sourceCode) {
|
|
149
|
+
const firstToken = sourceCode.getFirstToken(node2);
|
|
150
|
+
if (!firstToken)
|
|
151
|
+
return false;
|
|
152
|
+
const lastToken = sourceCode.getLastToken(node2);
|
|
153
|
+
if (!lastToken)
|
|
154
|
+
return false;
|
|
155
|
+
return firstToken.loc.start.line === lastToken.loc.end.line;
|
|
156
|
+
}
|
|
157
|
+
function reportBodyOnSameLineAsCondition(context, body) {
|
|
158
|
+
const sourceCode = context.sourceCode;
|
|
159
|
+
if (body.type !== "BlockStatement") {
|
|
160
|
+
if (isOnSameLineAsCondition(body, sourceCode)) {
|
|
161
|
+
context.report({
|
|
162
|
+
fix: (fixer) => createBraceStyleFix(fixer, body, sourceCode),
|
|
163
|
+
messageId: "singleLine",
|
|
164
|
+
node: body
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
} else {
|
|
168
|
+
const isOnSameLine = isOnSameLineAsCondition(body, sourceCode);
|
|
169
|
+
const isSingleLine = isSingleLineStatement$1(body, sourceCode);
|
|
170
|
+
if (isOnSameLine && isSingleLine) {
|
|
171
|
+
context.report({
|
|
172
|
+
fix: (fixer) => createBraceStyleFix(fixer, body, sourceCode),
|
|
173
|
+
messageId: "singleLine",
|
|
174
|
+
node: body
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
function checkDoWhileStatementBraceStyle(node2, context) {
|
|
180
|
+
reportBodyOnSameLineAsCondition(context, node2.body);
|
|
181
|
+
}
|
|
182
|
+
function checkForStatementBraceStyle(node2, context) {
|
|
183
|
+
reportBodyOnSameLineAsCondition(context, node2.body);
|
|
184
|
+
}
|
|
185
|
+
function checkIfStatementBraceStyle(node2, context) {
|
|
186
|
+
const sourceCode = context.sourceCode;
|
|
187
|
+
reportBodyOnSameLineAsCondition(context, node2.consequent);
|
|
188
|
+
if (!node2.alternate)
|
|
189
|
+
return;
|
|
190
|
+
if (node2.alternate.type === "BlockStatement") {
|
|
191
|
+
reportBodyOnSameLineAsCondition(context, node2.alternate);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (node2.alternate.type !== "IfStatement") {
|
|
195
|
+
const alternate = node2.alternate;
|
|
196
|
+
if (isOnSameLineAsCondition(alternate, sourceCode)) {
|
|
197
|
+
context.report({
|
|
198
|
+
fix: (fixer) => createBraceStyleFix(fixer, alternate, sourceCode),
|
|
199
|
+
messageId: "singleLine",
|
|
200
|
+
node: alternate
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
function checkWhileStatementBraceStyle(node2, context) {
|
|
206
|
+
reportBodyOnSameLineAsCondition(context, node2.body);
|
|
207
|
+
}
|
|
208
|
+
const braceStyleControlStatements = {
|
|
209
|
+
create(context) {
|
|
210
|
+
return {
|
|
211
|
+
DoWhileStatement: (node2) => checkDoWhileStatementBraceStyle(node2, context),
|
|
212
|
+
ForStatement: (node2) => checkForStatementBraceStyle(node2, context),
|
|
213
|
+
IfStatement: (node2) => checkIfStatementBraceStyle(node2, context),
|
|
214
|
+
WhileStatement: (node2) => checkWhileStatementBraceStyle(node2, context)
|
|
215
|
+
};
|
|
216
|
+
},
|
|
217
|
+
meta: {
|
|
218
|
+
docs: {
|
|
219
|
+
description: "Enforce control statements to have multi-line body."
|
|
220
|
+
},
|
|
221
|
+
fixable: "code",
|
|
222
|
+
messages: {
|
|
223
|
+
singleLine: "Control statement body must be on a separate line"
|
|
224
|
+
},
|
|
225
|
+
schema: [],
|
|
226
|
+
type: "layout"
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
function checkClosingBrace(sourceCode, context, node2, closingBrace) {
|
|
230
|
+
const lastProperty = node2.properties[node2.properties.length - 1];
|
|
231
|
+
const closingLine = closingBrace.loc.end.line;
|
|
232
|
+
const closingBraceOnOwnLine = lastProperty.loc.end.line < closingLine;
|
|
233
|
+
if (!closingBraceOnOwnLine) {
|
|
234
|
+
context.report({
|
|
235
|
+
fix(fixer) {
|
|
236
|
+
return fixer.replaceTextRange(
|
|
237
|
+
[lastProperty.range[1], closingBrace.range[0]],
|
|
238
|
+
",\n" + getLineIndent$1(sourceCode, lastProperty.loc.end.line)
|
|
239
|
+
);
|
|
240
|
+
},
|
|
241
|
+
loc: closingBrace.loc,
|
|
242
|
+
messageId: "braceOnPropertyLine"
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
function checkNestedObjects(sourceCode, context, node2, checkObjectExpression2) {
|
|
247
|
+
for (const property of node2.properties) {
|
|
248
|
+
if (property.type === "Property" && property.value.type === "ObjectExpression")
|
|
249
|
+
checkObjectExpression2(sourceCode, context, property.value);
|
|
250
|
+
else if (property.type === "SpreadElement" && property.argument.type === "ObjectExpression")
|
|
251
|
+
checkObjectExpression2(sourceCode, context, property.argument);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
function checkOpeningBrace(sourceCode, context, node2, openingBrace) {
|
|
255
|
+
const firstProperty = node2.properties[0];
|
|
256
|
+
const openingLine = openingBrace.loc.start.line;
|
|
257
|
+
const openingBraceOnOwnLine = firstProperty.loc.start.line > openingLine;
|
|
258
|
+
if (!openingBraceOnOwnLine) {
|
|
259
|
+
context.report({
|
|
260
|
+
fix(fixer) {
|
|
261
|
+
return fixer.replaceTextRange(
|
|
262
|
+
[openingBrace.range[1], firstProperty.range[0]],
|
|
263
|
+
"\n" + getLineIndent$1(sourceCode, firstProperty.loc.start.line)
|
|
264
|
+
);
|
|
265
|
+
},
|
|
266
|
+
loc: openingBrace.loc,
|
|
267
|
+
messageId: "braceOnPropertyLine"
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
function checkPropertyOnOwnLine(sourceCode, context, prevPropertyEndLine, property) {
|
|
272
|
+
const propStartLine = property.loc.start.line;
|
|
273
|
+
if (propStartLine === prevPropertyEndLine) {
|
|
274
|
+
context.report({
|
|
275
|
+
fix(fixer) {
|
|
276
|
+
const lastNewLineIndex = sourceCode.getText().lastIndexOf("\n", property.range[0] - 1);
|
|
277
|
+
return fixer.replaceTextRange(
|
|
278
|
+
[lastNewLineIndex, property.range[0]],
|
|
279
|
+
"\n" + getLineIndent$1(sourceCode, property.loc.start.line)
|
|
280
|
+
);
|
|
281
|
+
},
|
|
282
|
+
loc: property.loc,
|
|
283
|
+
messageId: "propertiesOnSameLine"
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
function checkObjectExpression(sourceCode, context, node2) {
|
|
288
|
+
if (node2.properties.length === 0)
|
|
289
|
+
return;
|
|
290
|
+
const openingBrace = sourceCode.getFirstToken(node2);
|
|
291
|
+
const closingBrace = sourceCode.getLastToken(node2);
|
|
292
|
+
if (!openingBrace || !closingBrace)
|
|
293
|
+
return;
|
|
294
|
+
const openingLine = openingBrace.loc.start.line;
|
|
295
|
+
const closingLine = closingBrace.loc.end.line;
|
|
296
|
+
if (openingLine === closingLine)
|
|
297
|
+
return;
|
|
298
|
+
checkOpeningBrace(sourceCode, context, node2, openingBrace);
|
|
299
|
+
let prevPropertyEndLine = node2.properties[0].loc.start.line;
|
|
300
|
+
for (const property of node2.properties) {
|
|
301
|
+
if (property !== node2.properties[0])
|
|
302
|
+
checkPropertyOnOwnLine(sourceCode, context, prevPropertyEndLine, property);
|
|
303
|
+
prevPropertyEndLine = property.loc.end.line;
|
|
304
|
+
}
|
|
305
|
+
checkClosingBrace(sourceCode, context, node2, closingBrace);
|
|
306
|
+
checkNestedObjects(sourceCode, context, node2, checkObjectExpression);
|
|
307
|
+
}
|
|
308
|
+
const messageIds$c = {
|
|
309
|
+
braceOnPropertyLine: "Opening brace should be on its own line",
|
|
310
|
+
propertiesOnSameLine: "Multi-line objects must have each property on its own line"
|
|
311
|
+
};
|
|
312
|
+
const braceStyleObjectLiteral = {
|
|
313
|
+
create(context) {
|
|
314
|
+
const sourceCode = context.sourceCode ?? context.getSourceCode();
|
|
315
|
+
return {
|
|
316
|
+
ObjectExpression(node2) {
|
|
317
|
+
checkObjectExpression(sourceCode, context, node2);
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
},
|
|
321
|
+
meta: {
|
|
322
|
+
docs: {
|
|
323
|
+
description: "Enforce consistent brace positioning for object literals."
|
|
324
|
+
},
|
|
325
|
+
fixable: "code",
|
|
326
|
+
messages: messageIds$c,
|
|
327
|
+
schema: [{
|
|
328
|
+
additionalProperties: false,
|
|
329
|
+
properties: {},
|
|
330
|
+
type: "object"
|
|
331
|
+
}],
|
|
332
|
+
type: "layout"
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
function buildCompactFix(fixer, openingBracket, closingBracket, elements, sourceCode) {
|
|
336
|
+
const nonNullElements = elements.filter(
|
|
337
|
+
(el) => el !== null
|
|
338
|
+
);
|
|
339
|
+
const formattedItems = nonNullElements.map((element) => sourceCode.getText(element)).join(", ");
|
|
340
|
+
const newText = `[${formattedItems}]`;
|
|
341
|
+
return fixer.replaceTextRange(
|
|
342
|
+
[openingBracket.range[0], closingBracket.range[1]],
|
|
343
|
+
newText
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
function findBracketByRange(tokens, range, value) {
|
|
347
|
+
return tokens?.find(
|
|
348
|
+
(t) => t.range[0] === range[0] && t.value === value
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
function findClosingBracketByRange(tokens, range) {
|
|
352
|
+
return tokens?.find(
|
|
353
|
+
(t) => t.range[1] === range[1] && t.value === "]"
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
function hasElements(elements) {
|
|
357
|
+
const nonNull = elements.filter(
|
|
358
|
+
(el) => el !== null
|
|
359
|
+
);
|
|
360
|
+
return nonNull.length >= 1;
|
|
361
|
+
}
|
|
362
|
+
function hasMultilineItems(nonNullElements) {
|
|
363
|
+
return nonNullElements.some(
|
|
364
|
+
(el) => el.loc.start.line !== el.loc.end.line
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
function isBracketOnOwnLine(sourceCode, openingBracket) {
|
|
368
|
+
const nextToken = sourceCode.getTokenAfter(openingBracket, {
|
|
369
|
+
includeComments: false
|
|
370
|
+
});
|
|
371
|
+
if (!nextToken)
|
|
372
|
+
return false;
|
|
373
|
+
const text = sourceCode.getText();
|
|
374
|
+
const openingBracketEndIndex = openingBracket.range[1];
|
|
375
|
+
const textBetween = text.slice(
|
|
376
|
+
openingBracketEndIndex,
|
|
377
|
+
nextToken.range[0]
|
|
378
|
+
);
|
|
379
|
+
return textBetween.includes("\n");
|
|
380
|
+
}
|
|
381
|
+
const messageIds$b = {
|
|
382
|
+
compactItems: "Array items should be compact when the array spans multiple lines."
|
|
383
|
+
};
|
|
384
|
+
const compactArrayItems = {
|
|
385
|
+
create(context) {
|
|
386
|
+
const sourceCode = context.sourceCode ?? context.getSourceCode();
|
|
387
|
+
return {
|
|
388
|
+
ArrayExpression(node2) {
|
|
389
|
+
if (!hasElements(node2.elements))
|
|
390
|
+
return;
|
|
391
|
+
const tokens = sourceCode.ast.tokens;
|
|
392
|
+
const openingBracket = findBracketByRange(tokens, node2.range, "[");
|
|
393
|
+
const closingBracket = findClosingBracketByRange(
|
|
394
|
+
tokens,
|
|
395
|
+
node2.range
|
|
396
|
+
);
|
|
397
|
+
if (!openingBracket || !closingBracket)
|
|
398
|
+
return;
|
|
399
|
+
if (!isBracketOnOwnLine(sourceCode, openingBracket))
|
|
400
|
+
return;
|
|
401
|
+
const nonNullElements = node2.elements.filter(
|
|
402
|
+
(el) => el !== null
|
|
403
|
+
);
|
|
404
|
+
if (!hasMultilineItems(nonNullElements))
|
|
405
|
+
return;
|
|
406
|
+
context.report({
|
|
407
|
+
fix: (fixer) => buildCompactFix(
|
|
408
|
+
fixer,
|
|
409
|
+
openingBracket,
|
|
410
|
+
closingBracket,
|
|
411
|
+
node2.elements,
|
|
412
|
+
sourceCode
|
|
413
|
+
),
|
|
414
|
+
messageId: "compactItems",
|
|
415
|
+
node: node2
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
},
|
|
420
|
+
meta: {
|
|
421
|
+
docs: {
|
|
422
|
+
description: "Enforce arrays with multiline items to have a compact, inline bracket style."
|
|
423
|
+
},
|
|
424
|
+
fixable: "code",
|
|
425
|
+
messages: messageIds$b,
|
|
426
|
+
schema: [],
|
|
427
|
+
type: "layout"
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
function getNameFromDeclaration(node2) {
|
|
431
|
+
const names = [];
|
|
432
|
+
switch (node2.type) {
|
|
433
|
+
case "ClassDeclaration":
|
|
434
|
+
if (node2.id)
|
|
435
|
+
names.push(node2.id.name);
|
|
436
|
+
break;
|
|
437
|
+
case "FunctionDeclaration":
|
|
438
|
+
if (node2.id)
|
|
439
|
+
names.push(node2.id.name);
|
|
440
|
+
break;
|
|
441
|
+
case "TSInterfaceDeclaration":
|
|
442
|
+
names.push(node2.id.name);
|
|
443
|
+
break;
|
|
444
|
+
case "TSTypeAliasDeclaration":
|
|
445
|
+
names.push(node2.id.name);
|
|
446
|
+
break;
|
|
447
|
+
case "VariableDeclaration":
|
|
448
|
+
for (const d of node2.declarations) {
|
|
449
|
+
if (d.id.type === "Identifier")
|
|
450
|
+
names.push(d.id.name);
|
|
451
|
+
}
|
|
452
|
+
break;
|
|
453
|
+
}
|
|
454
|
+
return names;
|
|
455
|
+
}
|
|
456
|
+
function getNamesFromSpecifiers(node2) {
|
|
457
|
+
if (!node2.specifiers?.length)
|
|
458
|
+
return [];
|
|
459
|
+
const names = [];
|
|
460
|
+
for (const specifier of node2.specifiers) {
|
|
461
|
+
if (specifier.exported.type === "Identifier")
|
|
462
|
+
names.push(specifier.exported.name);
|
|
463
|
+
}
|
|
464
|
+
return names;
|
|
465
|
+
}
|
|
466
|
+
function getExportedNames(node2) {
|
|
467
|
+
const specifierNames = getNamesFromSpecifiers(node2);
|
|
468
|
+
if (!node2.declaration)
|
|
469
|
+
return specifierNames;
|
|
470
|
+
const declarationNames = getNameFromDeclaration(node2.declaration);
|
|
471
|
+
return [...specifierNames, ...declarationNames];
|
|
472
|
+
}
|
|
473
|
+
function stripExtension(filename) {
|
|
474
|
+
return path.basename(filename, path.extname(filename));
|
|
475
|
+
}
|
|
476
|
+
function isExempt$2(filename) {
|
|
477
|
+
const name = stripExtension(filename);
|
|
478
|
+
return name === "index" || name.endsWith(".test") || name.endsWith(".spec") || name.endsWith(".config");
|
|
479
|
+
}
|
|
480
|
+
const messageIds$a = {
|
|
481
|
+
filenameMismatch: "File name must be '{{expectedName}}' instead of '{{currentName}}'."
|
|
482
|
+
};
|
|
483
|
+
const exportFilenameMatch = {
|
|
484
|
+
create(context) {
|
|
485
|
+
const fileName = context.filename;
|
|
486
|
+
const baseName = path.basename(fileName);
|
|
487
|
+
const ext = path.extname(baseName);
|
|
488
|
+
const fileNameWithoutExt = baseName.slice(0, -ext.length);
|
|
489
|
+
if (isExempt$2(fileName))
|
|
490
|
+
return {};
|
|
491
|
+
const exportNames = [];
|
|
492
|
+
return {
|
|
493
|
+
ExportNamedDeclaration(node2) {
|
|
494
|
+
const names = getExportedNames(node2);
|
|
495
|
+
exportNames.push(...names);
|
|
496
|
+
},
|
|
497
|
+
"Program:exit"(programNode) {
|
|
498
|
+
if (exportNames.length === 1) {
|
|
499
|
+
const [exportName] = exportNames;
|
|
500
|
+
if (exportName !== fileNameWithoutExt) {
|
|
501
|
+
context.report({
|
|
502
|
+
data: {
|
|
503
|
+
currentName: `${fileNameWithoutExt}${ext}`,
|
|
504
|
+
expectedName: `${exportName}${ext}`
|
|
505
|
+
},
|
|
506
|
+
messageId: "filenameMismatch",
|
|
507
|
+
node: programNode
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
};
|
|
513
|
+
},
|
|
514
|
+
meta: {
|
|
515
|
+
docs: {
|
|
516
|
+
description: "Enforce filename matches the single named export."
|
|
517
|
+
},
|
|
518
|
+
messages: messageIds$a,
|
|
519
|
+
schema: [],
|
|
520
|
+
type: "suggestion"
|
|
521
|
+
}
|
|
522
|
+
};
|
|
523
|
+
function findLinesWithMultipleNodes(nodes) {
|
|
524
|
+
const lines = [];
|
|
525
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
526
|
+
const node2 = nodes[i];
|
|
527
|
+
const nodeLine = node2.loc.start.line;
|
|
528
|
+
if (i < nodes.length - 1) {
|
|
529
|
+
const nextNode = nodes[i + 1];
|
|
530
|
+
if (nextNode.loc.start.line === nodeLine)
|
|
531
|
+
lines.push(nodeLine);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
return lines;
|
|
535
|
+
}
|
|
536
|
+
function formatArgs(sourceCode, nodes, indent) {
|
|
537
|
+
return nodes.map((arg, index) => {
|
|
538
|
+
const argText = sourceCode.getText(arg);
|
|
539
|
+
const isLast = index === nodes.length - 1;
|
|
540
|
+
if (isLast)
|
|
541
|
+
return argText;
|
|
542
|
+
const comma = sourceCode.getTokenAfter(arg, (token) => token.value === ",");
|
|
543
|
+
if (comma && comma.loc.end.line === arg.loc.end.line)
|
|
544
|
+
return argText + ",";
|
|
545
|
+
return argText;
|
|
546
|
+
}).map(
|
|
547
|
+
(text, index) => index === 0 ? `${indent}${text}` : `
|
|
548
|
+
${indent}${text}`
|
|
549
|
+
).join("");
|
|
550
|
+
}
|
|
551
|
+
function getLineStartIndex(sourceCode, line) {
|
|
552
|
+
const lines = sourceCode.getLines();
|
|
553
|
+
return lines.slice(0, line - 1).reduce(
|
|
554
|
+
(acc, l) => acc + l.length + 1,
|
|
555
|
+
0
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
function checkMultilineArgs(sourceCode, context, args, maxLength) {
|
|
559
|
+
const linesWithMultipleArgs = findLinesWithMultipleNodes(args);
|
|
560
|
+
for (const line of linesWithMultipleArgs) {
|
|
561
|
+
const lineLength = getLineLength(sourceCode, line);
|
|
562
|
+
if (lineLength > maxLength) {
|
|
563
|
+
context.report({
|
|
564
|
+
data: { maxLength },
|
|
565
|
+
fix: (fixer) => {
|
|
566
|
+
const nodesOnLine = args.filter(
|
|
567
|
+
(arg) => arg.loc.start.line <= line && arg.loc.end.line >= line
|
|
568
|
+
);
|
|
569
|
+
const lastNode = nodesOnLine[nodesOnLine.length - 1];
|
|
570
|
+
const lineStartIndex = getLineStartIndex(sourceCode, line);
|
|
571
|
+
const baseIndent = sourceCode.getText().match(/^[\t ]*/)?.[0] ?? "";
|
|
572
|
+
const indent = baseIndent + " ";
|
|
573
|
+
const fixed = formatArgs(sourceCode, nodesOnLine, indent);
|
|
574
|
+
return fixer.replaceTextRange(
|
|
575
|
+
[lineStartIndex, lastNode.range[1]],
|
|
576
|
+
fixed
|
|
577
|
+
);
|
|
578
|
+
},
|
|
579
|
+
loc: {
|
|
580
|
+
end: {
|
|
581
|
+
column: lineLength,
|
|
582
|
+
line
|
|
583
|
+
},
|
|
584
|
+
start: {
|
|
585
|
+
column: 0,
|
|
586
|
+
line
|
|
587
|
+
}
|
|
588
|
+
},
|
|
589
|
+
messageId: "multipleOnSameLine"
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
function checkSingleLineArgs(sourceCode, context, args, parens, maxLength) {
|
|
595
|
+
const { closingParen, openingParen } = parens;
|
|
596
|
+
const lineLength = getLineLength(sourceCode, openingParen.loc.start.line);
|
|
597
|
+
if (lineLength <= maxLength)
|
|
598
|
+
return;
|
|
599
|
+
if (args.length === 1) {
|
|
600
|
+
context.report({
|
|
601
|
+
data: { maxLength },
|
|
602
|
+
loc: {
|
|
603
|
+
end: {
|
|
604
|
+
column: lineLength,
|
|
605
|
+
line: closingParen.loc.end.line
|
|
606
|
+
},
|
|
607
|
+
start: {
|
|
608
|
+
column: 0,
|
|
609
|
+
line: openingParen.loc.start.line
|
|
610
|
+
}
|
|
611
|
+
},
|
|
612
|
+
messageId: "exceedsMaxLength"
|
|
613
|
+
});
|
|
614
|
+
return;
|
|
615
|
+
}
|
|
616
|
+
context.report({
|
|
617
|
+
data: { maxLength },
|
|
618
|
+
fix: (fixer) => {
|
|
619
|
+
const indent = sourceCode.getText().match(/^[\t ]*/)?.[0] ?? "";
|
|
620
|
+
const argTexts = args.map((arg) => {
|
|
621
|
+
const argText = sourceCode.getText(arg);
|
|
622
|
+
const comma = sourceCode.getTokenAfter(
|
|
623
|
+
arg,
|
|
624
|
+
(token) => token.value === ","
|
|
625
|
+
);
|
|
626
|
+
if (comma && comma.loc.end.line === arg.loc.end.line)
|
|
627
|
+
return argText + ",";
|
|
628
|
+
return argText;
|
|
629
|
+
});
|
|
630
|
+
const fixed = [
|
|
631
|
+
"(\n",
|
|
632
|
+
`${indent} ${argTexts.join(`
|
|
633
|
+
${indent} `)}
|
|
634
|
+
`,
|
|
635
|
+
`${indent})`
|
|
636
|
+
].join("");
|
|
637
|
+
return fixer.replaceTextRange(
|
|
638
|
+
[openingParen.range[0], closingParen.range[1]],
|
|
639
|
+
fixed
|
|
640
|
+
);
|
|
641
|
+
},
|
|
642
|
+
loc: {
|
|
643
|
+
end: {
|
|
644
|
+
column: lineLength,
|
|
645
|
+
line: closingParen.loc.end.line
|
|
646
|
+
},
|
|
647
|
+
start: {
|
|
648
|
+
column: 0,
|
|
649
|
+
line: openingParen.loc.start.line
|
|
650
|
+
}
|
|
651
|
+
},
|
|
652
|
+
messageId: "multipleOnSameLine"
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
const defaultOptions$5 = {
|
|
656
|
+
maxLength: 80
|
|
657
|
+
};
|
|
658
|
+
function getParens$1(sourceCode, nodes) {
|
|
659
|
+
if (nodes.length === 0)
|
|
660
|
+
return null;
|
|
661
|
+
const firstNode = nodes[0];
|
|
662
|
+
const lastNode = nodes[nodes.length - 1];
|
|
663
|
+
const openingParen = sourceCode.getTokenBefore(firstNode);
|
|
664
|
+
const closingParen = sourceCode.getTokenAfter(lastNode);
|
|
665
|
+
if (!openingParen || !closingParen)
|
|
666
|
+
return null;
|
|
667
|
+
return { closingParen, openingParen };
|
|
668
|
+
}
|
|
669
|
+
function isValidParens(parens) {
|
|
670
|
+
if (!parens)
|
|
671
|
+
return false;
|
|
672
|
+
return parens.openingParen.value === "(" && parens.closingParen.value === ")";
|
|
673
|
+
}
|
|
674
|
+
function checkCall(sourceCode, context, node2) {
|
|
675
|
+
const options = context.options[0] ?? {};
|
|
676
|
+
const maxLength = options.maxLength ?? defaultOptions$5.maxLength;
|
|
677
|
+
const args = node2.arguments;
|
|
678
|
+
const parens = getParens$1(sourceCode, args);
|
|
679
|
+
if (!isValidParens(parens))
|
|
680
|
+
return;
|
|
681
|
+
const firstLine = parens.openingParen.loc.start.line;
|
|
682
|
+
const lastLine = parens.closingParen.loc.end.line;
|
|
683
|
+
if (firstLine === lastLine)
|
|
684
|
+
checkSingleLineArgs(sourceCode, context, args, parens, maxLength);
|
|
685
|
+
else
|
|
686
|
+
checkMultilineArgs(sourceCode, context, args, maxLength);
|
|
687
|
+
}
|
|
688
|
+
const messageIds$9 = {
|
|
689
|
+
exceedsMaxLength: "Refactor this function call as it exceeds {{maxLength}} characters",
|
|
690
|
+
multipleOnSameLine: "Each argument must be on its own line"
|
|
691
|
+
};
|
|
692
|
+
const functionCallArgumentLineBreak = {
|
|
693
|
+
create(context) {
|
|
694
|
+
const sourceCode = context.sourceCode ?? context.getSourceCode();
|
|
695
|
+
return {
|
|
696
|
+
CallExpression(node2) {
|
|
697
|
+
checkCall(sourceCode, context, node2);
|
|
698
|
+
},
|
|
699
|
+
OptionalCallExpression(node2) {
|
|
700
|
+
checkCall(sourceCode, context, node2);
|
|
701
|
+
}
|
|
702
|
+
};
|
|
703
|
+
},
|
|
704
|
+
meta: {
|
|
705
|
+
docs: {
|
|
706
|
+
description: "Enforce each function call argument to be on its own line when line exceeds max length."
|
|
707
|
+
},
|
|
708
|
+
fixable: "code",
|
|
709
|
+
messages: messageIds$9,
|
|
710
|
+
schema: [{
|
|
711
|
+
additionalProperties: false,
|
|
712
|
+
properties: {
|
|
713
|
+
maxLength: {
|
|
714
|
+
type: "number"
|
|
715
|
+
}
|
|
716
|
+
},
|
|
717
|
+
type: "object"
|
|
718
|
+
}],
|
|
719
|
+
type: "layout"
|
|
720
|
+
}
|
|
721
|
+
};
|
|
722
|
+
function isNodeWithType(value) {
|
|
723
|
+
return value !== null && typeof value === "object" && "type" in value;
|
|
724
|
+
}
|
|
725
|
+
const SKIP_KEYS = /* @__PURE__ */ new Set(["loc", "parent", "range"]);
|
|
726
|
+
function getChildNodes(node2) {
|
|
727
|
+
const children = [];
|
|
728
|
+
for (const key of Object.keys(node2)) {
|
|
729
|
+
if (SKIP_KEYS.has(key))
|
|
730
|
+
continue;
|
|
731
|
+
const value = node2[key];
|
|
732
|
+
if (Array.isArray(value)) {
|
|
733
|
+
for (const item of value) {
|
|
734
|
+
if (isNodeWithType(item))
|
|
735
|
+
children.push(item);
|
|
736
|
+
}
|
|
737
|
+
} else if (isNodeWithType(value))
|
|
738
|
+
children.push(value);
|
|
739
|
+
}
|
|
740
|
+
return children;
|
|
741
|
+
}
|
|
742
|
+
const INCREMENTABLE_TYPES = /* @__PURE__ */ new Set([
|
|
743
|
+
"ConditionalExpression",
|
|
744
|
+
"DoWhileStatement",
|
|
745
|
+
"ForInStatement",
|
|
746
|
+
"ForOfStatement",
|
|
747
|
+
"ForStatement",
|
|
748
|
+
"IfStatement",
|
|
749
|
+
"LogicalExpression",
|
|
750
|
+
"SwitchStatement",
|
|
751
|
+
"TryStatement",
|
|
752
|
+
"WhileStatement"
|
|
753
|
+
]);
|
|
754
|
+
function isIncrementableControlFlow(node2) {
|
|
755
|
+
return INCREMENTABLE_TYPES.has(node2.type);
|
|
756
|
+
}
|
|
757
|
+
function traverse(node2, nestingLevel, state) {
|
|
758
|
+
if (isIncrementableControlFlow(node2)) {
|
|
759
|
+
state.complexity += 1 + nestingLevel;
|
|
760
|
+
nestingLevel++;
|
|
761
|
+
}
|
|
762
|
+
const children = getChildNodes(node2);
|
|
763
|
+
for (const child of children)
|
|
764
|
+
traverse(child, nestingLevel, state);
|
|
765
|
+
}
|
|
766
|
+
function calculateCognitiveComplexity(node2) {
|
|
767
|
+
const state = {
|
|
768
|
+
complexity: 0
|
|
769
|
+
};
|
|
770
|
+
const children = getChildNodes(node2);
|
|
771
|
+
for (const child of children)
|
|
772
|
+
traverse(child, 0, state);
|
|
773
|
+
return state.complexity;
|
|
774
|
+
}
|
|
775
|
+
function getNameFromCallExpression(node2) {
|
|
776
|
+
if (node2?.type === "CallExpression" && node2.callee?.type === "Identifier")
|
|
777
|
+
return `${node2.callee.name} callback`;
|
|
778
|
+
return null;
|
|
779
|
+
}
|
|
780
|
+
function getNameFromProperty(node2) {
|
|
781
|
+
if (node2?.type === "Property" && node2.key?.type === "Identifier")
|
|
782
|
+
return node2.key.name;
|
|
783
|
+
return null;
|
|
784
|
+
}
|
|
785
|
+
function getNameFromVariableDeclarator(node2) {
|
|
786
|
+
if (node2?.type === "VariableDeclarator" && node2.id?.type === "Identifier")
|
|
787
|
+
return node2.id.name;
|
|
788
|
+
return null;
|
|
789
|
+
}
|
|
790
|
+
function getArrowFunctionExpressionName(node2) {
|
|
791
|
+
const parent = node2.parent;
|
|
792
|
+
const nameFromVar = getNameFromVariableDeclarator(parent);
|
|
793
|
+
if (nameFromVar)
|
|
794
|
+
return nameFromVar;
|
|
795
|
+
const nameFromProp = getNameFromProperty(parent);
|
|
796
|
+
if (nameFromProp)
|
|
797
|
+
return nameFromProp;
|
|
798
|
+
const nameFromCall = getNameFromCallExpression(parent);
|
|
799
|
+
if (nameFromCall)
|
|
800
|
+
return nameFromCall;
|
|
801
|
+
return null;
|
|
802
|
+
}
|
|
803
|
+
function getNameFromMethodDefinition(node2) {
|
|
804
|
+
if (node2?.type === "MethodDefinition" && node2.key?.type === "Identifier")
|
|
805
|
+
return node2.key.name;
|
|
806
|
+
return null;
|
|
807
|
+
}
|
|
808
|
+
function getFunctionExpressionName(node2) {
|
|
809
|
+
const parent = node2.parent;
|
|
810
|
+
const nameFromVar = getNameFromVariableDeclarator(parent);
|
|
811
|
+
if (nameFromVar)
|
|
812
|
+
return nameFromVar;
|
|
813
|
+
const nameFromProp = getNameFromProperty(parent);
|
|
814
|
+
if (nameFromProp)
|
|
815
|
+
return nameFromProp;
|
|
816
|
+
const nameFromMethod = getNameFromMethodDefinition(parent);
|
|
817
|
+
if (nameFromMethod)
|
|
818
|
+
return nameFromMethod;
|
|
819
|
+
return null;
|
|
820
|
+
}
|
|
821
|
+
function getFunctionName$1(node2) {
|
|
822
|
+
if (node2.type === "FunctionDeclaration" && node2.id?.name)
|
|
823
|
+
return node2.id.name;
|
|
824
|
+
if (node2.type === "FunctionExpression")
|
|
825
|
+
return getFunctionExpressionName(node2);
|
|
826
|
+
if (node2.type === "ArrowFunctionExpression")
|
|
827
|
+
return getArrowFunctionExpressionName(node2);
|
|
828
|
+
return null;
|
|
829
|
+
}
|
|
830
|
+
const messageIds$8 = {
|
|
831
|
+
tooHighCognitiveComplexity: "Function '{{name}}' has cognitive complexity of {{actual}} (max: {{max}}). Consider extracting sub-functions.",
|
|
832
|
+
tooHighCognitiveComplexityAnonymous: "Anonymous function has cognitive complexity of {{actual}} (max: {{max}}). Consider extracting sub-functions."
|
|
833
|
+
};
|
|
834
|
+
const DEFAULT_MAX_COGNITIVE_COMPLEXITY = 15;
|
|
835
|
+
const functionCognitiveComplexity = {
|
|
836
|
+
create(context) {
|
|
837
|
+
const options = context.options[0] ?? {};
|
|
838
|
+
const maxCognitiveComplexity = options.maxCognitiveComplexity ?? DEFAULT_MAX_COGNITIVE_COMPLEXITY;
|
|
839
|
+
function checkFunction2(node2) {
|
|
840
|
+
const complexity = calculateCognitiveComplexity(node2);
|
|
841
|
+
if (complexity > maxCognitiveComplexity) {
|
|
842
|
+
const name = getFunctionName$1(node2);
|
|
843
|
+
if (name) {
|
|
844
|
+
context.report({
|
|
845
|
+
data: {
|
|
846
|
+
actual: complexity,
|
|
847
|
+
max: maxCognitiveComplexity,
|
|
848
|
+
name
|
|
849
|
+
},
|
|
850
|
+
messageId: "tooHighCognitiveComplexity",
|
|
851
|
+
node: node2
|
|
852
|
+
});
|
|
853
|
+
} else {
|
|
854
|
+
context.report({
|
|
855
|
+
data: {
|
|
856
|
+
actual: complexity,
|
|
857
|
+
max: maxCognitiveComplexity
|
|
858
|
+
},
|
|
859
|
+
messageId: "tooHighCognitiveComplexityAnonymous",
|
|
860
|
+
node: node2
|
|
861
|
+
});
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
return {
|
|
866
|
+
ArrowFunctionExpression(node2) {
|
|
867
|
+
checkFunction2(node2);
|
|
868
|
+
},
|
|
869
|
+
FunctionDeclaration(node2) {
|
|
870
|
+
checkFunction2(node2);
|
|
871
|
+
},
|
|
872
|
+
FunctionExpression(node2) {
|
|
873
|
+
checkFunction2(node2);
|
|
874
|
+
}
|
|
875
|
+
};
|
|
876
|
+
},
|
|
877
|
+
meta: {
|
|
878
|
+
docs: {
|
|
879
|
+
description: "Enforce cognitive complexity threshold for functions."
|
|
880
|
+
},
|
|
881
|
+
messages: messageIds$8,
|
|
882
|
+
schema: [{
|
|
883
|
+
additionalProperties: false,
|
|
884
|
+
properties: {
|
|
885
|
+
maxCognitiveComplexity: {
|
|
886
|
+
type: "number"
|
|
887
|
+
}
|
|
888
|
+
},
|
|
889
|
+
type: "object"
|
|
890
|
+
}],
|
|
891
|
+
type: "suggestion"
|
|
892
|
+
}
|
|
893
|
+
};
|
|
894
|
+
function formatParams(sourceCode, nodes, indent) {
|
|
895
|
+
return nodes.map((param, index) => {
|
|
896
|
+
const paramText = sourceCode.getText(param);
|
|
897
|
+
const isLast = index === nodes.length - 1;
|
|
898
|
+
if (isLast)
|
|
899
|
+
return paramText;
|
|
900
|
+
const comma = sourceCode.getTokenAfter(
|
|
901
|
+
param,
|
|
902
|
+
(token) => token.value === ","
|
|
903
|
+
);
|
|
904
|
+
if (comma && comma.loc.end.line === param.loc.end.line)
|
|
905
|
+
return paramText + ",";
|
|
906
|
+
return paramText;
|
|
907
|
+
}).map(
|
|
908
|
+
(text, index) => index === 0 ? `${indent}${text}` : `
|
|
909
|
+
${indent}${text}`
|
|
910
|
+
).join("");
|
|
911
|
+
}
|
|
912
|
+
function checkMultilineParams(sourceCode, context, params, parens, maxLength) {
|
|
913
|
+
const linesWithMultipleParams = findLinesWithMultipleNodes(params);
|
|
914
|
+
for (const line of linesWithMultipleParams) {
|
|
915
|
+
const lineLength = getLineLength(sourceCode, line);
|
|
916
|
+
if (lineLength > maxLength) {
|
|
917
|
+
context.report({
|
|
918
|
+
data: { maxLength },
|
|
919
|
+
fix: (fixer) => {
|
|
920
|
+
const nodesOnLine = params.filter(
|
|
921
|
+
(param) => param.loc.start.line <= line && param.loc.end.line >= line
|
|
922
|
+
);
|
|
923
|
+
const lastNode = nodesOnLine[nodesOnLine.length - 1];
|
|
924
|
+
const lineStartIndex = getLineStartIndex(sourceCode, line);
|
|
925
|
+
const baseIndent = sourceCode.getText().match(/^[\t ]*/)?.[0] ?? "";
|
|
926
|
+
const indent = baseIndent + " ";
|
|
927
|
+
const fixed = formatParams(sourceCode, nodesOnLine, indent);
|
|
928
|
+
return fixer.replaceTextRange(
|
|
929
|
+
[lineStartIndex, lastNode.range[1]],
|
|
930
|
+
fixed
|
|
931
|
+
);
|
|
932
|
+
},
|
|
933
|
+
loc: {
|
|
934
|
+
end: {
|
|
935
|
+
column: lineLength,
|
|
936
|
+
line
|
|
937
|
+
},
|
|
938
|
+
start: {
|
|
939
|
+
column: 0,
|
|
940
|
+
line
|
|
941
|
+
}
|
|
942
|
+
},
|
|
943
|
+
messageId: "multipleOnSameLine"
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
function checkSingleLineParams(sourceCode, context, params, parens, maxLength) {
|
|
949
|
+
const { closingParen, openingParen } = parens;
|
|
950
|
+
const lineLength = getLineLength(sourceCode, openingParen.loc.start.line);
|
|
951
|
+
if (lineLength <= maxLength)
|
|
952
|
+
return;
|
|
953
|
+
if (params.length === 1) {
|
|
954
|
+
context.report({
|
|
955
|
+
data: { maxLength },
|
|
956
|
+
loc: {
|
|
957
|
+
end: {
|
|
958
|
+
column: lineLength,
|
|
959
|
+
line: closingParen.loc.end.line
|
|
960
|
+
},
|
|
961
|
+
start: {
|
|
962
|
+
column: 0,
|
|
963
|
+
line: openingParen.loc.start.line
|
|
964
|
+
}
|
|
965
|
+
},
|
|
966
|
+
messageId: "exceedsMaxLength"
|
|
967
|
+
});
|
|
968
|
+
return;
|
|
969
|
+
}
|
|
970
|
+
context.report({
|
|
971
|
+
data: { maxLength },
|
|
972
|
+
fix: (fixer) => {
|
|
973
|
+
const indent = sourceCode.getText().match(/^[\t ]*/)?.[0] ?? "";
|
|
974
|
+
const paramTexts = params.map((param) => {
|
|
975
|
+
const paramText = sourceCode.getText(param);
|
|
976
|
+
const comma = sourceCode.getTokenAfter(
|
|
977
|
+
param,
|
|
978
|
+
(token) => token.value === ","
|
|
979
|
+
);
|
|
980
|
+
if (comma && comma.loc.end.line === param.loc.end.line)
|
|
981
|
+
return paramText + ",";
|
|
982
|
+
return paramText;
|
|
983
|
+
});
|
|
984
|
+
const fixed = [
|
|
985
|
+
"(\n",
|
|
986
|
+
`${indent} ${paramTexts.join(`
|
|
987
|
+
${indent} `)}
|
|
988
|
+
`,
|
|
989
|
+
`${indent})`
|
|
990
|
+
].join("");
|
|
991
|
+
return fixer.replaceTextRange(
|
|
992
|
+
[openingParen.range[0], closingParen.range[1]],
|
|
993
|
+
fixed
|
|
994
|
+
);
|
|
995
|
+
},
|
|
996
|
+
loc: {
|
|
997
|
+
end: {
|
|
998
|
+
column: lineLength,
|
|
999
|
+
line: closingParen.loc.end.line
|
|
1000
|
+
},
|
|
1001
|
+
start: {
|
|
1002
|
+
column: 0,
|
|
1003
|
+
line: openingParen.loc.start.line
|
|
1004
|
+
}
|
|
1005
|
+
},
|
|
1006
|
+
messageId: "multipleOnSameLine"
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1009
|
+
const defaultOptions$4 = {
|
|
1010
|
+
maxLength: 80
|
|
1011
|
+
};
|
|
1012
|
+
function checkFunction$1(sourceCode, context, node2) {
|
|
1013
|
+
const options = context.options[0] ?? {};
|
|
1014
|
+
const maxLength = options.maxLength ?? defaultOptions$4.maxLength;
|
|
1015
|
+
const params = node2.params;
|
|
1016
|
+
if (params.length === 0)
|
|
1017
|
+
return;
|
|
1018
|
+
const parens = getParens$1(sourceCode, params);
|
|
1019
|
+
if (!isValidParens(parens))
|
|
1020
|
+
return;
|
|
1021
|
+
const firstLine = parens.openingParen.loc.start.line;
|
|
1022
|
+
const lastLine = parens.closingParen.loc.end.line;
|
|
1023
|
+
if (firstLine === lastLine)
|
|
1024
|
+
checkSingleLineParams(sourceCode, context, params, parens, maxLength);
|
|
1025
|
+
else
|
|
1026
|
+
checkMultilineParams(sourceCode, context, params, parens, maxLength);
|
|
1027
|
+
}
|
|
1028
|
+
const messageIds$7 = {
|
|
1029
|
+
exceedsMaxLength: "Refactor this function signature as it exceeds {{maxLength}} characters",
|
|
1030
|
+
multipleOnSameLine: "Each parameter must be on its own line"
|
|
1031
|
+
};
|
|
1032
|
+
const functionParameterLineBreak = {
|
|
1033
|
+
create(context) {
|
|
1034
|
+
const sourceCode = context.sourceCode ?? context.getSourceCode();
|
|
1035
|
+
return {
|
|
1036
|
+
ArrowFunctionExpression(node2) {
|
|
1037
|
+
if (node2.expression)
|
|
1038
|
+
return;
|
|
1039
|
+
checkFunction$1(sourceCode, context, node2);
|
|
1040
|
+
},
|
|
1041
|
+
FunctionDeclaration(node2) {
|
|
1042
|
+
checkFunction$1(sourceCode, context, node2);
|
|
1043
|
+
},
|
|
1044
|
+
FunctionExpression(node2) {
|
|
1045
|
+
checkFunction$1(sourceCode, context, node2);
|
|
1046
|
+
},
|
|
1047
|
+
TSCallSignatureDeclaration(node2) {
|
|
1048
|
+
checkFunction$1(sourceCode, context, node2);
|
|
1049
|
+
},
|
|
1050
|
+
TSFunctionType(node2) {
|
|
1051
|
+
checkFunction$1(sourceCode, context, node2);
|
|
1052
|
+
},
|
|
1053
|
+
TSMethodSignature(node2) {
|
|
1054
|
+
checkFunction$1(sourceCode, context, node2);
|
|
1055
|
+
}
|
|
1056
|
+
};
|
|
1057
|
+
},
|
|
1058
|
+
meta: {
|
|
1059
|
+
docs: {
|
|
1060
|
+
description: "Enforce each function parameter to be on its own line when line exceeds max length."
|
|
1061
|
+
},
|
|
1062
|
+
fixable: "code",
|
|
1063
|
+
messages: messageIds$7,
|
|
1064
|
+
schema: [{
|
|
1065
|
+
additionalProperties: false,
|
|
1066
|
+
properties: {
|
|
1067
|
+
maxLength: {
|
|
1068
|
+
type: "number"
|
|
1069
|
+
}
|
|
1070
|
+
},
|
|
1071
|
+
type: "object"
|
|
1072
|
+
}],
|
|
1073
|
+
type: "layout"
|
|
1074
|
+
}
|
|
1075
|
+
};
|
|
7
1076
|
function getStatementType(statement) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1077
|
+
if (statement.type === "ImportDeclaration")
|
|
1078
|
+
return "import";
|
|
1079
|
+
if (statement.type === "ExportAllDeclaration")
|
|
1080
|
+
return "re-export";
|
|
1081
|
+
if (statement.type === "ExportNamedDeclaration") {
|
|
1082
|
+
if (statement.source !== null)
|
|
1083
|
+
return "re-export";
|
|
1084
|
+
}
|
|
1085
|
+
return "other";
|
|
1086
|
+
}
|
|
17
1087
|
function isImportDeclaration(statement) {
|
|
18
|
-
|
|
1088
|
+
return statement.type === "ImportDeclaration";
|
|
19
1089
|
}
|
|
20
|
-
//#endregion
|
|
21
|
-
//#region src/rules/importsAndReExportsAtTop/isReExport.ts
|
|
22
1090
|
function isReExport(statement) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
1091
|
+
if (statement.type === "ExportAllDeclaration")
|
|
1092
|
+
return true;
|
|
1093
|
+
if (statement.type === "ExportNamedDeclaration")
|
|
1094
|
+
return statement.source !== null;
|
|
1095
|
+
return false;
|
|
26
1096
|
}
|
|
27
|
-
//#endregion
|
|
28
|
-
//#region src/rules/importsAndReExportsAtTop/categorizeStatements.ts
|
|
29
1097
|
function categorizeStatements(statements) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
1098
|
+
const result = {
|
|
1099
|
+
imports: [],
|
|
1100
|
+
other: [],
|
|
1101
|
+
reExports: []
|
|
1102
|
+
};
|
|
1103
|
+
for (const statement of statements) {
|
|
1104
|
+
const type = getStatementType(statement);
|
|
1105
|
+
if (type === "import" && isImportDeclaration(statement))
|
|
1106
|
+
result.imports.push(statement);
|
|
1107
|
+
else if (type === "re-export" && isReExport(statement))
|
|
1108
|
+
result.reExports.push(statement);
|
|
1109
|
+
else
|
|
1110
|
+
result.other.push(statement);
|
|
1111
|
+
}
|
|
1112
|
+
return result;
|
|
1113
|
+
}
|
|
45
1114
|
function findStatementIndices(statements) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
//#endregion
|
|
62
|
-
//#region src/rules/importsAndReExportsAtTop/generateSortedText.ts
|
|
1115
|
+
let firstRegularStatement = -1;
|
|
1116
|
+
let lastImport = -1;
|
|
1117
|
+
let lastReExport = -1;
|
|
1118
|
+
for (let i = 0; i < statements.length; i++) {
|
|
1119
|
+
const type = getStatementType(statements[i]);
|
|
1120
|
+
if (type === "import")
|
|
1121
|
+
lastImport = i;
|
|
1122
|
+
else if (type === "re-export")
|
|
1123
|
+
lastReExport = i;
|
|
1124
|
+
else if (type === "other" && firstRegularStatement === -1)
|
|
1125
|
+
firstRegularStatement = i;
|
|
1126
|
+
}
|
|
1127
|
+
return { firstRegularStatement, lastImport, lastReExport };
|
|
1128
|
+
}
|
|
63
1129
|
function generateSortedText(context, categories) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
1130
|
+
const allStatements = [
|
|
1131
|
+
...categories.imports,
|
|
1132
|
+
...categories.reExports,
|
|
1133
|
+
...categories.other
|
|
1134
|
+
];
|
|
1135
|
+
return allStatements.map(
|
|
1136
|
+
(node2) => context.sourceCode.getText(node2)
|
|
1137
|
+
).join("\n");
|
|
1138
|
+
}
|
|
1139
|
+
function hasImportOrderViolation(indices, categories) {
|
|
1140
|
+
const { firstRegularStatement, lastImport, lastReExport } = indices;
|
|
1141
|
+
if (categories.imports.length === 0 && categories.reExports.length === 0)
|
|
1142
|
+
return false;
|
|
1143
|
+
const hasImportAfterRegularStatement = categories.imports.length > 0 && firstRegularStatement !== -1 && lastImport > firstRegularStatement;
|
|
1144
|
+
const hasReExportAfterRegularStatement = categories.reExports.length > 0 && firstRegularStatement !== -1 && lastReExport > firstRegularStatement;
|
|
1145
|
+
return hasImportAfterRegularStatement || hasReExportAfterRegularStatement;
|
|
1146
|
+
}
|
|
81
1147
|
const importsAndReExportsAtTop = {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
|
|
1148
|
+
create(context) {
|
|
1149
|
+
return {
|
|
1150
|
+
Program(node2) {
|
|
1151
|
+
const statements = node2.body;
|
|
1152
|
+
const categories = categorizeStatements(statements);
|
|
1153
|
+
const indices = findStatementIndices(statements);
|
|
1154
|
+
if (!hasImportOrderViolation(indices, categories))
|
|
1155
|
+
return;
|
|
1156
|
+
context.report({
|
|
1157
|
+
fix(fixer) {
|
|
1158
|
+
const sortedText = generateSortedText(context, categories);
|
|
1159
|
+
return fixer.replaceText(node2, sortedText);
|
|
1160
|
+
},
|
|
1161
|
+
messageId: "importsAndReExportsAtTop",
|
|
1162
|
+
node: node2
|
|
1163
|
+
});
|
|
1164
|
+
}
|
|
1165
|
+
};
|
|
1166
|
+
},
|
|
1167
|
+
meta: {
|
|
1168
|
+
docs: {
|
|
1169
|
+
description: "Enforce imports and re-exports at the top of the file."
|
|
1170
|
+
},
|
|
1171
|
+
fixable: "code",
|
|
1172
|
+
messages: {
|
|
1173
|
+
importsAndReExportsAtTop: "Imports and re-exports should be at the top of the file."
|
|
1174
|
+
},
|
|
1175
|
+
schema: [],
|
|
1176
|
+
type: "suggestion"
|
|
1177
|
+
}
|
|
1178
|
+
};
|
|
107
1179
|
const individualImports = {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
1180
|
+
create(context) {
|
|
1181
|
+
return {
|
|
1182
|
+
ImportDeclaration(node2) {
|
|
1183
|
+
if (node2.specifiers.length <= 1)
|
|
1184
|
+
return;
|
|
1185
|
+
context.report({
|
|
1186
|
+
fix(fixer) {
|
|
1187
|
+
const source = node2.source.raw;
|
|
1188
|
+
const specifiers = node2.specifiers.filter((s) => s.type === "ImportSpecifier").map((s) => `import {${s.local.name}} from ${source}`).join("\n");
|
|
1189
|
+
return fixer.replaceText(node2, specifiers);
|
|
1190
|
+
},
|
|
1191
|
+
messageId: "individualImports",
|
|
1192
|
+
node: node2
|
|
1193
|
+
});
|
|
1194
|
+
}
|
|
1195
|
+
};
|
|
1196
|
+
},
|
|
1197
|
+
meta: {
|
|
1198
|
+
docs: {
|
|
1199
|
+
description: "Enforce individual imports instead of grouped imports."
|
|
1200
|
+
},
|
|
1201
|
+
fixable: "code",
|
|
1202
|
+
messages: {
|
|
1203
|
+
individualImports: "Use individual imports instead of grouped imports."
|
|
1204
|
+
},
|
|
1205
|
+
schema: [],
|
|
1206
|
+
type: "suggestion"
|
|
1207
|
+
}
|
|
1208
|
+
};
|
|
132
1209
|
const individualReExports = {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
function
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
|
|
1210
|
+
create(context) {
|
|
1211
|
+
return {
|
|
1212
|
+
ExportNamedDeclaration(node2) {
|
|
1213
|
+
if (!node2.source || node2.specifiers.length <= 1)
|
|
1214
|
+
return;
|
|
1215
|
+
context.report({
|
|
1216
|
+
fix(fixer) {
|
|
1217
|
+
const source = node2.source.value;
|
|
1218
|
+
const typeKeyword = node2.exportKind === "type" ? "type " : "";
|
|
1219
|
+
const specifiers = node2.specifiers.map((s) => {
|
|
1220
|
+
const localName = s.local.type === "Identifier" ? s.local.name : s.local.value;
|
|
1221
|
+
const exportedName = s.exported.type === "Identifier" ? s.exported.name : s.exported.value;
|
|
1222
|
+
const name = localName === exportedName ? localName : `${localName} as ${exportedName}`;
|
|
1223
|
+
return `export ${typeKeyword}{${name}} from '${source}'`;
|
|
1224
|
+
}).join("\n");
|
|
1225
|
+
return fixer.replaceText(node2, specifiers);
|
|
1226
|
+
},
|
|
1227
|
+
messageId: "individualReExports",
|
|
1228
|
+
node: node2
|
|
1229
|
+
});
|
|
1230
|
+
}
|
|
1231
|
+
};
|
|
1232
|
+
},
|
|
1233
|
+
meta: {
|
|
1234
|
+
docs: {
|
|
1235
|
+
description: "Enforce individual exports instead of grouped exports."
|
|
1236
|
+
},
|
|
1237
|
+
fixable: "code",
|
|
1238
|
+
messages: {
|
|
1239
|
+
individualReExports: "Use individual exports instead of grouped exports."
|
|
1240
|
+
},
|
|
1241
|
+
schema: [],
|
|
1242
|
+
type: "suggestion"
|
|
1243
|
+
}
|
|
1244
|
+
};
|
|
1245
|
+
function formatTypeLiteral(sourceCode, typeLiteral, baseIndent) {
|
|
1246
|
+
const members = typeLiteral.members;
|
|
1247
|
+
if (members.length === 0)
|
|
1248
|
+
return "{}";
|
|
1249
|
+
const memberTexts = members.map((member) => {
|
|
1250
|
+
if (member.type === "TSPropertySignature") {
|
|
1251
|
+
const memberText = sourceCode.getText(member);
|
|
1252
|
+
return memberText.replace(/,\s*$/, "");
|
|
1253
|
+
}
|
|
1254
|
+
return sourceCode.getText(member).replace(/,\s*$/, "");
|
|
1255
|
+
});
|
|
1256
|
+
const innerIndent = baseIndent + " ";
|
|
1257
|
+
const lines = [
|
|
1258
|
+
"{",
|
|
1259
|
+
innerIndent + memberTexts.join(`
|
|
1260
|
+
${innerIndent}`),
|
|
1261
|
+
`${baseIndent}}`
|
|
1262
|
+
];
|
|
1263
|
+
return lines.join("\n");
|
|
1264
|
+
}
|
|
1265
|
+
function checkMultilineMembers(sourceCode, context, members, maxLength) {
|
|
1266
|
+
for (const member of members) {
|
|
1267
|
+
const memberLine = member.loc.start.line;
|
|
1268
|
+
const lineLength = getLineLength(sourceCode, memberLine);
|
|
1269
|
+
if (lineLength > maxLength) {
|
|
1270
|
+
let fix;
|
|
1271
|
+
if (member.type === "TSPropertySignature" && member.typeAnnotation && member.typeAnnotation.typeAnnotation.type === "TSTypeLiteral") {
|
|
1272
|
+
const typeLiteral = member.typeAnnotation.typeAnnotation;
|
|
1273
|
+
fix = (fixer) => {
|
|
1274
|
+
const baseIndent = getLineIndent$1(sourceCode, memberLine);
|
|
1275
|
+
const formatted = formatTypeLiteral(
|
|
1276
|
+
sourceCode,
|
|
1277
|
+
typeLiteral,
|
|
1278
|
+
baseIndent
|
|
1279
|
+
);
|
|
1280
|
+
return fixer.replaceText(typeLiteral, formatted);
|
|
1281
|
+
};
|
|
1282
|
+
}
|
|
1283
|
+
context.report({
|
|
1284
|
+
data: { maxLength },
|
|
1285
|
+
fix,
|
|
1286
|
+
loc: {
|
|
1287
|
+
end: {
|
|
1288
|
+
column: lineLength,
|
|
1289
|
+
line: memberLine
|
|
1290
|
+
},
|
|
1291
|
+
start: {
|
|
1292
|
+
column: 0,
|
|
1293
|
+
line: memberLine
|
|
1294
|
+
}
|
|
1295
|
+
},
|
|
1296
|
+
messageId: "exceedsMaxLength"
|
|
1297
|
+
});
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
function checkSingleLineMembers(sourceCode, context, members, parens, maxLength) {
|
|
1302
|
+
const { closingBrace, openingBrace } = parens;
|
|
1303
|
+
const lineLength = getLineLength(sourceCode, openingBrace.loc.start.line);
|
|
1304
|
+
if (lineLength <= maxLength)
|
|
1305
|
+
return;
|
|
1306
|
+
if (members.length === 1) {
|
|
1307
|
+
context.report({
|
|
1308
|
+
data: { maxLength },
|
|
1309
|
+
loc: {
|
|
1310
|
+
end: {
|
|
1311
|
+
column: lineLength,
|
|
1312
|
+
line: closingBrace.loc.end.line
|
|
1313
|
+
},
|
|
1314
|
+
start: {
|
|
1315
|
+
column: 0,
|
|
1316
|
+
line: openingBrace.loc.start.line
|
|
1317
|
+
}
|
|
1318
|
+
},
|
|
1319
|
+
messageId: "exceedsMaxLength"
|
|
1320
|
+
});
|
|
1321
|
+
return;
|
|
1322
|
+
}
|
|
1323
|
+
context.report({
|
|
1324
|
+
data: { maxLength },
|
|
1325
|
+
fix: (fixer) => {
|
|
1326
|
+
const indent = sourceCode.getText().match(/^[\t ]*/)?.[0] ?? "";
|
|
1327
|
+
const memberTexts = members.map((member, index) => {
|
|
1328
|
+
const memberText = sourceCode.getText(member).replace(/,\s*$/, "");
|
|
1329
|
+
const isLast = index === members.length - 1;
|
|
1330
|
+
if (!isLast)
|
|
1331
|
+
return memberText + ",";
|
|
1332
|
+
return memberText;
|
|
1333
|
+
});
|
|
1334
|
+
const fixed = [
|
|
1335
|
+
"{\n",
|
|
1336
|
+
`${indent} ${memberTexts.join(`
|
|
1337
|
+
${indent} `)}
|
|
1338
|
+
`,
|
|
1339
|
+
`${indent}}`
|
|
1340
|
+
].join("");
|
|
1341
|
+
return fixer.replaceTextRange(
|
|
1342
|
+
[openingBrace.range[0], closingBrace.range[1]],
|
|
1343
|
+
fixed
|
|
1344
|
+
);
|
|
1345
|
+
},
|
|
1346
|
+
loc: {
|
|
1347
|
+
end: {
|
|
1348
|
+
column: lineLength,
|
|
1349
|
+
line: closingBrace.loc.end.line
|
|
1350
|
+
},
|
|
1351
|
+
start: {
|
|
1352
|
+
column: 0,
|
|
1353
|
+
line: openingBrace.loc.start.line
|
|
1354
|
+
}
|
|
1355
|
+
},
|
|
1356
|
+
messageId: "multipleOnSameLine"
|
|
1357
|
+
});
|
|
1358
|
+
}
|
|
1359
|
+
const defaultOptions$3 = {
|
|
1360
|
+
maxLength: 80
|
|
1361
|
+
};
|
|
1362
|
+
function getBraces$1(sourceCode, body) {
|
|
1363
|
+
const openingBrace = sourceCode.getTokenBefore(body.body[0]);
|
|
1364
|
+
const closingBrace = sourceCode.getTokenAfter(body.body[body.body.length - 1]);
|
|
1365
|
+
if (!openingBrace || !closingBrace)
|
|
1366
|
+
return null;
|
|
1367
|
+
return { closingBrace, openingBrace };
|
|
1368
|
+
}
|
|
1369
|
+
function checkInterface(sourceCode, context, node2) {
|
|
1370
|
+
const options = context.options[0] ?? {};
|
|
1371
|
+
const maxLength = options.maxLength ?? defaultOptions$3.maxLength;
|
|
1372
|
+
const body = node2.body;
|
|
1373
|
+
if (!body || body.body.length === 0)
|
|
1374
|
+
return;
|
|
1375
|
+
const braces = getBraces$1(sourceCode, body);
|
|
1376
|
+
if (!braces)
|
|
1377
|
+
return;
|
|
1378
|
+
const firstLine = braces.openingBrace.loc.start.line;
|
|
1379
|
+
const lastLine = braces.closingBrace.loc.end.line;
|
|
1380
|
+
if (firstLine === lastLine)
|
|
1381
|
+
checkSingleLineMembers(sourceCode, context, body.body, braces, maxLength);
|
|
1382
|
+
else
|
|
1383
|
+
checkMultilineMembers(sourceCode, context, body.body, maxLength);
|
|
1384
|
+
}
|
|
1385
|
+
const messageIds$6 = {
|
|
1386
|
+
exceedsMaxLength: "Interface line exceeds {{maxLength}} characters",
|
|
1387
|
+
multipleOnSameLine: "Interface members should each be on their own line when line exceeds {{maxLength}} characters"
|
|
1388
|
+
};
|
|
1389
|
+
const interfacePropertyLineBreak = {
|
|
1390
|
+
create(context) {
|
|
1391
|
+
const sourceCode = context.sourceCode ?? context.getSourceCode();
|
|
1392
|
+
return {
|
|
1393
|
+
TSInterfaceDeclaration(node2) {
|
|
1394
|
+
checkInterface(sourceCode, context, node2);
|
|
1395
|
+
}
|
|
1396
|
+
};
|
|
1397
|
+
},
|
|
1398
|
+
meta: {
|
|
1399
|
+
docs: {
|
|
1400
|
+
description: "Enforce each interface member to be on its own line when line exceeds max length."
|
|
1401
|
+
},
|
|
1402
|
+
fixable: "code",
|
|
1403
|
+
messages: messageIds$6,
|
|
1404
|
+
schema: [{
|
|
1405
|
+
additionalProperties: false,
|
|
1406
|
+
properties: {
|
|
1407
|
+
maxLength: {
|
|
1408
|
+
type: "number"
|
|
1409
|
+
}
|
|
1410
|
+
},
|
|
1411
|
+
type: "object"
|
|
1412
|
+
}],
|
|
1413
|
+
type: "layout"
|
|
1414
|
+
}
|
|
1415
|
+
};
|
|
1416
|
+
function collectVariableDeclarators(node2, types) {
|
|
1417
|
+
for (const declarator of node2.declarations) {
|
|
1418
|
+
if (declarator.id.type === "Identifier" && declarator.id.name)
|
|
1419
|
+
types.add(declarator.id.name);
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
function isTopLevel(node2) {
|
|
1423
|
+
if (node2.parent?.type === "Program")
|
|
1424
|
+
return true;
|
|
1425
|
+
if (node2.parent?.type === "ExportNamedDeclaration" && node2.parent.parent?.type === "Program")
|
|
1426
|
+
return true;
|
|
1427
|
+
return false;
|
|
1428
|
+
}
|
|
1429
|
+
function handleClassDeclaration(node2, functions) {
|
|
1430
|
+
if (isTopLevel(node2) && node2.id?.name)
|
|
1431
|
+
functions.add(node2.id.name);
|
|
1432
|
+
}
|
|
1433
|
+
function handleFunctionDeclaration(node2, functions) {
|
|
1434
|
+
if (isTopLevel(node2) && node2.id?.name)
|
|
1435
|
+
functions.add(node2.id.name);
|
|
1436
|
+
}
|
|
1437
|
+
function handleTSDeclareFunction(node2, functions) {
|
|
1438
|
+
if (isTopLevel(node2) && node2.id?.name)
|
|
1439
|
+
functions.add(node2.id.name);
|
|
1440
|
+
}
|
|
1441
|
+
function handleTSEnumDeclaration(node2, types) {
|
|
1442
|
+
if (isTopLevel(node2) && node2.id?.name)
|
|
1443
|
+
types.add(node2.id.name);
|
|
1444
|
+
}
|
|
1445
|
+
function handleTSInterfaceDeclaration(node2, types) {
|
|
1446
|
+
if (isTopLevel(node2) && node2.id?.name)
|
|
1447
|
+
types.add(node2.id.name);
|
|
1448
|
+
}
|
|
1449
|
+
function handleTSTypeAliasDeclaration(node2, types) {
|
|
1450
|
+
if (isTopLevel(node2) && node2.id?.name)
|
|
1451
|
+
types.add(node2.id.name);
|
|
1452
|
+
}
|
|
1453
|
+
function isExempt$1(filename) {
|
|
1454
|
+
const name = path.basename(filename, path.extname(filename));
|
|
1455
|
+
const isTest = name.endsWith(".test");
|
|
1456
|
+
const isSpec = name.endsWith(".spec");
|
|
1457
|
+
const isConfig = name.endsWith(".config");
|
|
1458
|
+
return isTest || isSpec || isConfig;
|
|
1459
|
+
}
|
|
1460
|
+
function isExportedDeclaration(parent) {
|
|
1461
|
+
return parent?.type === "ExportNamedDeclaration";
|
|
1462
|
+
}
|
|
1463
|
+
const messageIds$5 = {
|
|
1464
|
+
tooManyDeclarations: "File has {{count}} declarations. Put each function/class/const/type declaration in its own file."
|
|
1465
|
+
};
|
|
1466
|
+
const maxDeclarationsPerFile = {
|
|
1467
|
+
create(context) {
|
|
1468
|
+
const filename = context.filename;
|
|
1469
|
+
if (isExempt$1(filename))
|
|
1470
|
+
return {};
|
|
1471
|
+
const functions = /* @__PURE__ */ new Set();
|
|
1472
|
+
const types = /* @__PURE__ */ new Set();
|
|
1473
|
+
return {
|
|
1474
|
+
ClassDeclaration(node2) {
|
|
1475
|
+
handleClassDeclaration(node2, functions);
|
|
1476
|
+
},
|
|
1477
|
+
FunctionDeclaration(node2) {
|
|
1478
|
+
handleFunctionDeclaration(node2, functions);
|
|
1479
|
+
},
|
|
1480
|
+
"Program:exit"(_programNode) {
|
|
1481
|
+
const totalDeclarations = functions.size + types.size;
|
|
1482
|
+
if (totalDeclarations > 1) {
|
|
1483
|
+
context.report({
|
|
1484
|
+
data: {
|
|
1485
|
+
count: totalDeclarations,
|
|
1486
|
+
functions: functions.size,
|
|
1487
|
+
types: types.size
|
|
1488
|
+
},
|
|
1489
|
+
messageId: "tooManyDeclarations",
|
|
1490
|
+
node: _programNode
|
|
1491
|
+
});
|
|
1492
|
+
}
|
|
1493
|
+
},
|
|
1494
|
+
TSDeclareFunction(node2) {
|
|
1495
|
+
handleTSDeclareFunction(node2, functions);
|
|
1496
|
+
},
|
|
1497
|
+
TSEnumDeclaration(node2) {
|
|
1498
|
+
handleTSEnumDeclaration(node2, types);
|
|
1499
|
+
},
|
|
1500
|
+
TSInterfaceDeclaration(node2) {
|
|
1501
|
+
handleTSInterfaceDeclaration(node2, types);
|
|
1502
|
+
},
|
|
1503
|
+
TSTypeAliasDeclaration(node2) {
|
|
1504
|
+
handleTSTypeAliasDeclaration(node2, types);
|
|
1505
|
+
},
|
|
1506
|
+
VariableDeclaration(node2) {
|
|
1507
|
+
if (!isTopLevel(node2))
|
|
1508
|
+
return;
|
|
1509
|
+
const parent = node2.parent;
|
|
1510
|
+
if (!isExportedDeclaration(parent) && !node2.declare)
|
|
1511
|
+
return;
|
|
1512
|
+
collectVariableDeclarators(node2, types);
|
|
1513
|
+
},
|
|
1514
|
+
"VariableDeclaration > VariableDeclarator > ArrowFunctionExpression"(_node) {
|
|
1515
|
+
if (!isTopLevel(_node.parent?.parent))
|
|
1516
|
+
return;
|
|
1517
|
+
const declarator = _node.parent;
|
|
1518
|
+
if (declarator.id.type === "Identifier" && declarator.id.name)
|
|
1519
|
+
functions.add(declarator.id.name);
|
|
1520
|
+
}
|
|
1521
|
+
};
|
|
1522
|
+
},
|
|
1523
|
+
meta: {
|
|
1524
|
+
docs: {
|
|
1525
|
+
description: "Enforce single top-level declaration per file."
|
|
1526
|
+
},
|
|
1527
|
+
messages: messageIds$5,
|
|
1528
|
+
schema: [],
|
|
1529
|
+
type: "suggestion"
|
|
1530
|
+
}
|
|
1531
|
+
};
|
|
1532
|
+
function createFix(fixer, node2, sourceCode) {
|
|
1533
|
+
const types = node2.types.map((t) => sourceCode.getText(t));
|
|
1534
|
+
const formattedTypes = types.map((t) => ` | ${t}`).join("\n");
|
|
1535
|
+
const result = `
|
|
1536
|
+
${formattedTypes}`;
|
|
1537
|
+
return fixer.replaceText(node2, result);
|
|
1538
|
+
}
|
|
1539
|
+
function isMultiline(unionType) {
|
|
1540
|
+
const { end, start } = unionType.loc ?? {};
|
|
1541
|
+
return start?.line !== end?.line;
|
|
1542
|
+
}
|
|
1543
|
+
const multilineUnionTypeAliases = {
|
|
1544
|
+
create(context) {
|
|
1545
|
+
return {
|
|
1546
|
+
TSUnionType(node2) {
|
|
1547
|
+
if (node2.types.length < 2)
|
|
1548
|
+
return;
|
|
1549
|
+
const parent = node2.parent;
|
|
1550
|
+
if (!parent || parent.type !== "TSTypeAliasDeclaration")
|
|
1551
|
+
return;
|
|
1552
|
+
const sourceCode = context.sourceCode;
|
|
1553
|
+
const text = sourceCode.getText(node2);
|
|
1554
|
+
if (text.trim().startsWith("|"))
|
|
1555
|
+
return;
|
|
1556
|
+
if (!isMultiline(node2)) {
|
|
1557
|
+
context.report({
|
|
1558
|
+
fix: (fixer) => createFix(fixer, node2, sourceCode),
|
|
1559
|
+
messageId: "singleLine",
|
|
1560
|
+
node: node2
|
|
1561
|
+
});
|
|
1562
|
+
return;
|
|
1563
|
+
}
|
|
1564
|
+
context.report({
|
|
1565
|
+
fix: (fixer) => createFix(fixer, node2, sourceCode),
|
|
1566
|
+
messageId: "missingPipes",
|
|
1567
|
+
node: node2
|
|
1568
|
+
});
|
|
1569
|
+
}
|
|
1570
|
+
};
|
|
1571
|
+
},
|
|
1572
|
+
meta: {
|
|
1573
|
+
docs: {
|
|
1574
|
+
description: "Enforce union type aliases with multiple members to be on multiple lines."
|
|
1575
|
+
},
|
|
1576
|
+
fixable: "code",
|
|
1577
|
+
messages: {
|
|
1578
|
+
missingPipes: "Multiline union type aliases should have leading pipes on each member",
|
|
1579
|
+
singleLine: "Union type aliases with multiple members should be on multiple lines"
|
|
1580
|
+
},
|
|
1581
|
+
schema: [],
|
|
1582
|
+
type: "layout"
|
|
1583
|
+
}
|
|
1584
|
+
};
|
|
1585
|
+
function isExempt(name) {
|
|
1586
|
+
return name.startsWith("_");
|
|
1587
|
+
}
|
|
1588
|
+
function isPascalCase(name) {
|
|
1589
|
+
if (!/^[A-Z]/.test(name))
|
|
1590
|
+
return false;
|
|
1591
|
+
return /^[A-Z][\dA-Za-z]*$/.test(name);
|
|
1592
|
+
}
|
|
1593
|
+
function isSeparator(char) {
|
|
1594
|
+
return char === "_" || char === "-" || char === " ";
|
|
1595
|
+
}
|
|
1596
|
+
function isWordBoundary(char, currentWord, prevChar, nextChar) {
|
|
1597
|
+
if (!currentWord)
|
|
1598
|
+
return false;
|
|
1599
|
+
const isUpper = /[A-Z]/.test(char);
|
|
1600
|
+
const prevIsUpper = /[A-Z]/.test(prevChar);
|
|
1601
|
+
const nextIsLower = /[a-z]/.test(nextChar);
|
|
1602
|
+
if (isUpper) {
|
|
1603
|
+
const isStartOfNewWord = !prevIsUpper || prevIsUpper && nextIsLower;
|
|
1604
|
+
return isStartOfNewWord;
|
|
1605
|
+
}
|
|
1606
|
+
return false;
|
|
1607
|
+
}
|
|
1608
|
+
function capitalize(word) {
|
|
1609
|
+
return word.charAt(0).toUpperCase() + word.slice(1);
|
|
1610
|
+
}
|
|
1611
|
+
function wordsToCamelCase(words) {
|
|
1612
|
+
if (words.length === 0)
|
|
1613
|
+
return "";
|
|
1614
|
+
if (words.length === 1)
|
|
1615
|
+
return words[0].toLowerCase();
|
|
1616
|
+
const firstWord = words[0].toLowerCase();
|
|
1617
|
+
const restWords = words.slice(1).map(capitalize);
|
|
1618
|
+
return firstWord + restWords.join("");
|
|
1619
|
+
}
|
|
1620
|
+
function toCamelCase(name) {
|
|
1621
|
+
const words = [];
|
|
1622
|
+
let currentWord = "";
|
|
1623
|
+
for (let i = 0; i < name.length; i++) {
|
|
1624
|
+
const char = name[i];
|
|
1625
|
+
const prevChar = i > 0 ? name[i - 1] : "";
|
|
1626
|
+
const nextChar = i < name.length - 1 ? name[i + 1] : "";
|
|
1627
|
+
if (isSeparator(char)) {
|
|
1628
|
+
if (currentWord) {
|
|
1629
|
+
words.push(currentWord.toLowerCase());
|
|
1630
|
+
currentWord = "";
|
|
1631
|
+
}
|
|
1632
|
+
continue;
|
|
1633
|
+
}
|
|
1634
|
+
if (isWordBoundary(char, currentWord, prevChar, nextChar)) {
|
|
1635
|
+
words.push(currentWord.toLowerCase());
|
|
1636
|
+
currentWord = char;
|
|
1637
|
+
continue;
|
|
1638
|
+
}
|
|
1639
|
+
currentWord += char;
|
|
1640
|
+
}
|
|
1641
|
+
if (currentWord)
|
|
1642
|
+
words.push(currentWord.toLowerCase());
|
|
1643
|
+
return wordsToCamelCase(words);
|
|
1644
|
+
}
|
|
1645
|
+
function toPascalCase$1(name) {
|
|
1646
|
+
const camelCase = toCamelCase(name);
|
|
1647
|
+
return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);
|
|
1648
|
+
}
|
|
1649
|
+
function checkClass(id, context) {
|
|
1650
|
+
if (!id)
|
|
1651
|
+
return;
|
|
1652
|
+
const name = id.name;
|
|
1653
|
+
if (isExempt(name))
|
|
1654
|
+
return;
|
|
1655
|
+
if (!isPascalCase(name)) {
|
|
1656
|
+
context.report({
|
|
1657
|
+
data: {
|
|
1658
|
+
name,
|
|
1659
|
+
type: "Class"
|
|
1660
|
+
},
|
|
1661
|
+
fix(fixer) {
|
|
1662
|
+
return fixer.replaceText(id, toPascalCase$1(name));
|
|
1663
|
+
},
|
|
1664
|
+
messageId: "notPascalCase",
|
|
1665
|
+
node: id
|
|
1666
|
+
});
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
function checkNamedEntity(name, node2, type, context) {
|
|
1670
|
+
if (isExempt(name))
|
|
1671
|
+
return;
|
|
1672
|
+
if (!isPascalCase(name)) {
|
|
1673
|
+
context.report({
|
|
1674
|
+
data: { name, type },
|
|
1675
|
+
fix(fixer) {
|
|
1676
|
+
return fixer.replaceText(node2, toPascalCase$1(name));
|
|
1677
|
+
},
|
|
1678
|
+
messageId: "notPascalCase",
|
|
1679
|
+
node: node2
|
|
1680
|
+
});
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
function isCamelCase(name) {
|
|
1684
|
+
if (!/^[a-z]/.test(name))
|
|
1685
|
+
return false;
|
|
1686
|
+
return /^[a-z][\dA-Za-z]*$/.test(name);
|
|
1687
|
+
}
|
|
1688
|
+
function isUpperCase(name) {
|
|
1689
|
+
return /^[A-Z][\dA-Z_]*$/.test(name);
|
|
1690
|
+
}
|
|
1691
|
+
function checkConstant(name, node2, context) {
|
|
1692
|
+
if (!isCamelCase(name) && !isUpperCase(name)) {
|
|
1693
|
+
context.report({
|
|
1694
|
+
data: { name },
|
|
1695
|
+
messageId: "notUpperCase",
|
|
1696
|
+
node: node2
|
|
1697
|
+
});
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
function checkVariable(name, node2, context) {
|
|
1701
|
+
if (!isCamelCase(name)) {
|
|
1702
|
+
context.report({
|
|
1703
|
+
data: { name },
|
|
1704
|
+
fix(fixer) {
|
|
1705
|
+
return fixer.replaceText(node2, toCamelCase(name));
|
|
1706
|
+
},
|
|
1707
|
+
messageId: "notCamelCase",
|
|
1708
|
+
node: node2
|
|
1709
|
+
});
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
function isFunction(init) {
|
|
1713
|
+
if (!init)
|
|
1714
|
+
return false;
|
|
1715
|
+
return init.type === "FunctionExpression" || init.type === "ArrowFunctionExpression";
|
|
1716
|
+
}
|
|
1717
|
+
function checkVariableDeclarator(node2, context) {
|
|
1718
|
+
const id = node2.id;
|
|
1719
|
+
const name = id.name;
|
|
1720
|
+
if (isExempt(name))
|
|
1721
|
+
return;
|
|
1722
|
+
if (isFunction(node2.init))
|
|
1723
|
+
return;
|
|
1724
|
+
const parent = node2.parent;
|
|
1725
|
+
if (parent?.type !== "VariableDeclaration")
|
|
1726
|
+
return;
|
|
1727
|
+
const kind = parent.kind;
|
|
1728
|
+
if (kind === "const")
|
|
1729
|
+
checkConstant(name, id, context);
|
|
1730
|
+
else
|
|
1731
|
+
checkVariable(name, id, context);
|
|
1732
|
+
}
|
|
1733
|
+
function getFunctionName(node2, parent) {
|
|
1734
|
+
if (node2.type === "FunctionDeclaration" && node2.id)
|
|
1735
|
+
return node2.id.name;
|
|
1736
|
+
if ((node2.type === "FunctionExpression" || node2.type === "ArrowFunctionExpression") && parent?.type === "VariableDeclarator" && parent.id.type === "Identifier")
|
|
1737
|
+
return parent.id.name;
|
|
1738
|
+
return null;
|
|
1739
|
+
}
|
|
1740
|
+
function getReturnTypeText(sourceCode, node2) {
|
|
1741
|
+
if (!node2.returnType)
|
|
1742
|
+
return void 0;
|
|
1743
|
+
return sourceCode.getText(node2.returnType.typeAnnotation);
|
|
1744
|
+
}
|
|
1745
|
+
function isReactComponent(returnTypeText) {
|
|
1746
|
+
if (!returnTypeText)
|
|
1747
|
+
return false;
|
|
1748
|
+
const patterns = [
|
|
1749
|
+
"JSX.Element",
|
|
1750
|
+
"React.JSX.Element",
|
|
1751
|
+
"ReactElement",
|
|
1752
|
+
"ReactNode"
|
|
1753
|
+
];
|
|
1754
|
+
return patterns.some((pattern) => returnTypeText.includes(pattern));
|
|
1755
|
+
}
|
|
1756
|
+
const messageIds$4 = {
|
|
1757
|
+
notCamelCase: 'Function "{{name}}" should use camelCase',
|
|
1758
|
+
notPascalCase: '{{type}} "{{name}}" should use PascalCase',
|
|
1759
|
+
notUpperCase: 'Constant "{{name}}" should use UPPER_CASE'
|
|
1760
|
+
};
|
|
1761
|
+
function getFunctionIdentifierNodeForFixer(node2, parent) {
|
|
1762
|
+
if (node2.type === "FunctionDeclaration")
|
|
1763
|
+
return node2.id;
|
|
1764
|
+
if (parent?.type === "VariableDeclarator")
|
|
1765
|
+
return parent.id;
|
|
1766
|
+
return null;
|
|
1767
|
+
}
|
|
1768
|
+
function getFunctionNameForFixer(node2, parent) {
|
|
1769
|
+
if (node2.type === "FunctionDeclaration" && node2.id)
|
|
1770
|
+
return node2.id.name;
|
|
1771
|
+
if (parent?.type === "VariableDeclarator" && parent.id.type === "Identifier")
|
|
1772
|
+
return parent.id.name;
|
|
1773
|
+
return "";
|
|
1774
|
+
}
|
|
1775
|
+
function createFunctionFixer(node2, parent, convert) {
|
|
1776
|
+
return (fixer) => {
|
|
1777
|
+
const fixedName = convert(getFunctionNameForFixer(node2, parent));
|
|
1778
|
+
const identifierNode = getFunctionIdentifierNodeForFixer(node2, parent);
|
|
1779
|
+
if (identifierNode)
|
|
1780
|
+
return fixer.replaceText(identifierNode, fixedName);
|
|
1781
|
+
return null;
|
|
1782
|
+
};
|
|
1783
|
+
}
|
|
1784
|
+
function getFunctionReportNode(node2, parent) {
|
|
1785
|
+
if (node2.type === "FunctionDeclaration")
|
|
1786
|
+
return node2;
|
|
1787
|
+
return parent ?? node2;
|
|
1788
|
+
}
|
|
1789
|
+
function reportComponentViolation(node2, parent, name, context) {
|
|
1790
|
+
if (isPascalCase(name))
|
|
1791
|
+
return;
|
|
1792
|
+
context.report({
|
|
1793
|
+
data: {
|
|
1794
|
+
name,
|
|
1795
|
+
type: "React component"
|
|
1796
|
+
},
|
|
1797
|
+
fix: createFunctionFixer(node2, parent, toPascalCase$1),
|
|
1798
|
+
messageId: "notPascalCase",
|
|
1799
|
+
node: getFunctionReportNode(node2, parent)
|
|
1800
|
+
});
|
|
1801
|
+
}
|
|
1802
|
+
function reportFunctionViolation(node2, parent, name, context) {
|
|
1803
|
+
if (isCamelCase(name))
|
|
1804
|
+
return;
|
|
1805
|
+
context.report({
|
|
1806
|
+
data: { name },
|
|
1807
|
+
fix: createFunctionFixer(node2, parent, toCamelCase),
|
|
1808
|
+
messageId: "notCamelCase",
|
|
1809
|
+
node: getFunctionReportNode(node2, parent)
|
|
1810
|
+
});
|
|
1811
|
+
}
|
|
1812
|
+
const namingConvention = {
|
|
1813
|
+
create(context) {
|
|
1814
|
+
const sourceCode = context.sourceCode ?? context.getSourceCode();
|
|
1815
|
+
return {
|
|
1816
|
+
ArrowFunctionExpression(node2) {
|
|
1817
|
+
checkFunction2(node2, node2.parent);
|
|
1818
|
+
},
|
|
1819
|
+
ClassDeclaration(node2) {
|
|
1820
|
+
checkClass(node2.id, context);
|
|
1821
|
+
},
|
|
1822
|
+
ClassExpression(node2) {
|
|
1823
|
+
checkClass(node2.id, context);
|
|
1824
|
+
},
|
|
1825
|
+
FunctionDeclaration(node2) {
|
|
1826
|
+
checkFunction2(node2);
|
|
1827
|
+
},
|
|
1828
|
+
FunctionExpression(node2) {
|
|
1829
|
+
checkFunction2(node2, node2.parent);
|
|
1830
|
+
},
|
|
1831
|
+
TSEnumDeclaration(node2) {
|
|
1832
|
+
checkNamedEntity(
|
|
1833
|
+
node2.id.name,
|
|
1834
|
+
node2.id,
|
|
1835
|
+
"Enum",
|
|
1836
|
+
context
|
|
1837
|
+
);
|
|
1838
|
+
},
|
|
1839
|
+
TSInterfaceDeclaration(node2) {
|
|
1840
|
+
checkNamedEntity(
|
|
1841
|
+
node2.id.name,
|
|
1842
|
+
node2.id,
|
|
1843
|
+
"Interface",
|
|
1844
|
+
context
|
|
1845
|
+
);
|
|
1846
|
+
},
|
|
1847
|
+
TSTypeAliasDeclaration(node2) {
|
|
1848
|
+
if (node2.id.type !== "Identifier")
|
|
1849
|
+
return;
|
|
1850
|
+
checkNamedEntity(
|
|
1851
|
+
node2.id.name,
|
|
1852
|
+
node2.id,
|
|
1853
|
+
"Type",
|
|
1854
|
+
context
|
|
1855
|
+
);
|
|
1856
|
+
},
|
|
1857
|
+
VariableDeclarator(node2) {
|
|
1858
|
+
if (node2.id.type !== "Identifier")
|
|
1859
|
+
return;
|
|
1860
|
+
checkVariableDeclarator(node2, context);
|
|
1861
|
+
}
|
|
1862
|
+
};
|
|
1863
|
+
function checkFunction2(node2, parent) {
|
|
1864
|
+
const name = getFunctionName(node2, parent);
|
|
1865
|
+
if (!name || isExempt(name))
|
|
1866
|
+
return;
|
|
1867
|
+
const returnTypeText = getReturnTypeText(sourceCode, node2);
|
|
1868
|
+
const isComponent = isReactComponent(returnTypeText);
|
|
1869
|
+
if (isComponent)
|
|
1870
|
+
reportComponentViolation(node2, parent, name, context);
|
|
1871
|
+
else
|
|
1872
|
+
reportFunctionViolation(node2, parent, name, context);
|
|
1873
|
+
}
|
|
1874
|
+
},
|
|
1875
|
+
meta: {
|
|
1876
|
+
docs: {
|
|
1877
|
+
description: "Enforce consistent naming conventions."
|
|
1878
|
+
},
|
|
1879
|
+
fixable: "code",
|
|
1880
|
+
messages: messageIds$4,
|
|
1881
|
+
schema: [],
|
|
1882
|
+
type: "suggestion"
|
|
1883
|
+
}
|
|
1884
|
+
};
|
|
1885
|
+
function checkTypeParameters(node2, containsInline) {
|
|
1886
|
+
if (!("typeParameters" in node2) || !node2.typeParameters)
|
|
1887
|
+
return null;
|
|
1888
|
+
for (const param of node2.typeParameters.params) {
|
|
1889
|
+
const result = containsInline(param);
|
|
1890
|
+
if (result)
|
|
1891
|
+
return result;
|
|
1892
|
+
}
|
|
1893
|
+
return null;
|
|
1894
|
+
}
|
|
1895
|
+
function checkUnionOrIntersectionTypes(node2, containsInline) {
|
|
1896
|
+
for (const type of node2.types) {
|
|
1897
|
+
const result = containsInline(type);
|
|
1898
|
+
if (result)
|
|
1899
|
+
return result;
|
|
1900
|
+
}
|
|
1901
|
+
return null;
|
|
1902
|
+
}
|
|
1903
|
+
function isInlineObjectType(node2) {
|
|
1904
|
+
return node2.type === "TSTypeLiteral";
|
|
1905
|
+
}
|
|
1906
|
+
function containsInlineObjectType(node2) {
|
|
1907
|
+
if (isInlineObjectType(node2))
|
|
1908
|
+
return node2;
|
|
1909
|
+
if (node2.type === "TSIntersectionType" || node2.type === "TSUnionType") {
|
|
1910
|
+
const result = checkUnionOrIntersectionTypes(
|
|
1911
|
+
node2,
|
|
1912
|
+
containsInlineObjectType
|
|
1913
|
+
);
|
|
1914
|
+
if (result)
|
|
1915
|
+
return result;
|
|
1916
|
+
}
|
|
1917
|
+
if (node2.type === "TSArrayType")
|
|
1918
|
+
return containsInlineObjectType(node2.elementType);
|
|
1919
|
+
const typeParamResult = checkTypeParameters(node2, containsInlineObjectType);
|
|
1920
|
+
if (typeParamResult)
|
|
1921
|
+
return typeParamResult;
|
|
1922
|
+
if (node2.type === "TSTypeAnnotation")
|
|
1923
|
+
return containsInlineObjectType(node2.typeAnnotation);
|
|
1924
|
+
return null;
|
|
1925
|
+
}
|
|
1926
|
+
function toPascalCase(str) {
|
|
1927
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
1928
|
+
}
|
|
1929
|
+
function getInlineTypeName(usedNames, _existingInterfaces, parameterName) {
|
|
1930
|
+
const baseName = parameterName ? toPascalCase(parameterName) : "InlineType";
|
|
1931
|
+
if (!usedNames.has(baseName)) {
|
|
1932
|
+
usedNames.add(baseName);
|
|
1933
|
+
return baseName;
|
|
1934
|
+
}
|
|
1935
|
+
let counter = 2;
|
|
1936
|
+
while (usedNames.has(`${baseName}${counter}`))
|
|
1937
|
+
counter++;
|
|
1938
|
+
const name = `${baseName}${counter}`;
|
|
1939
|
+
usedNames.add(name);
|
|
1940
|
+
return name;
|
|
1941
|
+
}
|
|
1942
|
+
function getParameterNameFromFunction(parent) {
|
|
1943
|
+
if (parent.type === "ArrowFunctionExpression" || parent.type === "FunctionDeclaration" || parent.type === "FunctionExpression") {
|
|
1944
|
+
const funcNode = parent;
|
|
1945
|
+
return funcNode.id?.name;
|
|
1946
|
+
}
|
|
1947
|
+
return void 0;
|
|
1948
|
+
}
|
|
1949
|
+
function getParameterNameFromIdentifier(parent) {
|
|
1950
|
+
const grandParent = parent.parent;
|
|
1951
|
+
if (grandParent?.type === "ArrowFunctionExpression" || grandParent?.type === "FunctionDeclaration" || grandParent?.type === "FunctionExpression")
|
|
1952
|
+
return parent.name;
|
|
1953
|
+
return void 0;
|
|
1954
|
+
}
|
|
1955
|
+
function getParameterNameFromObjectPattern(parent) {
|
|
1956
|
+
const grandParent = parent.parent;
|
|
1957
|
+
if (grandParent?.type === "ArrowFunctionExpression" || grandParent?.type === "FunctionDeclaration" || grandParent?.type === "FunctionExpression")
|
|
1958
|
+
return "Options";
|
|
1959
|
+
return void 0;
|
|
1960
|
+
}
|
|
1961
|
+
function getTopLevelDeclaration(node2) {
|
|
1962
|
+
let current = node2;
|
|
1963
|
+
const topLevelTypes = /* @__PURE__ */ new Set([
|
|
1964
|
+
"ArrowFunctionExpression",
|
|
1965
|
+
"FunctionDeclaration",
|
|
1966
|
+
"FunctionExpression",
|
|
1967
|
+
"TSInterfaceDeclaration",
|
|
1968
|
+
"TSTypeAliasDeclaration",
|
|
1969
|
+
"VariableDeclaration"
|
|
1970
|
+
]);
|
|
1971
|
+
while (current) {
|
|
1972
|
+
if (topLevelTypes.has(current.type)) {
|
|
1973
|
+
const parent = current.parent;
|
|
1974
|
+
const exported = parent?.type === "ExportNamedDeclaration";
|
|
1975
|
+
if (exported && parent) {
|
|
1976
|
+
return {
|
|
1977
|
+
insertLocation: parent,
|
|
1978
|
+
isExported: true,
|
|
1979
|
+
node: current
|
|
1980
|
+
};
|
|
1981
|
+
}
|
|
1982
|
+
return {
|
|
1983
|
+
insertLocation: current,
|
|
1984
|
+
isExported: false,
|
|
1985
|
+
node: current
|
|
1986
|
+
};
|
|
1987
|
+
}
|
|
1988
|
+
current = current.parent;
|
|
1989
|
+
}
|
|
1990
|
+
return void 0;
|
|
1991
|
+
}
|
|
1992
|
+
function handleInlineType(node2, typeLiteral, inlineTypes) {
|
|
1993
|
+
const result = getTopLevelDeclaration(node2);
|
|
1994
|
+
if (!result)
|
|
1995
|
+
return;
|
|
1996
|
+
let parameterName;
|
|
1997
|
+
const parent = node2.parent;
|
|
1998
|
+
if (parent?.type === "Identifier")
|
|
1999
|
+
parameterName = getParameterNameFromIdentifier(parent);
|
|
2000
|
+
else if (parent?.type === "ObjectPattern")
|
|
2001
|
+
parameterName = getParameterNameFromObjectPattern(parent);
|
|
2002
|
+
else
|
|
2003
|
+
parameterName = getParameterNameFromFunction(parent);
|
|
2004
|
+
inlineTypes.push({
|
|
2005
|
+
annotationNode: node2,
|
|
2006
|
+
insertLocation: result.insertLocation,
|
|
2007
|
+
isExported: result.isExported,
|
|
2008
|
+
location: result.node,
|
|
2009
|
+
parameterName,
|
|
2010
|
+
typeLiteral
|
|
2011
|
+
});
|
|
2012
|
+
}
|
|
2013
|
+
function isIdentifierInFunction(parent) {
|
|
2014
|
+
return parent?.type === "Identifier" && (parent.parent?.type === "FunctionDeclaration" || parent.parent?.type === "FunctionExpression" || parent.parent?.type === "ArrowFunctionExpression");
|
|
2015
|
+
}
|
|
2016
|
+
function isPropertySignatureInTypeLiteral(parent) {
|
|
2017
|
+
return parent?.type === "TSPropertySignature" && (parent.parent?.type === "TSTypeLiteral" || parent.parent?.type === "TSInterfaceBody");
|
|
2018
|
+
}
|
|
2019
|
+
function traverseUpForTypeLiteral(current) {
|
|
2020
|
+
const skipTypes = /* @__PURE__ */ new Set([
|
|
2021
|
+
"TSArrayType",
|
|
2022
|
+
"TSIntersectionType",
|
|
2023
|
+
"TSPropertySignature",
|
|
2024
|
+
"TSTypeReference",
|
|
2025
|
+
"TSUnionType"
|
|
2026
|
+
]);
|
|
2027
|
+
while (current) {
|
|
2028
|
+
if (current.type === "TSTypeLiteral")
|
|
2029
|
+
return true;
|
|
2030
|
+
if (skipTypes.has(current.type)) {
|
|
2031
|
+
current = current.parent;
|
|
2032
|
+
continue;
|
|
2033
|
+
}
|
|
2034
|
+
break;
|
|
2035
|
+
}
|
|
2036
|
+
return false;
|
|
2037
|
+
}
|
|
2038
|
+
function isNestedTypeAnnotation(node2) {
|
|
2039
|
+
const parent = node2.parent;
|
|
2040
|
+
if (isPropertySignatureInTypeLiteral(parent))
|
|
2041
|
+
return true;
|
|
2042
|
+
if (isIdentifierInFunction(parent))
|
|
2043
|
+
return false;
|
|
2044
|
+
if (parent?.type === "ArrowFunctionExpression" || parent?.type === "FunctionDeclaration" || parent?.type === "FunctionExpression")
|
|
2045
|
+
return false;
|
|
2046
|
+
const foundTypeLiteral = traverseUpForTypeLiteral(parent);
|
|
2047
|
+
return foundTypeLiteral;
|
|
2048
|
+
}
|
|
2049
|
+
function prepareFix(sourceCode, inlineTypes) {
|
|
2050
|
+
const interfaceDeclarations = inlineTypes.map(({ name, typeLiteral }) => {
|
|
2051
|
+
const typeText = sourceCode.getText(typeLiteral);
|
|
2052
|
+
return `interface ${name} ${typeText}`;
|
|
2053
|
+
});
|
|
2054
|
+
const interfaceBlock = interfaceDeclarations.join("\n");
|
|
2055
|
+
const replacements = inlineTypes.map(
|
|
2056
|
+
({ name, typeLiteral }) => ({ name, typeLiteral })
|
|
2057
|
+
);
|
|
2058
|
+
return {
|
|
2059
|
+
firstUsageLocation: inlineTypes[0].typeLiteral,
|
|
2060
|
+
interfaceBlock,
|
|
2061
|
+
replacements
|
|
2062
|
+
};
|
|
2063
|
+
}
|
|
2064
|
+
const noInlineObjectTypes = {
|
|
2065
|
+
create(context) {
|
|
2066
|
+
const sourceCode = context.sourceCode;
|
|
2067
|
+
const inlineTypes = [];
|
|
2068
|
+
const listener = {
|
|
2069
|
+
TSTypeAnnotation(node2) {
|
|
2070
|
+
if (isNestedTypeAnnotation(node2))
|
|
2071
|
+
return;
|
|
2072
|
+
const typeLiteral = containsInlineObjectType(node2);
|
|
2073
|
+
if (!typeLiteral)
|
|
2074
|
+
return;
|
|
2075
|
+
handleInlineType(node2, typeLiteral, inlineTypes);
|
|
2076
|
+
}
|
|
2077
|
+
};
|
|
2078
|
+
return {
|
|
2079
|
+
...listener,
|
|
2080
|
+
"Program:exit"() {
|
|
2081
|
+
if (inlineTypes.length === 0)
|
|
2082
|
+
return;
|
|
2083
|
+
const usedNames = /* @__PURE__ */ new Set();
|
|
2084
|
+
const locations = [...new Set(inlineTypes.map((t) => t.insertLocation))];
|
|
2085
|
+
for (const loc of locations) {
|
|
2086
|
+
const typesAtLocation = inlineTypes.filter(
|
|
2087
|
+
(t) => t.insertLocation === loc
|
|
2088
|
+
);
|
|
2089
|
+
const typesForLocation = typesAtLocation.map((entry) => {
|
|
2090
|
+
const name = getInlineTypeName(usedNames, [], entry.parameterName);
|
|
2091
|
+
return {
|
|
2092
|
+
name,
|
|
2093
|
+
parameterName: entry.parameterName,
|
|
2094
|
+
typeLiteral: entry.typeLiteral
|
|
2095
|
+
};
|
|
2096
|
+
});
|
|
2097
|
+
const fixResult = prepareFix(
|
|
2098
|
+
sourceCode,
|
|
2099
|
+
typesForLocation
|
|
2100
|
+
);
|
|
2101
|
+
context.report({
|
|
2102
|
+
fix(fixer) {
|
|
2103
|
+
const fixes = [];
|
|
2104
|
+
for (const replacement of fixResult.replacements) {
|
|
2105
|
+
fixes.push(
|
|
2106
|
+
fixer.replaceText(
|
|
2107
|
+
replacement.typeLiteral,
|
|
2108
|
+
replacement.name
|
|
2109
|
+
)
|
|
2110
|
+
);
|
|
2111
|
+
}
|
|
2112
|
+
const isExported = typesAtLocation[0].isExported;
|
|
2113
|
+
if (isExported && typesAtLocation[0].insertLocation.type === "ExportNamedDeclaration") {
|
|
2114
|
+
fixes.push(
|
|
2115
|
+
fixer.insertTextAfter(
|
|
2116
|
+
typesAtLocation[0].insertLocation,
|
|
2117
|
+
`
|
|
2118
|
+
${fixResult.interfaceBlock}`
|
|
2119
|
+
)
|
|
2120
|
+
);
|
|
2121
|
+
} else {
|
|
2122
|
+
fixes.push(
|
|
2123
|
+
fixer.insertTextBefore(
|
|
2124
|
+
loc,
|
|
2125
|
+
`${fixResult.interfaceBlock}
|
|
2126
|
+
`
|
|
2127
|
+
)
|
|
2128
|
+
);
|
|
2129
|
+
}
|
|
2130
|
+
return fixes;
|
|
2131
|
+
},
|
|
2132
|
+
messageId: "inlineObjectType",
|
|
2133
|
+
node: typesAtLocation[0].annotationNode
|
|
2134
|
+
});
|
|
2135
|
+
}
|
|
2136
|
+
}
|
|
2137
|
+
};
|
|
2138
|
+
},
|
|
2139
|
+
meta: {
|
|
2140
|
+
docs: {
|
|
2141
|
+
description: "Disallow inline object type literals in type annotations."
|
|
2142
|
+
},
|
|
2143
|
+
fixable: "code",
|
|
2144
|
+
messages: {
|
|
2145
|
+
inlineObjectType: "Inline object types are not allowed. Use a named interface or type instead."
|
|
2146
|
+
},
|
|
2147
|
+
schema: [],
|
|
2148
|
+
type: "suggestion"
|
|
2149
|
+
}
|
|
2150
|
+
};
|
|
2151
|
+
function getLineIndent(sourceCode, line) {
|
|
2152
|
+
const text = sourceCode.getText();
|
|
2153
|
+
const lines = text.split("\n");
|
|
2154
|
+
const lineText = lines[line - 1] ?? "";
|
|
2155
|
+
const match = lineText.match(/^(\s*)/);
|
|
2156
|
+
return match?.[1] ?? "";
|
|
2157
|
+
}
|
|
2158
|
+
function getReplacementText(statementText, baseIndent, hasElseAfter) {
|
|
2159
|
+
const statementIndent = `${baseIndent} `;
|
|
2160
|
+
if (hasElseAfter)
|
|
2161
|
+
return `
|
|
2162
|
+
${statementIndent}${statementText}
|
|
2163
|
+
${baseIndent}`;
|
|
2164
|
+
return `
|
|
2165
|
+
${statementIndent}${statementText}`;
|
|
2166
|
+
}
|
|
2167
|
+
function isSingleLineStatement(node2, sourceCode) {
|
|
2168
|
+
const firstToken = sourceCode.getFirstToken(node2);
|
|
2169
|
+
const lastToken = sourceCode.getLastToken(node2);
|
|
2170
|
+
if (!firstToken || !lastToken)
|
|
2171
|
+
return false;
|
|
2172
|
+
return firstToken.loc.start.line === lastToken.loc.end.line;
|
|
2173
|
+
}
|
|
2174
|
+
function checkBlockStatement(node2, context) {
|
|
2175
|
+
if (node2.body.length !== 1)
|
|
2176
|
+
return;
|
|
2177
|
+
const statement = node2.body[0];
|
|
2178
|
+
const sourceCode = context.getSourceCode();
|
|
2179
|
+
if (isSingleLineStatement(statement, sourceCode)) {
|
|
2180
|
+
context.report({
|
|
2181
|
+
fix(fixer) {
|
|
2182
|
+
const statementText = sourceCode.getText(statement);
|
|
2183
|
+
const tokenBefore = sourceCode.getTokenBefore(node2);
|
|
2184
|
+
const tokenBeforeLine = tokenBefore?.loc?.start?.line ?? node2.loc?.start?.line ?? 1;
|
|
2185
|
+
const baseIndent = getLineIndent(sourceCode, tokenBeforeLine);
|
|
2186
|
+
const rangeStart = tokenBefore ? tokenBefore.range[1] : node2.range[0];
|
|
2187
|
+
const range = [rangeStart, node2.range[1]];
|
|
2188
|
+
const tokenAfter = sourceCode.getTokenAfter(node2);
|
|
2189
|
+
const hasElseAfter = tokenAfter && tokenAfter.value === "else";
|
|
2190
|
+
const replacementText = getReplacementText(
|
|
2191
|
+
statementText,
|
|
2192
|
+
baseIndent,
|
|
2193
|
+
hasElseAfter
|
|
2194
|
+
);
|
|
2195
|
+
return fixer.replaceTextRange(range, replacementText);
|
|
2196
|
+
},
|
|
2197
|
+
messageId: "unnecessaryBraces",
|
|
2198
|
+
node: node2
|
|
2199
|
+
});
|
|
2200
|
+
}
|
|
2201
|
+
}
|
|
2202
|
+
function detectIndentStep(sourceCode) {
|
|
2203
|
+
const text = sourceCode.getText();
|
|
2204
|
+
const lines = text.split("\n");
|
|
2205
|
+
const indentCounts = /* @__PURE__ */ new Map();
|
|
2206
|
+
for (const line of lines) {
|
|
2207
|
+
const match = line.match(/^( *)/);
|
|
2208
|
+
if (match) {
|
|
2209
|
+
const spaces = match[1].length;
|
|
2210
|
+
if (spaces > 0)
|
|
2211
|
+
indentCounts.set(spaces, (indentCounts.get(spaces) ?? 0) + 1);
|
|
2212
|
+
}
|
|
2213
|
+
}
|
|
2214
|
+
const sortedIndents = Array.from(indentCounts.entries()).filter(([spaces]) => spaces > 0).sort((a, b) => a[0] - b[0]);
|
|
2215
|
+
if (sortedIndents.length === 0)
|
|
2216
|
+
return 2;
|
|
2217
|
+
const minIndent = sortedIndents[0][0];
|
|
2218
|
+
for (const step of [2, 4]) {
|
|
2219
|
+
const isMultipleOfStep = sortedIndents.every(([n]) => n % step === 0);
|
|
2220
|
+
if (isMultipleOfStep)
|
|
2221
|
+
return step;
|
|
2222
|
+
}
|
|
2223
|
+
return minIndent;
|
|
2224
|
+
}
|
|
2225
|
+
function reindentText(text, newBaseIndent, indentStep) {
|
|
2226
|
+
const lines = text.split("\n");
|
|
2227
|
+
let minIndent = Infinity;
|
|
2228
|
+
for (let i = 1; i < lines.length; i++) {
|
|
2229
|
+
const line = lines[i];
|
|
2230
|
+
if (line.trim() === "")
|
|
2231
|
+
continue;
|
|
2232
|
+
const match = line.match(/^( *)/);
|
|
2233
|
+
if (match)
|
|
2234
|
+
minIndent = Math.min(minIndent, match[1].length);
|
|
2235
|
+
}
|
|
2236
|
+
if (minIndent === Infinity) {
|
|
2237
|
+
return lines.map((line) => {
|
|
2238
|
+
if (line.trim() === "")
|
|
2239
|
+
return "";
|
|
2240
|
+
return newBaseIndent + indentStep + line.trimStart();
|
|
2241
|
+
}).join("\n");
|
|
2242
|
+
}
|
|
2243
|
+
return lines.map((line, index) => {
|
|
2244
|
+
if (line.trim() === "")
|
|
2245
|
+
return "";
|
|
2246
|
+
if (index === 0)
|
|
2247
|
+
return newBaseIndent + indentStep + line.trimStart();
|
|
2248
|
+
const relativeIndent = line.slice(minIndent);
|
|
2249
|
+
return newBaseIndent + indentStep + relativeIndent;
|
|
2250
|
+
}).join("\n");
|
|
2251
|
+
}
|
|
2252
|
+
function checkNonBlockStatement(node2, context) {
|
|
2253
|
+
if (node2.type === "BlockStatement")
|
|
2254
|
+
return;
|
|
2255
|
+
const sourceCode = context.getSourceCode();
|
|
2256
|
+
if (!isSingleLineStatement(node2, sourceCode)) {
|
|
2257
|
+
context.report({
|
|
2258
|
+
fix(fixer) {
|
|
2259
|
+
const statementText = sourceCode.getText(node2);
|
|
2260
|
+
const parent = node2.parent;
|
|
2261
|
+
const parentLine = parent?.loc?.start?.line ?? node2.loc?.start?.line ?? 1;
|
|
2262
|
+
const baseIndent = getLineIndent$1(sourceCode, parentLine);
|
|
2263
|
+
const indentStepSize = detectIndentStep(sourceCode);
|
|
2264
|
+
const indentStep = " ".repeat(indentStepSize);
|
|
2265
|
+
const reindentedText = reindentText(
|
|
2266
|
+
statementText,
|
|
2267
|
+
baseIndent,
|
|
2268
|
+
indentStep
|
|
2269
|
+
);
|
|
2270
|
+
const fixed = `{
|
|
2271
|
+
${reindentedText}
|
|
2272
|
+
${baseIndent}}`;
|
|
2273
|
+
return [fixer.replaceText(node2, fixed)];
|
|
2274
|
+
},
|
|
2275
|
+
messageId: "missingBraces",
|
|
2276
|
+
node: node2
|
|
2277
|
+
});
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
function checkDoWhileStatement(node2, context) {
|
|
2281
|
+
if (node2.body.type === "BlockStatement")
|
|
2282
|
+
checkBlockStatement(node2.body, context);
|
|
2283
|
+
else
|
|
2284
|
+
checkNonBlockStatement(node2.body, context);
|
|
2285
|
+
}
|
|
2286
|
+
function checkForInStatement(node2, context) {
|
|
2287
|
+
if (node2.body.type === "BlockStatement")
|
|
2288
|
+
checkBlockStatement(node2.body, context);
|
|
2289
|
+
else
|
|
2290
|
+
checkNonBlockStatement(node2.body, context);
|
|
2291
|
+
}
|
|
2292
|
+
function checkForOfStatement(node2, context) {
|
|
2293
|
+
if (node2.body.type === "BlockStatement")
|
|
2294
|
+
checkBlockStatement(node2.body, context);
|
|
2295
|
+
else
|
|
2296
|
+
checkNonBlockStatement(node2.body, context);
|
|
2297
|
+
}
|
|
2298
|
+
function checkForStatement(node2, context) {
|
|
2299
|
+
if (node2.body.type === "BlockStatement")
|
|
2300
|
+
checkBlockStatement(node2.body, context);
|
|
2301
|
+
else
|
|
2302
|
+
checkNonBlockStatement(node2.body, context);
|
|
2303
|
+
}
|
|
2304
|
+
function checkIfStatement(node2, context) {
|
|
2305
|
+
if (node2.consequent.type === "BlockStatement")
|
|
2306
|
+
checkBlockStatement(node2.consequent, context);
|
|
2307
|
+
else
|
|
2308
|
+
checkNonBlockStatement(node2.consequent, context);
|
|
2309
|
+
if (!node2.alternate)
|
|
2310
|
+
return;
|
|
2311
|
+
if (node2.alternate.type === "IfStatement")
|
|
2312
|
+
return;
|
|
2313
|
+
if (node2.alternate.type === "BlockStatement")
|
|
2314
|
+
checkBlockStatement(node2.alternate, context);
|
|
2315
|
+
else
|
|
2316
|
+
checkNonBlockStatement(node2.alternate, context);
|
|
2317
|
+
}
|
|
2318
|
+
function checkWhileStatement(node2, context) {
|
|
2319
|
+
if (node2.body.type === "BlockStatement")
|
|
2320
|
+
checkBlockStatement(node2.body, context);
|
|
2321
|
+
else
|
|
2322
|
+
checkNonBlockStatement(node2.body, context);
|
|
2323
|
+
}
|
|
2324
|
+
const noUnnecessaryBraces = {
|
|
2325
|
+
create(context) {
|
|
2326
|
+
return {
|
|
2327
|
+
DoWhileStatement: (node2) => checkDoWhileStatement(node2, context),
|
|
2328
|
+
ForInStatement: (node2) => checkForInStatement(node2, context),
|
|
2329
|
+
ForOfStatement: (node2) => checkForOfStatement(node2, context),
|
|
2330
|
+
ForStatement: (node2) => checkForStatement(node2, context),
|
|
2331
|
+
IfStatement: (node2) => checkIfStatement(node2, context),
|
|
2332
|
+
WhileStatement: (node2) => checkWhileStatement(node2, context)
|
|
2333
|
+
};
|
|
2334
|
+
},
|
|
2335
|
+
meta: {
|
|
2336
|
+
docs: {
|
|
2337
|
+
description: "Enforce consistent brace usage for single-statement control bodies."
|
|
2338
|
+
},
|
|
2339
|
+
fixable: "code",
|
|
2340
|
+
messages: {
|
|
2341
|
+
missingBraces: "Multi-line statement must be wrapped in braces",
|
|
2342
|
+
unnecessaryBraces: "Unnecessary braces around single-line statement"
|
|
2343
|
+
},
|
|
2344
|
+
schema: [],
|
|
2345
|
+
type: "suggestion"
|
|
2346
|
+
}
|
|
2347
|
+
};
|
|
2348
|
+
function isShorthandProperty(property) {
|
|
2349
|
+
return property.shorthand;
|
|
2350
|
+
}
|
|
2351
|
+
function areAllShorthand(properties) {
|
|
2352
|
+
return properties.every(isShorthandProperty);
|
|
2353
|
+
}
|
|
2354
|
+
function getPropertyText(sourceCode, property) {
|
|
2355
|
+
return sourceCode.getText(property);
|
|
2356
|
+
}
|
|
2357
|
+
function getInlineObjectLength(sourceCode, properties) {
|
|
2358
|
+
if (properties.length === 0)
|
|
2359
|
+
return 2;
|
|
2360
|
+
const propLengths = properties.map((p) => getPropertyText(sourceCode, p).length);
|
|
2361
|
+
const propsTotal = propLengths.reduce((a, b) => a + b, 0);
|
|
2362
|
+
const commas = Math.max(0, properties.length - 1);
|
|
2363
|
+
return 2 + propsTotal + commas;
|
|
2364
|
+
}
|
|
2365
|
+
function checkMultiline(sourceCode, context, node2, braces, maxLength) {
|
|
2366
|
+
const properties = node2.properties;
|
|
2367
|
+
const allShorthand = areAllShorthand(properties);
|
|
2368
|
+
if (!allShorthand)
|
|
2369
|
+
return;
|
|
2370
|
+
const inlineLength = getInlineObjectLength(sourceCode, properties);
|
|
2371
|
+
if (inlineLength > maxLength)
|
|
2372
|
+
return;
|
|
2373
|
+
context.report({
|
|
2374
|
+
fix(fixer) {
|
|
2375
|
+
const names = [];
|
|
2376
|
+
for (const prop of properties) {
|
|
2377
|
+
if (prop.key.type === "Identifier")
|
|
2378
|
+
names.push(prop.key.name);
|
|
2379
|
+
else
|
|
2380
|
+
names.push(sourceCode.getText(prop));
|
|
2381
|
+
}
|
|
2382
|
+
return fixer.replaceText(node2, `{${names.join(", ")}}`);
|
|
2383
|
+
},
|
|
2384
|
+
messageId: "multilineCanBeSingleLine",
|
|
2385
|
+
node: properties[0]
|
|
2386
|
+
});
|
|
2387
|
+
}
|
|
2388
|
+
function buildMultilineFix(fixer, braces, properties, sourceCode) {
|
|
2389
|
+
const indentStep = detectIndentStep(sourceCode);
|
|
2390
|
+
const lineIndent = sourceCode.getLines()[braces.openingBrace.loc.start.line - 1].match(/^\s*/)?.[0] ?? "";
|
|
2391
|
+
const indent = lineIndent + " ".repeat(indentStep);
|
|
2392
|
+
const lines = ["{"];
|
|
2393
|
+
for (const prop of properties) {
|
|
2394
|
+
const propText = sourceCode.getText(prop);
|
|
2395
|
+
lines.push(`${indent}${propText},`);
|
|
2396
|
+
}
|
|
2397
|
+
lines.push(`${lineIndent}}`);
|
|
2398
|
+
return fixer.replaceTextRange(
|
|
2399
|
+
[braces.openingBrace.range[0], braces.closingBrace.range[1]],
|
|
2400
|
+
lines.join("\n")
|
|
2401
|
+
);
|
|
2402
|
+
}
|
|
2403
|
+
function getPropertyName(sourceCode, prop) {
|
|
2404
|
+
if (prop.key.type === "Identifier")
|
|
2405
|
+
return prop.key.name;
|
|
2406
|
+
return sourceCode.getText(prop);
|
|
2407
|
+
}
|
|
2408
|
+
function buildShorthandFix(fixer, braces, properties, sourceCode) {
|
|
2409
|
+
const names = properties.map((p) => getPropertyName(sourceCode, p));
|
|
2410
|
+
return fixer.replaceTextRange(
|
|
2411
|
+
[braces.openingBrace.range[0], braces.closingBrace.range[1]],
|
|
2412
|
+
`{${names.join(", ")}}`
|
|
2413
|
+
);
|
|
2414
|
+
}
|
|
2415
|
+
function canConvertToShorthand(property) {
|
|
2416
|
+
if (property.shorthand)
|
|
2417
|
+
return true;
|
|
2418
|
+
if (property.kind !== "init")
|
|
2419
|
+
return false;
|
|
2420
|
+
if (property.key.type !== "Identifier")
|
|
2421
|
+
return false;
|
|
2422
|
+
if (property.value.type !== "Identifier")
|
|
2423
|
+
return false;
|
|
2424
|
+
return property.key.name === property.value.name;
|
|
2425
|
+
}
|
|
2426
|
+
function shouldCollapseToShorthand(properties, sourceCode, maxLength) {
|
|
2427
|
+
const anyShorthand = properties.some((p) => p.shorthand);
|
|
2428
|
+
const allCanConvert = properties.every(canConvertToShorthand);
|
|
2429
|
+
const shorthandLength = allCanConvert ? getInlineObjectLength(sourceCode, properties) : Infinity;
|
|
2430
|
+
return !anyShorthand && allCanConvert && shorthandLength <= maxLength;
|
|
2431
|
+
}
|
|
2432
|
+
function checkSingleLine(sourceCode, context, properties, braces, maxLength) {
|
|
2433
|
+
if (properties.length === 1)
|
|
2434
|
+
return;
|
|
2435
|
+
const allShorthand = areAllShorthand(properties);
|
|
2436
|
+
const inlineLength = getInlineObjectLength(sourceCode, properties);
|
|
2437
|
+
if (allShorthand && inlineLength <= maxLength)
|
|
2438
|
+
return;
|
|
2439
|
+
if (!allShorthand) {
|
|
2440
|
+
if (shouldCollapseToShorthand(properties, sourceCode, maxLength)) {
|
|
2441
|
+
context.report({
|
|
2442
|
+
fix: (fixer) => buildShorthandFix(fixer, braces, properties, sourceCode),
|
|
2443
|
+
messageId: "mixedPropertiesNotAllowed",
|
|
2444
|
+
node: properties[0]
|
|
2445
|
+
});
|
|
2446
|
+
return;
|
|
2447
|
+
}
|
|
2448
|
+
context.report({
|
|
2449
|
+
fix: (fixer) => buildMultilineFix(fixer, braces, properties, sourceCode),
|
|
2450
|
+
messageId: "mixedPropertiesNotAllowed",
|
|
2451
|
+
node: properties[0]
|
|
2452
|
+
});
|
|
2453
|
+
return;
|
|
2454
|
+
}
|
|
2455
|
+
context.report({
|
|
2456
|
+
fix: (fixer) => buildMultilineFix(fixer, braces, properties, sourceCode),
|
|
2457
|
+
messageId: "singleLineExceedsMaxLength",
|
|
2458
|
+
node: properties[0]
|
|
2459
|
+
});
|
|
2460
|
+
}
|
|
2461
|
+
const defaultOptions$2 = {
|
|
2462
|
+
maxLength: 80
|
|
2463
|
+
};
|
|
2464
|
+
function getBraces(sourceCode, node2) {
|
|
2465
|
+
const properties = node2.properties;
|
|
2466
|
+
if (properties.length === 0)
|
|
2467
|
+
return null;
|
|
2468
|
+
const firstProp = properties[0];
|
|
2469
|
+
const lastProp = properties[properties.length - 1];
|
|
2470
|
+
const openingBrace = sourceCode.getTokenBefore(firstProp);
|
|
2471
|
+
const closingBrace = sourceCode.getTokenAfter(lastProp);
|
|
2472
|
+
if (!openingBrace || !closingBrace)
|
|
2473
|
+
return null;
|
|
2474
|
+
return { closingBrace, openingBrace };
|
|
2475
|
+
}
|
|
2476
|
+
function checkObject(sourceCode, context, node2) {
|
|
2477
|
+
const options = context.options[0] ?? {};
|
|
2478
|
+
const maxLength = options.maxLength ?? defaultOptions$2.maxLength;
|
|
2479
|
+
const properties = node2.properties;
|
|
2480
|
+
if (properties.length === 0)
|
|
2481
|
+
return;
|
|
2482
|
+
const braces = getBraces(sourceCode, node2);
|
|
2483
|
+
if (!braces)
|
|
2484
|
+
return;
|
|
2485
|
+
const firstLine = braces.openingBrace.loc.start.line;
|
|
2486
|
+
const lastLine = braces.closingBrace.loc.end.line;
|
|
2487
|
+
if (firstLine === lastLine)
|
|
2488
|
+
checkSingleLine(sourceCode, context, properties, braces, maxLength);
|
|
2489
|
+
else
|
|
2490
|
+
checkMultiline(sourceCode, context, node2, braces, maxLength);
|
|
2491
|
+
}
|
|
2492
|
+
const messageIds$3 = {
|
|
2493
|
+
mixedPropertiesNotAllowed: "mixedPropertiesNotAllowed",
|
|
2494
|
+
multilineCanBeSingleLine: "multilineCanBeSingleLine",
|
|
2495
|
+
singleLineExceedsMaxLength: "singleLineExceedsMaxLength"
|
|
2496
|
+
};
|
|
2497
|
+
const objectPropertyLineBreak = {
|
|
2498
|
+
create(context) {
|
|
2499
|
+
const sourceCode = context.sourceCode ?? context.getSourceCode();
|
|
2500
|
+
return {
|
|
2501
|
+
ObjectExpression(node2) {
|
|
2502
|
+
checkObject(sourceCode, context, node2);
|
|
2503
|
+
}
|
|
2504
|
+
};
|
|
2505
|
+
},
|
|
2506
|
+
meta: {
|
|
2507
|
+
docs: {
|
|
2508
|
+
description: "Enforce object literal formatting based on complexity and line length."
|
|
2509
|
+
},
|
|
2510
|
+
fixable: "code",
|
|
2511
|
+
messages: messageIds$3,
|
|
2512
|
+
schema: [{
|
|
2513
|
+
additionalProperties: false,
|
|
2514
|
+
properties: {
|
|
2515
|
+
maxLength: {
|
|
2516
|
+
type: "number"
|
|
2517
|
+
}
|
|
2518
|
+
},
|
|
2519
|
+
type: "object"
|
|
2520
|
+
}],
|
|
2521
|
+
type: "layout"
|
|
2522
|
+
}
|
|
2523
|
+
};
|
|
2524
|
+
const messageIds$2 = {
|
|
2525
|
+
tooManyExports: "Only one export is allowed per file. Found {{count}} exports."
|
|
2526
|
+
};
|
|
2527
|
+
const oneExportPerFile = {
|
|
2528
|
+
create(context) {
|
|
2529
|
+
const filename = context.filename;
|
|
2530
|
+
if (isExempt$2(filename))
|
|
2531
|
+
return {};
|
|
2532
|
+
let exportCount = 0;
|
|
2533
|
+
return {
|
|
2534
|
+
ExportDefaultDeclaration(_node) {
|
|
2535
|
+
exportCount++;
|
|
2536
|
+
},
|
|
2537
|
+
ExportNamedDeclaration(_node) {
|
|
2538
|
+
exportCount++;
|
|
2539
|
+
},
|
|
2540
|
+
"Program:exit"(programNode) {
|
|
2541
|
+
if (exportCount > 1) {
|
|
2542
|
+
context.report({
|
|
2543
|
+
data: { count: exportCount },
|
|
2544
|
+
messageId: "tooManyExports",
|
|
2545
|
+
node: programNode
|
|
2546
|
+
});
|
|
2547
|
+
}
|
|
2548
|
+
}
|
|
2549
|
+
};
|
|
2550
|
+
},
|
|
2551
|
+
meta: {
|
|
2552
|
+
docs: {
|
|
2553
|
+
description: "Enforce single export per file."
|
|
2554
|
+
},
|
|
2555
|
+
messages: messageIds$2,
|
|
2556
|
+
schema: [],
|
|
2557
|
+
type: "suggestion"
|
|
2558
|
+
}
|
|
2559
|
+
};
|
|
2560
|
+
function isValidExportSpecifier(specifier, localDeclarations) {
|
|
2561
|
+
if (specifier.local.type !== "Identifier")
|
|
2562
|
+
return false;
|
|
2563
|
+
if (specifier.exported.type !== "Identifier")
|
|
2564
|
+
return false;
|
|
2565
|
+
if (specifier.local.name !== specifier.exported.name)
|
|
2566
|
+
return false;
|
|
2567
|
+
return localDeclarations.has(specifier.local.name);
|
|
2568
|
+
}
|
|
2569
|
+
function canInlineSpecifiers(specifiers, localDeclarations) {
|
|
2570
|
+
return specifiers.every(
|
|
2571
|
+
(spec) => isValidExportSpecifier(spec, localDeclarations)
|
|
2572
|
+
);
|
|
2573
|
+
}
|
|
2574
|
+
function getDeclarationName(node2) {
|
|
2575
|
+
if (node2.type !== "VariableDeclaration")
|
|
2576
|
+
return node2.id?.name ?? null;
|
|
2577
|
+
const declarations = node2.declarations;
|
|
2578
|
+
if (declarations.length === 1) {
|
|
2579
|
+
const id = declarations[0].id;
|
|
2580
|
+
if (id.type === "Identifier")
|
|
2581
|
+
return id.name;
|
|
2582
|
+
}
|
|
2583
|
+
return null;
|
|
2584
|
+
}
|
|
2585
|
+
function isExportableDeclaration(node2) {
|
|
2586
|
+
const type = node2.type;
|
|
2587
|
+
return type === "TSInterfaceDeclaration" || type === "TSTypeAliasDeclaration" || type === "ClassDeclaration" || type === "FunctionDeclaration" || type === "VariableDeclaration";
|
|
2588
|
+
}
|
|
2589
|
+
const preferInlineExport = {
|
|
2590
|
+
create(context) {
|
|
2591
|
+
const localDeclarations = /* @__PURE__ */ new Map();
|
|
2592
|
+
function visitDeclaration(node2) {
|
|
2593
|
+
if (!isExportableDeclaration(node2))
|
|
2594
|
+
return;
|
|
2595
|
+
const name = getDeclarationName(node2);
|
|
2596
|
+
if (name)
|
|
2597
|
+
localDeclarations.set(name, { name, node: node2 });
|
|
2598
|
+
}
|
|
2599
|
+
return {
|
|
2600
|
+
ClassDeclaration: visitDeclaration,
|
|
2601
|
+
ExportNamedDeclaration(node2) {
|
|
2602
|
+
if (node2.source)
|
|
2603
|
+
return;
|
|
2604
|
+
if (!node2.specifiers || node2.specifiers.length === 0)
|
|
2605
|
+
return;
|
|
2606
|
+
if (!canInlineSpecifiers(node2.specifiers, localDeclarations))
|
|
2607
|
+
return;
|
|
2608
|
+
context.report({
|
|
2609
|
+
fix(fixer) {
|
|
2610
|
+
const fixes = [];
|
|
2611
|
+
for (const specifier of node2.specifiers) {
|
|
2612
|
+
const name = specifier.local.name;
|
|
2613
|
+
const decl = localDeclarations.get(name);
|
|
2614
|
+
if (decl)
|
|
2615
|
+
fixes.push(fixer.insertTextBefore(decl.node, "export "));
|
|
2616
|
+
}
|
|
2617
|
+
fixes.push(fixer.remove(node2));
|
|
2618
|
+
return fixes;
|
|
2619
|
+
},
|
|
2620
|
+
messageId: "preferInline",
|
|
2621
|
+
node: node2
|
|
2622
|
+
});
|
|
2623
|
+
},
|
|
2624
|
+
FunctionDeclaration: visitDeclaration,
|
|
2625
|
+
TSInterfaceDeclaration: visitDeclaration,
|
|
2626
|
+
TSTypeAliasDeclaration: visitDeclaration,
|
|
2627
|
+
VariableDeclaration: visitDeclaration
|
|
2628
|
+
};
|
|
2629
|
+
},
|
|
2630
|
+
meta: {
|
|
2631
|
+
docs: {
|
|
2632
|
+
description: "Enforce using inline export syntax instead of separate export statements."
|
|
2633
|
+
},
|
|
2634
|
+
fixable: "code",
|
|
2635
|
+
messages: {
|
|
2636
|
+
preferInline: "Use inline export instead of separate export statement"
|
|
2637
|
+
},
|
|
2638
|
+
schema: [],
|
|
2639
|
+
type: "suggestion"
|
|
2640
|
+
}
|
|
2641
|
+
};
|
|
2642
|
+
function buildCollapsedParams(sourceCode, params) {
|
|
2643
|
+
const paramsText = params.map((param, index) => {
|
|
2644
|
+
const text = sourceCode.getText(param);
|
|
2645
|
+
const isLastParam = index === params.length - 1;
|
|
2646
|
+
return isLastParam ? text : text + ",";
|
|
2647
|
+
}).join(" ");
|
|
2648
|
+
return `(${paramsText})`;
|
|
2649
|
+
}
|
|
2650
|
+
function calculateCollapsedLength(sourceCode, openingParen, collapsedParams, returnType) {
|
|
2651
|
+
let returnTypeText = "";
|
|
2652
|
+
if (returnType)
|
|
2653
|
+
returnTypeText = sourceCode.getText(returnType);
|
|
2654
|
+
const allLines = sourceCode.getText().split("\n");
|
|
2655
|
+
const closingLine = allLines[openingParen.loc.start.line - 1];
|
|
2656
|
+
const textAfterClosingParen = closingLine.slice(openingParen.loc.start.column);
|
|
2657
|
+
return openingParen.loc.start.column + collapsedParams.length + returnTypeText.length + textAfterClosingParen.length;
|
|
2658
|
+
}
|
|
2659
|
+
const defaultOptions$1 = {
|
|
2660
|
+
maxLength: 80
|
|
2661
|
+
};
|
|
2662
|
+
function getArrowFunctionParens(sourceCode, params) {
|
|
2663
|
+
if (params.length === 0)
|
|
2664
|
+
return null;
|
|
2665
|
+
const firstParam = params[0];
|
|
2666
|
+
const lastParam = params[params.length - 1];
|
|
2667
|
+
const openingParen = sourceCode.getTokenBefore(firstParam);
|
|
2668
|
+
let closingParen = sourceCode.getTokenAfter(lastParam);
|
|
2669
|
+
while (closingParen && closingParen.value === ",")
|
|
2670
|
+
closingParen = sourceCode.getTokenAfter(closingParen);
|
|
2671
|
+
if (!openingParen || !closingParen)
|
|
2672
|
+
return null;
|
|
2673
|
+
if (openingParen.value !== "(" || closingParen.value !== ")")
|
|
2674
|
+
return null;
|
|
2675
|
+
return { closingParen, openingParen };
|
|
2676
|
+
}
|
|
2677
|
+
function isShorthand(sourceCode, node2) {
|
|
2678
|
+
if (node2.params.length !== 1)
|
|
2679
|
+
return false;
|
|
2680
|
+
const firstParam = node2.params[0];
|
|
2681
|
+
const tokenBefore = sourceCode.getTokenBefore(firstParam);
|
|
2682
|
+
return !tokenBefore || tokenBefore.value !== "(";
|
|
2683
|
+
}
|
|
2684
|
+
function reportViolation(context, node2, collapsedParams, returnTypeText, arrowToken, openingParen) {
|
|
2685
|
+
context.report({
|
|
2686
|
+
fix: (fixer) => fixer.replaceTextRange(
|
|
2687
|
+
[openingParen.range[0], arrowToken.range[1]],
|
|
2688
|
+
collapsedParams + returnTypeText + " =>"
|
|
2689
|
+
),
|
|
2690
|
+
messageId: "singleLine",
|
|
2691
|
+
node: node2
|
|
2692
|
+
});
|
|
2693
|
+
}
|
|
2694
|
+
function checkArrowFunction(sourceCode, context, node2) {
|
|
2695
|
+
const options = context.options[0] ?? {};
|
|
2696
|
+
const maxLength = options.maxLength ?? defaultOptions$1.maxLength;
|
|
2697
|
+
if (isShorthand(sourceCode, node2))
|
|
2698
|
+
return;
|
|
2699
|
+
const parens = getArrowFunctionParens(sourceCode, node2.params);
|
|
2700
|
+
if (!parens)
|
|
2701
|
+
return;
|
|
2702
|
+
const { closingParen, openingParen } = parens;
|
|
2703
|
+
if (openingParen.loc.start.line === closingParen.loc.end.line)
|
|
2704
|
+
return;
|
|
2705
|
+
const arrowToken = sourceCode.getTokenAfter(
|
|
2706
|
+
closingParen,
|
|
2707
|
+
(token) => token.value === "=>"
|
|
2708
|
+
);
|
|
2709
|
+
if (!arrowToken)
|
|
2710
|
+
return;
|
|
2711
|
+
const collapsedParams = buildCollapsedParams(sourceCode, node2.params);
|
|
2712
|
+
const collapsedLength = calculateCollapsedLength(
|
|
2713
|
+
sourceCode,
|
|
2714
|
+
openingParen,
|
|
2715
|
+
collapsedParams,
|
|
2716
|
+
node2.returnType
|
|
2717
|
+
);
|
|
2718
|
+
if (collapsedLength <= maxLength) {
|
|
2719
|
+
const returnTypeText = node2.returnType ? sourceCode.getText(node2.returnType) : "";
|
|
2720
|
+
reportViolation(
|
|
2721
|
+
context,
|
|
2722
|
+
node2,
|
|
2723
|
+
collapsedParams,
|
|
2724
|
+
returnTypeText,
|
|
2725
|
+
arrowToken,
|
|
2726
|
+
openingParen
|
|
2727
|
+
);
|
|
2728
|
+
}
|
|
2729
|
+
}
|
|
2730
|
+
const messageIds$1 = {
|
|
2731
|
+
singleLine: "Arrow function parameters can be on a single line"
|
|
2732
|
+
};
|
|
2733
|
+
const singleLineArrowFunctionParameters = {
|
|
2734
|
+
create(context) {
|
|
2735
|
+
const sourceCode = context.sourceCode ?? context.getSourceCode();
|
|
2736
|
+
return {
|
|
2737
|
+
ArrowFunctionExpression(node2) {
|
|
2738
|
+
if (node2.params.length === 0)
|
|
2739
|
+
return;
|
|
2740
|
+
checkArrowFunction(sourceCode, context, node2);
|
|
2741
|
+
}
|
|
2742
|
+
};
|
|
2743
|
+
},
|
|
2744
|
+
meta: {
|
|
2745
|
+
docs: {
|
|
2746
|
+
description: "Enforce arrow function parameters to be on a single line when they fit."
|
|
2747
|
+
},
|
|
2748
|
+
fixable: "code",
|
|
2749
|
+
messages: messageIds$1,
|
|
2750
|
+
schema: [{
|
|
2751
|
+
additionalProperties: false,
|
|
2752
|
+
properties: {
|
|
2753
|
+
maxLength: {
|
|
2754
|
+
type: "number"
|
|
2755
|
+
}
|
|
2756
|
+
},
|
|
2757
|
+
type: "object"
|
|
2758
|
+
}],
|
|
2759
|
+
type: "layout"
|
|
2760
|
+
}
|
|
2761
|
+
};
|
|
2762
|
+
const defaultOptions = {
|
|
2763
|
+
maxLength: 80
|
|
2764
|
+
};
|
|
2765
|
+
function getParens(sourceCode, nodes) {
|
|
2766
|
+
if (nodes.length === 0)
|
|
2767
|
+
return null;
|
|
2768
|
+
const firstNode = nodes[0];
|
|
2769
|
+
const lastNode = nodes[nodes.length - 1];
|
|
2770
|
+
const openingParen = sourceCode.getTokenBefore(
|
|
2771
|
+
firstNode,
|
|
2772
|
+
(token) => token.value === "("
|
|
2773
|
+
);
|
|
2774
|
+
const closingParen = sourceCode.getTokenAfter(
|
|
2775
|
+
lastNode,
|
|
2776
|
+
(token) => token.value === ")"
|
|
2777
|
+
);
|
|
2778
|
+
if (!openingParen || !closingParen)
|
|
2779
|
+
return null;
|
|
2780
|
+
return { closingParen, openingParen };
|
|
2781
|
+
}
|
|
2782
|
+
function checkFunction(sourceCode, context, node2) {
|
|
2783
|
+
const options = context.options[0] ?? {};
|
|
2784
|
+
const maxLength = options.maxLength ?? defaultOptions.maxLength;
|
|
2785
|
+
const params = node2.params;
|
|
2786
|
+
if (params.length === 0)
|
|
2787
|
+
return;
|
|
2788
|
+
const parens = getParens(sourceCode, params);
|
|
2789
|
+
if (!isValidParens(parens))
|
|
2790
|
+
return;
|
|
2791
|
+
if (parens.openingParen.loc.start.line === parens.closingParen.loc.end.line)
|
|
2792
|
+
return;
|
|
2793
|
+
const paramsText = params.map((param, index) => {
|
|
2794
|
+
const text = sourceCode.getText(param);
|
|
2795
|
+
const isLastParam = index === params.length - 1;
|
|
2796
|
+
if (isLastParam)
|
|
2797
|
+
return text;
|
|
2798
|
+
const comma = sourceCode.getTokenAfter(
|
|
2799
|
+
param,
|
|
2800
|
+
(token) => token.value === ","
|
|
2801
|
+
);
|
|
2802
|
+
if (comma && comma.loc.end.line === param.loc.end.line)
|
|
2803
|
+
return text + ",";
|
|
2804
|
+
return text;
|
|
2805
|
+
}).join(" ");
|
|
2806
|
+
const closingLine = parens.closingParen.loc.end.line;
|
|
2807
|
+
const closingCol = parens.closingParen.loc.end.column;
|
|
2808
|
+
const closingLineText = getLineLength(sourceCode, closingLine) > closingCol ? sourceCode.getText().split("\n")[closingLine - 1].slice(closingCol) : "";
|
|
2809
|
+
const singleLineLength = parens.openingParen.loc.start.column + 1 + paramsText.length + 1 + closingLineText.length;
|
|
2810
|
+
if (singleLineLength <= maxLength) {
|
|
2811
|
+
context.report({
|
|
2812
|
+
fix: (fixer) => fixer.replaceTextRange(
|
|
2813
|
+
[parens.openingParen.range[0], parens.closingParen.range[1]],
|
|
2814
|
+
`(${paramsText})`
|
|
2815
|
+
),
|
|
2816
|
+
messageId: "singleLine",
|
|
2817
|
+
node: node2
|
|
2818
|
+
});
|
|
2819
|
+
}
|
|
2820
|
+
}
|
|
2821
|
+
const messageIds = {
|
|
2822
|
+
singleLine: "Function parameters can be on a single line"
|
|
2823
|
+
};
|
|
2824
|
+
const singleLineFunctionParameters = {
|
|
2825
|
+
create(context) {
|
|
2826
|
+
const sourceCode = context.sourceCode ?? context.getSourceCode();
|
|
2827
|
+
return {
|
|
2828
|
+
FunctionDeclaration(node2) {
|
|
2829
|
+
checkFunction(sourceCode, context, node2);
|
|
2830
|
+
},
|
|
2831
|
+
FunctionExpression(node2) {
|
|
2832
|
+
checkFunction(sourceCode, context, node2);
|
|
2833
|
+
},
|
|
2834
|
+
TSCallSignatureDeclaration(node2) {
|
|
2835
|
+
checkFunction(sourceCode, context, node2);
|
|
2836
|
+
},
|
|
2837
|
+
TSFunctionType(node2) {
|
|
2838
|
+
checkFunction(sourceCode, context, node2);
|
|
2839
|
+
},
|
|
2840
|
+
TSMethodSignature(node2) {
|
|
2841
|
+
checkFunction(sourceCode, context, node2);
|
|
2842
|
+
}
|
|
2843
|
+
};
|
|
2844
|
+
},
|
|
2845
|
+
meta: {
|
|
2846
|
+
docs: {
|
|
2847
|
+
description: "Enforce function parameters to be on a single line when they fit."
|
|
2848
|
+
},
|
|
2849
|
+
fixable: "code",
|
|
2850
|
+
messages: messageIds,
|
|
2851
|
+
schema: [{
|
|
2852
|
+
additionalProperties: false,
|
|
2853
|
+
properties: {
|
|
2854
|
+
maxLength: {
|
|
2855
|
+
type: "number"
|
|
2856
|
+
}
|
|
2857
|
+
},
|
|
2858
|
+
type: "object"
|
|
2859
|
+
}],
|
|
2860
|
+
type: "layout"
|
|
2861
|
+
}
|
|
2862
|
+
};
|
|
208
2863
|
function formatAttributes(attributes) {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
2864
|
+
if (attributes.length === 0)
|
|
2865
|
+
return "";
|
|
2866
|
+
const formatted = attributes.map(
|
|
2867
|
+
(attr) => {
|
|
2868
|
+
const key = attr.key.type === "Identifier" ? attr.key.name : attr.key.value;
|
|
2869
|
+
const value = attr.value.value;
|
|
2870
|
+
return `${key}: '${value}'`;
|
|
2871
|
+
}
|
|
2872
|
+
).join(", ");
|
|
2873
|
+
return ` with {${formatted}}`;
|
|
213
2874
|
}
|
|
214
|
-
//#endregion
|
|
215
|
-
//#region src/rules/singleLineImports/formatNamed.ts
|
|
216
2875
|
function formatNamed(specifiers, sourceCode) {
|
|
217
|
-
|
|
2876
|
+
return specifiers.map((s) => sourceCode.getText(s)).join(", ");
|
|
218
2877
|
}
|
|
219
|
-
//#endregion
|
|
220
|
-
//#region src/rules/singleLineImports/formatSpecifiers.ts
|
|
221
2878
|
function formatSpecifiers(declaration, sourceCode) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
2879
|
+
const defaultSpecifier = declaration.specifiers.find(
|
|
2880
|
+
(s) => s.type === "ImportDefaultSpecifier"
|
|
2881
|
+
);
|
|
2882
|
+
const namespaceSpecifier = declaration.specifiers.find(
|
|
2883
|
+
(s) => s.type === "ImportNamespaceSpecifier"
|
|
2884
|
+
);
|
|
2885
|
+
const namedSpecifiers = declaration.specifiers.filter(
|
|
2886
|
+
(s) => s.type === "ImportSpecifier"
|
|
2887
|
+
);
|
|
2888
|
+
if (namespaceSpecifier)
|
|
2889
|
+
return `* as ${namespaceSpecifier.local.name}`;
|
|
2890
|
+
if (defaultSpecifier && namedSpecifiers.length > 0) {
|
|
2891
|
+
return `${defaultSpecifier.local.name}, {${formatNamed(
|
|
2892
|
+
namedSpecifiers,
|
|
2893
|
+
sourceCode
|
|
2894
|
+
)}}`;
|
|
2895
|
+
}
|
|
2896
|
+
if (defaultSpecifier)
|
|
2897
|
+
return defaultSpecifier.local.name;
|
|
2898
|
+
if (namedSpecifiers.length === 0)
|
|
2899
|
+
return "";
|
|
2900
|
+
return `{${formatNamed(namedSpecifiers, sourceCode)}}`;
|
|
2901
|
+
}
|
|
2902
|
+
function createImportFix$1(fixer, declaration, sourceCode) {
|
|
2903
|
+
const source = declaration.source.value;
|
|
2904
|
+
const prefix = declaration.importKind === "type" ? "import type " : "import ";
|
|
2905
|
+
const specifiers = formatSpecifiers(declaration, sourceCode);
|
|
2906
|
+
const attributes = formatAttributes(declaration.attributes);
|
|
2907
|
+
if (specifiers === "") {
|
|
2908
|
+
const result2 = `${prefix}'${source}'${attributes}`;
|
|
2909
|
+
return fixer.replaceText(declaration, result2);
|
|
2910
|
+
}
|
|
2911
|
+
const result = `${prefix}${specifiers} from '${source}'${attributes}`;
|
|
2912
|
+
return fixer.replaceText(declaration, result);
|
|
2913
|
+
}
|
|
2914
|
+
function isMultilineImport(declaration) {
|
|
2915
|
+
const { end, start } = declaration.loc ?? {};
|
|
2916
|
+
return start?.line !== end?.line;
|
|
2917
|
+
}
|
|
253
2918
|
const singleLineImports = {
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
2919
|
+
create(context) {
|
|
2920
|
+
return {
|
|
2921
|
+
ImportDeclaration(node2) {
|
|
2922
|
+
if (!isMultilineImport(node2))
|
|
2923
|
+
return;
|
|
2924
|
+
context.report({
|
|
2925
|
+
fix: (fixer) => createImportFix$1(fixer, node2, context.sourceCode),
|
|
2926
|
+
messageId: "multiline",
|
|
2927
|
+
node: node2
|
|
2928
|
+
});
|
|
2929
|
+
}
|
|
2930
|
+
};
|
|
2931
|
+
},
|
|
2932
|
+
meta: {
|
|
2933
|
+
docs: {
|
|
2934
|
+
description: "Enforce imports to be on a single line."
|
|
2935
|
+
},
|
|
2936
|
+
fixable: "code",
|
|
2937
|
+
messages: {
|
|
2938
|
+
multiline: "Import should be on a single line"
|
|
2939
|
+
},
|
|
2940
|
+
schema: [],
|
|
2941
|
+
type: "layout"
|
|
2942
|
+
}
|
|
2943
|
+
};
|
|
2944
|
+
function createReExportFix$1(fixer, declaration, sourceCode) {
|
|
2945
|
+
const source = declaration.source.value;
|
|
2946
|
+
if (declaration.type === "ExportAllDeclaration") {
|
|
2947
|
+
const exported = declaration.exported ? `* as ${sourceCode.getText(declaration.exported)}` : "*";
|
|
2948
|
+
const attributes2 = formatAttributes(declaration.attributes);
|
|
2949
|
+
const result2 = `export ${exported} from '${source}'${attributes2}`;
|
|
2950
|
+
return fixer.replaceText(declaration, result2);
|
|
2951
|
+
}
|
|
2952
|
+
const prefix = declaration.exportKind === "type" ? "export type " : "export ";
|
|
2953
|
+
const specifiers = declaration.specifiers.map(
|
|
2954
|
+
(s) => sourceCode.getText(s)
|
|
2955
|
+
).join(", ");
|
|
2956
|
+
const attributes = formatAttributes(declaration.attributes);
|
|
2957
|
+
const result = `${prefix}{${specifiers}} from '${source}'${attributes}`;
|
|
2958
|
+
return fixer.replaceText(declaration, result);
|
|
2959
|
+
}
|
|
2960
|
+
function isMultilineReExport(declaration) {
|
|
2961
|
+
const { end, start } = declaration.loc ?? {};
|
|
2962
|
+
return start?.line !== end?.line;
|
|
2963
|
+
}
|
|
291
2964
|
const singleLineReExports = {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
2965
|
+
create(context) {
|
|
2966
|
+
const checkDeclaration = (node2, declaration) => {
|
|
2967
|
+
if (!declaration.source)
|
|
2968
|
+
return;
|
|
2969
|
+
if (!isMultilineReExport(declaration))
|
|
2970
|
+
return;
|
|
2971
|
+
context.report({
|
|
2972
|
+
fix: (fixer) => createReExportFix$1(fixer, declaration, context.sourceCode),
|
|
2973
|
+
messageId: "multiline",
|
|
2974
|
+
node: node2
|
|
2975
|
+
});
|
|
2976
|
+
};
|
|
2977
|
+
return {
|
|
2978
|
+
ExportAllDeclaration: (node2) => {
|
|
2979
|
+
checkDeclaration(node2, node2);
|
|
2980
|
+
},
|
|
2981
|
+
ExportNamedDeclaration: (node2) => {
|
|
2982
|
+
checkDeclaration(node2, node2);
|
|
2983
|
+
}
|
|
2984
|
+
};
|
|
2985
|
+
},
|
|
2986
|
+
meta: {
|
|
2987
|
+
docs: {
|
|
2988
|
+
description: "Enforce re-exports to be on a single line."
|
|
2989
|
+
},
|
|
2990
|
+
fixable: "code",
|
|
2991
|
+
messages: {
|
|
2992
|
+
multiline: "Re-export should be on a single line"
|
|
2993
|
+
},
|
|
2994
|
+
schema: [],
|
|
2995
|
+
type: "layout"
|
|
2996
|
+
}
|
|
2997
|
+
};
|
|
317
2998
|
function categorizeImport(declaration) {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
2999
|
+
if (declaration.specifiers.some((s) => s.type === "ImportNamespaceSpecifier")) {
|
|
3000
|
+
return declaration.importKind === "type" ? "type-namespace" : "namespace";
|
|
3001
|
+
}
|
|
3002
|
+
if (declaration.specifiers.some((s) => s.type === "ImportDefaultSpecifier")) {
|
|
3003
|
+
return declaration.importKind === "type" ? "type-default" : "default";
|
|
3004
|
+
}
|
|
3005
|
+
if (declaration.importKind === "type")
|
|
3006
|
+
return "type-named";
|
|
3007
|
+
if (declaration.specifiers.length === 0)
|
|
3008
|
+
return "side-effect";
|
|
3009
|
+
return "named";
|
|
3010
|
+
}
|
|
3011
|
+
function getImportSortKey(declaration) {
|
|
3012
|
+
const group = categorizeImport(declaration);
|
|
3013
|
+
if (group === "side-effect")
|
|
3014
|
+
return declaration.source.value;
|
|
3015
|
+
if (group === "namespace" || group === "type-namespace") {
|
|
3016
|
+
const namespaceSpecifier = declaration.specifiers.find(
|
|
3017
|
+
(s) => s.type === "ImportNamespaceSpecifier"
|
|
3018
|
+
);
|
|
3019
|
+
return `*${namespaceSpecifier?.local.name ?? ""}`;
|
|
3020
|
+
}
|
|
3021
|
+
if (group === "default" || group === "type-default") {
|
|
3022
|
+
const defaultSpecifier = declaration.specifiers.find(
|
|
3023
|
+
(s) => s.type === "ImportDefaultSpecifier"
|
|
3024
|
+
);
|
|
3025
|
+
return defaultSpecifier?.local.name ?? "";
|
|
3026
|
+
}
|
|
3027
|
+
const specifier = declaration.specifiers[0];
|
|
3028
|
+
return specifier.local.name;
|
|
3029
|
+
}
|
|
335
3030
|
function categorizeImports(declarations) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
}
|
|
342
|
-
//#endregion
|
|
343
|
-
//#region src/lib/compare.ts
|
|
3031
|
+
return declarations.map((declaration) => ({
|
|
3032
|
+
declaration,
|
|
3033
|
+
group: categorizeImport(declaration),
|
|
3034
|
+
sortKey: getImportSortKey(declaration)
|
|
3035
|
+
}));
|
|
3036
|
+
}
|
|
344
3037
|
function compare(a, b) {
|
|
345
|
-
|
|
3038
|
+
return a.localeCompare(b, "en", { sensitivity: "case" });
|
|
346
3039
|
}
|
|
347
|
-
//#endregion
|
|
348
|
-
//#region src/rules/sortedImports/ImportGroupOrder.ts
|
|
349
3040
|
const importGroupOrder = [
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
3041
|
+
"side-effect",
|
|
3042
|
+
"namespace",
|
|
3043
|
+
"default",
|
|
3044
|
+
"named",
|
|
3045
|
+
"type-namespace",
|
|
3046
|
+
"type-default",
|
|
3047
|
+
"type-named"
|
|
355
3048
|
];
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
|
|
3049
|
+
function checkAlphabeticalSorting$1(categorizedImports) {
|
|
3050
|
+
const errors = [];
|
|
3051
|
+
for (const importGroup of importGroupOrder) {
|
|
3052
|
+
const groupImports = categorizedImports.filter((c) => c.group === importGroup);
|
|
3053
|
+
const expectedSortedImports = [...groupImports].sort((a, b) => compare(
|
|
3054
|
+
a.sortKey,
|
|
3055
|
+
b.sortKey
|
|
3056
|
+
));
|
|
3057
|
+
for (let i = 0; i < groupImports.length; i++) {
|
|
3058
|
+
if (groupImports[i] !== expectedSortedImports[i]) {
|
|
3059
|
+
errors.push({
|
|
3060
|
+
messageId: "sortedImports",
|
|
3061
|
+
node: groupImports[i].declaration
|
|
3062
|
+
});
|
|
3063
|
+
}
|
|
3064
|
+
}
|
|
3065
|
+
}
|
|
3066
|
+
return errors;
|
|
3067
|
+
}
|
|
3068
|
+
function checkGroupOrdering$1(categorizedImports) {
|
|
3069
|
+
const errors = [];
|
|
3070
|
+
let currentGroupIndex = -1;
|
|
3071
|
+
for (const { declaration, group: importGroup } of categorizedImports) {
|
|
3072
|
+
const groupIndex = importGroupOrder.indexOf(importGroup);
|
|
3073
|
+
if (groupIndex < currentGroupIndex) {
|
|
3074
|
+
errors.push({
|
|
3075
|
+
messageId: "wrongGroup",
|
|
3076
|
+
node: declaration
|
|
3077
|
+
});
|
|
3078
|
+
} else
|
|
3079
|
+
currentGroupIndex = groupIndex;
|
|
3080
|
+
}
|
|
3081
|
+
return errors;
|
|
3082
|
+
}
|
|
3083
|
+
function getImportSpecifierName(specifier) {
|
|
3084
|
+
return specifier.imported.type === "Identifier" ? specifier.imported.name : String(specifier.imported.value);
|
|
3085
|
+
}
|
|
392
3086
|
function areSpecifiersSorted$1(specifiers) {
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
3087
|
+
const names = specifiers.map((s) => getImportSpecifierName(s));
|
|
3088
|
+
const sorted = [...names].sort((a, b) => compare(a, b));
|
|
3089
|
+
return names.every((name, i) => name === sorted[i]);
|
|
396
3090
|
}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
3091
|
+
function getImportNamedSpecifiers(declaration) {
|
|
3092
|
+
return declaration.specifiers.filter(
|
|
3093
|
+
(s) => s.type === "ImportSpecifier"
|
|
3094
|
+
);
|
|
401
3095
|
}
|
|
402
|
-
//#endregion
|
|
403
|
-
//#region src/rules/sortedImports/checkSpecifiersSorting.ts
|
|
404
3096
|
function checkSpecifiersSorting$1(categorized) {
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
function
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
function
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
3097
|
+
const errors = [];
|
|
3098
|
+
const namedImportDeclarations = categorized.filter((c) => c.group === "named");
|
|
3099
|
+
for (const { declaration } of namedImportDeclarations) {
|
|
3100
|
+
const namedSpecifiers = getImportNamedSpecifiers(declaration);
|
|
3101
|
+
if (namedSpecifiers.length > 1 && !areSpecifiersSorted$1(namedSpecifiers)) {
|
|
3102
|
+
errors.push({
|
|
3103
|
+
messageId: "sortedNames",
|
|
3104
|
+
node: declaration
|
|
3105
|
+
});
|
|
3106
|
+
}
|
|
3107
|
+
}
|
|
3108
|
+
return errors;
|
|
3109
|
+
}
|
|
3110
|
+
function sortImportSpecifiersText(specifiers, sourceCode) {
|
|
3111
|
+
const sorted = [...specifiers].sort((a, b) => {
|
|
3112
|
+
const nameA = getImportSpecifierName(a);
|
|
3113
|
+
const nameB = getImportSpecifierName(b);
|
|
3114
|
+
return compare(nameA, nameB);
|
|
3115
|
+
});
|
|
3116
|
+
return sorted.map((s) => sourceCode.getText(s)).join(", ");
|
|
3117
|
+
}
|
|
3118
|
+
function formatNamedImportSpecifiers(declaration, sourceCode) {
|
|
3119
|
+
const specifiers = getImportNamedSpecifiers(declaration);
|
|
3120
|
+
if (specifiers.length > 1 && !areSpecifiersSorted$1(specifiers)) {
|
|
3121
|
+
const sortedSpecifiers = sortImportSpecifiersText(specifiers, sourceCode);
|
|
3122
|
+
const source = declaration.source.value;
|
|
3123
|
+
const prefix = declaration.importKind === "type" ? "import type " : "import ";
|
|
3124
|
+
return `${prefix}{${sortedSpecifiers}} from '${source}'`;
|
|
3125
|
+
}
|
|
3126
|
+
return sourceCode.getText(declaration);
|
|
3127
|
+
}
|
|
3128
|
+
function buildSortedImportCode(grouped, sourceCode) {
|
|
3129
|
+
const sortedCode = [];
|
|
3130
|
+
for (const group of importGroupOrder) {
|
|
3131
|
+
for (const { declaration } of grouped[group] ?? []) {
|
|
3132
|
+
if (group === "named" || group === "type-named")
|
|
3133
|
+
sortedCode.push(formatNamedImportSpecifiers(declaration, sourceCode));
|
|
3134
|
+
else
|
|
3135
|
+
sortedCode.push(sourceCode.getText(declaration));
|
|
3136
|
+
}
|
|
3137
|
+
}
|
|
3138
|
+
return sortedCode;
|
|
3139
|
+
}
|
|
444
3140
|
function groupImportsByType(categorized) {
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
3141
|
+
const grouped = {
|
|
3142
|
+
default: [],
|
|
3143
|
+
named: [],
|
|
3144
|
+
namespace: [],
|
|
3145
|
+
"side-effect": [],
|
|
3146
|
+
"type-default": [],
|
|
3147
|
+
"type-named": [],
|
|
3148
|
+
"type-namespace": []
|
|
3149
|
+
};
|
|
3150
|
+
for (const item of categorized)
|
|
3151
|
+
grouped[item.group].push(item);
|
|
3152
|
+
return grouped;
|
|
3153
|
+
}
|
|
457
3154
|
function sortImportGroups(grouped) {
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
3155
|
+
grouped["side-effect"].sort((a, b) => compare(a.sortKey, b.sortKey));
|
|
3156
|
+
grouped["namespace"].sort((a, b) => compare(a.sortKey, b.sortKey));
|
|
3157
|
+
grouped["default"].sort((a, b) => compare(a.sortKey, b.sortKey));
|
|
3158
|
+
grouped["named"].sort((a, b) => compare(a.sortKey, b.sortKey));
|
|
3159
|
+
grouped["type-namespace"].sort((a, b) => compare(a.sortKey, b.sortKey));
|
|
3160
|
+
grouped["type-default"].sort((a, b) => compare(a.sortKey, b.sortKey));
|
|
3161
|
+
grouped["type-named"].sort((a, b) => compare(a.sortKey, b.sortKey));
|
|
3162
|
+
}
|
|
466
3163
|
function createFixForGroup$1(fixer, importDeclarations, sourceCode) {
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
3164
|
+
if (importDeclarations.length === 0)
|
|
3165
|
+
return null;
|
|
3166
|
+
const categorized = categorizeImports(importDeclarations);
|
|
3167
|
+
const grouped = groupImportsByType(categorized);
|
|
3168
|
+
sortImportGroups(grouped);
|
|
3169
|
+
const sortedCode = buildSortedImportCode(grouped, sourceCode).join("\n");
|
|
3170
|
+
const firstImport = importDeclarations[0];
|
|
3171
|
+
const lastImport = importDeclarations[importDeclarations.length - 1];
|
|
3172
|
+
return fixer.replaceTextRange(
|
|
3173
|
+
[firstImport.range[0], lastImport.range[1]],
|
|
3174
|
+
sortedCode
|
|
3175
|
+
);
|
|
3176
|
+
}
|
|
3177
|
+
function createImportFix(fixer, importGroups, sourceCode) {
|
|
3178
|
+
const fixes = [];
|
|
3179
|
+
for (const group of importGroups) {
|
|
3180
|
+
const fix = createFixForGroup$1(fixer, group, sourceCode);
|
|
3181
|
+
if (fix)
|
|
3182
|
+
fixes.push(fix);
|
|
3183
|
+
}
|
|
3184
|
+
return fixes;
|
|
3185
|
+
}
|
|
485
3186
|
function getImportGroups(programBody) {
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
//#region src/rules/sortedImports/index.ts
|
|
3187
|
+
const groups = [];
|
|
3188
|
+
let currentImportGroup = [];
|
|
3189
|
+
for (const statement of programBody) {
|
|
3190
|
+
if (statement.type === "ImportDeclaration") {
|
|
3191
|
+
currentImportGroup.push(statement);
|
|
3192
|
+
continue;
|
|
3193
|
+
}
|
|
3194
|
+
if (currentImportGroup.length > 0) {
|
|
3195
|
+
groups.push(currentImportGroup);
|
|
3196
|
+
currentImportGroup = [];
|
|
3197
|
+
}
|
|
3198
|
+
}
|
|
3199
|
+
if (currentImportGroup.length > 0)
|
|
3200
|
+
groups.push(currentImportGroup);
|
|
3201
|
+
return groups;
|
|
3202
|
+
}
|
|
503
3203
|
const sortedImports = {
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
3204
|
+
create(context) {
|
|
3205
|
+
return {
|
|
3206
|
+
Program(node2) {
|
|
3207
|
+
const programBody = node2.body;
|
|
3208
|
+
const importGroups = getImportGroups(programBody);
|
|
3209
|
+
if (importGroups.length === 0)
|
|
3210
|
+
return;
|
|
3211
|
+
const allImportErrors = [];
|
|
3212
|
+
for (const group of importGroups) {
|
|
3213
|
+
const categorized = categorizeImports(group);
|
|
3214
|
+
const errors = [
|
|
3215
|
+
...checkGroupOrdering$1(categorized),
|
|
3216
|
+
...checkAlphabeticalSorting$1(categorized),
|
|
3217
|
+
...checkSpecifiersSorting$1(categorized)
|
|
3218
|
+
];
|
|
3219
|
+
allImportErrors.push(...errors);
|
|
3220
|
+
}
|
|
3221
|
+
for (const error of allImportErrors) {
|
|
3222
|
+
context.report({
|
|
3223
|
+
fix(fixer) {
|
|
3224
|
+
const sourceCode = context.sourceCode;
|
|
3225
|
+
return createImportFix(fixer, importGroups, sourceCode);
|
|
3226
|
+
},
|
|
3227
|
+
messageId: error.messageId,
|
|
3228
|
+
node: error.node
|
|
3229
|
+
});
|
|
3230
|
+
}
|
|
3231
|
+
}
|
|
3232
|
+
};
|
|
3233
|
+
},
|
|
3234
|
+
meta: {
|
|
3235
|
+
docs: {
|
|
3236
|
+
description: "Enforce sorted imports alphabetically."
|
|
3237
|
+
},
|
|
3238
|
+
fixable: "code",
|
|
3239
|
+
messages: {
|
|
3240
|
+
sortedImports: "Imports should be sorted alphabetically",
|
|
3241
|
+
sortedNames: "Named imports should be sorted alphabetically",
|
|
3242
|
+
wrongGroup: "Import is in wrong group"
|
|
3243
|
+
},
|
|
3244
|
+
schema: [],
|
|
3245
|
+
type: "suggestion"
|
|
3246
|
+
}
|
|
3247
|
+
};
|
|
543
3248
|
function categorizeReExport(declaration) {
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
3249
|
+
if (declaration.type === "ExportAllDeclaration") {
|
|
3250
|
+
if (declaration.exportKind === "type") {
|
|
3251
|
+
if (declaration.exported)
|
|
3252
|
+
return "type-namespace";
|
|
3253
|
+
return "type-all";
|
|
3254
|
+
}
|
|
3255
|
+
if (declaration.exported)
|
|
3256
|
+
return "re-export-namespace";
|
|
3257
|
+
return "re-export-all";
|
|
3258
|
+
}
|
|
3259
|
+
if (declaration.exportKind === "type")
|
|
3260
|
+
return "type-named";
|
|
3261
|
+
if (declaration.specifiers?.some((s) => s.exportKind === "type"))
|
|
3262
|
+
return "type-named";
|
|
3263
|
+
return "re-export-named";
|
|
3264
|
+
}
|
|
3265
|
+
function getReExportSortKey(declaration) {
|
|
3266
|
+
const group = categorizeReExport(declaration);
|
|
3267
|
+
if (declaration.type === "ExportAllDeclaration") {
|
|
3268
|
+
if (group === "re-export-namespace") {
|
|
3269
|
+
if (declaration.exported?.type === "Identifier")
|
|
3270
|
+
return `*${declaration.exported.name}`;
|
|
3271
|
+
}
|
|
3272
|
+
return declaration.source.value;
|
|
3273
|
+
}
|
|
3274
|
+
const specifier = declaration.specifiers[0];
|
|
3275
|
+
if (!specifier)
|
|
3276
|
+
return "";
|
|
3277
|
+
return specifier.local.type === "Identifier" ? specifier.local.name : specifier.local.value;
|
|
3278
|
+
}
|
|
567
3279
|
function categorizeReExports(declarations) {
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
}
|
|
576
|
-
//#endregion
|
|
577
|
-
//#region src/rules/sortedReExports/ReExportGroupOrder.ts
|
|
3280
|
+
return declarations.map((declaration) => {
|
|
3281
|
+
return {
|
|
3282
|
+
declaration,
|
|
3283
|
+
group: categorizeReExport(declaration),
|
|
3284
|
+
sortKey: getReExportSortKey(declaration)
|
|
3285
|
+
};
|
|
3286
|
+
});
|
|
3287
|
+
}
|
|
578
3288
|
const reExportGroupOrder = [
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
3289
|
+
"re-export-all",
|
|
3290
|
+
"re-export-namespace",
|
|
3291
|
+
"re-export-named",
|
|
3292
|
+
"type-all",
|
|
3293
|
+
"type-namespace",
|
|
3294
|
+
"type-named"
|
|
583
3295
|
];
|
|
584
|
-
//#endregion
|
|
585
|
-
//#region src/rules/sortedReExports/checkAlphabeticalSorting.ts
|
|
586
3296
|
function checkAlphabeticalSorting(categorized) {
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
3297
|
+
const errors = [];
|
|
3298
|
+
for (const group of reExportGroupOrder) {
|
|
3299
|
+
const groupReExports = categorized.filter((c) => c.group === group);
|
|
3300
|
+
const sorted = [...groupReExports].sort(
|
|
3301
|
+
(a, b) => compare(a.sortKey, b.sortKey)
|
|
3302
|
+
);
|
|
3303
|
+
for (let i = 0; i < groupReExports.length; i++) {
|
|
3304
|
+
if (groupReExports[i] !== sorted[i]) {
|
|
3305
|
+
errors.push({
|
|
3306
|
+
messageId: "sortedReExports",
|
|
3307
|
+
node: groupReExports[i].declaration
|
|
3308
|
+
});
|
|
3309
|
+
}
|
|
3310
|
+
}
|
|
3311
|
+
}
|
|
3312
|
+
return errors;
|
|
3313
|
+
}
|
|
600
3314
|
function checkGroupOrdering(categorized) {
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
|
|
3315
|
+
const errors = [];
|
|
3316
|
+
let currentGroupIndex = -1;
|
|
3317
|
+
for (const { declaration, group } of categorized) {
|
|
3318
|
+
const groupIndex = reExportGroupOrder.indexOf(group);
|
|
3319
|
+
if (groupIndex < currentGroupIndex) {
|
|
3320
|
+
errors.push({
|
|
3321
|
+
messageId: "wrongGroup",
|
|
3322
|
+
node: declaration
|
|
3323
|
+
});
|
|
3324
|
+
} else
|
|
3325
|
+
currentGroupIndex = groupIndex;
|
|
3326
|
+
}
|
|
3327
|
+
return errors;
|
|
3328
|
+
}
|
|
615
3329
|
function getSpecifierName(specifier) {
|
|
616
|
-
|
|
3330
|
+
return specifier.local.type === "Identifier" ? specifier.local.name : String(specifier.local.value);
|
|
617
3331
|
}
|
|
618
|
-
//#endregion
|
|
619
|
-
//#region src/rules/sortedReExports/areSpecifiersSorted.ts
|
|
620
3332
|
function areSpecifiersSorted(specifiers) {
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
3333
|
+
const names = specifiers.map((s) => getSpecifierName(s));
|
|
3334
|
+
const sorted = [...names].sort((a, b) => compare(a, b));
|
|
3335
|
+
return names.every((name, i) => name === sorted[i]);
|
|
624
3336
|
}
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
3337
|
+
function getReExportNamedSpecifiers(declaration) {
|
|
3338
|
+
return declaration.specifiers.filter(
|
|
3339
|
+
(s) => s.type === "ExportSpecifier" && s.local.type === "Identifier"
|
|
3340
|
+
);
|
|
629
3341
|
}
|
|
630
|
-
//#endregion
|
|
631
|
-
//#region src/rules/sortedReExports/isNamedReExport.ts
|
|
632
3342
|
function isNamedReExport(x) {
|
|
633
|
-
|
|
3343
|
+
return x.group !== "re-export-all" && x.group !== "re-export-namespace";
|
|
634
3344
|
}
|
|
635
|
-
//#endregion
|
|
636
|
-
//#region src/rules/sortedReExports/checkSpecifiersSorting.ts
|
|
637
3345
|
function checkSpecifiersSorting(categorized) {
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
|
|
3346
|
+
const errors = [];
|
|
3347
|
+
const namedReExports = categorized.filter(isNamedReExport);
|
|
3348
|
+
for (const { declaration } of namedReExports) {
|
|
3349
|
+
const specifiers = getReExportNamedSpecifiers(declaration);
|
|
3350
|
+
const isSorted = areSpecifiersSorted(specifiers);
|
|
3351
|
+
if (specifiers.length > 1 && !isSorted) {
|
|
3352
|
+
errors.push({
|
|
3353
|
+
messageId: "sortedNames",
|
|
3354
|
+
node: declaration
|
|
3355
|
+
});
|
|
3356
|
+
}
|
|
3357
|
+
}
|
|
3358
|
+
return errors;
|
|
3359
|
+
}
|
|
652
3360
|
function sortSpecifiersText(specifiers, sourceCode) {
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
function
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
3361
|
+
const sorted = [...specifiers].sort((a, b) => {
|
|
3362
|
+
const nameA = getSpecifierName(a);
|
|
3363
|
+
const nameB = getSpecifierName(b);
|
|
3364
|
+
return compare(nameA, nameB);
|
|
3365
|
+
});
|
|
3366
|
+
return sorted.map((s) => sourceCode.getText(s)).join(", ");
|
|
3367
|
+
}
|
|
3368
|
+
function formatNamedReExportSpecifiers(declaration, sourceCode) {
|
|
3369
|
+
const specifiers = getReExportNamedSpecifiers(declaration);
|
|
3370
|
+
if (specifiers.length > 1 && !areSpecifiersSorted(specifiers)) {
|
|
3371
|
+
const sortedSpecifiers = sortSpecifiersText(specifiers, sourceCode);
|
|
3372
|
+
const source = declaration.source.value;
|
|
3373
|
+
const prefix = declaration.exportKind === "type" ? "export type " : "export ";
|
|
3374
|
+
return `${prefix}{${sortedSpecifiers}} from '${source}'`;
|
|
3375
|
+
}
|
|
3376
|
+
return sourceCode.getText(declaration);
|
|
3377
|
+
}
|
|
3378
|
+
function buildSortedReExportCode(grouped, sourceCode) {
|
|
3379
|
+
const sortedCode = [];
|
|
3380
|
+
for (const group of reExportGroupOrder) {
|
|
3381
|
+
for (const item of grouped[group]) {
|
|
3382
|
+
if (isNamedReExport(item)) {
|
|
3383
|
+
sortedCode.push(
|
|
3384
|
+
formatNamedReExportSpecifiers(
|
|
3385
|
+
item.declaration,
|
|
3386
|
+
sourceCode
|
|
3387
|
+
)
|
|
3388
|
+
);
|
|
3389
|
+
} else
|
|
3390
|
+
sortedCode.push(sourceCode.getText(item.declaration));
|
|
3391
|
+
}
|
|
3392
|
+
}
|
|
3393
|
+
return sortedCode;
|
|
3394
|
+
}
|
|
678
3395
|
function groupReExportsByType(categorized) {
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
3396
|
+
const grouped = {
|
|
3397
|
+
"re-export-all": [],
|
|
3398
|
+
"re-export-named": [],
|
|
3399
|
+
"re-export-namespace": [],
|
|
3400
|
+
"type-all": [],
|
|
3401
|
+
"type-named": [],
|
|
3402
|
+
"type-namespace": []
|
|
3403
|
+
};
|
|
3404
|
+
for (const item of categorized)
|
|
3405
|
+
grouped[item.group].push(item);
|
|
3406
|
+
return grouped;
|
|
3407
|
+
}
|
|
690
3408
|
function sortExportGroups(grouped) {
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
3409
|
+
grouped["re-export-all"].sort((a, b) => compare(a.sortKey, b.sortKey));
|
|
3410
|
+
grouped["re-export-namespace"].sort((a, b) => compare(a.sortKey, b.sortKey));
|
|
3411
|
+
grouped["re-export-named"].sort((a, b) => compare(a.sortKey, b.sortKey));
|
|
3412
|
+
grouped["type-all"].sort((a, b) => compare(a.sortKey, b.sortKey));
|
|
3413
|
+
grouped["type-namespace"].sort((a, b) => compare(a.sortKey, b.sortKey));
|
|
3414
|
+
grouped["type-named"].sort((a, b) => compare(a.sortKey, b.sortKey));
|
|
695
3415
|
}
|
|
696
|
-
//#endregion
|
|
697
|
-
//#region src/rules/sortedReExports/createFix/index.ts
|
|
698
3416
|
function createFixForGroup(fixer, reExportDeclarations, sourceCode) {
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
3417
|
+
if (reExportDeclarations.length === 0)
|
|
3418
|
+
return null;
|
|
3419
|
+
const categorized = categorizeReExports(reExportDeclarations);
|
|
3420
|
+
const grouped = groupReExportsByType(categorized);
|
|
3421
|
+
sortExportGroups(grouped);
|
|
3422
|
+
const sortedCode = buildSortedReExportCode(grouped, sourceCode).join("\n");
|
|
3423
|
+
const firstReExport = reExportDeclarations[0];
|
|
3424
|
+
const lastReExport = reExportDeclarations[reExportDeclarations.length - 1];
|
|
3425
|
+
return fixer.replaceTextRange(
|
|
3426
|
+
[firstReExport.range[0], lastReExport.range[1]],
|
|
3427
|
+
sortedCode
|
|
3428
|
+
);
|
|
3429
|
+
}
|
|
3430
|
+
function createReExportFix(fixer, reExportGroups, sourceCode) {
|
|
3431
|
+
const fixes = [];
|
|
3432
|
+
for (const group of reExportGroups) {
|
|
3433
|
+
const fix = createFixForGroup(fixer, group, sourceCode);
|
|
3434
|
+
if (fix)
|
|
3435
|
+
fixes.push(fix);
|
|
3436
|
+
}
|
|
3437
|
+
return fixes;
|
|
3438
|
+
}
|
|
717
3439
|
function isReExportDeclaration(statement) {
|
|
718
|
-
|
|
3440
|
+
return statement.type === "ExportNamedDeclaration" && statement.source !== null || statement.type === "ExportAllDeclaration";
|
|
719
3441
|
}
|
|
720
3442
|
function getReExportGroups(programBody) {
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
//#region src/rules/sortedReExports/index.ts
|
|
3443
|
+
const groups = [];
|
|
3444
|
+
let currentGroup = [];
|
|
3445
|
+
for (const statement of programBody) {
|
|
3446
|
+
if (isReExportDeclaration(statement)) {
|
|
3447
|
+
currentGroup.push(statement);
|
|
3448
|
+
continue;
|
|
3449
|
+
}
|
|
3450
|
+
if (currentGroup.length > 0) {
|
|
3451
|
+
groups.push(currentGroup);
|
|
3452
|
+
currentGroup = [];
|
|
3453
|
+
}
|
|
3454
|
+
}
|
|
3455
|
+
if (currentGroup.length > 0)
|
|
3456
|
+
groups.push(currentGroup);
|
|
3457
|
+
return groups;
|
|
3458
|
+
}
|
|
738
3459
|
const sortedReExports = {
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
3460
|
+
create(context) {
|
|
3461
|
+
return {
|
|
3462
|
+
Program(node2) {
|
|
3463
|
+
const programBody = node2.body;
|
|
3464
|
+
const reExportGroups = getReExportGroups(programBody);
|
|
3465
|
+
if (reExportGroups.length === 0)
|
|
3466
|
+
return;
|
|
3467
|
+
const allReExportErrors = [];
|
|
3468
|
+
for (const group of reExportGroups) {
|
|
3469
|
+
const categorizedReExports = categorizeReExports(group);
|
|
3470
|
+
const groupErrors = [
|
|
3471
|
+
...checkGroupOrdering(categorizedReExports),
|
|
3472
|
+
...checkAlphabeticalSorting(categorizedReExports),
|
|
3473
|
+
...checkSpecifiersSorting(categorizedReExports)
|
|
3474
|
+
];
|
|
3475
|
+
allReExportErrors.push(...groupErrors);
|
|
3476
|
+
}
|
|
3477
|
+
for (const error of allReExportErrors) {
|
|
3478
|
+
context.report({
|
|
3479
|
+
fix(fixer) {
|
|
3480
|
+
const sourceCode = context.sourceCode;
|
|
3481
|
+
return createReExportFix(fixer, reExportGroups, sourceCode);
|
|
3482
|
+
},
|
|
3483
|
+
messageId: error.messageId,
|
|
3484
|
+
node: error.node
|
|
3485
|
+
});
|
|
3486
|
+
}
|
|
3487
|
+
}
|
|
3488
|
+
};
|
|
3489
|
+
},
|
|
3490
|
+
meta: {
|
|
3491
|
+
docs: {
|
|
3492
|
+
description: "Enforce sorted exports alphabetically."
|
|
3493
|
+
},
|
|
3494
|
+
fixable: "code",
|
|
3495
|
+
messages: {
|
|
3496
|
+
sortedNames: "Named exports should be sorted alphabetically",
|
|
3497
|
+
sortedReExports: "Exports should be sorted alphabetically",
|
|
3498
|
+
wrongGroup: "Export is in wrong group"
|
|
3499
|
+
},
|
|
3500
|
+
schema: [],
|
|
3501
|
+
type: "suggestion"
|
|
3502
|
+
}
|
|
3503
|
+
};
|
|
3504
|
+
const customRules = {
|
|
3505
|
+
plugins: {
|
|
3506
|
+
"@borela-tech": {
|
|
3507
|
+
rules: {
|
|
3508
|
+
"array-items-line-break": arrayItemsLineBreak,
|
|
3509
|
+
"brace-style-control-statements": braceStyleControlStatements,
|
|
3510
|
+
"brace-style-object-literal": braceStyleObjectLiteral,
|
|
3511
|
+
"compact-array-items": compactArrayItems,
|
|
3512
|
+
"export-filename-match": exportFilenameMatch,
|
|
3513
|
+
"function-call-argument-line-break": functionCallArgumentLineBreak,
|
|
3514
|
+
"function-cognitive-complexity": functionCognitiveComplexity,
|
|
3515
|
+
"function-parameter-line-break": functionParameterLineBreak,
|
|
3516
|
+
"imports-and-re-exports-at-top": importsAndReExportsAtTop,
|
|
3517
|
+
"individual-imports": individualImports,
|
|
3518
|
+
"individual-re-exports": individualReExports,
|
|
3519
|
+
"interface-property-line-break": interfacePropertyLineBreak,
|
|
3520
|
+
"max-declarations-per-file": maxDeclarationsPerFile,
|
|
3521
|
+
"multiline-union-type-aliases": multilineUnionTypeAliases,
|
|
3522
|
+
"naming-convention": namingConvention,
|
|
3523
|
+
"no-inline-object-types": noInlineObjectTypes,
|
|
3524
|
+
"no-unnecessary-braces": noUnnecessaryBraces,
|
|
3525
|
+
"object-property-line-break": objectPropertyLineBreak,
|
|
3526
|
+
"one-export-per-file": oneExportPerFile,
|
|
3527
|
+
"prefer-inline-export": preferInlineExport,
|
|
3528
|
+
"single-line-arrow-function-parameters": singleLineArrowFunctionParameters,
|
|
3529
|
+
"single-line-function-parameters": singleLineFunctionParameters,
|
|
3530
|
+
"single-line-imports": singleLineImports,
|
|
3531
|
+
"single-line-re-exports": singleLineReExports,
|
|
3532
|
+
"sorted-imports": sortedImports,
|
|
3533
|
+
"sorted-re-exports": sortedReExports
|
|
3534
|
+
}
|
|
3535
|
+
}
|
|
3536
|
+
},
|
|
3537
|
+
rules: {
|
|
3538
|
+
"@borela-tech/array-items-line-break": [
|
|
3539
|
+
"error",
|
|
3540
|
+
{ maxLength: 80 }
|
|
3541
|
+
],
|
|
3542
|
+
"@borela-tech/brace-style-control-statements": "error",
|
|
3543
|
+
"@borela-tech/brace-style-object-literal": "error",
|
|
3544
|
+
"@borela-tech/compact-array-items": "error",
|
|
3545
|
+
"@borela-tech/export-filename-match": "error",
|
|
3546
|
+
"@borela-tech/function-call-argument-line-break": [
|
|
3547
|
+
"error",
|
|
3548
|
+
{ maxLength: 80 }
|
|
3549
|
+
],
|
|
3550
|
+
"@borela-tech/function-cognitive-complexity": [
|
|
3551
|
+
"error",
|
|
3552
|
+
{ maxCognitiveComplexity: 15 }
|
|
3553
|
+
],
|
|
3554
|
+
"@borela-tech/function-parameter-line-break": [
|
|
3555
|
+
"error",
|
|
3556
|
+
{ maxLength: 80 }
|
|
3557
|
+
],
|
|
3558
|
+
"@borela-tech/imports-and-re-exports-at-top": "error",
|
|
3559
|
+
"@borela-tech/individual-imports": "error",
|
|
3560
|
+
"@borela-tech/individual-re-exports": "error",
|
|
3561
|
+
"@borela-tech/interface-property-line-break": [
|
|
3562
|
+
"error",
|
|
3563
|
+
{ maxLength: 80 }
|
|
3564
|
+
],
|
|
3565
|
+
"@borela-tech/max-declarations-per-file": "error",
|
|
3566
|
+
"@borela-tech/multiline-union-type-aliases": "error",
|
|
3567
|
+
"@borela-tech/naming-convention": "error",
|
|
3568
|
+
"@borela-tech/no-inline-object-types": "error",
|
|
3569
|
+
"@borela-tech/no-unnecessary-braces": "error",
|
|
3570
|
+
"@borela-tech/object-property-line-break": "error",
|
|
3571
|
+
"@borela-tech/one-export-per-file": "error",
|
|
3572
|
+
"@borela-tech/prefer-inline-export": "error",
|
|
3573
|
+
"@borela-tech/single-line-arrow-function-parameters": [
|
|
3574
|
+
"error",
|
|
3575
|
+
{ maxLength: 80 }
|
|
3576
|
+
],
|
|
3577
|
+
"@borela-tech/single-line-function-parameters": [
|
|
3578
|
+
"error",
|
|
3579
|
+
{ maxLength: 80 }
|
|
3580
|
+
],
|
|
3581
|
+
"@borela-tech/single-line-imports": "error",
|
|
3582
|
+
"@borela-tech/single-line-re-exports": "error",
|
|
3583
|
+
"@borela-tech/sorted-imports": "error",
|
|
3584
|
+
"@borela-tech/sorted-re-exports": "error"
|
|
3585
|
+
}
|
|
3586
|
+
};
|
|
3587
|
+
const generalRules = {
|
|
3588
|
+
rules: {
|
|
3589
|
+
"capitalized-comments": [
|
|
3590
|
+
"error",
|
|
3591
|
+
"always",
|
|
3592
|
+
{ ignoreConsecutiveComments: true }
|
|
3593
|
+
],
|
|
3594
|
+
complexity: ["error", 10],
|
|
3595
|
+
"no-restricted-exports": ["error", {
|
|
3596
|
+
restrictDefaultExports: {
|
|
3597
|
+
direct: true
|
|
3598
|
+
}
|
|
3599
|
+
}],
|
|
3600
|
+
"react/react-in-jsx-scope": "off"
|
|
3601
|
+
}
|
|
3602
|
+
};
|
|
3603
|
+
const ignores = {
|
|
3604
|
+
ignores: [
|
|
3605
|
+
"src/graphql/sdk.ts",
|
|
3606
|
+
"**/node_modules/**",
|
|
3607
|
+
"**/dist/**"
|
|
3608
|
+
]
|
|
3609
|
+
};
|
|
3610
|
+
const languageOptions = {
|
|
3611
|
+
languageOptions: {
|
|
3612
|
+
parserOptions: {
|
|
3613
|
+
projectService: true
|
|
3614
|
+
}
|
|
3615
|
+
},
|
|
3616
|
+
settings: {
|
|
3617
|
+
react: {
|
|
3618
|
+
version: "19"
|
|
3619
|
+
}
|
|
3620
|
+
}
|
|
3621
|
+
};
|
|
3622
|
+
const perfectionistRules = {
|
|
3623
|
+
plugins: { perfectionist },
|
|
3624
|
+
rules: {
|
|
3625
|
+
"perfectionist/sort-array-includes": ["error", {
|
|
3626
|
+
order: "asc",
|
|
3627
|
+
type: "natural"
|
|
3628
|
+
}],
|
|
3629
|
+
"perfectionist/sort-decorators": ["error", {
|
|
3630
|
+
order: "asc",
|
|
3631
|
+
type: "natural"
|
|
3632
|
+
}],
|
|
3633
|
+
"perfectionist/sort-enums": ["error", {
|
|
3634
|
+
order: "asc",
|
|
3635
|
+
type: "natural"
|
|
3636
|
+
}],
|
|
3637
|
+
"perfectionist/sort-heritage-clauses": ["error", {
|
|
3638
|
+
order: "asc",
|
|
3639
|
+
type: "natural"
|
|
3640
|
+
}],
|
|
3641
|
+
"perfectionist/sort-interfaces": ["error", {
|
|
3642
|
+
order: "asc",
|
|
3643
|
+
type: "natural"
|
|
3644
|
+
}],
|
|
3645
|
+
"perfectionist/sort-intersection-types": ["error", {
|
|
3646
|
+
order: "asc",
|
|
3647
|
+
type: "natural"
|
|
3648
|
+
}],
|
|
3649
|
+
"perfectionist/sort-jsx-props": ["error", {
|
|
3650
|
+
order: "asc",
|
|
3651
|
+
type: "natural"
|
|
3652
|
+
}],
|
|
3653
|
+
"perfectionist/sort-maps": ["error", {
|
|
3654
|
+
order: "asc",
|
|
3655
|
+
type: "natural"
|
|
3656
|
+
}],
|
|
3657
|
+
"perfectionist/sort-object-types": ["error", {
|
|
3658
|
+
order: "asc",
|
|
3659
|
+
type: "natural"
|
|
3660
|
+
}],
|
|
3661
|
+
"perfectionist/sort-objects": ["error", {
|
|
3662
|
+
order: "asc",
|
|
3663
|
+
type: "natural"
|
|
3664
|
+
}],
|
|
3665
|
+
"perfectionist/sort-sets": ["error", {
|
|
3666
|
+
order: "asc",
|
|
3667
|
+
type: "natural"
|
|
3668
|
+
}],
|
|
3669
|
+
"perfectionist/sort-switch-case": ["error", {
|
|
3670
|
+
order: "asc",
|
|
3671
|
+
type: "natural"
|
|
3672
|
+
}],
|
|
3673
|
+
"perfectionist/sort-union-types": ["error", {
|
|
3674
|
+
order: "asc",
|
|
3675
|
+
type: "natural"
|
|
3676
|
+
}]
|
|
3677
|
+
}
|
|
3678
|
+
};
|
|
3679
|
+
const reactHooks = {
|
|
3680
|
+
plugins: {
|
|
3681
|
+
"react-hooks": rule
|
|
3682
|
+
},
|
|
3683
|
+
rules: rule.configs.recommended.rules
|
|
3684
|
+
};
|
|
3685
|
+
const stylisticRules = {
|
|
3686
|
+
rules: {
|
|
3687
|
+
"@stylistic/array-bracket-spacing": [
|
|
3688
|
+
"error",
|
|
3689
|
+
"never"
|
|
3690
|
+
],
|
|
3691
|
+
"@stylistic/arrow-parens": [
|
|
3692
|
+
"error",
|
|
3693
|
+
"as-needed"
|
|
3694
|
+
],
|
|
3695
|
+
"@stylistic/block-spacing": "off",
|
|
3696
|
+
"@stylistic/brace-style": [
|
|
3697
|
+
"error",
|
|
3698
|
+
"1tbs",
|
|
3699
|
+
{ allowSingleLine: true }
|
|
3700
|
+
],
|
|
3701
|
+
"@stylistic/indent": [
|
|
3702
|
+
"error",
|
|
3703
|
+
2,
|
|
3704
|
+
{ ignoredNodes: ["TSMappedType > *"] }
|
|
3705
|
+
],
|
|
3706
|
+
"@stylistic/jsx-tag-spacing": ["error", {
|
|
3707
|
+
afterOpening: "never",
|
|
3708
|
+
beforeClosing: "never",
|
|
3709
|
+
beforeSelfClosing: "never",
|
|
3710
|
+
closingSlash: "never"
|
|
3711
|
+
}],
|
|
3712
|
+
"@stylistic/jsx-wrap-multilines": "off",
|
|
3713
|
+
"@stylistic/lines-between-class-members": "off",
|
|
3714
|
+
"@stylistic/object-curly-newline": "off",
|
|
3715
|
+
"@stylistic/object-curly-spacing": [
|
|
3716
|
+
"error",
|
|
3717
|
+
"never"
|
|
3718
|
+
],
|
|
3719
|
+
"@stylistic/operator-linebreak": [
|
|
3720
|
+
"error",
|
|
3721
|
+
"before",
|
|
3722
|
+
{ overrides: { "=": "after" } }
|
|
3723
|
+
],
|
|
3724
|
+
"@stylistic/quote-props": [
|
|
3725
|
+
"error",
|
|
3726
|
+
"as-needed"
|
|
3727
|
+
],
|
|
3728
|
+
"@stylistic/quotes": [
|
|
3729
|
+
"error",
|
|
3730
|
+
"single",
|
|
3731
|
+
{ avoidEscape: true }
|
|
3732
|
+
],
|
|
3733
|
+
"@stylistic/semi": [
|
|
3734
|
+
"error",
|
|
3735
|
+
"never",
|
|
3736
|
+
{ beforeStatementContinuationChars: "always" }
|
|
3737
|
+
]
|
|
3738
|
+
}
|
|
3739
|
+
};
|
|
3740
|
+
const typescriptRules = {
|
|
3741
|
+
rules: {
|
|
3742
|
+
"@typescript-eslint/consistent-indexed-object-style": "off",
|
|
3743
|
+
"@typescript-eslint/consistent-type-imports": [
|
|
3744
|
+
"error",
|
|
3745
|
+
{ fixStyle: "separate-type-imports" }
|
|
3746
|
+
],
|
|
3747
|
+
"@typescript-eslint/explicit-function-return-type": "error",
|
|
3748
|
+
"@typescript-eslint/no-empty-function": "off",
|
|
3749
|
+
"@typescript-eslint/no-unused-vars": ["error", {
|
|
3750
|
+
argsIgnorePattern: "^_",
|
|
3751
|
+
caughtErrorsIgnorePattern: "^_",
|
|
3752
|
+
varsIgnorePattern: "^_"
|
|
3753
|
+
}]
|
|
3754
|
+
}
|
|
3755
|
+
};
|
|
3756
|
+
function getDefaultExportFromCjs(x) {
|
|
3757
|
+
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
|
|
3758
|
+
}
|
|
3759
|
+
const builtin = { "AggregateError": false, "Array": false, "ArrayBuffer": false, "Atomics": false, "BigInt": false, "BigInt64Array": false, "BigUint64Array": false, "Boolean": false, "constructor": false, "DataView": false, "Date": false, "decodeURI": false, "decodeURIComponent": false, "encodeURI": false, "encodeURIComponent": false, "Error": false, "escape": false, "eval": false, "EvalError": false, "FinalizationRegistry": false, "Float32Array": false, "Float64Array": false, "Function": false, "globalThis": false, "hasOwnProperty": false, "Infinity": false, "Int16Array": false, "Int32Array": false, "Int8Array": false, "isFinite": false, "isNaN": false, "isPrototypeOf": false, "JSON": false, "Map": false, "Math": false, "NaN": false, "Number": false, "Object": false, "parseFloat": false, "parseInt": false, "Promise": false, "propertyIsEnumerable": false, "Proxy": false, "RangeError": false, "ReferenceError": false, "Reflect": false, "RegExp": false, "Set": false, "SharedArrayBuffer": false, "String": false, "Symbol": false, "SyntaxError": false, "toLocaleString": false, "toString": false, "TypeError": false, "Uint16Array": false, "Uint32Array": false, "Uint8Array": false, "Uint8ClampedArray": false, "undefined": false, "unescape": false, "URIError": false, "valueOf": false, "WeakMap": false, "WeakRef": false, "WeakSet": false };
|
|
3760
|
+
const es5 = { "Array": false, "Boolean": false, "constructor": false, "Date": false, "decodeURI": false, "decodeURIComponent": false, "encodeURI": false, "encodeURIComponent": false, "Error": false, "escape": false, "eval": false, "EvalError": false, "Function": false, "hasOwnProperty": false, "Infinity": false, "isFinite": false, "isNaN": false, "isPrototypeOf": false, "JSON": false, "Math": false, "NaN": false, "Number": false, "Object": false, "parseFloat": false, "parseInt": false, "propertyIsEnumerable": false, "RangeError": false, "ReferenceError": false, "RegExp": false, "String": false, "SyntaxError": false, "toLocaleString": false, "toString": false, "TypeError": false, "undefined": false, "unescape": false, "URIError": false, "valueOf": false };
|
|
3761
|
+
const es2015 = { "Array": false, "ArrayBuffer": false, "Boolean": false, "constructor": false, "DataView": false, "Date": false, "decodeURI": false, "decodeURIComponent": false, "encodeURI": false, "encodeURIComponent": false, "Error": false, "escape": false, "eval": false, "EvalError": false, "Float32Array": false, "Float64Array": false, "Function": false, "hasOwnProperty": false, "Infinity": false, "Int16Array": false, "Int32Array": false, "Int8Array": false, "isFinite": false, "isNaN": false, "isPrototypeOf": false, "JSON": false, "Map": false, "Math": false, "NaN": false, "Number": false, "Object": false, "parseFloat": false, "parseInt": false, "Promise": false, "propertyIsEnumerable": false, "Proxy": false, "RangeError": false, "ReferenceError": false, "Reflect": false, "RegExp": false, "Set": false, "String": false, "Symbol": false, "SyntaxError": false, "toLocaleString": false, "toString": false, "TypeError": false, "Uint16Array": false, "Uint32Array": false, "Uint8Array": false, "Uint8ClampedArray": false, "undefined": false, "unescape": false, "URIError": false, "valueOf": false, "WeakMap": false, "WeakSet": false };
|
|
3762
|
+
const es2017 = { "Array": false, "ArrayBuffer": false, "Atomics": false, "Boolean": false, "constructor": false, "DataView": false, "Date": false, "decodeURI": false, "decodeURIComponent": false, "encodeURI": false, "encodeURIComponent": false, "Error": false, "escape": false, "eval": false, "EvalError": false, "Float32Array": false, "Float64Array": false, "Function": false, "hasOwnProperty": false, "Infinity": false, "Int16Array": false, "Int32Array": false, "Int8Array": false, "isFinite": false, "isNaN": false, "isPrototypeOf": false, "JSON": false, "Map": false, "Math": false, "NaN": false, "Number": false, "Object": false, "parseFloat": false, "parseInt": false, "Promise": false, "propertyIsEnumerable": false, "Proxy": false, "RangeError": false, "ReferenceError": false, "Reflect": false, "RegExp": false, "Set": false, "SharedArrayBuffer": false, "String": false, "Symbol": false, "SyntaxError": false, "toLocaleString": false, "toString": false, "TypeError": false, "Uint16Array": false, "Uint32Array": false, "Uint8Array": false, "Uint8ClampedArray": false, "undefined": false, "unescape": false, "URIError": false, "valueOf": false, "WeakMap": false, "WeakSet": false };
|
|
3763
|
+
const es2020 = { "Array": false, "ArrayBuffer": false, "Atomics": false, "BigInt": false, "BigInt64Array": false, "BigUint64Array": false, "Boolean": false, "constructor": false, "DataView": false, "Date": false, "decodeURI": false, "decodeURIComponent": false, "encodeURI": false, "encodeURIComponent": false, "Error": false, "escape": false, "eval": false, "EvalError": false, "Float32Array": false, "Float64Array": false, "Function": false, "globalThis": false, "hasOwnProperty": false, "Infinity": false, "Int16Array": false, "Int32Array": false, "Int8Array": false, "isFinite": false, "isNaN": false, "isPrototypeOf": false, "JSON": false, "Map": false, "Math": false, "NaN": false, "Number": false, "Object": false, "parseFloat": false, "parseInt": false, "Promise": false, "propertyIsEnumerable": false, "Proxy": false, "RangeError": false, "ReferenceError": false, "Reflect": false, "RegExp": false, "Set": false, "SharedArrayBuffer": false, "String": false, "Symbol": false, "SyntaxError": false, "toLocaleString": false, "toString": false, "TypeError": false, "Uint16Array": false, "Uint32Array": false, "Uint8Array": false, "Uint8ClampedArray": false, "undefined": false, "unescape": false, "URIError": false, "valueOf": false, "WeakMap": false, "WeakSet": false };
|
|
3764
|
+
const es2021 = { "AggregateError": false, "Array": false, "ArrayBuffer": false, "Atomics": false, "BigInt": false, "BigInt64Array": false, "BigUint64Array": false, "Boolean": false, "constructor": false, "DataView": false, "Date": false, "decodeURI": false, "decodeURIComponent": false, "encodeURI": false, "encodeURIComponent": false, "Error": false, "escape": false, "eval": false, "EvalError": false, "FinalizationRegistry": false, "Float32Array": false, "Float64Array": false, "Function": false, "globalThis": false, "hasOwnProperty": false, "Infinity": false, "Int16Array": false, "Int32Array": false, "Int8Array": false, "isFinite": false, "isNaN": false, "isPrototypeOf": false, "JSON": false, "Map": false, "Math": false, "NaN": false, "Number": false, "Object": false, "parseFloat": false, "parseInt": false, "Promise": false, "propertyIsEnumerable": false, "Proxy": false, "RangeError": false, "ReferenceError": false, "Reflect": false, "RegExp": false, "Set": false, "SharedArrayBuffer": false, "String": false, "Symbol": false, "SyntaxError": false, "toLocaleString": false, "toString": false, "TypeError": false, "Uint16Array": false, "Uint32Array": false, "Uint8Array": false, "Uint8ClampedArray": false, "undefined": false, "unescape": false, "URIError": false, "valueOf": false, "WeakMap": false, "WeakRef": false, "WeakSet": false };
|
|
3765
|
+
const browser = /* @__PURE__ */ JSON.parse('{"AbortController":false,"AbortSignal":false,"addEventListener":false,"alert":false,"AnalyserNode":false,"Animation":false,"AnimationEffectReadOnly":false,"AnimationEffectTiming":false,"AnimationEffectTimingReadOnly":false,"AnimationEvent":false,"AnimationPlaybackEvent":false,"AnimationTimeline":false,"applicationCache":false,"ApplicationCache":false,"ApplicationCacheErrorEvent":false,"atob":false,"Attr":false,"Audio":false,"AudioBuffer":false,"AudioBufferSourceNode":false,"AudioContext":false,"AudioDestinationNode":false,"AudioListener":false,"AudioNode":false,"AudioParam":false,"AudioProcessingEvent":false,"AudioScheduledSourceNode":false,"AudioWorkletGlobalScope":false,"AudioWorkletNode":false,"AudioWorkletProcessor":false,"BarProp":false,"BaseAudioContext":false,"BatteryManager":false,"BeforeUnloadEvent":false,"BiquadFilterNode":false,"Blob":false,"BlobEvent":false,"blur":false,"BroadcastChannel":false,"btoa":false,"BudgetService":false,"ByteLengthQueuingStrategy":false,"Cache":false,"caches":false,"CacheStorage":false,"cancelAnimationFrame":false,"cancelIdleCallback":false,"CanvasCaptureMediaStreamTrack":false,"CanvasGradient":false,"CanvasPattern":false,"CanvasRenderingContext2D":false,"ChannelMergerNode":false,"ChannelSplitterNode":false,"CharacterData":false,"clearInterval":false,"clearTimeout":false,"clientInformation":false,"ClipboardEvent":false,"ClipboardItem":false,"close":false,"closed":false,"CloseEvent":false,"Comment":false,"CompositionEvent":false,"CompressionStream":false,"confirm":false,"console":false,"ConstantSourceNode":false,"ConvolverNode":false,"CountQueuingStrategy":false,"createImageBitmap":false,"Credential":false,"CredentialsContainer":false,"crypto":false,"Crypto":false,"CryptoKey":false,"CSS":false,"CSSConditionRule":false,"CSSFontFaceRule":false,"CSSGroupingRule":false,"CSSImportRule":false,"CSSKeyframeRule":false,"CSSKeyframesRule":false,"CSSMatrixComponent":false,"CSSMediaRule":false,"CSSNamespaceRule":false,"CSSPageRule":false,"CSSPerspective":false,"CSSRotate":false,"CSSRule":false,"CSSRuleList":false,"CSSScale":false,"CSSSkew":false,"CSSSkewX":false,"CSSSkewY":false,"CSSStyleDeclaration":false,"CSSStyleRule":false,"CSSStyleSheet":false,"CSSSupportsRule":false,"CSSTransformValue":false,"CSSTranslate":false,"CustomElementRegistry":false,"customElements":false,"CustomEvent":false,"DataTransfer":false,"DataTransferItem":false,"DataTransferItemList":false,"DecompressionStream":false,"defaultstatus":false,"defaultStatus":false,"DelayNode":false,"DeviceMotionEvent":false,"DeviceOrientationEvent":false,"devicePixelRatio":false,"dispatchEvent":false,"document":false,"Document":false,"DocumentFragment":false,"DocumentType":false,"DOMError":false,"DOMException":false,"DOMImplementation":false,"DOMMatrix":false,"DOMMatrixReadOnly":false,"DOMParser":false,"DOMPoint":false,"DOMPointReadOnly":false,"DOMQuad":false,"DOMRect":false,"DOMRectList":false,"DOMRectReadOnly":false,"DOMStringList":false,"DOMStringMap":false,"DOMTokenList":false,"DragEvent":false,"DynamicsCompressorNode":false,"Element":false,"ErrorEvent":false,"event":false,"Event":false,"EventSource":false,"EventTarget":false,"external":false,"fetch":false,"File":false,"FileList":false,"FileReader":false,"find":false,"focus":false,"FocusEvent":false,"FontFace":false,"FontFaceSetLoadEvent":false,"FormData":false,"FormDataEvent":false,"frameElement":false,"frames":false,"GainNode":false,"Gamepad":false,"GamepadButton":false,"GamepadEvent":false,"getComputedStyle":false,"getSelection":false,"HashChangeEvent":false,"Headers":false,"history":false,"History":false,"HTMLAllCollection":false,"HTMLAnchorElement":false,"HTMLAreaElement":false,"HTMLAudioElement":false,"HTMLBaseElement":false,"HTMLBodyElement":false,"HTMLBRElement":false,"HTMLButtonElement":false,"HTMLCanvasElement":false,"HTMLCollection":false,"HTMLContentElement":false,"HTMLDataElement":false,"HTMLDataListElement":false,"HTMLDetailsElement":false,"HTMLDialogElement":false,"HTMLDirectoryElement":false,"HTMLDivElement":false,"HTMLDListElement":false,"HTMLDocument":false,"HTMLElement":false,"HTMLEmbedElement":false,"HTMLFieldSetElement":false,"HTMLFontElement":false,"HTMLFormControlsCollection":false,"HTMLFormElement":false,"HTMLFrameElement":false,"HTMLFrameSetElement":false,"HTMLHeadElement":false,"HTMLHeadingElement":false,"HTMLHRElement":false,"HTMLHtmlElement":false,"HTMLIFrameElement":false,"HTMLImageElement":false,"HTMLInputElement":false,"HTMLLabelElement":false,"HTMLLegendElement":false,"HTMLLIElement":false,"HTMLLinkElement":false,"HTMLMapElement":false,"HTMLMarqueeElement":false,"HTMLMediaElement":false,"HTMLMenuElement":false,"HTMLMetaElement":false,"HTMLMeterElement":false,"HTMLModElement":false,"HTMLObjectElement":false,"HTMLOListElement":false,"HTMLOptGroupElement":false,"HTMLOptionElement":false,"HTMLOptionsCollection":false,"HTMLOutputElement":false,"HTMLParagraphElement":false,"HTMLParamElement":false,"HTMLPictureElement":false,"HTMLPreElement":false,"HTMLProgressElement":false,"HTMLQuoteElement":false,"HTMLScriptElement":false,"HTMLSelectElement":false,"HTMLShadowElement":false,"HTMLSlotElement":false,"HTMLSourceElement":false,"HTMLSpanElement":false,"HTMLStyleElement":false,"HTMLTableCaptionElement":false,"HTMLTableCellElement":false,"HTMLTableColElement":false,"HTMLTableElement":false,"HTMLTableRowElement":false,"HTMLTableSectionElement":false,"HTMLTemplateElement":false,"HTMLTextAreaElement":false,"HTMLTimeElement":false,"HTMLTitleElement":false,"HTMLTrackElement":false,"HTMLUListElement":false,"HTMLUnknownElement":false,"HTMLVideoElement":false,"IDBCursor":false,"IDBCursorWithValue":false,"IDBDatabase":false,"IDBFactory":false,"IDBIndex":false,"IDBKeyRange":false,"IDBObjectStore":false,"IDBOpenDBRequest":false,"IDBRequest":false,"IDBTransaction":false,"IDBVersionChangeEvent":false,"IdleDeadline":false,"IIRFilterNode":false,"Image":false,"ImageBitmap":false,"ImageBitmapRenderingContext":false,"ImageCapture":false,"ImageData":false,"indexedDB":false,"innerHeight":false,"innerWidth":false,"InputEvent":false,"IntersectionObserver":false,"IntersectionObserverEntry":false,"Intl":false,"isSecureContext":false,"KeyboardEvent":false,"KeyframeEffect":false,"KeyframeEffectReadOnly":false,"length":false,"localStorage":false,"location":true,"Location":false,"locationbar":false,"matchMedia":false,"MediaDeviceInfo":false,"MediaDevices":false,"MediaElementAudioSourceNode":false,"MediaEncryptedEvent":false,"MediaError":false,"MediaKeyMessageEvent":false,"MediaKeySession":false,"MediaKeyStatusMap":false,"MediaKeySystemAccess":false,"MediaList":false,"MediaMetadata":false,"MediaQueryList":false,"MediaQueryListEvent":false,"MediaRecorder":false,"MediaSettingsRange":false,"MediaSource":false,"MediaStream":false,"MediaStreamAudioDestinationNode":false,"MediaStreamAudioSourceNode":false,"MediaStreamConstraints":false,"MediaStreamEvent":false,"MediaStreamTrack":false,"MediaStreamTrackEvent":false,"menubar":false,"MessageChannel":false,"MessageEvent":false,"MessagePort":false,"MIDIAccess":false,"MIDIConnectionEvent":false,"MIDIInput":false,"MIDIInputMap":false,"MIDIMessageEvent":false,"MIDIOutput":false,"MIDIOutputMap":false,"MIDIPort":false,"MimeType":false,"MimeTypeArray":false,"MouseEvent":false,"moveBy":false,"moveTo":false,"MutationEvent":false,"MutationObserver":false,"MutationRecord":false,"name":false,"NamedNodeMap":false,"NavigationPreloadManager":false,"navigator":false,"Navigator":false,"NavigatorUAData":false,"NetworkInformation":false,"Node":false,"NodeFilter":false,"NodeIterator":false,"NodeList":false,"Notification":false,"OfflineAudioCompletionEvent":false,"OfflineAudioContext":false,"offscreenBuffering":false,"OffscreenCanvas":true,"OffscreenCanvasRenderingContext2D":false,"onabort":true,"onafterprint":true,"onanimationend":true,"onanimationiteration":true,"onanimationstart":true,"onappinstalled":true,"onauxclick":true,"onbeforeinstallprompt":true,"onbeforeprint":true,"onbeforeunload":true,"onblur":true,"oncancel":true,"oncanplay":true,"oncanplaythrough":true,"onchange":true,"onclick":true,"onclose":true,"oncontextmenu":true,"oncuechange":true,"ondblclick":true,"ondevicemotion":true,"ondeviceorientation":true,"ondeviceorientationabsolute":true,"ondrag":true,"ondragend":true,"ondragenter":true,"ondragleave":true,"ondragover":true,"ondragstart":true,"ondrop":true,"ondurationchange":true,"onemptied":true,"onended":true,"onerror":true,"onfocus":true,"ongotpointercapture":true,"onhashchange":true,"oninput":true,"oninvalid":true,"onkeydown":true,"onkeypress":true,"onkeyup":true,"onlanguagechange":true,"onload":true,"onloadeddata":true,"onloadedmetadata":true,"onloadstart":true,"onlostpointercapture":true,"onmessage":true,"onmessageerror":true,"onmousedown":true,"onmouseenter":true,"onmouseleave":true,"onmousemove":true,"onmouseout":true,"onmouseover":true,"onmouseup":true,"onmousewheel":true,"onoffline":true,"ononline":true,"onpagehide":true,"onpageshow":true,"onpause":true,"onplay":true,"onplaying":true,"onpointercancel":true,"onpointerdown":true,"onpointerenter":true,"onpointerleave":true,"onpointermove":true,"onpointerout":true,"onpointerover":true,"onpointerup":true,"onpopstate":true,"onprogress":true,"onratechange":true,"onrejectionhandled":true,"onreset":true,"onresize":true,"onscroll":true,"onsearch":true,"onseeked":true,"onseeking":true,"onselect":true,"onstalled":true,"onstorage":true,"onsubmit":true,"onsuspend":true,"ontimeupdate":true,"ontoggle":true,"ontransitionend":true,"onunhandledrejection":true,"onunload":true,"onvolumechange":true,"onwaiting":true,"onwheel":true,"open":false,"openDatabase":false,"opener":false,"Option":false,"origin":false,"OscillatorNode":false,"outerHeight":false,"outerWidth":false,"OverconstrainedError":false,"PageTransitionEvent":false,"pageXOffset":false,"pageYOffset":false,"PannerNode":false,"parent":false,"Path2D":false,"PaymentAddress":false,"PaymentRequest":false,"PaymentRequestUpdateEvent":false,"PaymentResponse":false,"performance":false,"Performance":false,"PerformanceEntry":false,"PerformanceLongTaskTiming":false,"PerformanceMark":false,"PerformanceMeasure":false,"PerformanceNavigation":false,"PerformanceNavigationTiming":false,"PerformanceObserver":false,"PerformanceObserverEntryList":false,"PerformancePaintTiming":false,"PerformanceResourceTiming":false,"PerformanceTiming":false,"PeriodicWave":false,"Permissions":false,"PermissionStatus":false,"personalbar":false,"PhotoCapabilities":false,"Plugin":false,"PluginArray":false,"PointerEvent":false,"PopStateEvent":false,"postMessage":false,"Presentation":false,"PresentationAvailability":false,"PresentationConnection":false,"PresentationConnectionAvailableEvent":false,"PresentationConnectionCloseEvent":false,"PresentationConnectionList":false,"PresentationReceiver":false,"PresentationRequest":false,"print":false,"ProcessingInstruction":false,"ProgressEvent":false,"PromiseRejectionEvent":false,"prompt":false,"PushManager":false,"PushSubscription":false,"PushSubscriptionOptions":false,"queueMicrotask":false,"RadioNodeList":false,"Range":false,"ReadableByteStreamController":false,"ReadableStream":false,"ReadableStreamBYOBReader":false,"ReadableStreamBYOBRequest":false,"ReadableStreamDefaultController":false,"ReadableStreamDefaultReader":false,"registerProcessor":false,"RemotePlayback":false,"removeEventListener":false,"reportError":false,"Request":false,"requestAnimationFrame":false,"requestIdleCallback":false,"resizeBy":false,"ResizeObserver":false,"ResizeObserverEntry":false,"resizeTo":false,"Response":false,"RTCCertificate":false,"RTCDataChannel":false,"RTCDataChannelEvent":false,"RTCDtlsTransport":false,"RTCIceCandidate":false,"RTCIceGatherer":false,"RTCIceTransport":false,"RTCPeerConnection":false,"RTCPeerConnectionIceEvent":false,"RTCRtpContributingSource":false,"RTCRtpReceiver":false,"RTCRtpSender":false,"RTCSctpTransport":false,"RTCSessionDescription":false,"RTCStatsReport":false,"RTCTrackEvent":false,"screen":false,"Screen":false,"screenLeft":false,"ScreenOrientation":false,"screenTop":false,"screenX":false,"screenY":false,"ScriptProcessorNode":false,"scroll":false,"scrollbars":false,"scrollBy":false,"scrollTo":false,"scrollX":false,"scrollY":false,"SecurityPolicyViolationEvent":false,"Selection":false,"self":false,"ServiceWorker":false,"ServiceWorkerContainer":false,"ServiceWorkerRegistration":false,"sessionStorage":false,"setInterval":false,"setTimeout":false,"ShadowRoot":false,"SharedWorker":false,"SourceBuffer":false,"SourceBufferList":false,"speechSynthesis":false,"SpeechSynthesisEvent":false,"SpeechSynthesisUtterance":false,"StaticRange":false,"status":false,"statusbar":false,"StereoPannerNode":false,"stop":false,"Storage":false,"StorageEvent":false,"StorageManager":false,"structuredClone":false,"styleMedia":false,"StyleSheet":false,"StyleSheetList":false,"SubmitEvent":false,"SubtleCrypto":false,"SVGAElement":false,"SVGAngle":false,"SVGAnimatedAngle":false,"SVGAnimatedBoolean":false,"SVGAnimatedEnumeration":false,"SVGAnimatedInteger":false,"SVGAnimatedLength":false,"SVGAnimatedLengthList":false,"SVGAnimatedNumber":false,"SVGAnimatedNumberList":false,"SVGAnimatedPreserveAspectRatio":false,"SVGAnimatedRect":false,"SVGAnimatedString":false,"SVGAnimatedTransformList":false,"SVGAnimateElement":false,"SVGAnimateMotionElement":false,"SVGAnimateTransformElement":false,"SVGAnimationElement":false,"SVGCircleElement":false,"SVGClipPathElement":false,"SVGComponentTransferFunctionElement":false,"SVGDefsElement":false,"SVGDescElement":false,"SVGDiscardElement":false,"SVGElement":false,"SVGEllipseElement":false,"SVGFEBlendElement":false,"SVGFEColorMatrixElement":false,"SVGFEComponentTransferElement":false,"SVGFECompositeElement":false,"SVGFEConvolveMatrixElement":false,"SVGFEDiffuseLightingElement":false,"SVGFEDisplacementMapElement":false,"SVGFEDistantLightElement":false,"SVGFEDropShadowElement":false,"SVGFEFloodElement":false,"SVGFEFuncAElement":false,"SVGFEFuncBElement":false,"SVGFEFuncGElement":false,"SVGFEFuncRElement":false,"SVGFEGaussianBlurElement":false,"SVGFEImageElement":false,"SVGFEMergeElement":false,"SVGFEMergeNodeElement":false,"SVGFEMorphologyElement":false,"SVGFEOffsetElement":false,"SVGFEPointLightElement":false,"SVGFESpecularLightingElement":false,"SVGFESpotLightElement":false,"SVGFETileElement":false,"SVGFETurbulenceElement":false,"SVGFilterElement":false,"SVGForeignObjectElement":false,"SVGGElement":false,"SVGGeometryElement":false,"SVGGradientElement":false,"SVGGraphicsElement":false,"SVGImageElement":false,"SVGLength":false,"SVGLengthList":false,"SVGLinearGradientElement":false,"SVGLineElement":false,"SVGMarkerElement":false,"SVGMaskElement":false,"SVGMatrix":false,"SVGMetadataElement":false,"SVGMPathElement":false,"SVGNumber":false,"SVGNumberList":false,"SVGPathElement":false,"SVGPatternElement":false,"SVGPoint":false,"SVGPointList":false,"SVGPolygonElement":false,"SVGPolylineElement":false,"SVGPreserveAspectRatio":false,"SVGRadialGradientElement":false,"SVGRect":false,"SVGRectElement":false,"SVGScriptElement":false,"SVGSetElement":false,"SVGStopElement":false,"SVGStringList":false,"SVGStyleElement":false,"SVGSVGElement":false,"SVGSwitchElement":false,"SVGSymbolElement":false,"SVGTextContentElement":false,"SVGTextElement":false,"SVGTextPathElement":false,"SVGTextPositioningElement":false,"SVGTitleElement":false,"SVGTransform":false,"SVGTransformList":false,"SVGTSpanElement":false,"SVGUnitTypes":false,"SVGUseElement":false,"SVGViewElement":false,"TaskAttributionTiming":false,"Text":false,"TextDecoder":false,"TextDecoderStream":false,"TextEncoder":false,"TextEncoderStream":false,"TextEvent":false,"TextMetrics":false,"TextTrack":false,"TextTrackCue":false,"TextTrackCueList":false,"TextTrackList":false,"TimeRanges":false,"ToggleEvent":false,"toolbar":false,"top":false,"Touch":false,"TouchEvent":false,"TouchList":false,"TrackEvent":false,"TransformStream":false,"TransformStreamDefaultController":false,"TransitionEvent":false,"TreeWalker":false,"UIEvent":false,"URL":false,"URLSearchParams":false,"ValidityState":false,"visualViewport":false,"VisualViewport":false,"VTTCue":false,"WaveShaperNode":false,"WebAssembly":false,"WebGL2RenderingContext":false,"WebGLActiveInfo":false,"WebGLBuffer":false,"WebGLContextEvent":false,"WebGLFramebuffer":false,"WebGLProgram":false,"WebGLQuery":false,"WebGLRenderbuffer":false,"WebGLRenderingContext":false,"WebGLSampler":false,"WebGLShader":false,"WebGLShaderPrecisionFormat":false,"WebGLSync":false,"WebGLTexture":false,"WebGLTransformFeedback":false,"WebGLUniformLocation":false,"WebGLVertexArrayObject":false,"WebSocket":false,"WheelEvent":false,"window":false,"Window":false,"Worker":false,"WritableStream":false,"WritableStreamDefaultController":false,"WritableStreamDefaultWriter":false,"XMLDocument":false,"XMLHttpRequest":false,"XMLHttpRequestEventTarget":false,"XMLHttpRequestUpload":false,"XMLSerializer":false,"XPathEvaluator":false,"XPathExpression":false,"XPathResult":false,"XRAnchor":false,"XRBoundedReferenceSpace":false,"XRCPUDepthInformation":false,"XRDepthInformation":false,"XRFrame":false,"XRInputSource":false,"XRInputSourceArray":false,"XRInputSourceEvent":false,"XRInputSourcesChangeEvent":false,"XRPose":false,"XRReferenceSpace":false,"XRReferenceSpaceEvent":false,"XRRenderState":false,"XRRigidTransform":false,"XRSession":false,"XRSessionEvent":false,"XRSpace":false,"XRSystem":false,"XRView":false,"XRViewerPose":false,"XRViewport":false,"XRWebGLBinding":false,"XRWebGLDepthInformation":false,"XRWebGLLayer":false,"XSLTProcessor":false}');
|
|
3766
|
+
const worker = { "addEventListener": false, "applicationCache": false, "atob": false, "Blob": false, "BroadcastChannel": false, "btoa": false, "ByteLengthQueuingStrategy": false, "Cache": false, "caches": false, "clearInterval": false, "clearTimeout": false, "close": true, "CompressionStream": false, "console": false, "CountQueuingStrategy": false, "crypto": false, "Crypto": false, "CryptoKey": false, "CustomEvent": false, "DecompressionStream": false, "ErrorEvent": false, "Event": false, "fetch": false, "File": false, "FileReaderSync": false, "FormData": false, "Headers": false, "IDBCursor": false, "IDBCursorWithValue": false, "IDBDatabase": false, "IDBFactory": false, "IDBIndex": false, "IDBKeyRange": false, "IDBObjectStore": false, "IDBOpenDBRequest": false, "IDBRequest": false, "IDBTransaction": false, "IDBVersionChangeEvent": false, "ImageData": false, "importScripts": true, "indexedDB": false, "location": false, "MessageChannel": false, "MessageEvent": false, "MessagePort": false, "name": false, "navigator": false, "Notification": false, "onclose": true, "onconnect": true, "onerror": true, "onlanguagechange": true, "onmessage": true, "onoffline": true, "ononline": true, "onrejectionhandled": true, "onunhandledrejection": true, "performance": false, "Performance": false, "PerformanceEntry": false, "PerformanceMark": false, "PerformanceMeasure": false, "PerformanceNavigation": false, "PerformanceObserver": false, "PerformanceObserverEntryList": false, "PerformanceResourceTiming": false, "PerformanceTiming": false, "postMessage": true, "Promise": false, "queueMicrotask": false, "ReadableByteStreamController": false, "ReadableStream": false, "ReadableStreamBYOBReader": false, "ReadableStreamBYOBRequest": false, "ReadableStreamDefaultController": false, "ReadableStreamDefaultReader": false, "removeEventListener": false, "reportError": false, "Request": false, "Response": false, "self": true, "ServiceWorkerRegistration": false, "setInterval": false, "setTimeout": false, "SubtleCrypto": false, "TextDecoder": false, "TextDecoderStream": false, "TextEncoder": false, "TextEncoderStream": false, "TransformStream": false, "TransformStreamDefaultController": false, "URL": false, "URLSearchParams": false, "WebAssembly": false, "WebSocket": false, "Worker": false, "WorkerGlobalScope": false, "WritableStream": false, "WritableStreamDefaultController": false, "WritableStreamDefaultWriter": false, "XMLHttpRequest": false };
|
|
3767
|
+
const node = { "__dirname": false, "__filename": false, "AbortController": false, "AbortSignal": false, "atob": false, "Blob": false, "BroadcastChannel": false, "btoa": false, "Buffer": false, "ByteLengthQueuingStrategy": false, "clearImmediate": false, "clearInterval": false, "clearTimeout": false, "CompressionStream": false, "console": false, "CountQueuingStrategy": false, "crypto": false, "Crypto": false, "CryptoKey": false, "CustomEvent": false, "DecompressionStream": false, "DOMException": false, "Event": false, "EventTarget": false, "exports": true, "fetch": false, "File": false, "FormData": false, "global": false, "Headers": false, "Intl": false, "MessageChannel": false, "MessageEvent": false, "MessagePort": false, "module": false, "performance": false, "PerformanceEntry": false, "PerformanceMark": false, "PerformanceMeasure": false, "PerformanceObserver": false, "PerformanceObserverEntryList": false, "PerformanceResourceTiming": false, "process": false, "queueMicrotask": false, "ReadableByteStreamController": false, "ReadableStream": false, "ReadableStreamBYOBReader": false, "ReadableStreamBYOBRequest": false, "ReadableStreamDefaultController": false, "ReadableStreamDefaultReader": false, "Request": false, "require": false, "Response": false, "setImmediate": false, "setInterval": false, "setTimeout": false, "structuredClone": false, "SubtleCrypto": false, "TextDecoder": false, "TextDecoderStream": false, "TextEncoder": false, "TextEncoderStream": false, "TransformStream": false, "TransformStreamDefaultController": false, "URL": false, "URLSearchParams": false, "WebAssembly": false, "WritableStream": false, "WritableStreamDefaultController": false, "WritableStreamDefaultWriter": false };
|
|
3768
|
+
const nodeBuiltin = { "AbortController": false, "AbortSignal": false, "atob": false, "Blob": false, "BroadcastChannel": false, "btoa": false, "Buffer": false, "ByteLengthQueuingStrategy": false, "clearImmediate": false, "clearInterval": false, "clearTimeout": false, "CompressionStream": false, "console": false, "CountQueuingStrategy": false, "crypto": false, "Crypto": false, "CryptoKey": false, "CustomEvent": false, "DecompressionStream": false, "DOMException": false, "Event": false, "EventTarget": false, "fetch": false, "File": false, "FormData": false, "global": false, "Headers": false, "Intl": false, "MessageChannel": false, "MessageEvent": false, "MessagePort": false, "performance": false, "PerformanceEntry": false, "PerformanceMark": false, "PerformanceMeasure": false, "PerformanceObserver": false, "PerformanceObserverEntryList": false, "PerformanceResourceTiming": false, "process": false, "queueMicrotask": false, "ReadableByteStreamController": false, "ReadableStream": false, "ReadableStreamBYOBReader": false, "ReadableStreamBYOBRequest": false, "ReadableStreamDefaultController": false, "ReadableStreamDefaultReader": false, "Request": false, "Response": false, "setImmediate": false, "setInterval": false, "setTimeout": false, "structuredClone": false, "SubtleCrypto": false, "TextDecoder": false, "TextDecoderStream": false, "TextEncoder": false, "TextEncoderStream": false, "TransformStream": false, "TransformStreamDefaultController": false, "URL": false, "URLSearchParams": false, "WebAssembly": false, "WritableStream": false, "WritableStreamDefaultController": false, "WritableStreamDefaultWriter": false };
|
|
3769
|
+
const commonjs = { "exports": true, "global": false, "module": false, "require": false };
|
|
3770
|
+
const amd = { "define": false, "require": false };
|
|
3771
|
+
const mocha = { "after": false, "afterEach": false, "before": false, "beforeEach": false, "context": false, "describe": false, "it": false, "mocha": false, "run": false, "setup": false, "specify": false, "suite": false, "suiteSetup": false, "suiteTeardown": false, "teardown": false, "test": false, "xcontext": false, "xdescribe": false, "xit": false, "xspecify": false };
|
|
3772
|
+
const jasmine = { "afterAll": false, "afterEach": false, "beforeAll": false, "beforeEach": false, "describe": false, "expect": false, "expectAsync": false, "fail": false, "fdescribe": false, "fit": false, "it": false, "jasmine": false, "pending": false, "runs": false, "spyOn": false, "spyOnAllFunctions": false, "spyOnProperty": false, "waits": false, "waitsFor": false, "xdescribe": false, "xit": false };
|
|
3773
|
+
const jest = { "afterAll": false, "afterEach": false, "beforeAll": false, "beforeEach": false, "describe": false, "expect": false, "fdescribe": false, "fit": false, "it": false, "jest": false, "pit": false, "require": false, "test": false, "xdescribe": false, "xit": false, "xtest": false };
|
|
3774
|
+
const qunit = { "asyncTest": false, "deepEqual": false, "equal": false, "expect": false, "module": false, "notDeepEqual": false, "notEqual": false, "notOk": false, "notPropEqual": false, "notStrictEqual": false, "ok": false, "propEqual": false, "QUnit": false, "raises": false, "start": false, "stop": false, "strictEqual": false, "test": false, "throws": false };
|
|
3775
|
+
const phantomjs = { "console": true, "exports": true, "phantom": true, "require": true, "WebPage": true };
|
|
3776
|
+
const couch = { "emit": false, "exports": false, "getRow": false, "log": false, "module": false, "provides": false, "require": false, "respond": false, "send": false, "start": false, "sum": false };
|
|
3777
|
+
const rhino = { "defineClass": false, "deserialize": false, "gc": false, "help": false, "importClass": false, "importPackage": false, "java": false, "load": false, "loadClass": false, "Packages": false, "print": false, "quit": false, "readFile": false, "readUrl": false, "runCommand": false, "seal": false, "serialize": false, "spawn": false, "sync": false, "toint32": false, "version": false };
|
|
3778
|
+
const nashorn = { "__DIR__": false, "__FILE__": false, "__LINE__": false, "com": false, "edu": false, "exit": false, "java": false, "Java": false, "javafx": false, "JavaImporter": false, "javax": false, "JSAdapter": false, "load": false, "loadWithNewGlobal": false, "org": false, "Packages": false, "print": false, "quit": false };
|
|
3779
|
+
const wsh = { "ActiveXObject": false, "CollectGarbage": false, "Debug": false, "Enumerator": false, "GetObject": false, "RuntimeObject": false, "ScriptEngine": false, "ScriptEngineBuildVersion": false, "ScriptEngineMajorVersion": false, "ScriptEngineMinorVersion": false, "VBArray": false, "WScript": false, "WSH": false };
|
|
3780
|
+
const jquery = { "$": false, "jQuery": false };
|
|
3781
|
+
const yui = { "YAHOO": false, "YAHOO_config": false, "YUI": false, "YUI_config": false };
|
|
3782
|
+
const shelljs = { "cat": false, "cd": false, "chmod": false, "config": false, "cp": false, "dirs": false, "echo": false, "env": false, "error": false, "exec": false, "exit": false, "find": false, "grep": false, "ln": false, "ls": false, "mkdir": false, "mv": false, "popd": false, "pushd": false, "pwd": false, "rm": false, "sed": false, "set": false, "target": false, "tempdir": false, "test": false, "touch": false, "which": false };
|
|
3783
|
+
const prototypejs = { "$": false, "$$": false, "$A": false, "$break": false, "$continue": false, "$F": false, "$H": false, "$R": false, "$w": false, "Abstract": false, "Ajax": false, "Autocompleter": false, "Builder": false, "Class": false, "Control": false, "Draggable": false, "Draggables": false, "Droppables": false, "Effect": false, "Element": false, "Enumerable": false, "Event": false, "Field": false, "Form": false, "Hash": false, "Insertion": false, "ObjectRange": false, "PeriodicalExecuter": false, "Position": false, "Prototype": false, "Scriptaculous": false, "Selector": false, "Sortable": false, "SortableObserver": false, "Sound": false, "Template": false, "Toggle": false, "Try": false };
|
|
3784
|
+
const meteor = { "$": false, "Accounts": false, "AccountsClient": false, "AccountsCommon": false, "AccountsServer": false, "App": false, "Assets": false, "Blaze": false, "check": false, "Cordova": false, "DDP": false, "DDPRateLimiter": false, "DDPServer": false, "Deps": false, "EJSON": false, "Email": false, "HTTP": false, "Log": false, "Match": false, "Meteor": false, "Mongo": false, "MongoInternals": false, "Npm": false, "Package": false, "Plugin": false, "process": false, "Random": false, "ReactiveDict": false, "ReactiveVar": false, "Router": false, "ServiceConfiguration": false, "Session": false, "share": false, "Spacebars": false, "Template": false, "Tinytest": false, "Tracker": false, "UI": false, "Utils": false, "WebApp": false, "WebAppInternals": false };
|
|
3785
|
+
const mongo = { "_isWindows": false, "_rand": false, "BulkWriteResult": false, "cat": false, "cd": false, "connect": false, "db": false, "getHostName": false, "getMemInfo": false, "hostname": false, "ISODate": false, "listFiles": false, "load": false, "ls": false, "md5sumFile": false, "mkdir": false, "Mongo": false, "NumberInt": false, "NumberLong": false, "ObjectId": false, "PlanCache": false, "print": false, "printjson": false, "pwd": false, "quit": false, "removeFile": false, "rs": false, "sh": false, "UUID": false, "version": false, "WriteResult": false };
|
|
3786
|
+
const applescript = { "$": false, "Application": false, "Automation": false, "console": false, "delay": false, "Library": false, "ObjC": false, "ObjectSpecifier": false, "Path": false, "Progress": false, "Ref": false };
|
|
3787
|
+
const serviceworker = { "addEventListener": false, "applicationCache": false, "atob": false, "Blob": false, "BroadcastChannel": false, "btoa": false, "ByteLengthQueuingStrategy": false, "Cache": false, "caches": false, "CacheStorage": false, "clearInterval": false, "clearTimeout": false, "Client": false, "clients": false, "Clients": false, "close": true, "CompressionStream": false, "console": false, "CountQueuingStrategy": false, "crypto": false, "Crypto": false, "CryptoKey": false, "CustomEvent": false, "DecompressionStream": false, "ErrorEvent": false, "Event": false, "ExtendableEvent": false, "ExtendableMessageEvent": false, "fetch": false, "FetchEvent": false, "File": false, "FileReaderSync": false, "FormData": false, "Headers": false, "IDBCursor": false, "IDBCursorWithValue": false, "IDBDatabase": false, "IDBFactory": false, "IDBIndex": false, "IDBKeyRange": false, "IDBObjectStore": false, "IDBOpenDBRequest": false, "IDBRequest": false, "IDBTransaction": false, "IDBVersionChangeEvent": false, "ImageData": false, "importScripts": false, "indexedDB": false, "location": false, "MessageChannel": false, "MessageEvent": false, "MessagePort": false, "name": false, "navigator": false, "Notification": false, "onclose": true, "onconnect": true, "onerror": true, "onfetch": true, "oninstall": true, "onlanguagechange": true, "onmessage": true, "onmessageerror": true, "onnotificationclick": true, "onnotificationclose": true, "onoffline": true, "ononline": true, "onpush": true, "onpushsubscriptionchange": true, "onrejectionhandled": true, "onsync": true, "onunhandledrejection": true, "performance": false, "Performance": false, "PerformanceEntry": false, "PerformanceMark": false, "PerformanceMeasure": false, "PerformanceNavigation": false, "PerformanceObserver": false, "PerformanceObserverEntryList": false, "PerformanceResourceTiming": false, "PerformanceTiming": false, "postMessage": true, "Promise": false, "queueMicrotask": false, "ReadableByteStreamController": false, "ReadableStream": false, "ReadableStreamBYOBReader": false, "ReadableStreamBYOBRequest": false, "ReadableStreamDefaultController": false, "ReadableStreamDefaultReader": false, "registration": false, "removeEventListener": false, "Request": false, "Response": false, "self": false, "ServiceWorker": false, "ServiceWorkerContainer": false, "ServiceWorkerGlobalScope": false, "ServiceWorkerMessageEvent": false, "ServiceWorkerRegistration": false, "setInterval": false, "setTimeout": false, "skipWaiting": false, "SubtleCrypto": false, "TextDecoder": false, "TextDecoderStream": false, "TextEncoder": false, "TextEncoderStream": false, "TransformStream": false, "TransformStreamDefaultController": false, "URL": false, "URLSearchParams": false, "WebAssembly": false, "WebSocket": false, "WindowClient": false, "Worker": false, "WorkerGlobalScope": false, "WritableStream": false, "WritableStreamDefaultController": false, "WritableStreamDefaultWriter": false, "XMLHttpRequest": false };
|
|
3788
|
+
const atomtest = { "advanceClock": false, "atom": false, "fakeClearInterval": false, "fakeClearTimeout": false, "fakeSetInterval": false, "fakeSetTimeout": false, "resetTimeouts": false, "waitsForPromise": false };
|
|
3789
|
+
const embertest = { "andThen": false, "click": false, "currentPath": false, "currentRouteName": false, "currentURL": false, "fillIn": false, "find": false, "findAll": false, "findWithAssert": false, "keyEvent": false, "pauseTest": false, "resumeTest": false, "triggerEvent": false, "visit": false, "wait": false };
|
|
3790
|
+
const protractor = { "$": false, "$$": false, "browser": false, "by": false, "By": false, "DartObject": false, "element": false, "protractor": false };
|
|
3791
|
+
const webextensions = { "browser": false, "chrome": false, "opr": false };
|
|
3792
|
+
const greasemonkey = { "cloneInto": false, "createObjectIn": false, "exportFunction": false, "GM": false, "GM_addElement": false, "GM_addStyle": false, "GM_addValueChangeListener": false, "GM_deleteValue": false, "GM_download": false, "GM_getResourceText": false, "GM_getResourceURL": false, "GM_getTab": false, "GM_getTabs": false, "GM_getValue": false, "GM_info": false, "GM_listValues": false, "GM_log": false, "GM_notification": false, "GM_openInTab": false, "GM_registerMenuCommand": false, "GM_removeValueChangeListener": false, "GM_saveTab": false, "GM_setClipboard": false, "GM_setValue": false, "GM_unregisterMenuCommand": false, "GM_xmlhttpRequest": false, "unsafeWindow": false };
|
|
3793
|
+
const devtools = { "$": false, "$_": false, "$$": false, "$0": false, "$1": false, "$2": false, "$3": false, "$4": false, "$x": false, "chrome": false, "clear": false, "copy": false, "debug": false, "dir": false, "dirxml": false, "getEventListeners": false, "inspect": false, "keys": false, "monitor": false, "monitorEvents": false, "profile": false, "profileEnd": false, "queryObjects": false, "table": false, "undebug": false, "unmonitor": false, "unmonitorEvents": false, "values": false };
|
|
3794
|
+
const require$$0 = {
|
|
3795
|
+
builtin,
|
|
3796
|
+
es5,
|
|
3797
|
+
es2015,
|
|
3798
|
+
es2017,
|
|
3799
|
+
es2020,
|
|
3800
|
+
es2021,
|
|
3801
|
+
browser,
|
|
3802
|
+
worker,
|
|
3803
|
+
node,
|
|
3804
|
+
nodeBuiltin,
|
|
3805
|
+
commonjs,
|
|
3806
|
+
amd,
|
|
3807
|
+
mocha,
|
|
3808
|
+
jasmine,
|
|
3809
|
+
jest,
|
|
3810
|
+
qunit,
|
|
3811
|
+
phantomjs,
|
|
3812
|
+
couch,
|
|
3813
|
+
rhino,
|
|
3814
|
+
nashorn,
|
|
3815
|
+
wsh,
|
|
3816
|
+
jquery,
|
|
3817
|
+
yui,
|
|
3818
|
+
shelljs,
|
|
3819
|
+
prototypejs,
|
|
3820
|
+
meteor,
|
|
3821
|
+
mongo,
|
|
3822
|
+
applescript,
|
|
3823
|
+
serviceworker,
|
|
3824
|
+
atomtest,
|
|
3825
|
+
embertest,
|
|
3826
|
+
protractor,
|
|
3827
|
+
"shared-node-browser": { "AbortController": false, "AbortSignal": false, "atob": false, "Blob": false, "BroadcastChannel": false, "btoa": false, "ByteLengthQueuingStrategy": false, "clearInterval": false, "clearTimeout": false, "CompressionStream": false, "console": false, "CountQueuingStrategy": false, "crypto": false, "Crypto": false, "CryptoKey": false, "CustomEvent": false, "DecompressionStream": false, "DOMException": false, "Event": false, "EventTarget": false, "fetch": false, "File": false, "FormData": false, "Headers": false, "Intl": false, "MessageChannel": false, "MessageEvent": false, "MessagePort": false, "performance": false, "PerformanceEntry": false, "PerformanceMark": false, "PerformanceMeasure": false, "PerformanceObserver": false, "PerformanceObserverEntryList": false, "PerformanceResourceTiming": false, "queueMicrotask": false, "ReadableByteStreamController": false, "ReadableStream": false, "ReadableStreamBYOBReader": false, "ReadableStreamBYOBRequest": false, "ReadableStreamDefaultController": false, "ReadableStreamDefaultReader": false, "Request": false, "Response": false, "setInterval": false, "setTimeout": false, "structuredClone": false, "SubtleCrypto": false, "TextDecoder": false, "TextDecoderStream": false, "TextEncoder": false, "TextEncoderStream": false, "TransformStream": false, "TransformStreamDefaultController": false, "URL": false, "URLSearchParams": false, "WebAssembly": false, "WritableStream": false, "WritableStreamDefaultController": false, "WritableStreamDefaultWriter": false },
|
|
3828
|
+
webextensions,
|
|
3829
|
+
greasemonkey,
|
|
3830
|
+
devtools
|
|
3831
|
+
};
|
|
3832
|
+
var globals$1;
|
|
3833
|
+
var hasRequiredGlobals;
|
|
3834
|
+
function requireGlobals() {
|
|
3835
|
+
if (hasRequiredGlobals) return globals$1;
|
|
3836
|
+
hasRequiredGlobals = 1;
|
|
3837
|
+
globals$1 = require$$0;
|
|
3838
|
+
return globals$1;
|
|
3839
|
+
}
|
|
3840
|
+
var globalsExports = /* @__PURE__ */ requireGlobals();
|
|
3841
|
+
const globals = /* @__PURE__ */ getDefaultExportFromCjs(globalsExports);
|
|
3842
|
+
const unicornRules = {
|
|
3843
|
+
languageOptions: {
|
|
3844
|
+
globals: {
|
|
3845
|
+
...globals.builtin
|
|
3846
|
+
}
|
|
3847
|
+
},
|
|
3848
|
+
plugins: {
|
|
3849
|
+
unicorn: eslintPluginUnicorn
|
|
3850
|
+
},
|
|
3851
|
+
rules: {
|
|
3852
|
+
"unicorn/better-regex": "error",
|
|
3853
|
+
"unicorn/catch-error-name": "error",
|
|
3854
|
+
"unicorn/consistent-date-clone": "error",
|
|
3855
|
+
"unicorn/consistent-destructuring": "error",
|
|
3856
|
+
"unicorn/escape-case": "error",
|
|
3857
|
+
"unicorn/no-array-for-each": "error",
|
|
3858
|
+
"unicorn/no-array-reduce": "error",
|
|
3859
|
+
"unicorn/no-await-in-promise-methods": "error",
|
|
3860
|
+
"unicorn/no-invalid-remove-event-listener": "error",
|
|
3861
|
+
"unicorn/no-new-array": "error",
|
|
3862
|
+
"unicorn/no-new-buffer": "error",
|
|
3863
|
+
"unicorn/no-object-as-default-parameter": "error",
|
|
3864
|
+
"unicorn/no-single-promise-in-promise-methods": "error",
|
|
3865
|
+
"unicorn/no-unnecessary-await": "error",
|
|
3866
|
+
"unicorn/no-unreadable-iife": "error",
|
|
3867
|
+
"unicorn/no-useless-collection-argument": "error",
|
|
3868
|
+
"unicorn/no-useless-error-capture-stack-trace": "error",
|
|
3869
|
+
"unicorn/no-useless-fallback-in-spread": "error",
|
|
3870
|
+
"unicorn/no-useless-promise-resolve-reject": "error",
|
|
3871
|
+
"unicorn/no-useless-spread": "error",
|
|
3872
|
+
"unicorn/no-useless-switch-case": "error",
|
|
3873
|
+
"unicorn/number-literal-case": "error",
|
|
3874
|
+
"unicorn/numeric-separators-style": "error",
|
|
3875
|
+
"unicorn/prefer-array-find": "error",
|
|
3876
|
+
"unicorn/prefer-array-flat": "error",
|
|
3877
|
+
"unicorn/prefer-array-flat-map": "error",
|
|
3878
|
+
"unicorn/prefer-array-index-of": "error",
|
|
3879
|
+
"unicorn/prefer-array-some": "error",
|
|
3880
|
+
"unicorn/prefer-bigint-literals": "error",
|
|
3881
|
+
"unicorn/prefer-blob-reading-methods": "error",
|
|
3882
|
+
"unicorn/prefer-date-now": "error",
|
|
3883
|
+
"unicorn/prefer-import-meta-properties": "error",
|
|
3884
|
+
"unicorn/prefer-includes": "error",
|
|
3885
|
+
"unicorn/prefer-logical-operator-over-ternary": "error",
|
|
3886
|
+
"unicorn/prefer-number-properties": "error",
|
|
3887
|
+
"unicorn/prefer-object-from-entries": "error",
|
|
3888
|
+
"unicorn/prefer-optional-catch-binding": "error",
|
|
3889
|
+
"unicorn/prefer-prototype-methods": "error",
|
|
3890
|
+
"unicorn/prefer-response-static-json": "error",
|
|
3891
|
+
"unicorn/prefer-set-has": "error",
|
|
3892
|
+
"unicorn/prefer-set-size": "error",
|
|
3893
|
+
"unicorn/prefer-string-raw": "error",
|
|
3894
|
+
"unicorn/prefer-string-replace-all": "error",
|
|
3895
|
+
"unicorn/prefer-string-starts-ends-with": "error",
|
|
3896
|
+
"unicorn/prefer-string-trim-start-end": "error",
|
|
3897
|
+
"unicorn/prefer-structured-clone": "error",
|
|
3898
|
+
"unicorn/prefer-switch": "error",
|
|
3899
|
+
"unicorn/require-module-attributes": "error",
|
|
3900
|
+
"unicorn/require-module-specifiers": "error",
|
|
3901
|
+
"unicorn/template-indent": "error"
|
|
3902
|
+
}
|
|
3903
|
+
};
|
|
3904
|
+
const config = [
|
|
3905
|
+
ignores,
|
|
3906
|
+
languageOptions,
|
|
3907
|
+
//////////////////////////////////////////////////////////////////////////////
|
|
3908
|
+
eslint.configs.recommended,
|
|
3909
|
+
react.configs.flat.recommended,
|
|
3910
|
+
stylistic.configs.recommended,
|
|
3911
|
+
...typescript.configs.recommended,
|
|
3912
|
+
...typescript.configs.stylistic,
|
|
3913
|
+
//////////////////////////////////////////////////////////////////////////////
|
|
3914
|
+
customRules,
|
|
3915
|
+
generalRules,
|
|
3916
|
+
perfectionistRules,
|
|
3917
|
+
reactHooks,
|
|
3918
|
+
stylisticRules,
|
|
3919
|
+
typescriptRules,
|
|
3920
|
+
unicornRules
|
|
868
3921
|
];
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
//# sourceMappingURL=index.mjs.map
|
|
3922
|
+
export {
|
|
3923
|
+
config
|
|
3924
|
+
};
|
|
3925
|
+
//# sourceMappingURL=index.mjs.map
|