@fenge/eslint-plugin 0.1.2 → 0.1.3
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/CHANGELOG.md +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/rules/no-instanceof-builtin.d.ts.map +1 -1
- package/dist/rules/no-instanceof-builtin.js +4 -1
- package/dist/rules/no-jsx-in-non-jsx-file.d.ts.map +1 -1
- package/dist/rules/no-jsx-in-non-jsx-file.js +3 -4
- package/dist/rules/no-nested-class.d.ts +6 -0
- package/dist/rules/no-nested-class.d.ts.map +1 -0
- package/dist/rules/no-nested-class.js +23 -0
- package/dist/rules/no-nested-function.d.ts +6 -0
- package/dist/rules/no-nested-function.d.ts.map +1 -0
- package/dist/rules/no-nested-function.js +27 -0
- package/dist/rules/no-top-level-arrow-function.d.ts +6 -0
- package/dist/rules/no-top-level-arrow-function.d.ts.map +1 -0
- package/dist/rules/no-top-level-arrow-function.js +27 -0
- package/doc/rules/call-arguments-length.md +52 -0
- package/doc/rules/no-instanceof-builtin.md +50 -0
- package/doc/rules/no-jsx-in-non-jsx-file.md +37 -0
- package/doc/rules/no-nested-class.md +31 -0
- package/doc/rules/no-nested-function.md +40 -0
- package/doc/rules/no-restricted-loops.md +23 -0
- package/doc/rules/no-top-level-arrow-function.md +41 -0
- package/doc/rules/no-unnecessary-template-string.md +34 -0
- package/package.json +4 -6
- package/src/index.ts +6 -0
- package/src/rules/call-arguments-length.spec.ts +1 -1
- package/src/rules/no-instanceof-builtin.spec.ts +1 -1
- package/src/rules/no-instanceof-builtin.ts +3 -0
- package/src/rules/no-jsx-in-non-jsx-file.spec.ts +1 -1
- package/src/rules/no-jsx-in-non-jsx-file.ts +2 -6
- package/src/rules/no-nested-class.spec.ts +27 -0
- package/src/rules/no-nested-class.ts +31 -0
- package/src/rules/no-nested-function.spec.ts +47 -0
- package/src/rules/no-nested-function.ts +32 -0
- package/src/rules/no-restricted-loops.spec.ts +1 -1
- package/src/rules/no-top-level-arrow-function.spec.ts +29 -0
- package/src/rules/no-top-level-arrow-function.ts +34 -0
- package/src/rules/no-unnecessary-template-string.spec.ts +1 -1
- package/src/test.spec.ts +0 -51
package/CHANGELOG.md
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,KAAK;;CASjB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import { callArgumentsLength } from "./rules/call-arguments-length.js";
|
|
2
2
|
import { noInstanceofBuiltin } from "./rules/no-instanceof-builtin.js";
|
|
3
3
|
import { noJsxInNonJsxFile } from "./rules/no-jsx-in-non-jsx-file.js";
|
|
4
|
+
import { noNestedClass } from "./rules/no-nested-class.js";
|
|
5
|
+
import { noNestedFunction } from "./rules/no-nested-function.js";
|
|
4
6
|
import { noRestrictedLoops } from "./rules/no-restricted-loops.js";
|
|
7
|
+
import { noTopLevelArrowFunction } from "./rules/no-top-level-arrow-function.js";
|
|
5
8
|
import { noUnnecessaryTemplateString } from "./rules/no-unnecessary-template-string.js";
|
|
6
9
|
export const rules = {
|
|
7
10
|
[callArgumentsLength.name]: callArgumentsLength.rule,
|
|
8
11
|
[noInstanceofBuiltin.name]: noInstanceofBuiltin.rule,
|
|
9
12
|
[noJsxInNonJsxFile.name]: noJsxInNonJsxFile.rule,
|
|
13
|
+
[noNestedClass.name]: noNestedClass.rule,
|
|
14
|
+
[noNestedFunction.name]: noNestedFunction.rule,
|
|
10
15
|
[noRestrictedLoops.name]: noRestrictedLoops.rule,
|
|
16
|
+
[noTopLevelArrowFunction.name]: noTopLevelArrowFunction.rule,
|
|
11
17
|
[noUnnecessaryTemplateString.name]: noUnnecessaryTemplateString.rule,
|
|
12
18
|
};
|
|
13
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
19
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDdkUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDdkUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDdEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzNELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ25FLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBQ2pGLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLDJDQUEyQyxDQUFDO0FBRXhGLE1BQU0sQ0FBQyxNQUFNLEtBQUssR0FBRztJQUNuQixDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxFQUFFLG1CQUFtQixDQUFDLElBQUk7SUFDcEQsQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsRUFBRSxtQkFBbUIsQ0FBQyxJQUFJO0lBQ3BELENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEVBQUUsaUJBQWlCLENBQUMsSUFBSTtJQUNoRCxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsRUFBRSxhQUFhLENBQUMsSUFBSTtJQUN4QyxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxFQUFFLGdCQUFnQixDQUFDLElBQUk7SUFDOUMsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxJQUFJO0lBQ2hELENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLEVBQUUsdUJBQXVCLENBQUMsSUFBSTtJQUM1RCxDQUFDLDJCQUEyQixDQUFDLElBQUksQ0FBQyxFQUFFLDJCQUEyQixDQUFDLElBQUk7Q0FDckUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNhbGxBcmd1bWVudHNMZW5ndGggfSBmcm9tIFwiLi9ydWxlcy9jYWxsLWFyZ3VtZW50cy1sZW5ndGguanNcIjtcbmltcG9ydCB7IG5vSW5zdGFuY2VvZkJ1aWx0aW4gfSBmcm9tIFwiLi9ydWxlcy9uby1pbnN0YW5jZW9mLWJ1aWx0aW4uanNcIjtcbmltcG9ydCB7IG5vSnN4SW5Ob25Kc3hGaWxlIH0gZnJvbSBcIi4vcnVsZXMvbm8tanN4LWluLW5vbi1qc3gtZmlsZS5qc1wiO1xuaW1wb3J0IHsgbm9OZXN0ZWRDbGFzcyB9IGZyb20gXCIuL3J1bGVzL25vLW5lc3RlZC1jbGFzcy5qc1wiO1xuaW1wb3J0IHsgbm9OZXN0ZWRGdW5jdGlvbiB9IGZyb20gXCIuL3J1bGVzL25vLW5lc3RlZC1mdW5jdGlvbi5qc1wiO1xuaW1wb3J0IHsgbm9SZXN0cmljdGVkTG9vcHMgfSBmcm9tIFwiLi9ydWxlcy9uby1yZXN0cmljdGVkLWxvb3BzLmpzXCI7XG5pbXBvcnQgeyBub1RvcExldmVsQXJyb3dGdW5jdGlvbiB9IGZyb20gXCIuL3J1bGVzL25vLXRvcC1sZXZlbC1hcnJvdy1mdW5jdGlvbi5qc1wiO1xuaW1wb3J0IHsgbm9Vbm5lY2Vzc2FyeVRlbXBsYXRlU3RyaW5nIH0gZnJvbSBcIi4vcnVsZXMvbm8tdW5uZWNlc3NhcnktdGVtcGxhdGUtc3RyaW5nLmpzXCI7XG5cbmV4cG9ydCBjb25zdCBydWxlcyA9IHtcbiAgW2NhbGxBcmd1bWVudHNMZW5ndGgubmFtZV06IGNhbGxBcmd1bWVudHNMZW5ndGgucnVsZSxcbiAgW25vSW5zdGFuY2VvZkJ1aWx0aW4ubmFtZV06IG5vSW5zdGFuY2VvZkJ1aWx0aW4ucnVsZSxcbiAgW25vSnN4SW5Ob25Kc3hGaWxlLm5hbWVdOiBub0pzeEluTm9uSnN4RmlsZS5ydWxlLFxuICBbbm9OZXN0ZWRDbGFzcy5uYW1lXTogbm9OZXN0ZWRDbGFzcy5ydWxlLFxuICBbbm9OZXN0ZWRGdW5jdGlvbi5uYW1lXTogbm9OZXN0ZWRGdW5jdGlvbi5ydWxlLFxuICBbbm9SZXN0cmljdGVkTG9vcHMubmFtZV06IG5vUmVzdHJpY3RlZExvb3BzLnJ1bGUsXG4gIFtub1RvcExldmVsQXJyb3dGdW5jdGlvbi5uYW1lXTogbm9Ub3BMZXZlbEFycm93RnVuY3Rpb24ucnVsZSxcbiAgW25vVW5uZWNlc3NhcnlUZW1wbGF0ZVN0cmluZy5uYW1lXTogbm9Vbm5lY2Vzc2FyeVRlbXBsYXRlU3RyaW5nLnJ1bGUsXG59O1xuIl19
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-instanceof-builtin.d.ts","sourceRoot":"","sources":["../../src/rules/no-instanceof-builtin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"no-instanceof-builtin.d.ts","sourceRoot":"","sources":["../../src/rules/no-instanceof-builtin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AA6CnC,eAAO,MAAM,mBAAmB;;;CAAiB,CAAC"}
|
|
@@ -13,6 +13,9 @@ const rule = {
|
|
|
13
13
|
create: (context) => {
|
|
14
14
|
let builtins = undefined;
|
|
15
15
|
return {
|
|
16
|
+
// ESLint visit the Node from root to leaf. The Program Node is the root.
|
|
17
|
+
// Therefore, Program will be called before BinaryExpression.
|
|
18
|
+
// https://eslint.org/docs/latest/extend/code-path-analysis
|
|
16
19
|
Program: (node) => {
|
|
17
20
|
const scope = context.sourceCode.getScope(node);
|
|
18
21
|
builtins = new Set([
|
|
@@ -35,4 +38,4 @@ const rule = {
|
|
|
35
38
|
},
|
|
36
39
|
};
|
|
37
40
|
export const noInstanceofBuiltin = { name, rule };
|
|
38
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
41
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8taW5zdGFuY2VvZi1idWlsdGluLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bGVzL25vLWluc3RhbmNlb2YtYnVpbHRpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRTFDLHVJQUF1STtBQUN2SSxNQUFNLElBQUksR0FBRyxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUMxQyxNQUFNLElBQUksR0FBb0I7SUFDNUIsSUFBSSxFQUFFO1FBQ0osSUFBSSxFQUFFO1lBQ0osV0FBVyxFQUFFLHNEQUFzRDtTQUNwRTtRQUNELFFBQVEsRUFBRTtZQUNSLENBQUMsR0FBRyxJQUFJLFFBQVEsQ0FBQyxFQUFFLHNEQUFzRDtTQUMxRTtLQUNGO0lBQ0QsTUFBTSxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUU7UUFDbEIsSUFBSSxRQUFRLEdBQTRCLFNBQVMsQ0FBQztRQUNsRCxPQUFPO1lBQ0wseUVBQXlFO1lBQ3pFLDZEQUE2RDtZQUM3RCwyREFBMkQ7WUFDM0QsT0FBTyxFQUFFLENBQUMsSUFBSSxFQUFFLEVBQUU7Z0JBQ2hCLE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNoRCxRQUFRLEdBQUcsSUFBSSxHQUFHLENBQUM7b0JBQ2pCLGtDQUFrQztvQkFDbEMsR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztvQkFDckMsZ0NBQWdDO29CQUNoQyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQztpQkFDbkQsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUNELGdCQUFnQixFQUFFLENBQUMsSUFBSSxFQUFFLEVBQUU7Z0JBQ3pCLElBQ0UsSUFBSSxDQUFDLFFBQVEsS0FBSyxZQUFZO29CQUM5QixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxZQUFZLEVBQ2hDLENBQUM7b0JBQ0QsT0FBTztnQkFDVCxDQUFDO2dCQUVELElBQUksUUFBUSxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDO29CQUMzQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLEdBQUcsSUFBSSxRQUFRLEVBQUUsQ0FBQyxDQUFDO2dCQUNuRSxDQUFDO1lBQ0gsQ0FBQztTQUNGLENBQUM7SUFDSixDQUFDO0NBQ0YsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBSdWxlIH0gZnJvbSBcImVzbGludFwiO1xuaW1wb3J0IHsgZ2V0UnVsZU5hbWUgfSBmcm9tIFwiLi4vdXRpbHMuanNcIjtcblxuLy8gVE9ETzogSWYgaHR0cHM6Ly9naXRodWIuY29tL3NpbmRyZXNvcmh1cy9lc2xpbnQtcGx1Z2luLXVuaWNvcm4vaXNzdWVzLzI0NTIgaXMgYWNjZXB0ZWQsIG1pZ3JhdGUgdGhpcyBydWxlIHRvIGBlc2xpbnQtcGx1Z2luLXVuaWNvcm5gXG5jb25zdCBuYW1lID0gZ2V0UnVsZU5hbWUoaW1wb3J0Lm1ldGEudXJsKTtcbmNvbnN0IHJ1bGU6IFJ1bGUuUnVsZU1vZHVsZSA9IHtcbiAgbWV0YToge1xuICAgIGRvY3M6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcIlJpZ2h0IGhhbmQgb2YgYGluc3RhbmNlb2ZgIGNhbid0IGJlIGEgYnVpbHRpbiBjbGFzcy5cIixcbiAgICB9LFxuICAgIG1lc3NhZ2VzOiB7XG4gICAgICBbYCR7bmFtZX0vZXJyb3JgXTogXCJSaWdodCBoYW5kIG9mIGBpbnN0YW5jZW9mYCBjYW4ndCBiZSBhIGJ1aWx0aW4gY2xhc3MuXCIsXG4gICAgfSxcbiAgfSxcbiAgY3JlYXRlOiAoY29udGV4dCkgPT4ge1xuICAgIGxldCBidWlsdGluczogU2V0PHN0cmluZz4gfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIHtcbiAgICAgIC8vIEVTTGludCB2aXNpdCB0aGUgTm9kZSBmcm9tIHJvb3QgdG8gbGVhZi4gVGhlIFByb2dyYW0gTm9kZSBpcyB0aGUgcm9vdC5cbiAgICAgIC8vIFRoZXJlZm9yZSwgUHJvZ3JhbSB3aWxsIGJlIGNhbGxlZCBiZWZvcmUgQmluYXJ5RXhwcmVzc2lvbi5cbiAgICAgIC8vIGh0dHBzOi8vZXNsaW50Lm9yZy9kb2NzL2xhdGVzdC9leHRlbmQvY29kZS1wYXRoLWFuYWx5c2lzXG4gICAgICBQcm9ncmFtOiAobm9kZSkgPT4ge1xuICAgICAgICBjb25zdCBzY29wZSA9IGNvbnRleHQuc291cmNlQ29kZS5nZXRTY29wZShub2RlKTtcbiAgICAgICAgYnVpbHRpbnMgPSBuZXcgU2V0KFtcbiAgICAgICAgICAvLyBWYXJpYWJsZXMgZGVjbGFyZWQgaW4gYGdsb2JhbHNgXG4gICAgICAgICAgLi4uc2NvcGUudmFyaWFibGVzLm1hcCgodikgPT4gdi5uYW1lKSxcbiAgICAgICAgICAvLyBWYXJpYWJsZXMgbm90IGRlY2xhcmVkIGF0IGFsbFxuICAgICAgICAgIC4uLnNjb3BlLnRocm91Z2gubWFwKChyZWYpID0+IHJlZi5pZGVudGlmaWVyLm5hbWUpLFxuICAgICAgICBdKTtcbiAgICAgIH0sXG4gICAgICBCaW5hcnlFeHByZXNzaW9uOiAobm9kZSkgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgbm9kZS5vcGVyYXRvciAhPT0gXCJpbnN0YW5jZW9mXCIgfHxcbiAgICAgICAgICBub2RlLnJpZ2h0LnR5cGUgIT09IFwiSWRlbnRpZmllclwiXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChidWlsdGlucz8uaGFzKG5vZGUucmlnaHQubmFtZSkgPz8gdHJ1ZSkge1xuICAgICAgICAgIGNvbnRleHQucmVwb3J0KHsgbm9kZTogbm9kZS5yaWdodCwgbWVzc2FnZUlkOiBgJHtuYW1lfS9lcnJvcmAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfTtcbiAgfSxcbn07XG5cbmV4cG9ydCBjb25zdCBub0luc3RhbmNlb2ZCdWlsdGluID0geyBuYW1lLCBydWxlIH07XG4iXX0=
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-jsx-in-non-jsx-file.d.ts","sourceRoot":"","sources":["../../src/rules/no-jsx-in-non-jsx-file.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"no-jsx-in-non-jsx-file.d.ts","sourceRoot":"","sources":["../../src/rules/no-jsx-in-non-jsx-file.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAyBnC,eAAO,MAAM,iBAAiB;;;CAAiB,CAAC"}
|
|
@@ -10,10 +10,9 @@ const rule = {
|
|
|
10
10
|
},
|
|
11
11
|
},
|
|
12
12
|
create: (context) => {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
// ignore jsx files
|
|
14
|
+
if (/\.[tj]sx$/.test(context.filename))
|
|
15
15
|
return {};
|
|
16
|
-
}
|
|
17
16
|
return {
|
|
18
17
|
":matches(JSXElement, JSXFragment)": (node) => {
|
|
19
18
|
context.report({ node, messageId: `${name}/error` });
|
|
@@ -22,4 +21,4 @@ const rule = {
|
|
|
22
21
|
},
|
|
23
22
|
};
|
|
24
23
|
export const noJsxInNonJsxFile = { name, rule };
|
|
25
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
24
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8tanN4LWluLW5vbi1qc3gtZmlsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydWxlcy9uby1qc3gtaW4tbm9uLWpzeC1maWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFMUMsTUFBTSxJQUFJLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDMUMsTUFBTSxJQUFJLEdBQW9CO0lBQzVCLElBQUksRUFBRTtRQUNKLElBQUksRUFBRTtZQUNKLFdBQVcsRUFBRSxrREFBa0Q7U0FDaEU7UUFDRCxRQUFRLEVBQUU7WUFDUixDQUFDLEdBQUcsSUFBSSxRQUFRLENBQUMsRUFBRSxrREFBa0Q7U0FDdEU7S0FDRjtJQUNELE1BQU0sRUFBRSxDQUFDLE9BQU8sRUFBRSxFQUFFO1FBQ2xCLG1CQUFtQjtRQUNuQixJQUFJLFdBQVcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQztZQUFFLE9BQU8sRUFBRSxDQUFDO1FBQ2xELE9BQU87WUFDTCxtQ0FBbUMsRUFBRSxDQUFDLElBQVUsRUFBRSxFQUFFO2dCQUNsRCxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxHQUFHLElBQUksUUFBUSxFQUFFLENBQUMsQ0FBQztZQUN2RCxDQUFDO1NBQ0YsQ0FBQztJQUNKLENBQUM7Q0FDRixDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IFJ1bGUgfSBmcm9tIFwiZXNsaW50XCI7XG5pbXBvcnQgdHlwZSB7IE5vZGUgfSBmcm9tIFwiZXN0cmVlXCI7XG5pbXBvcnQgeyBnZXRSdWxlTmFtZSB9IGZyb20gXCIuLi91dGlscy5qc1wiO1xuXG5jb25zdCBuYW1lID0gZ2V0UnVsZU5hbWUoaW1wb3J0Lm1ldGEudXJsKTtcbmNvbnN0IHJ1bGU6IFJ1bGUuUnVsZU1vZHVsZSA9IHtcbiAgbWV0YToge1xuICAgIGRvY3M6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcIk9ubHkgYWxsb3cgSlNYIHN5bnRheCBpbiBgLmpzeGAgYW5kIGAudHN4YCBmaWxlLlwiLFxuICAgIH0sXG4gICAgbWVzc2FnZXM6IHtcbiAgICAgIFtgJHtuYW1lfS9lcnJvcmBdOiBcIk9ubHkgYWxsb3cgSlNYIHN5bnRheCBpbiBgLmpzeGAgYW5kIGAudHN4YCBmaWxlLlwiLFxuICAgIH0sXG4gIH0sXG4gIGNyZWF0ZTogKGNvbnRleHQpID0+IHtcbiAgICAvLyBpZ25vcmUganN4IGZpbGVzXG4gICAgaWYgKC9cXC5bdGpdc3gkLy50ZXN0KGNvbnRleHQuZmlsZW5hbWUpKSByZXR1cm4ge307XG4gICAgcmV0dXJuIHtcbiAgICAgIFwiOm1hdGNoZXMoSlNYRWxlbWVudCwgSlNYRnJhZ21lbnQpXCI6IChub2RlOiBOb2RlKSA9PiB7XG4gICAgICAgIGNvbnRleHQucmVwb3J0KHsgbm9kZSwgbWVzc2FnZUlkOiBgJHtuYW1lfS9lcnJvcmAgfSk7XG4gICAgICB9LFxuICAgIH07XG4gIH0sXG59O1xuXG5leHBvcnQgY29uc3Qgbm9Kc3hJbk5vbkpzeEZpbGUgPSB7IG5hbWUsIHJ1bGUgfTtcbiJdfQ==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-nested-class.d.ts","sourceRoot":"","sources":["../../src/rules/no-nested-class.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AA8BnC,eAAO,MAAM,aAAa;;;CAAiB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { getRuleName } from "../utils.js";
|
|
2
|
+
const name = getRuleName(import.meta.url);
|
|
3
|
+
const rule = {
|
|
4
|
+
meta: {
|
|
5
|
+
docs: {
|
|
6
|
+
description: "Disallow nested class. Classes are expected to place at top level.",
|
|
7
|
+
},
|
|
8
|
+
messages: {
|
|
9
|
+
[`${name}/error`]: "Disallow nested class. Classes are expected to place at top level.",
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
create: (context) => {
|
|
13
|
+
const handle = (node) => context.report({ node, messageId: `${name}/error` });
|
|
14
|
+
return {
|
|
15
|
+
// ClassDeclaration is only allowed when parent is Program, or parent is ExportNamedDeclaration, or parent is ExportDefaultDeclaration
|
|
16
|
+
"ClassDeclaration[parent.type!='Program'][parent.type!='ExportNamedDeclaration'][parent.type!='ExportDefaultDeclaration']": handle,
|
|
17
|
+
// ClassExpression is only allowed when parent is ExportNamedDeclaration, or parent is ExportDefaultDeclaration
|
|
18
|
+
"ClassExpression[parent.type!='ExportNamedDeclaration'][parent.type!='ExportDefaultDeclaration']": handle,
|
|
19
|
+
};
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
export const noNestedClass = { name, rule };
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8tbmVzdGVkLWNsYXNzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bGVzL25vLW5lc3RlZC1jbGFzcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRTFDLE1BQU0sSUFBSSxHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzFDLE1BQU0sSUFBSSxHQUFvQjtJQUM1QixJQUFJLEVBQUU7UUFDSixJQUFJLEVBQUU7WUFDSixXQUFXLEVBQ1Qsb0VBQW9FO1NBQ3ZFO1FBQ0QsUUFBUSxFQUFFO1lBQ1IsQ0FBQyxHQUFHLElBQUksUUFBUSxDQUFDLEVBQ2Ysb0VBQW9FO1NBQ3ZFO0tBQ0Y7SUFDRCxNQUFNLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRTtRQUNsQixNQUFNLE1BQU0sR0FBRyxDQUFDLElBQVUsRUFBRSxFQUFFLENBQzVCLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLEdBQUcsSUFBSSxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZELE9BQU87WUFDTCxzSUFBc0k7WUFDdEksMEhBQTBILEVBQ3hILE1BQU07WUFDUiwrR0FBK0c7WUFDL0csaUdBQWlHLEVBQy9GLE1BQU07U0FDVCxDQUFDO0lBQ0osQ0FBQztDQUNGLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxhQUFhLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IFJ1bGUgfSBmcm9tIFwiZXNsaW50XCI7XG5pbXBvcnQgdHlwZSB7IE5vZGUgfSBmcm9tIFwiZXN0cmVlXCI7XG5pbXBvcnQgeyBnZXRSdWxlTmFtZSB9IGZyb20gXCIuLi91dGlscy5qc1wiO1xuXG5jb25zdCBuYW1lID0gZ2V0UnVsZU5hbWUoaW1wb3J0Lm1ldGEudXJsKTtcbmNvbnN0IHJ1bGU6IFJ1bGUuUnVsZU1vZHVsZSA9IHtcbiAgbWV0YToge1xuICAgIGRvY3M6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICBcIkRpc2FsbG93IG5lc3RlZCBjbGFzcy4gQ2xhc3NlcyBhcmUgZXhwZWN0ZWQgdG8gcGxhY2UgYXQgdG9wIGxldmVsLlwiLFxuICAgIH0sXG4gICAgbWVzc2FnZXM6IHtcbiAgICAgIFtgJHtuYW1lfS9lcnJvcmBdOlxuICAgICAgICBcIkRpc2FsbG93IG5lc3RlZCBjbGFzcy4gQ2xhc3NlcyBhcmUgZXhwZWN0ZWQgdG8gcGxhY2UgYXQgdG9wIGxldmVsLlwiLFxuICAgIH0sXG4gIH0sXG4gIGNyZWF0ZTogKGNvbnRleHQpID0+IHtcbiAgICBjb25zdCBoYW5kbGUgPSAobm9kZTogTm9kZSkgPT5cbiAgICAgIGNvbnRleHQucmVwb3J0KHsgbm9kZSwgbWVzc2FnZUlkOiBgJHtuYW1lfS9lcnJvcmAgfSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIC8vIENsYXNzRGVjbGFyYXRpb24gaXMgb25seSBhbGxvd2VkIHdoZW4gcGFyZW50IGlzIFByb2dyYW0sIG9yIHBhcmVudCBpcyBFeHBvcnROYW1lZERlY2xhcmF0aW9uLCBvciBwYXJlbnQgaXMgRXhwb3J0RGVmYXVsdERlY2xhcmF0aW9uXG4gICAgICBcIkNsYXNzRGVjbGFyYXRpb25bcGFyZW50LnR5cGUhPSdQcm9ncmFtJ11bcGFyZW50LnR5cGUhPSdFeHBvcnROYW1lZERlY2xhcmF0aW9uJ11bcGFyZW50LnR5cGUhPSdFeHBvcnREZWZhdWx0RGVjbGFyYXRpb24nXVwiOlxuICAgICAgICBoYW5kbGUsXG4gICAgICAvLyBDbGFzc0V4cHJlc3Npb24gaXMgb25seSBhbGxvd2VkIHdoZW4gcGFyZW50IGlzIEV4cG9ydE5hbWVkRGVjbGFyYXRpb24sIG9yIHBhcmVudCBpcyBFeHBvcnREZWZhdWx0RGVjbGFyYXRpb25cbiAgICAgIFwiQ2xhc3NFeHByZXNzaW9uW3BhcmVudC50eXBlIT0nRXhwb3J0TmFtZWREZWNsYXJhdGlvbiddW3BhcmVudC50eXBlIT0nRXhwb3J0RGVmYXVsdERlY2xhcmF0aW9uJ11cIjpcbiAgICAgICAgaGFuZGxlLFxuICAgIH07XG4gIH0sXG59O1xuXG5leHBvcnQgY29uc3Qgbm9OZXN0ZWRDbGFzcyA9IHsgbmFtZSwgcnVsZSB9O1xuIl19
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-nested-function.d.ts","sourceRoot":"","sources":["../../src/rules/no-nested-function.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AA+BnC,eAAO,MAAM,gBAAgB;;;CAAiB,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { getRuleName } from "../utils.js";
|
|
2
|
+
const name = getRuleName(import.meta.url);
|
|
3
|
+
const rule = {
|
|
4
|
+
meta: {
|
|
5
|
+
docs: {
|
|
6
|
+
description: "Non top-level functions are expected to be arrow functions instead of function declarations.",
|
|
7
|
+
},
|
|
8
|
+
messages: {
|
|
9
|
+
[`${name}/error`]: "Non top-level functions are expected to be arrow functions instead of function declarations.",
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
create: (context) => {
|
|
13
|
+
const selectors = [
|
|
14
|
+
// FunctionDeclaration is only allowed when parent is Program, or parent is ExportNamedDeclaration, or parent is ExportDefaultDeclaration
|
|
15
|
+
"FunctionDeclaration[parent.type!='Program'][parent.type!='ExportNamedDeclaration'][parent.type!='ExportDefaultDeclaration']", // function foo(){}
|
|
16
|
+
// FunctionExpression is only allowed when parent is MethodDefinition
|
|
17
|
+
"FunctionExpression[parent.type!='MethodDefinition']", // function (){}
|
|
18
|
+
];
|
|
19
|
+
return {
|
|
20
|
+
[`:matches(${selectors.join(", ")})`]: (node) => {
|
|
21
|
+
context.report({ node, messageId: `${name}/error` });
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
export const noNestedFunction = { name, rule };
|
|
27
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8tbmVzdGVkLWZ1bmN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bGVzL25vLW5lc3RlZC1mdW5jdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRTFDLE1BQU0sSUFBSSxHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzFDLE1BQU0sSUFBSSxHQUFvQjtJQUM1QixJQUFJLEVBQUU7UUFDSixJQUFJLEVBQUU7WUFDSixXQUFXLEVBQ1QsOEZBQThGO1NBQ2pHO1FBQ0QsUUFBUSxFQUFFO1lBQ1IsQ0FBQyxHQUFHLElBQUksUUFBUSxDQUFDLEVBQ2YsOEZBQThGO1NBQ2pHO0tBQ0Y7SUFDRCxNQUFNLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRTtRQUNsQixNQUFNLFNBQVMsR0FBRztZQUNoQix5SUFBeUk7WUFDekksNkhBQTZILEVBQUUsbUJBQW1CO1lBQ2xKLHFFQUFxRTtZQUNyRSxxREFBcUQsRUFBRSxnQkFBZ0I7U0FDeEUsQ0FBQztRQUNGLE9BQU87WUFDTCxDQUFDLFlBQVksU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFVLEVBQUUsRUFBRTtnQkFDcEQsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsR0FBRyxJQUFJLFFBQVEsRUFBRSxDQUFDLENBQUM7WUFDdkQsQ0FBQztTQUNGLENBQUM7SUFDSixDQUFDO0NBQ0YsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBSdWxlIH0gZnJvbSBcImVzbGludFwiO1xuaW1wb3J0IHR5cGUgeyBOb2RlIH0gZnJvbSBcImVzdHJlZVwiO1xuaW1wb3J0IHsgZ2V0UnVsZU5hbWUgfSBmcm9tIFwiLi4vdXRpbHMuanNcIjtcblxuY29uc3QgbmFtZSA9IGdldFJ1bGVOYW1lKGltcG9ydC5tZXRhLnVybCk7XG5jb25zdCBydWxlOiBSdWxlLlJ1bGVNb2R1bGUgPSB7XG4gIG1ldGE6IHtcbiAgICBkb2NzOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgXCJOb24gdG9wLWxldmVsIGZ1bmN0aW9ucyBhcmUgZXhwZWN0ZWQgdG8gYmUgYXJyb3cgZnVuY3Rpb25zIGluc3RlYWQgb2YgZnVuY3Rpb24gZGVjbGFyYXRpb25zLlwiLFxuICAgIH0sXG4gICAgbWVzc2FnZXM6IHtcbiAgICAgIFtgJHtuYW1lfS9lcnJvcmBdOlxuICAgICAgICBcIk5vbiB0b3AtbGV2ZWwgZnVuY3Rpb25zIGFyZSBleHBlY3RlZCB0byBiZSBhcnJvdyBmdW5jdGlvbnMgaW5zdGVhZCBvZiBmdW5jdGlvbiBkZWNsYXJhdGlvbnMuXCIsXG4gICAgfSxcbiAgfSxcbiAgY3JlYXRlOiAoY29udGV4dCkgPT4ge1xuICAgIGNvbnN0IHNlbGVjdG9ycyA9IFtcbiAgICAgIC8vIEZ1bmN0aW9uRGVjbGFyYXRpb24gaXMgb25seSBhbGxvd2VkIHdoZW4gcGFyZW50IGlzIFByb2dyYW0sIG9yIHBhcmVudCBpcyBFeHBvcnROYW1lZERlY2xhcmF0aW9uLCBvciBwYXJlbnQgaXMgRXhwb3J0RGVmYXVsdERlY2xhcmF0aW9uXG4gICAgICBcIkZ1bmN0aW9uRGVjbGFyYXRpb25bcGFyZW50LnR5cGUhPSdQcm9ncmFtJ11bcGFyZW50LnR5cGUhPSdFeHBvcnROYW1lZERlY2xhcmF0aW9uJ11bcGFyZW50LnR5cGUhPSdFeHBvcnREZWZhdWx0RGVjbGFyYXRpb24nXVwiLCAvLyBmdW5jdGlvbiBmb28oKXt9XG4gICAgICAvLyBGdW5jdGlvbkV4cHJlc3Npb24gaXMgb25seSBhbGxvd2VkIHdoZW4gcGFyZW50IGlzIE1ldGhvZERlZmluaXRpb25cbiAgICAgIFwiRnVuY3Rpb25FeHByZXNzaW9uW3BhcmVudC50eXBlIT0nTWV0aG9kRGVmaW5pdGlvbiddXCIsIC8vIGZ1bmN0aW9uICgpe31cbiAgICBdO1xuICAgIHJldHVybiB7XG4gICAgICBbYDptYXRjaGVzKCR7c2VsZWN0b3JzLmpvaW4oXCIsIFwiKX0pYF06IChub2RlOiBOb2RlKSA9PiB7XG4gICAgICAgIGNvbnRleHQucmVwb3J0KHsgbm9kZSwgbWVzc2FnZUlkOiBgJHtuYW1lfS9lcnJvcmAgfSk7XG4gICAgICB9LFxuICAgIH07XG4gIH0sXG59O1xuXG5leHBvcnQgY29uc3Qgbm9OZXN0ZWRGdW5jdGlvbiA9IHsgbmFtZSwgcnVsZSB9O1xuIl19
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-top-level-arrow-function.d.ts","sourceRoot":"","sources":["../../src/rules/no-top-level-arrow-function.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAiCnC,eAAO,MAAM,uBAAuB;;;CAAiB,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { getRuleName } from "../utils.js";
|
|
2
|
+
const name = getRuleName(import.meta.url);
|
|
3
|
+
const rule = {
|
|
4
|
+
meta: {
|
|
5
|
+
docs: {
|
|
6
|
+
description: "Top-level functions are expected to be function declarations instead of arrow functions.",
|
|
7
|
+
},
|
|
8
|
+
messages: {
|
|
9
|
+
[`${name}/error`]: "Top-level functions are expected to be function declarations instead of arrow functions.",
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
create: (context) => {
|
|
13
|
+
const handle = (node) => {
|
|
14
|
+
if (node.loc?.start.line === node.loc?.end.line)
|
|
15
|
+
return;
|
|
16
|
+
context.report({ node, messageId: `${name}/error` });
|
|
17
|
+
};
|
|
18
|
+
return {
|
|
19
|
+
"VariableDeclaration[parent.type='Program'] > VariableDeclarator > ArrowFunctionExpression": handle,
|
|
20
|
+
"ExpressionStatement[parent.type='Program'] > AssignmentExpression > ArrowFunctionExpression": handle,
|
|
21
|
+
"ExportNamedDeclaration > VariableDeclaration > VariableDeclarator > ArrowFunctionExpression": handle,
|
|
22
|
+
"ExportDefaultDeclaration > ArrowFunctionExpression": handle,
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
export const noTopLevelArrowFunction = { name, rule };
|
|
27
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8tdG9wLWxldmVsLWFycm93LWZ1bmN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bGVzL25vLXRvcC1sZXZlbC1hcnJvdy1mdW5jdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRTFDLE1BQU0sSUFBSSxHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzFDLE1BQU0sSUFBSSxHQUFvQjtJQUM1QixJQUFJLEVBQUU7UUFDSixJQUFJLEVBQUU7WUFDSixXQUFXLEVBQ1QsMEZBQTBGO1NBQzdGO1FBQ0QsUUFBUSxFQUFFO1lBQ1IsQ0FBQyxHQUFHLElBQUksUUFBUSxDQUFDLEVBQ2YsMEZBQTBGO1NBQzdGO0tBQ0Y7SUFDRCxNQUFNLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRTtRQUNsQixNQUFNLE1BQU0sR0FBRyxDQUFDLElBQVUsRUFBRSxFQUFFO1lBQzVCLElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUk7Z0JBQUUsT0FBTztZQUN4RCxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxHQUFHLElBQUksUUFBUSxFQUFFLENBQUMsQ0FBQztRQUN2RCxDQUFDLENBQUM7UUFDRixPQUFPO1lBQ0wsMkZBQTJGLEVBQ3pGLE1BQU07WUFDUiw2RkFBNkYsRUFDM0YsTUFBTTtZQUNSLDZGQUE2RixFQUMzRixNQUFNO1lBQ1Isb0RBQW9ELEVBQUUsTUFBTTtTQUM3RCxDQUFDO0lBQ0osQ0FBQztDQUNGLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSx1QkFBdUIsR0FBRyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgUnVsZSB9IGZyb20gXCJlc2xpbnRcIjtcbmltcG9ydCB0eXBlIHsgTm9kZSB9IGZyb20gXCJlc3RyZWVcIjtcbmltcG9ydCB7IGdldFJ1bGVOYW1lIH0gZnJvbSBcIi4uL3V0aWxzLmpzXCI7XG5cbmNvbnN0IG5hbWUgPSBnZXRSdWxlTmFtZShpbXBvcnQubWV0YS51cmwpO1xuY29uc3QgcnVsZTogUnVsZS5SdWxlTW9kdWxlID0ge1xuICBtZXRhOiB7XG4gICAgZG9jczoge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgIFwiVG9wLWxldmVsIGZ1bmN0aW9ucyBhcmUgZXhwZWN0ZWQgdG8gYmUgZnVuY3Rpb24gZGVjbGFyYXRpb25zIGluc3RlYWQgb2YgYXJyb3cgZnVuY3Rpb25zLlwiLFxuICAgIH0sXG4gICAgbWVzc2FnZXM6IHtcbiAgICAgIFtgJHtuYW1lfS9lcnJvcmBdOlxuICAgICAgICBcIlRvcC1sZXZlbCBmdW5jdGlvbnMgYXJlIGV4cGVjdGVkIHRvIGJlIGZ1bmN0aW9uIGRlY2xhcmF0aW9ucyBpbnN0ZWFkIG9mIGFycm93IGZ1bmN0aW9ucy5cIixcbiAgICB9LFxuICB9LFxuICBjcmVhdGU6IChjb250ZXh0KSA9PiB7XG4gICAgY29uc3QgaGFuZGxlID0gKG5vZGU6IE5vZGUpID0+IHtcbiAgICAgIGlmIChub2RlLmxvYz8uc3RhcnQubGluZSA9PT0gbm9kZS5sb2M/LmVuZC5saW5lKSByZXR1cm47XG4gICAgICBjb250ZXh0LnJlcG9ydCh7IG5vZGUsIG1lc3NhZ2VJZDogYCR7bmFtZX0vZXJyb3JgIH0pO1xuICAgIH07XG4gICAgcmV0dXJuIHtcbiAgICAgIFwiVmFyaWFibGVEZWNsYXJhdGlvbltwYXJlbnQudHlwZT0nUHJvZ3JhbSddID4gVmFyaWFibGVEZWNsYXJhdG9yID4gQXJyb3dGdW5jdGlvbkV4cHJlc3Npb25cIjpcbiAgICAgICAgaGFuZGxlLFxuICAgICAgXCJFeHByZXNzaW9uU3RhdGVtZW50W3BhcmVudC50eXBlPSdQcm9ncmFtJ10gPiBBc3NpZ25tZW50RXhwcmVzc2lvbiA+IEFycm93RnVuY3Rpb25FeHByZXNzaW9uXCI6XG4gICAgICAgIGhhbmRsZSxcbiAgICAgIFwiRXhwb3J0TmFtZWREZWNsYXJhdGlvbiA+IFZhcmlhYmxlRGVjbGFyYXRpb24gPiBWYXJpYWJsZURlY2xhcmF0b3IgPiBBcnJvd0Z1bmN0aW9uRXhwcmVzc2lvblwiOlxuICAgICAgICBoYW5kbGUsXG4gICAgICBcIkV4cG9ydERlZmF1bHREZWNsYXJhdGlvbiA+IEFycm93RnVuY3Rpb25FeHByZXNzaW9uXCI6IGhhbmRsZSxcbiAgICB9O1xuICB9LFxufTtcblxuZXhwb3J0IGNvbnN0IG5vVG9wTGV2ZWxBcnJvd0Z1bmN0aW9uID0geyBuYW1lLCBydWxlIH07XG4iXX0=
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<!-- prettier-ignore-start -->
|
|
2
|
+
# call-arguments-length
|
|
3
|
+
|
|
4
|
+
Disallow calling a function with incorrect arguments length.
|
|
5
|
+
|
|
6
|
+
## Rule Details
|
|
7
|
+
|
|
8
|
+
### Fail
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
[].push()
|
|
12
|
+
foo.push()
|
|
13
|
+
foo.reduce()
|
|
14
|
+
[].reduce(()=>123)
|
|
15
|
+
foo.reduce(()=>123)
|
|
16
|
+
foo.reduce(bar)
|
|
17
|
+
[].reduceRight(()=>123)
|
|
18
|
+
foo.reduceRight(()=>123)
|
|
19
|
+
foo.reduceRight(bar)
|
|
20
|
+
[].reduce(...foo)
|
|
21
|
+
[].reduce(...foo, ...bar)
|
|
22
|
+
Math.max()
|
|
23
|
+
Math.max(1)
|
|
24
|
+
Math.min(foo)
|
|
25
|
+
new Set(...foo)
|
|
26
|
+
new Set(foo,bar)
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Pass
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
push()
|
|
33
|
+
[].push('')
|
|
34
|
+
foo.push('')
|
|
35
|
+
foo.push(bar)
|
|
36
|
+
[].push('', '', '')
|
|
37
|
+
[].push(...foo)
|
|
38
|
+
foo.push(...([]))
|
|
39
|
+
[].reduce(()=>123, 0)
|
|
40
|
+
foo.reduce(()=>123, 0)
|
|
41
|
+
foo.reduce(bar, baz)
|
|
42
|
+
[].reduceRight(()=>123, 0)
|
|
43
|
+
foo.reduceRight(()=>123, 0)
|
|
44
|
+
foo.reduceRight(bar, baz)
|
|
45
|
+
reduce(()=>123)
|
|
46
|
+
foo.reduceLeft(()=>123)
|
|
47
|
+
Math.max(...foo)
|
|
48
|
+
new foo.Set(...bar)
|
|
49
|
+
new Set(bar)
|
|
50
|
+
new Set()
|
|
51
|
+
```
|
|
52
|
+
<!-- prettier-ignore-end -->
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<!-- prettier-ignore-start -->
|
|
2
|
+
# no-instanceof-builtin
|
|
3
|
+
|
|
4
|
+
Right hand of `instanceof` can't be a builtin class.
|
|
5
|
+
|
|
6
|
+
## Rule Details
|
|
7
|
+
|
|
8
|
+
### Fail
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
const i = {} instanceof Number
|
|
12
|
+
const i = {} instanceof String
|
|
13
|
+
const i = {} instanceof Boolean
|
|
14
|
+
const i = {} instanceof Symbol
|
|
15
|
+
const i = {} instanceof BigInt
|
|
16
|
+
const i = {} instanceof Object
|
|
17
|
+
const i = {} instanceof Array
|
|
18
|
+
const i = {} instanceof Function
|
|
19
|
+
const i = {} instanceof ArrayBuffer
|
|
20
|
+
const i = {} instanceof BigInt64Array
|
|
21
|
+
const i = {} instanceof BigUint64Array
|
|
22
|
+
const i = {} instanceof DataView
|
|
23
|
+
const i = {} instanceof Date
|
|
24
|
+
const i = {} instanceof Float32Array
|
|
25
|
+
const i = {} instanceof Float64Array
|
|
26
|
+
const i = {} instanceof Int16Array
|
|
27
|
+
const i = {} instanceof Int32Array
|
|
28
|
+
const i = {} instanceof Int8Array
|
|
29
|
+
const i = {} instanceof Map
|
|
30
|
+
const i = {} instanceof Error
|
|
31
|
+
const i = {} instanceof Promise
|
|
32
|
+
const i = {} instanceof Proxy
|
|
33
|
+
const i = {} instanceof RegExp
|
|
34
|
+
const i = {} instanceof Set
|
|
35
|
+
const i = {} instanceof SharedArrayBuffer
|
|
36
|
+
const i = {} instanceof Uint16Array
|
|
37
|
+
const i = {} instanceof Uint32Array
|
|
38
|
+
const i = {} instanceof Uint8Array
|
|
39
|
+
const i = {} instanceof Uint8ClampedArray
|
|
40
|
+
const i = {} instanceof WeakMap
|
|
41
|
+
const i = {} instanceof WeakSet
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Pass
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
const i = Math.random() > 0.5 ? true: false
|
|
48
|
+
const i = {} instanceof await import('http')
|
|
49
|
+
```
|
|
50
|
+
<!-- prettier-ignore-end -->
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<!-- prettier-ignore-start -->
|
|
2
|
+
# no-jsx-in-non-jsx-file
|
|
3
|
+
|
|
4
|
+
Only allow JSX syntax in `.jsx` and `.tsx` file.
|
|
5
|
+
|
|
6
|
+
## Rule Details
|
|
7
|
+
|
|
8
|
+
### Fail
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
const Foo = () => <div></div> // filename: foo.js
|
|
12
|
+
const Foo = () => <></> // filename: foo.js
|
|
13
|
+
function Foo(){const x = <div>foo</div>} // filename: foo.js
|
|
14
|
+
function Foo(){const x = <>foo</>} // filename: foo.js
|
|
15
|
+
const Foo = () => <div></div> // filename: foo.cjs
|
|
16
|
+
const Foo = () => <></> // filename: foo.cjs
|
|
17
|
+
function Foo(){const x = <div>foo</div>} // filename: foo.cjs
|
|
18
|
+
function Foo(){const x = <>foo</>} // filename: foo.cjs
|
|
19
|
+
const Foo = () => <div></div> // filename: foo.mjs
|
|
20
|
+
const Foo = () => <></> // filename: foo.mjs
|
|
21
|
+
function Foo(){const x = <div>foo</div>} // filename: foo.mjs
|
|
22
|
+
function Foo(){const x = <>foo</>} // filename: foo.mjs
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Pass
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
const Foo = () => <div></div> // filename: foo.jsx
|
|
29
|
+
const Foo = () => <></> // filename: foo.jsx
|
|
30
|
+
function Foo(){const x = <div>foo</div>} // filename: foo.jsx
|
|
31
|
+
function Foo(){const x = <>foo</>} // filename: foo.jsx
|
|
32
|
+
const Foo = () => <div></div> // filename: foo.tsx
|
|
33
|
+
const Foo = () => <></> // filename: foo.tsx
|
|
34
|
+
function Foo(){const x = <div>foo</div>} // filename: foo.tsx
|
|
35
|
+
function Foo(){const x = <>foo</>} // filename: foo.tsx
|
|
36
|
+
```
|
|
37
|
+
<!-- prettier-ignore-end -->
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<!-- prettier-ignore-start -->
|
|
2
|
+
# no-nested-class
|
|
3
|
+
|
|
4
|
+
Disallow nested class. Classes are expected to place at top level.
|
|
5
|
+
|
|
6
|
+
## Rule Details
|
|
7
|
+
|
|
8
|
+
### Fail
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
if(true) class Foo{}
|
|
12
|
+
if(true) const foo = class {}
|
|
13
|
+
function foo(){class Foo{}}
|
|
14
|
+
function foo(){const foo = class {}}
|
|
15
|
+
function foo(){return class Foo{}}
|
|
16
|
+
function foo(){return class{}}
|
|
17
|
+
const Foo = class{}
|
|
18
|
+
let Foo = class Bar{}
|
|
19
|
+
let Foo; Foo = class{}
|
|
20
|
+
(class {})
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Pass
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
class Foo{}
|
|
27
|
+
export class Foo{}
|
|
28
|
+
export default class Foo{}
|
|
29
|
+
export default class {}
|
|
30
|
+
```
|
|
31
|
+
<!-- prettier-ignore-end -->
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<!-- prettier-ignore-start -->
|
|
2
|
+
# no-nested-function
|
|
3
|
+
|
|
4
|
+
Non top-level functions are expected to be arrow functions instead of function declarations.
|
|
5
|
+
|
|
6
|
+
## Rule Details
|
|
7
|
+
|
|
8
|
+
### Fail
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
const foo = function(){}
|
|
12
|
+
const foo = function foo(){}
|
|
13
|
+
let foo; foo = function(){}
|
|
14
|
+
let foo; foo = function foo(){}
|
|
15
|
+
(function(){})
|
|
16
|
+
const foo = () => {function bar(){}}
|
|
17
|
+
function foo() {function bar(){}}
|
|
18
|
+
function foo() {let bar = function(){}}
|
|
19
|
+
function foo() {let bar = function bar(){}}
|
|
20
|
+
if(true) function foo(){}
|
|
21
|
+
class Foo{bar = function(){}}
|
|
22
|
+
class Foo{bar = function bar(){}}
|
|
23
|
+
const foo = {bar: function() {}}
|
|
24
|
+
const foo = {bar: function bar() {}}
|
|
25
|
+
const foo = {bar() {}}
|
|
26
|
+
setTimeout(function(){},100)
|
|
27
|
+
setTimeout(function callback(){},100)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Pass
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
function foo(){}
|
|
34
|
+
const foo = () => {}
|
|
35
|
+
export function foo() {}
|
|
36
|
+
export default function foo() {}
|
|
37
|
+
export default function() {}
|
|
38
|
+
class Foo{bar(){}}
|
|
39
|
+
```
|
|
40
|
+
<!-- prettier-ignore-end -->
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<!-- prettier-ignore-start -->
|
|
2
|
+
# no-restricted-loops
|
|
3
|
+
|
|
4
|
+
Only allow `while` and `for-of` loops. `for`, `for-in`, `do-while` and `for-await-of` loops are disallowed.
|
|
5
|
+
|
|
6
|
+
## Rule Details
|
|
7
|
+
|
|
8
|
+
### Fail
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
for(let i = 0; i < foo.length; i++) {}
|
|
12
|
+
for(const bar in foo) {}
|
|
13
|
+
do{}while(condition)
|
|
14
|
+
for await (const bar of foo()) {}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Pass
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
for(const bar of foo) {}
|
|
21
|
+
while(condition){}
|
|
22
|
+
```
|
|
23
|
+
<!-- prettier-ignore-end -->
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<!-- prettier-ignore-start -->
|
|
2
|
+
# no-top-level-arrow-function
|
|
3
|
+
|
|
4
|
+
Top-level functions are expected to be function declarations instead of arrow functions.
|
|
5
|
+
|
|
6
|
+
## Rule Details
|
|
7
|
+
|
|
8
|
+
### Fail
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
let foo = () => {
|
|
12
|
+
}
|
|
13
|
+
const foo = () => {
|
|
14
|
+
}
|
|
15
|
+
let foo; foo = () => {
|
|
16
|
+
}
|
|
17
|
+
export const foo = () => {
|
|
18
|
+
}
|
|
19
|
+
export let foo = () => {
|
|
20
|
+
}
|
|
21
|
+
export default () => {
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Pass
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
function foo(){}
|
|
29
|
+
const foo = function(){}
|
|
30
|
+
const foo = function foo(){}
|
|
31
|
+
if(true) const foo = () => {
|
|
32
|
+
}
|
|
33
|
+
let foo = () => ''
|
|
34
|
+
let foo = () => {}
|
|
35
|
+
const foo = () => {}
|
|
36
|
+
let foo; foo = () => {}
|
|
37
|
+
export const foo = () => {}
|
|
38
|
+
export let foo = () => {}
|
|
39
|
+
export default () => {}
|
|
40
|
+
```
|
|
41
|
+
<!-- prettier-ignore-end -->
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<!-- prettier-ignore-start -->
|
|
2
|
+
# no-unnecessary-template-string
|
|
3
|
+
|
|
4
|
+
Disallow using template string when it's unnecessary. Use normal literal string expression instead.
|
|
5
|
+
|
|
6
|
+
## Rule Details
|
|
7
|
+
|
|
8
|
+
### Fail
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
outdent`foo`
|
|
12
|
+
``
|
|
13
|
+
`abc`
|
|
14
|
+
`abc\n`
|
|
15
|
+
`\nabc`
|
|
16
|
+
`a\nbc`
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Pass
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
'abc'
|
|
23
|
+
"def"
|
|
24
|
+
`ab${cd}ef`
|
|
25
|
+
`
|
|
26
|
+
`
|
|
27
|
+
`abc
|
|
28
|
+
`
|
|
29
|
+
`
|
|
30
|
+
abc`
|
|
31
|
+
`a
|
|
32
|
+
bc`
|
|
33
|
+
```
|
|
34
|
+
<!-- prettier-ignore-end -->
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fenge/eslint-plugin",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "ESLint plugin for JavaScript.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"opinionated",
|
|
@@ -23,11 +23,9 @@
|
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@types/eslint": "8.56.11",
|
|
25
25
|
"@types/estree": "1.0.6",
|
|
26
|
-
"@types/
|
|
27
|
-
"
|
|
28
|
-
"@
|
|
29
|
-
"eslint": "8.57.1",
|
|
30
|
-
"tsx": "4.19.2"
|
|
26
|
+
"@types/node": "22.10.5",
|
|
27
|
+
"tsx": "4.19.2",
|
|
28
|
+
"@fenge/dev-utils": "0.0.0"
|
|
31
29
|
},
|
|
32
30
|
"scripts": {
|
|
33
31
|
"build": "tsc",
|
package/src/index.ts
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import { callArgumentsLength } from "./rules/call-arguments-length.js";
|
|
2
2
|
import { noInstanceofBuiltin } from "./rules/no-instanceof-builtin.js";
|
|
3
3
|
import { noJsxInNonJsxFile } from "./rules/no-jsx-in-non-jsx-file.js";
|
|
4
|
+
import { noNestedClass } from "./rules/no-nested-class.js";
|
|
5
|
+
import { noNestedFunction } from "./rules/no-nested-function.js";
|
|
4
6
|
import { noRestrictedLoops } from "./rules/no-restricted-loops.js";
|
|
7
|
+
import { noTopLevelArrowFunction } from "./rules/no-top-level-arrow-function.js";
|
|
5
8
|
import { noUnnecessaryTemplateString } from "./rules/no-unnecessary-template-string.js";
|
|
6
9
|
|
|
7
10
|
export const rules = {
|
|
8
11
|
[callArgumentsLength.name]: callArgumentsLength.rule,
|
|
9
12
|
[noInstanceofBuiltin.name]: noInstanceofBuiltin.rule,
|
|
10
13
|
[noJsxInNonJsxFile.name]: noJsxInNonJsxFile.rule,
|
|
14
|
+
[noNestedClass.name]: noNestedClass.rule,
|
|
15
|
+
[noNestedFunction.name]: noNestedFunction.rule,
|
|
11
16
|
[noRestrictedLoops.name]: noRestrictedLoops.rule,
|
|
17
|
+
[noTopLevelArrowFunction.name]: noTopLevelArrowFunction.rule,
|
|
12
18
|
[noUnnecessaryTemplateString.name]: noUnnecessaryTemplateString.rule,
|
|
13
19
|
};
|
|
@@ -15,6 +15,9 @@ const rule: Rule.RuleModule = {
|
|
|
15
15
|
create: (context) => {
|
|
16
16
|
let builtins: Set<string> | undefined = undefined;
|
|
17
17
|
return {
|
|
18
|
+
// ESLint visit the Node from root to leaf. The Program Node is the root.
|
|
19
|
+
// Therefore, Program will be called before BinaryExpression.
|
|
20
|
+
// https://eslint.org/docs/latest/extend/code-path-analysis
|
|
18
21
|
Program: (node) => {
|
|
19
22
|
const scope = context.sourceCode.getScope(node);
|
|
20
23
|
builtins = new Set([
|
|
@@ -13,12 +13,8 @@ const rule: Rule.RuleModule = {
|
|
|
13
13
|
},
|
|
14
14
|
},
|
|
15
15
|
create: (context) => {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
context.filename.endsWith(".tsx")
|
|
19
|
-
) {
|
|
20
|
-
return {};
|
|
21
|
-
}
|
|
16
|
+
// ignore jsx files
|
|
17
|
+
if (/\.[tj]sx$/.test(context.filename)) return {};
|
|
22
18
|
return {
|
|
23
19
|
":matches(JSXElement, JSXFragment)": (node: Node) => {
|
|
24
20
|
context.report({ node, messageId: `${name}/error` });
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { test } from "@fenge/dev-utils";
|
|
2
|
+
import { noNestedClass } from "./no-nested-class.js";
|
|
3
|
+
|
|
4
|
+
const valid = [
|
|
5
|
+
"class Foo{}",
|
|
6
|
+
"export class Foo{}",
|
|
7
|
+
"export default class Foo{}",
|
|
8
|
+
"export default class {}",
|
|
9
|
+
];
|
|
10
|
+
|
|
11
|
+
const invalid = [
|
|
12
|
+
// nested
|
|
13
|
+
"if(true) class Foo{}",
|
|
14
|
+
"if(true) const foo = class {}",
|
|
15
|
+
"function foo(){class Foo{}}",
|
|
16
|
+
"function foo(){const foo = class {}}",
|
|
17
|
+
"function foo(){return class Foo{}}",
|
|
18
|
+
"function foo(){return class{}}",
|
|
19
|
+
|
|
20
|
+
// normal
|
|
21
|
+
"const Foo = class{}",
|
|
22
|
+
"let Foo = class Bar{}",
|
|
23
|
+
"let Foo; Foo = class{}",
|
|
24
|
+
"(class {})",
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
test({ valid, invalid, ...noNestedClass });
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Rule } from "eslint";
|
|
2
|
+
import type { Node } from "estree";
|
|
3
|
+
import { getRuleName } from "../utils.js";
|
|
4
|
+
|
|
5
|
+
const name = getRuleName(import.meta.url);
|
|
6
|
+
const rule: Rule.RuleModule = {
|
|
7
|
+
meta: {
|
|
8
|
+
docs: {
|
|
9
|
+
description:
|
|
10
|
+
"Disallow nested class. Classes are expected to place at top level.",
|
|
11
|
+
},
|
|
12
|
+
messages: {
|
|
13
|
+
[`${name}/error`]:
|
|
14
|
+
"Disallow nested class. Classes are expected to place at top level.",
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
create: (context) => {
|
|
18
|
+
const handle = (node: Node) =>
|
|
19
|
+
context.report({ node, messageId: `${name}/error` });
|
|
20
|
+
return {
|
|
21
|
+
// ClassDeclaration is only allowed when parent is Program, or parent is ExportNamedDeclaration, or parent is ExportDefaultDeclaration
|
|
22
|
+
"ClassDeclaration[parent.type!='Program'][parent.type!='ExportNamedDeclaration'][parent.type!='ExportDefaultDeclaration']":
|
|
23
|
+
handle,
|
|
24
|
+
// ClassExpression is only allowed when parent is ExportNamedDeclaration, or parent is ExportDefaultDeclaration
|
|
25
|
+
"ClassExpression[parent.type!='ExportNamedDeclaration'][parent.type!='ExportDefaultDeclaration']":
|
|
26
|
+
handle,
|
|
27
|
+
};
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const noNestedClass = { name, rule };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { test } from "@fenge/dev-utils";
|
|
2
|
+
import { noNestedFunction } from "./no-nested-function.js";
|
|
3
|
+
|
|
4
|
+
const valid = [
|
|
5
|
+
// normal
|
|
6
|
+
"function foo(){}",
|
|
7
|
+
"const foo = () => {}",
|
|
8
|
+
|
|
9
|
+
// export
|
|
10
|
+
"export function foo() {}",
|
|
11
|
+
"export default function foo() {}",
|
|
12
|
+
"export default function() {}",
|
|
13
|
+
|
|
14
|
+
// class
|
|
15
|
+
"class Foo{bar(){}}",
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
const invalid = [
|
|
19
|
+
// normal
|
|
20
|
+
"const foo = function(){}",
|
|
21
|
+
"const foo = function foo(){}",
|
|
22
|
+
"let foo; foo = function(){}",
|
|
23
|
+
"let foo; foo = function foo(){}",
|
|
24
|
+
"(function(){})",
|
|
25
|
+
|
|
26
|
+
// nested
|
|
27
|
+
"const foo = () => {function bar(){}}",
|
|
28
|
+
"function foo() {function bar(){}}",
|
|
29
|
+
"function foo() {let bar = function(){}}",
|
|
30
|
+
"function foo() {let bar = function bar(){}}",
|
|
31
|
+
"if(true) function foo(){}",
|
|
32
|
+
|
|
33
|
+
// class
|
|
34
|
+
"class Foo{bar = function(){}}",
|
|
35
|
+
"class Foo{bar = function bar(){}}",
|
|
36
|
+
|
|
37
|
+
// object
|
|
38
|
+
"const foo = {bar: function() {}}",
|
|
39
|
+
"const foo = {bar: function bar() {}}",
|
|
40
|
+
"const foo = {bar() {}}", // disallow this case
|
|
41
|
+
|
|
42
|
+
// callback
|
|
43
|
+
"setTimeout(function(){},100)",
|
|
44
|
+
"setTimeout(function callback(){},100)",
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
test({ valid, invalid, ...noNestedFunction });
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Rule } from "eslint";
|
|
2
|
+
import type { Node } from "estree";
|
|
3
|
+
import { getRuleName } from "../utils.js";
|
|
4
|
+
|
|
5
|
+
const name = getRuleName(import.meta.url);
|
|
6
|
+
const rule: Rule.RuleModule = {
|
|
7
|
+
meta: {
|
|
8
|
+
docs: {
|
|
9
|
+
description:
|
|
10
|
+
"Non top-level functions are expected to be arrow functions instead of function declarations.",
|
|
11
|
+
},
|
|
12
|
+
messages: {
|
|
13
|
+
[`${name}/error`]:
|
|
14
|
+
"Non top-level functions are expected to be arrow functions instead of function declarations.",
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
create: (context) => {
|
|
18
|
+
const selectors = [
|
|
19
|
+
// FunctionDeclaration is only allowed when parent is Program, or parent is ExportNamedDeclaration, or parent is ExportDefaultDeclaration
|
|
20
|
+
"FunctionDeclaration[parent.type!='Program'][parent.type!='ExportNamedDeclaration'][parent.type!='ExportDefaultDeclaration']", // function foo(){}
|
|
21
|
+
// FunctionExpression is only allowed when parent is MethodDefinition
|
|
22
|
+
"FunctionExpression[parent.type!='MethodDefinition']", // function (){}
|
|
23
|
+
];
|
|
24
|
+
return {
|
|
25
|
+
[`:matches(${selectors.join(", ")})`]: (node: Node) => {
|
|
26
|
+
context.report({ node, messageId: `${name}/error` });
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const noNestedFunction = { name, rule };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { test } from "@fenge/dev-utils";
|
|
2
|
+
import { noTopLevelArrowFunction } from "./no-top-level-arrow-function.js";
|
|
3
|
+
|
|
4
|
+
const valid = [
|
|
5
|
+
"function foo(){}",
|
|
6
|
+
"const foo = function(){}",
|
|
7
|
+
"const foo = function foo(){}",
|
|
8
|
+
"if(true) const foo = () => {\n}",
|
|
9
|
+
|
|
10
|
+
// allow one-line function
|
|
11
|
+
"let foo = () => ''",
|
|
12
|
+
"let foo = () => {}",
|
|
13
|
+
"const foo = () => {}",
|
|
14
|
+
"let foo; foo = () => {}",
|
|
15
|
+
"export const foo = () => {}",
|
|
16
|
+
"export let foo = () => {}",
|
|
17
|
+
"export default () => {}",
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
const invalid = [
|
|
21
|
+
"let foo = () => {\n}",
|
|
22
|
+
"const foo = () => {\n}",
|
|
23
|
+
"let foo; foo = () => {\n}",
|
|
24
|
+
"export const foo = () => {\n}",
|
|
25
|
+
"export let foo = () => {\n}",
|
|
26
|
+
"export default () => {\n}",
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
test({ valid, invalid, ...noTopLevelArrowFunction });
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Rule } from "eslint";
|
|
2
|
+
import type { Node } from "estree";
|
|
3
|
+
import { getRuleName } from "../utils.js";
|
|
4
|
+
|
|
5
|
+
const name = getRuleName(import.meta.url);
|
|
6
|
+
const rule: Rule.RuleModule = {
|
|
7
|
+
meta: {
|
|
8
|
+
docs: {
|
|
9
|
+
description:
|
|
10
|
+
"Top-level functions are expected to be function declarations instead of arrow functions.",
|
|
11
|
+
},
|
|
12
|
+
messages: {
|
|
13
|
+
[`${name}/error`]:
|
|
14
|
+
"Top-level functions are expected to be function declarations instead of arrow functions.",
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
create: (context) => {
|
|
18
|
+
const handle = (node: Node) => {
|
|
19
|
+
if (node.loc?.start.line === node.loc?.end.line) return;
|
|
20
|
+
context.report({ node, messageId: `${name}/error` });
|
|
21
|
+
};
|
|
22
|
+
return {
|
|
23
|
+
"VariableDeclaration[parent.type='Program'] > VariableDeclarator > ArrowFunctionExpression":
|
|
24
|
+
handle,
|
|
25
|
+
"ExpressionStatement[parent.type='Program'] > AssignmentExpression > ArrowFunctionExpression":
|
|
26
|
+
handle,
|
|
27
|
+
"ExportNamedDeclaration > VariableDeclaration > VariableDeclarator > ArrowFunctionExpression":
|
|
28
|
+
handle,
|
|
29
|
+
"ExportDefaultDeclaration > ArrowFunctionExpression": handle,
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const noTopLevelArrowFunction = { name, rule };
|
package/src/test.spec.ts
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { createRequire } from "node:module";
|
|
2
|
-
import { describe, it } from "node:test";
|
|
3
|
-
import { RuleTester, type Rule } from "eslint";
|
|
4
|
-
|
|
5
|
-
export type TestCase = string | { code: string; filename?: string };
|
|
6
|
-
|
|
7
|
-
const tester = new RuleTester({
|
|
8
|
-
parser: createRequire(import.meta.url).resolve("@typescript-eslint/parser"),
|
|
9
|
-
parserOptions: { ecmaVersion: "latest", sourceType: "module" },
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
export async function test({
|
|
13
|
-
name,
|
|
14
|
-
rule,
|
|
15
|
-
valid,
|
|
16
|
-
invalid,
|
|
17
|
-
errors = 1,
|
|
18
|
-
}: {
|
|
19
|
-
name: string;
|
|
20
|
-
rule: Rule.RuleModule;
|
|
21
|
-
valid: TestCase[];
|
|
22
|
-
invalid: TestCase[];
|
|
23
|
-
errors?: number;
|
|
24
|
-
}) {
|
|
25
|
-
await describe(name, async () => {
|
|
26
|
-
await Promise.all(
|
|
27
|
-
valid.map(async (testCase) => {
|
|
28
|
-
await it(JSON.stringify(testCase), () => {
|
|
29
|
-
tester.run(name, rule, {
|
|
30
|
-
valid: [testCase],
|
|
31
|
-
invalid: [],
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
}),
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
await Promise.all(
|
|
38
|
-
invalid.map(async (testCase) => {
|
|
39
|
-
await it(JSON.stringify(testCase), () => {
|
|
40
|
-
const code = typeof testCase === "string" ? testCase : testCase.code;
|
|
41
|
-
const filename =
|
|
42
|
-
typeof testCase === "string" ? undefined : testCase.filename;
|
|
43
|
-
tester.run(name, rule, {
|
|
44
|
-
valid: [],
|
|
45
|
-
invalid: [{ code, errors, filename }],
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
}),
|
|
49
|
-
);
|
|
50
|
-
});
|
|
51
|
-
}
|