@wowlab/eslint-config 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/README.md +1 -1
- package/dist/core/base.js +6 -0
- package/dist/core/perfectionist.js +15 -2
- package/dist/core/plugin.d.ts +2 -0
- package/dist/core/plugin.js +6 -0
- package/dist/core/rules/function-padding.d.ts +2 -0
- package/dist/core/rules/function-padding.js +81 -0
- package/dist/core/stylistic.js +1 -1
- package/dist/presets/react.d.ts +2 -1
- package/dist/presets/react.js +16 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ export default createConfig({
|
|
|
43
43
|
- `deno` adds Deno globals.
|
|
44
44
|
- `next` adds the Next.js Core Web Vitals rules.
|
|
45
45
|
- `node` adds Node.js globals.
|
|
46
|
-
- `react` adds React rules for JavaScript. Set `typescript: true` to add TypeScript support or `typeChecked: true` to add
|
|
46
|
+
- `react` adds React rules for JavaScript. Set `typescript: true` to add TypeScript support or `typeChecked: true` to add type-aware React and TypeScript rules. Set `typescriptTypeChecked: false` when only the React rules need type information.
|
|
47
47
|
- `tanstackQuery` adds TanStack Query rules.
|
|
48
48
|
- `typescript` adds TypeScript rules, optionally using the project service.
|
|
49
49
|
|
package/dist/core/base.js
CHANGED
|
@@ -4,6 +4,7 @@ import sonarjs from "eslint-plugin-sonarjs";
|
|
|
4
4
|
import switchCase from "eslint-plugin-switch-case";
|
|
5
5
|
import unicorn from "eslint-plugin-unicorn";
|
|
6
6
|
import { perfectionistConfig } from "./perfectionist.js";
|
|
7
|
+
import { wowlabPlugin } from "./plugin.js";
|
|
7
8
|
import { stylisticConfig } from "./stylistic.js";
|
|
8
9
|
const ruleOverrides = {
|
|
9
10
|
"@eslint-community/eslint-comments/disable-enable-pair": [
|
|
@@ -37,6 +38,11 @@ export function createBaseConfig({ internalPatterns = [], } = {}) {
|
|
|
37
38
|
name: "wowlab/javascript",
|
|
38
39
|
},
|
|
39
40
|
perfectionistConfig(internalPatterns),
|
|
41
|
+
{
|
|
42
|
+
name: "wowlab/layout",
|
|
43
|
+
plugins: { wowlab: wowlabPlugin },
|
|
44
|
+
rules: { "wowlab/function-padding": "error" },
|
|
45
|
+
},
|
|
40
46
|
stylisticConfig,
|
|
41
47
|
{
|
|
42
48
|
name: "wowlab/switch-case",
|
|
@@ -30,7 +30,14 @@ export function perfectionistConfig(internalPatterns) {
|
|
|
30
30
|
rules: {
|
|
31
31
|
curly: ["error", "all"],
|
|
32
32
|
"perfectionist/sort-array-includes": "warn",
|
|
33
|
-
"perfectionist/sort-classes": [
|
|
33
|
+
"perfectionist/sort-classes": [
|
|
34
|
+
"warn",
|
|
35
|
+
{
|
|
36
|
+
groups: CLASS_GROUPS,
|
|
37
|
+
newlinesBetween: "ignore",
|
|
38
|
+
newlinesInside: "ignore",
|
|
39
|
+
},
|
|
40
|
+
],
|
|
34
41
|
"perfectionist/sort-decorators": "warn",
|
|
35
42
|
"perfectionist/sort-enums": ["warn", { partitionByComment: true }],
|
|
36
43
|
"perfectionist/sort-exports": "warn",
|
|
@@ -39,7 +46,13 @@ export function perfectionistConfig(internalPatterns) {
|
|
|
39
46
|
"perfectionist/sort-interfaces": "warn",
|
|
40
47
|
"perfectionist/sort-intersection-types": "warn",
|
|
41
48
|
"perfectionist/sort-maps": ["warn", { partitionByComment: true }],
|
|
42
|
-
"perfectionist/sort-modules":
|
|
49
|
+
"perfectionist/sort-modules": [
|
|
50
|
+
"warn",
|
|
51
|
+
{
|
|
52
|
+
newlinesBetween: "ignore",
|
|
53
|
+
newlinesInside: "ignore",
|
|
54
|
+
},
|
|
55
|
+
],
|
|
43
56
|
"perfectionist/sort-named-exports": "warn",
|
|
44
57
|
"perfectionist/sort-named-imports": "warn",
|
|
45
58
|
"perfectionist/sort-objects": ["warn", { partitionByComment: true }],
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
function functionDeclaration(statement) {
|
|
2
|
+
const declaration = statement.type === "ExportDefaultDeclaration" ||
|
|
3
|
+
statement.type === "ExportNamedDeclaration"
|
|
4
|
+
? statement.declaration
|
|
5
|
+
: statement;
|
|
6
|
+
if (!declaration ||
|
|
7
|
+
(declaration.type !== "FunctionDeclaration" &&
|
|
8
|
+
declaration.type !== "TSDeclareFunction")) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
return {
|
|
12
|
+
implementation: declaration.type === "FunctionDeclaration" && declaration.body != null,
|
|
13
|
+
name: declaration.id?.name,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function sameOverloadGroup(current, previous) {
|
|
17
|
+
return (!previous.implementation &&
|
|
18
|
+
current.name != null &&
|
|
19
|
+
current.name === previous.name);
|
|
20
|
+
}
|
|
21
|
+
export const functionPadding = {
|
|
22
|
+
create(context) {
|
|
23
|
+
const sourceCode = context.sourceCode;
|
|
24
|
+
function firstAttachedLine(current, previous) {
|
|
25
|
+
let startLine = current.loc?.start.line ?? 0;
|
|
26
|
+
const comments = sourceCode.getCommentsBefore(current);
|
|
27
|
+
for (let index = comments.length - 1; index >= 0; index -= 1) {
|
|
28
|
+
const comment = comments[index];
|
|
29
|
+
if (!comment?.loc ||
|
|
30
|
+
comment.loc.start.line <= (previous.loc?.end.line ?? 0) ||
|
|
31
|
+
startLine > comment.loc.end.line + 1) {
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
startLine = comment.loc.start.line;
|
|
35
|
+
}
|
|
36
|
+
return startLine;
|
|
37
|
+
}
|
|
38
|
+
function checkStatements(statements) {
|
|
39
|
+
for (let index = 1; index < statements.length; index += 1) {
|
|
40
|
+
const current = statements[index];
|
|
41
|
+
const previous = statements[index - 1];
|
|
42
|
+
if (!current || !previous || !current.loc || !previous.loc) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const currentFunction = functionDeclaration(current);
|
|
46
|
+
const previousFunction = functionDeclaration(previous);
|
|
47
|
+
const startLine = firstAttachedLine(current, previous);
|
|
48
|
+
if (!currentFunction ||
|
|
49
|
+
!previousFunction ||
|
|
50
|
+
sameOverloadGroup(currentFunction, previousFunction) ||
|
|
51
|
+
startLine > previous.loc.end.line + 1) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
const lineStart = sourceCode.text.lastIndexOf("\n", sourceCode.getIndexFromLoc({ column: 0, line: startLine }) - 1);
|
|
55
|
+
context.report({
|
|
56
|
+
fix: (fixer) => fixer.insertTextBeforeRange([lineStart + 1, lineStart + 1], "\n"),
|
|
57
|
+
messageId: "expected",
|
|
58
|
+
node: current,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
BlockStatement: (node) => checkStatements(node.body),
|
|
64
|
+
Program: (node) => checkStatements(node.body),
|
|
65
|
+
StaticBlock: (node) => checkStatements(node.body),
|
|
66
|
+
SwitchCase: (node) => checkStatements(node.consequent),
|
|
67
|
+
TSModuleBlock: (node) => checkStatements(node.body),
|
|
68
|
+
};
|
|
69
|
+
},
|
|
70
|
+
meta: {
|
|
71
|
+
docs: {
|
|
72
|
+
description: "Require blank lines around function declaration groups",
|
|
73
|
+
},
|
|
74
|
+
fixable: "whitespace",
|
|
75
|
+
messages: {
|
|
76
|
+
expected: "Expected a blank line around the function declaration.",
|
|
77
|
+
},
|
|
78
|
+
schema: [],
|
|
79
|
+
type: "layout",
|
|
80
|
+
},
|
|
81
|
+
};
|
package/dist/core/stylistic.js
CHANGED
|
@@ -68,7 +68,7 @@ const structuralRules = {
|
|
|
68
68
|
{ blankLine: "always", next: "*", prev: ["if", "for", "while", "switch", "try", "function", "class"] },
|
|
69
69
|
{ blankLine: "always", next: "block-like", prev: "block-like" },
|
|
70
70
|
{ blankLine: "always", next: "export", prev: "*" },
|
|
71
|
-
{ blankLine: "any", next: "function", prev: "function" },
|
|
71
|
+
{ blankLine: "any", next: ["function", "function-overload"], prev: ["function", "function-overload"] },
|
|
72
72
|
{ blankLine: "any", next: "export", prev: "export" },
|
|
73
73
|
],
|
|
74
74
|
"@stylistic/quotes": [
|
package/dist/presets/react.d.ts
CHANGED
|
@@ -5,5 +5,6 @@ export interface ReactOptions extends FilesOptions {
|
|
|
5
5
|
typeChecked?: boolean;
|
|
6
6
|
typescript?: boolean;
|
|
7
7
|
typescriptFiles?: string[];
|
|
8
|
+
typescriptTypeChecked?: boolean;
|
|
8
9
|
}
|
|
9
|
-
export declare function react({ files, tsconfigRootDir, typeChecked, typescript, typescriptFiles, }?: ReactOptions): Linter.Config[];
|
|
10
|
+
export declare function react({ files, tsconfigRootDir, typeChecked, typescript, typescriptFiles, typescriptTypeChecked, }?: ReactOptions): Linter.Config[];
|
package/dist/presets/react.js
CHANGED
|
@@ -3,7 +3,7 @@ import reactHooks from "eslint-plugin-react-hooks";
|
|
|
3
3
|
import { typescript as typescriptPreset } from "./typescript.js";
|
|
4
4
|
const JAVASCRIPT_FILES = ["**/*.{js,jsx,mjs,cjs}"];
|
|
5
5
|
const TYPESCRIPT_FILES = ["**/*.{ts,tsx,mts,cts}"];
|
|
6
|
-
export function react({ files = JAVASCRIPT_FILES, tsconfigRootDir, typeChecked = false, typescript = false, typescriptFiles = TYPESCRIPT_FILES, } = {}) {
|
|
6
|
+
export function react({ files = JAVASCRIPT_FILES, tsconfigRootDir, typeChecked = false, typescript = false, typescriptFiles = TYPESCRIPT_FILES, typescriptTypeChecked = typeChecked, } = {}) {
|
|
7
7
|
const typescriptConfigName = typeChecked
|
|
8
8
|
? "recommended-type-checked"
|
|
9
9
|
: "recommended";
|
|
@@ -35,8 +35,22 @@ export function react({ files = JAVASCRIPT_FILES, tsconfigRootDir, typeChecked =
|
|
|
35
35
|
...typescriptPreset({
|
|
36
36
|
files: typescriptFiles,
|
|
37
37
|
tsconfigRootDir,
|
|
38
|
-
typeChecked,
|
|
38
|
+
typeChecked: typescriptTypeChecked,
|
|
39
39
|
}),
|
|
40
|
+
...(typeChecked && !typescriptTypeChecked
|
|
41
|
+
? [
|
|
42
|
+
{
|
|
43
|
+
files: typescriptFiles,
|
|
44
|
+
languageOptions: {
|
|
45
|
+
parserOptions: {
|
|
46
|
+
projectService: true,
|
|
47
|
+
...(tsconfigRootDir ? { tsconfigRootDir } : {}),
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
name: "wowlab/react/typescript/project-service",
|
|
51
|
+
},
|
|
52
|
+
]
|
|
53
|
+
: []),
|
|
40
54
|
{
|
|
41
55
|
...typescriptConfig,
|
|
42
56
|
files: typescriptFiles,
|