@qlik/eslint-config 0.8.1 → 1.0.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 +137 -80
- package/package.json +37 -43
- package/src/configs/cjs.js +45 -0
- package/src/configs/esm.js +43 -0
- package/src/configs/jest.js +24 -0
- package/src/configs/playwright.js +19 -0
- package/src/configs/react.js +75 -0
- package/src/configs/recommended.js +64 -0
- package/src/configs/rules/eslint-core.js +970 -0
- package/src/configs/rules/import-x.js +159 -0
- package/src/configs/rules/index.js +17 -0
- package/src/configs/rules/node.js +10 -0
- package/src/configs/rules/react-a11y.js +232 -0
- package/src/configs/rules/react-hooks.js +16 -0
- package/src/configs/rules/react.js +479 -0
- package/src/configs/rules/svelte.js +11 -0
- package/src/configs/rules/testing-library.js +74 -0
- package/src/configs/rules/typescript.js +228 -0
- package/src/configs/svelte.js +48 -0
- package/src/configs/vitest.js +36 -0
- package/src/index.d.ts +24 -0
- package/src/index.js +29 -0
- package/src/types/index.ts +52 -0
- package/src/utils/compose.js +62 -0
- package/src/utils/config.js +22 -0
- package/src/utils/merge.js +28 -0
- package/configs/airbnb-base-mod.js +0 -77
- package/configs/airbnb-mod.js +0 -17
- package/configs/airbnb-ts-base-mod.js +0 -37
- package/configs/airbnb-ts-mod.js +0 -17
- package/configs/env.js +0 -11
- package/esm.js +0 -6
- package/index.js +0 -10
- package/jest.js +0 -25
- package/node.js +0 -10
- package/overrides/react.js +0 -27
- package/overrides/sveltejs.js +0 -25
- package/overrides/sveltets.js +0 -32
- package/overrides/ts.js +0 -23
- package/playwright.js +0 -12
- package/react-svelte.js +0 -6
- package/react.js +0 -3
- package/svelte-js.js +0 -6
- package/svelte.js +0 -6
- package/vitest.js +0 -13
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import eslintCoreRules from "./eslint-core.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @satisfies {import("../../types/index.js").ESLintFlatConfig["rules"]}
|
|
6
|
+
*
|
|
7
|
+
* typescript-eslint package https://typescript-eslint.io/rules/
|
|
8
|
+
*/
|
|
9
|
+
const rules = {
|
|
10
|
+
// note some eslint core rules are disabled by tsconfig https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/configs/eslint-recommended-raw.ts
|
|
11
|
+
|
|
12
|
+
// class methods don't have to use this, but should maybe be turned into static methods
|
|
13
|
+
// https://typescript-eslint.io/rules/class-methods-use-this
|
|
14
|
+
"class-methods-use-this": "off",
|
|
15
|
+
"@typescript-eslint/class-methods-use-this": eslintCoreRules["class-methods-use-this"],
|
|
16
|
+
|
|
17
|
+
// enforce consistent type imports
|
|
18
|
+
// https://typescript-eslint.io/rules/consistent-type-imports
|
|
19
|
+
"@typescript-eslint/consistent-type-imports": "error",
|
|
20
|
+
|
|
21
|
+
// enforce default parameters to be last
|
|
22
|
+
// https://typescript-eslint.io/rules/default-param-last
|
|
23
|
+
"default-param-last": "off",
|
|
24
|
+
"@typescript-eslint/default-param-last": eslintCoreRules["default-param-last"],
|
|
25
|
+
|
|
26
|
+
// enforce exported functions to have return types
|
|
27
|
+
// https://typescript-eslint.io/rules/explicit-module-boundary-types
|
|
28
|
+
"@typescript-eslint/explicit-module-boundary-types": "off",
|
|
29
|
+
|
|
30
|
+
// enforce method signatures has the same style
|
|
31
|
+
// https://typescript-eslint.io/rules/method-signature-style
|
|
32
|
+
"@typescript-eslint/method-signature-style": "error",
|
|
33
|
+
|
|
34
|
+
// don't use the delete operator on dynamic properties
|
|
35
|
+
// https://typescript-eslint.io/rules/no-dynamic-delete
|
|
36
|
+
"@typescript-eslint/no-dynamic-delete": "error",
|
|
37
|
+
|
|
38
|
+
// don't have classes with only static members
|
|
39
|
+
// https://typescript-eslint.io/rules/no-extraneous-class
|
|
40
|
+
"@typescript-eslint/no-extraneous-class": "error",
|
|
41
|
+
|
|
42
|
+
// use top-level type imports
|
|
43
|
+
// https://typescript-eslint.io/rules/no-import-type-side-effects
|
|
44
|
+
"@typescript-eslint/no-import-type-side-effects": "error",
|
|
45
|
+
|
|
46
|
+
// don't use void where it shouldn't be used
|
|
47
|
+
// https://typescript-eslint.io/rules/no-invalid-void-type
|
|
48
|
+
"@typescript-eslint/no-invalid-void-type": "error",
|
|
49
|
+
|
|
50
|
+
// don't do weird things in loops
|
|
51
|
+
// https://typescript-eslint.io/rules/no-loop-func
|
|
52
|
+
"no-loop-func": "off",
|
|
53
|
+
"@typescript-eslint/no-loop-func": eslintCoreRules["no-loop-func"],
|
|
54
|
+
|
|
55
|
+
// no magic numbers please
|
|
56
|
+
// https://typescript-eslint.io/rules/no-magic-numbers
|
|
57
|
+
"no-magic-numbers": "off",
|
|
58
|
+
"@typescript-eslint/no-magic-numbers": eslintCoreRules["no-magic-numbers"],
|
|
59
|
+
|
|
60
|
+
// disallow non-null assertions in the left operand of a nullish coalescing operator.
|
|
61
|
+
// https://typescript-eslint.io/rules/no-non-null-asserted-nullish-coalescing
|
|
62
|
+
"@typescript-eslint/no-non-null-asserted-nullish-coalescing": "error",
|
|
63
|
+
|
|
64
|
+
// https://typescript-eslint.io/rules/no-non-null-assertion
|
|
65
|
+
"@typescript-eslint/no-non-null-assertion": "error",
|
|
66
|
+
|
|
67
|
+
// don't allow redeclaration of variables
|
|
68
|
+
// https://typescript-eslint.io/rules/no-redeclare
|
|
69
|
+
"no-redeclare": "off",
|
|
70
|
+
"@typescript-eslint/no-redeclare": eslintCoreRules["no-redeclare"],
|
|
71
|
+
|
|
72
|
+
// add forbidden imports if needed
|
|
73
|
+
// https://typescript-eslint.io/rules/no-restricted-imports
|
|
74
|
+
"no-restricted-imports": "off",
|
|
75
|
+
"@typescript-eslint/no-restricted-imports": eslintCoreRules["no-restricted-imports"],
|
|
76
|
+
|
|
77
|
+
// add forbidden types if needed
|
|
78
|
+
// https://typescript-eslint.io/rules/no-restricted-types
|
|
79
|
+
"@typescript-eslint/no-restricted-types": ["error", {}],
|
|
80
|
+
|
|
81
|
+
// shadows from outer scopes are not allowed
|
|
82
|
+
// https://typescript-eslint.io/rules/no-shadow
|
|
83
|
+
"no-shadow": "off",
|
|
84
|
+
"@typescript-eslint/no-shadow": eslintCoreRules["no-shadow"],
|
|
85
|
+
|
|
86
|
+
// no unnecessary assignment of constructor property parameter.
|
|
87
|
+
// https://typescript-eslint.io/rules/no-unnecessary-parameter-property-assignment
|
|
88
|
+
"@typescript-eslint/no-unnecessary-parameter-property-assignment": "error",
|
|
89
|
+
|
|
90
|
+
// don't use stuff that hasn't been defined
|
|
91
|
+
// https://typescript-eslint.io/rules/no-useless-constructor
|
|
92
|
+
"no-useless-constructor": "off",
|
|
93
|
+
"@typescript-eslint/no-useless-constructor": eslintCoreRules["no-useless-constructor"],
|
|
94
|
+
|
|
95
|
+
// useless exports can be removed
|
|
96
|
+
// https://typescript-eslint.io/rules/no-useless-empty-export
|
|
97
|
+
"@typescript-eslint/no-useless-empty-export": "error",
|
|
98
|
+
|
|
99
|
+
// yes, please initialize your enums
|
|
100
|
+
// https://typescript-eslint.io/rules/prefer-enum-initializers
|
|
101
|
+
"@typescript-eslint/prefer-enum-initializers": "error",
|
|
102
|
+
|
|
103
|
+
// allow classic for loops
|
|
104
|
+
// https://typescript-eslint.io/rules/prefer-for-of
|
|
105
|
+
"@typescript-eslint/prefer-for-of": "off",
|
|
106
|
+
|
|
107
|
+
// enums are not based on dynamic values
|
|
108
|
+
// https://typescript-eslint.io/rules/prefer-literal-enum-member
|
|
109
|
+
"@typescript-eslint/prefer-literal-enum-member": "error",
|
|
110
|
+
|
|
111
|
+
// disallow two overloads that could be unified into one with a union or an optional/rest parameter.
|
|
112
|
+
// https://typescript-eslint.io/rules/unified-signatures
|
|
113
|
+
"@typescript-eslint/unified-signatures": "error",
|
|
114
|
+
|
|
115
|
+
// enforce explicityly set type exports
|
|
116
|
+
// https://typescript-eslint.io/rules/consistent-type-exports
|
|
117
|
+
"@typescript-eslint/consistent-type-exports": "error",
|
|
118
|
+
|
|
119
|
+
// void should not be assigned to variables
|
|
120
|
+
// https://typescript-eslint.io/rules/no-confusing-void-expression
|
|
121
|
+
"@typescript-eslint/no-confusing-void-expression": "error",
|
|
122
|
+
|
|
123
|
+
// https://typescript-eslint.io/rules/no-floating-promises
|
|
124
|
+
"@typescript-eslint/no-floating-promises": [
|
|
125
|
+
"error",
|
|
126
|
+
{
|
|
127
|
+
ignoreIIFE: true,
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
|
|
131
|
+
// remove void when it's not needed
|
|
132
|
+
// https://typescript-eslint.io/rules/no-meaningless-void-operator
|
|
133
|
+
"@typescript-eslint/no-meaningless-void-operator": "error",
|
|
134
|
+
|
|
135
|
+
// https://typescript-eslint.io/rules/no-misused-promises
|
|
136
|
+
"@typescript-eslint/no-misused-promises": [
|
|
137
|
+
"error",
|
|
138
|
+
{
|
|
139
|
+
checksConditionals: false,
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
|
|
143
|
+
// use constistent enum types
|
|
144
|
+
// https://typescript-eslint.io/rules/no-mixed-enums
|
|
145
|
+
"@typescript-eslint/no-mixed-enums": "error",
|
|
146
|
+
|
|
147
|
+
// don't do silly comparisons
|
|
148
|
+
// https://typescript-eslint.io/rules/no-unnecessary-boolean-literal-compare
|
|
149
|
+
"@typescript-eslint/no-unnecessary-boolean-literal-compare": "error",
|
|
150
|
+
|
|
151
|
+
// Lots of false/iffy positives
|
|
152
|
+
// watch out for always truthy conditions
|
|
153
|
+
// https://typescript-eslint.io/rules/no-unnecessary-condition
|
|
154
|
+
"@typescript-eslint/no-unnecessary-condition": "off",
|
|
155
|
+
|
|
156
|
+
// no unnecessary namespace qualifiers.
|
|
157
|
+
// https://typescript-eslint.io/rules/no-unnecessary-qualifier
|
|
158
|
+
"@typescript-eslint/no-unnecessary-qualifier": "error",
|
|
159
|
+
|
|
160
|
+
// no need for template literals if they just refer to a string
|
|
161
|
+
// https://typescript-eslint.io/rules/no-unnecessary-template-expression
|
|
162
|
+
"@typescript-eslint/no-unnecessary-template-expression": "error",
|
|
163
|
+
|
|
164
|
+
// don't use type arguments when they're not needed
|
|
165
|
+
// https://typescript-eslint.io/rules/no-unnecessary-type-arguments
|
|
166
|
+
"@typescript-eslint/no-unnecessary-type-arguments": "error",
|
|
167
|
+
|
|
168
|
+
// Not working 100%
|
|
169
|
+
// don't use type parameters when they're not needed
|
|
170
|
+
// https://typescript-eslint.io/rules/no-unnecessary-type-parameters
|
|
171
|
+
"@typescript-eslint/no-unnecessary-type-parameters": "off",
|
|
172
|
+
|
|
173
|
+
// reducers should be typed correctly
|
|
174
|
+
// https://typescript-eslint.io/rules/prefer-reduce-type-parameter
|
|
175
|
+
"@typescript-eslint/prefer-reduce-type-parameter": "error",
|
|
176
|
+
|
|
177
|
+
// https://typescript-eslint.io/rules/prefer-return-this-type
|
|
178
|
+
"@typescript-eslint/prefer-return-this-type": "error",
|
|
179
|
+
|
|
180
|
+
// https://typescript-eslint.io/rules/ban-ts-comment
|
|
181
|
+
"@typescript-eslint/ban-ts-comment": "error",
|
|
182
|
+
|
|
183
|
+
// https://typescript-eslint.io/rules/require-array-sort-compare
|
|
184
|
+
"@typescript-eslint/require-array-sort-compare": "error",
|
|
185
|
+
|
|
186
|
+
// not sure about this one
|
|
187
|
+
// https://typescript-eslint.io/rules/return-await
|
|
188
|
+
"no-return-await": "off",
|
|
189
|
+
"@typescript-eslint/return-await": "error",
|
|
190
|
+
|
|
191
|
+
// Not sure about this one
|
|
192
|
+
// disallow certain types in boolean expressions.
|
|
193
|
+
// https://typescript-eslint.io/rules/strict-boolean-expressions
|
|
194
|
+
"@typescript-eslint/strict-boolean-expressions": "off",
|
|
195
|
+
|
|
196
|
+
// make sure switch statements are exhaustive
|
|
197
|
+
// https://typescript-eslint.io/rules/switch-exhaustiveness-check
|
|
198
|
+
"@typescript-eslint/switch-exhaustiveness-check": "error",
|
|
199
|
+
|
|
200
|
+
// enforce typing arguments in Promise rejection callbacks as unknown
|
|
201
|
+
// https://typescript-eslint.io/rules/use-unknown-in-catch-callback-variable
|
|
202
|
+
"@typescript-eslint/use-unknown-in-catch-callback-variable": "error",
|
|
203
|
+
|
|
204
|
+
// Replace Airbnb 'camelcase' rule with '@typescript-eslint/naming-convention'
|
|
205
|
+
// https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/naming-convention.md
|
|
206
|
+
camelcase: "off",
|
|
207
|
+
// The `@typescript-eslint/naming-convention` rule allows `leadingUnderscore` and `trailingUnderscore` settings. However, the existing `no-underscore-dangle` rule already takes care of this.
|
|
208
|
+
"@typescript-eslint/naming-convention": [
|
|
209
|
+
"error",
|
|
210
|
+
// Allow camelCase variables (23.2), PascalCase variables (23.8), and UPPER_CASE variables (23.10)
|
|
211
|
+
{
|
|
212
|
+
selector: "variable",
|
|
213
|
+
format: ["camelCase", "PascalCase", "UPPER_CASE"],
|
|
214
|
+
},
|
|
215
|
+
// Allow camelCase functions (23.2), and PascalCase functions (23.8)
|
|
216
|
+
{
|
|
217
|
+
selector: "function",
|
|
218
|
+
format: ["camelCase", "PascalCase"],
|
|
219
|
+
},
|
|
220
|
+
// Airbnb recommends PascalCase for classes (23.3), and although Airbnb does not make TypeScript recommendations, we are assuming this rule would similarly apply to anything "type like", including interfaces, type aliases, and enums
|
|
221
|
+
{
|
|
222
|
+
selector: "typeLike",
|
|
223
|
+
format: ["PascalCase"],
|
|
224
|
+
},
|
|
225
|
+
],
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
export default rules;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import eslintPluginSvelte from "eslint-plugin-svelte";
|
|
3
|
+
import svelteParser from "svelte-eslint-parser";
|
|
4
|
+
import tsEslint from "typescript-eslint";
|
|
5
|
+
import { mergeConfigs } from "../utils/config.js";
|
|
6
|
+
import { recommendedJS, recommendedTS } from "./recommended.js";
|
|
7
|
+
import rules from "./rules/svelte.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @type {import("../types/index.js").ESLintFlatConfig}
|
|
11
|
+
* config for Svelte https://github.com/sveltejs/eslint-plugin-svelte
|
|
12
|
+
*/
|
|
13
|
+
const svelte = mergeConfigs(...eslintPluginSvelte.configs["flat/recommended"], {
|
|
14
|
+
name: "svelte",
|
|
15
|
+
files: ["**/*.svelte"],
|
|
16
|
+
languageOptions: {
|
|
17
|
+
parser: svelteParser,
|
|
18
|
+
parserOptions: {
|
|
19
|
+
parser: tsEslint.parser,
|
|
20
|
+
extraFileExtensions: [".svelte"],
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
rules: {
|
|
24
|
+
...rules,
|
|
25
|
+
// modify rules from eslint-plugin-svelte here
|
|
26
|
+
|
|
27
|
+
// Conflicting rules
|
|
28
|
+
// https://github.com/sveltejs/eslint-plugin-svelte3/blob/master/OTHER_PLUGINS.md
|
|
29
|
+
"import-x/first": "off",
|
|
30
|
+
"import-x/no-duplicates": "off",
|
|
31
|
+
"import-x/no-mutable-exports": "off",
|
|
32
|
+
"import-x/no-unresolved": "off",
|
|
33
|
+
"import-x/prefer-default-export": "off",
|
|
34
|
+
"import-x/extensions": "off",
|
|
35
|
+
|
|
36
|
+
"@typescript-eslint/no-unsafe-call": "off",
|
|
37
|
+
"@typescript-eslint/no-unsafe-return": "off",
|
|
38
|
+
"@typescript-eslint/no-unsafe-argument": "off",
|
|
39
|
+
"@typescript-eslint/no-unsafe-assignment": "off",
|
|
40
|
+
"@typescript-eslint/no-unsafe-member-access": "off",
|
|
41
|
+
|
|
42
|
+
// Issues with function types that define parameters
|
|
43
|
+
"no-unused-vars": "off",
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
export default [recommendedJS, recommendedTS, svelte];
|
|
48
|
+
export { svelte };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import vitestPlugin from "@vitest/eslint-plugin";
|
|
3
|
+
// @ts-expect-error no types yet
|
|
4
|
+
import testingLibraryPlugin from "eslint-plugin-testing-library";
|
|
5
|
+
import { mergeConfigs } from "../utils/config.js";
|
|
6
|
+
import rules from "./rules/index.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @satisfies {import("../types/index.js").ESLintFlatConfig["rules"]}
|
|
10
|
+
*/
|
|
11
|
+
const vitestCommon = {};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @type {import("../types/index.js").ESLintFlatConfig}
|
|
15
|
+
* config for jest https://github.com/jest-community/eslint-plugin-jest
|
|
16
|
+
*/
|
|
17
|
+
const vitest = mergeConfigs(vitestCommon, {
|
|
18
|
+
name: "vitest-js",
|
|
19
|
+
plugins: {
|
|
20
|
+
vitest: vitestPlugin,
|
|
21
|
+
"testing-library": testingLibraryPlugin,
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
files: ["**/__test__/**/*.{js,jsx,ts,tsx}", "**/__tests__/**/*.{js,jsx,ts,tsx}"],
|
|
25
|
+
|
|
26
|
+
rules: {
|
|
27
|
+
// modify rules from eslint-plugin-vitest here
|
|
28
|
+
...vitestPlugin.configs.recommended.rules, // you can also use vitest.configs.all.rules to enable all rules
|
|
29
|
+
...rules.testingLibraryRules,
|
|
30
|
+
"no-magic-numbers": "off",
|
|
31
|
+
"@typescript-eslint/no-magic-numbers": "off",
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
export default [vitest];
|
|
36
|
+
export { vitest };
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export default qlikEslintConfig;
|
|
2
|
+
|
|
3
|
+
declare namespace qlikEslintConfig {
|
|
4
|
+
export namespace configs {
|
|
5
|
+
export { cjs };
|
|
6
|
+
export { esm };
|
|
7
|
+
export { playwright };
|
|
8
|
+
export { jest };
|
|
9
|
+
export { react };
|
|
10
|
+
export { recommended };
|
|
11
|
+
export { svelte };
|
|
12
|
+
export { vitest };
|
|
13
|
+
}
|
|
14
|
+
export { compose };
|
|
15
|
+
}
|
|
16
|
+
import cjs from "./configs/cjs.js";
|
|
17
|
+
import esm from "./configs/esm.js";
|
|
18
|
+
import jest from "./configs/jest.js";
|
|
19
|
+
import playwright from "./configs/playwright.js";
|
|
20
|
+
import react from "./configs/react.js";
|
|
21
|
+
import recommended from "./configs/recommended.js";
|
|
22
|
+
import svelte from "./configs/svelte.js";
|
|
23
|
+
import vitest from "./configs/vitest.js";
|
|
24
|
+
import compose from "./utils/compose.js";
|
package/src/index.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Import ESLint configuration modules
|
|
2
|
+
import cjs from "./configs/cjs.js";
|
|
3
|
+
import esm from "./configs/esm.js";
|
|
4
|
+
import jest from "./configs/jest.js";
|
|
5
|
+
import playwright from "./configs/playwright.js";
|
|
6
|
+
import react from "./configs/react.js";
|
|
7
|
+
import recommended from "./configs/recommended.js";
|
|
8
|
+
import svelte from "./configs/svelte.js";
|
|
9
|
+
import vitest from "./configs/vitest.js";
|
|
10
|
+
import compose from "./utils/compose.js";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @satisfies {import("./types/index.js").QlikEslintConfig}
|
|
14
|
+
*/
|
|
15
|
+
const qlikEslintConfig = {
|
|
16
|
+
configs: {
|
|
17
|
+
cjs,
|
|
18
|
+
esm,
|
|
19
|
+
jest,
|
|
20
|
+
playwright,
|
|
21
|
+
react,
|
|
22
|
+
recommended,
|
|
23
|
+
svelte,
|
|
24
|
+
vitest,
|
|
25
|
+
},
|
|
26
|
+
compose,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export default qlikEslintConfig;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-empty-object-type */
|
|
2
|
+
import { TSESLint } from "@typescript-eslint/utils";
|
|
3
|
+
|
|
4
|
+
interface ESLintFlatConfig extends TSESLint.FlatConfig.Config {}
|
|
5
|
+
interface ESLintPlugin extends TSESLint.FlatConfig.Plugin {}
|
|
6
|
+
interface ESLintLanguageOptions extends TSESLint.FlatConfig.LanguageOptions {}
|
|
7
|
+
|
|
8
|
+
interface ESLintFlatConfigWithExtend extends ESLintFlatConfig {
|
|
9
|
+
/**
|
|
10
|
+
* Allows you to "extend" a set of configs similar to `extends` from the
|
|
11
|
+
* classic configs.
|
|
12
|
+
*
|
|
13
|
+
* This is just a convenience short-hand to help reduce duplication.
|
|
14
|
+
*
|
|
15
|
+
* ```js
|
|
16
|
+
* export default qlikEslint.compose({
|
|
17
|
+
* files: ['** /*.ts'],
|
|
18
|
+
* extend: [
|
|
19
|
+
* ...qlikEslint.configs.ts,
|
|
20
|
+
* ],
|
|
21
|
+
* rules: {
|
|
22
|
+
* '@typescript-eslint/array-type': 'error',
|
|
23
|
+
* '@typescript-eslint/consistent-type-imports': 'error',
|
|
24
|
+
* },
|
|
25
|
+
* })
|
|
26
|
+
*
|
|
27
|
+
* // expands to
|
|
28
|
+
*
|
|
29
|
+
* export default [
|
|
30
|
+
* ...qlikEslint.configs.ts.map(conf => ({
|
|
31
|
+
* ...conf,
|
|
32
|
+
* files: ['** /*.ts'],
|
|
33
|
+
* })),
|
|
34
|
+
* {
|
|
35
|
+
* files: ['** /*.ts'],
|
|
36
|
+
* rules: {
|
|
37
|
+
* '@typescript-eslint/array-type': 'error',
|
|
38
|
+
* '@typescript-eslint/consistent-type-imports': 'error',
|
|
39
|
+
* },
|
|
40
|
+
* },
|
|
41
|
+
* ]
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
extend?: ESLintFlatConfig[];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export type QlikEslintConfig = {
|
|
48
|
+
configs: Record<string, ESLintFlatConfig[]>;
|
|
49
|
+
compose: (...configs: ESLintFlatConfigWithExtend[]) => ESLintFlatConfig[];
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export type { ESLintFlatConfig, ESLintFlatConfigWithExtend, ESLintLanguageOptions, ESLintPlugin };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
/**
|
|
3
|
+
* Utility function to make it easy to strictly type your "Flat" config file
|
|
4
|
+
*
|
|
5
|
+
* @param {...(import("../types/index.js").ESLintFlatConfigWithExtend)} configs
|
|
6
|
+
* @returns {import("../types/index.js").ESLintFlatConfig[]}
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```js
|
|
10
|
+
* import eslint from '@eslint/js';
|
|
11
|
+
* import tseslint from 'typescript-eslint';
|
|
12
|
+
*
|
|
13
|
+
* export default qlik.compose(
|
|
14
|
+
* eslint.configs.recommended,
|
|
15
|
+
* ...tseslint.configs.recommended,
|
|
16
|
+
* {
|
|
17
|
+
* rules: {
|
|
18
|
+
* '@typescript-eslint/array-type': 'error',
|
|
19
|
+
* },
|
|
20
|
+
* },
|
|
21
|
+
* );
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export default function compose(...configs) {
|
|
25
|
+
return configs.flatMap((configWithExtends, configIndex) => {
|
|
26
|
+
const { extend: extendArr, ...config } = configWithExtends;
|
|
27
|
+
if (extendArr && !Array.isArray(extendArr)) {
|
|
28
|
+
throw new Error("extend property must be an array");
|
|
29
|
+
}
|
|
30
|
+
if (extendArr == null || extendArr.length === 0) {
|
|
31
|
+
return config;
|
|
32
|
+
}
|
|
33
|
+
const undefinedExtensions = extendArr.reduce((acc, extension, extensionIndex) => {
|
|
34
|
+
const maybeExtension = extension;
|
|
35
|
+
if (maybeExtension == null) {
|
|
36
|
+
acc.push(extensionIndex);
|
|
37
|
+
}
|
|
38
|
+
return acc;
|
|
39
|
+
}, /** @type {number[]} */ ([]));
|
|
40
|
+
if (undefinedExtensions.length) {
|
|
41
|
+
const configName = configWithExtends.name != null ? `, named "${configWithExtends.name}",` : " (anonymous)";
|
|
42
|
+
const extensionIndices = undefinedExtensions.join(", ");
|
|
43
|
+
throw new Error(
|
|
44
|
+
`Your config at index ${configIndex}${configName} contains undefined` +
|
|
45
|
+
` extensions at the following indices: ${extensionIndices}.`,
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return [
|
|
50
|
+
...extendArr.map((extension) => {
|
|
51
|
+
const name = [config.name, extension.name].filter(Boolean).join("__");
|
|
52
|
+
return {
|
|
53
|
+
...extension,
|
|
54
|
+
...(config.files && { files: config.files }),
|
|
55
|
+
...(config.ignores && { ignores: config.ignores }),
|
|
56
|
+
...(name && { name }),
|
|
57
|
+
};
|
|
58
|
+
}),
|
|
59
|
+
config,
|
|
60
|
+
];
|
|
61
|
+
});
|
|
62
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import tsEslint from "typescript-eslint";
|
|
2
|
+
import { merge } from "./merge.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Merges multiple configs into one.
|
|
6
|
+
*
|
|
7
|
+
* @param {...(import("../types/index.js").ESLintFlatConfig)} configs
|
|
8
|
+
* @returns {import("../types/index.js").ESLintFlatConfig}
|
|
9
|
+
*/
|
|
10
|
+
export function mergeConfigs(...configs) {
|
|
11
|
+
// merge all configs into one
|
|
12
|
+
const mergedConfig = configs.reduce((acc, conf) => {
|
|
13
|
+
return merge(acc, conf);
|
|
14
|
+
}, {});
|
|
15
|
+
|
|
16
|
+
if (mergedConfig.name && !mergedConfig.name.startsWith("@qlik/eslint-config/")) {
|
|
17
|
+
mergedConfig.name = `@qlik/eslint-config/${mergedConfig.name}`;
|
|
18
|
+
}
|
|
19
|
+
return mergedConfig;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const config = tsEslint.config;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// these ones will only do shallow merge, but the merge function will do deep merge
|
|
2
|
+
const noNeedToDeepMerge = ["plugins", "rules", "parser"];
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param {any} obj1
|
|
7
|
+
* @param {any} obj2
|
|
8
|
+
* @returns
|
|
9
|
+
*/
|
|
10
|
+
export const merge = (obj1, obj2) => {
|
|
11
|
+
// add error handling
|
|
12
|
+
if (typeof obj1 !== "object" || typeof obj2 !== "object") {
|
|
13
|
+
throw new Error("Both arguments must be objects");
|
|
14
|
+
}
|
|
15
|
+
const merged = { ...obj1 };
|
|
16
|
+
Object.keys(obj2).forEach((key) => {
|
|
17
|
+
if (Array.isArray(obj1[key]) && Array.isArray(obj2[key])) {
|
|
18
|
+
merged[key] = [...new Set([...obj1[key], ...obj2[key]])];
|
|
19
|
+
} else if (noNeedToDeepMerge.includes(key)) {
|
|
20
|
+
merged[key] = { ...obj1[key], ...obj2[key] };
|
|
21
|
+
} else if (typeof obj1[key] === "object" && typeof obj2[key] === "object") {
|
|
22
|
+
merged[key] = merge(obj1[key], obj2[key]);
|
|
23
|
+
} else {
|
|
24
|
+
merged[key] = obj2[key];
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
return merged;
|
|
28
|
+
};
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
rules: {
|
|
3
|
-
// modifies airbnb default rules
|
|
4
|
-
"no-void": "off",
|
|
5
|
-
"no-underscore-dangle": "off",
|
|
6
|
-
"class-methods-use-this": "off",
|
|
7
|
-
"no-plusplus": "off",
|
|
8
|
-
"prefer-destructuring": "off",
|
|
9
|
-
"guard-for-in": "off",
|
|
10
|
-
// allow prev to be re-assigned in reducers
|
|
11
|
-
"no-param-reassign": [
|
|
12
|
-
"error",
|
|
13
|
-
{
|
|
14
|
-
props: true,
|
|
15
|
-
ignorePropertyModificationsFor: [
|
|
16
|
-
"prev", // for reduce accumulators
|
|
17
|
-
"acc", // for reduce accumulators
|
|
18
|
-
"accumulator", // for reduce accumulators
|
|
19
|
-
"e", // for e.returnvalue
|
|
20
|
-
"ctx", // for Koa routing
|
|
21
|
-
"context", // for Koa routing
|
|
22
|
-
"req", // for Express requests
|
|
23
|
-
"request", // for Express requests
|
|
24
|
-
"res", // for Express responses
|
|
25
|
-
"response", // for Express responses
|
|
26
|
-
"$scope", // for Angular 1 scopes
|
|
27
|
-
"staticContext", // for ReactRouter context
|
|
28
|
-
],
|
|
29
|
-
},
|
|
30
|
-
],
|
|
31
|
-
|
|
32
|
-
// eslint import/order and prettier-plugin-organize-imports are currently incompatible
|
|
33
|
-
"import/order": "off",
|
|
34
|
-
|
|
35
|
-
// allows for..in and for..of
|
|
36
|
-
"no-restricted-syntax": [
|
|
37
|
-
"error",
|
|
38
|
-
// {
|
|
39
|
-
// selector: "ForInStatement",
|
|
40
|
-
// message:
|
|
41
|
-
// "for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array.",
|
|
42
|
-
// },
|
|
43
|
-
// {
|
|
44
|
-
// selector: "ForOfStatement",
|
|
45
|
-
// message:
|
|
46
|
-
// "iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.",
|
|
47
|
-
// },
|
|
48
|
-
{
|
|
49
|
-
selector: "LabeledStatement",
|
|
50
|
-
message: "Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand.",
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
selector: "WithStatement",
|
|
54
|
-
message: "`with` is disallowed in strict mode because it makes code impossible to predict and optimize.",
|
|
55
|
-
},
|
|
56
|
-
],
|
|
57
|
-
|
|
58
|
-
// modifies airbnb ts default rules
|
|
59
|
-
"lines-between-class-members": "off",
|
|
60
|
-
"no-use-before-define": "off",
|
|
61
|
-
"dot-notation": "off",
|
|
62
|
-
|
|
63
|
-
// import plugin
|
|
64
|
-
"import/prefer-default-export": "off",
|
|
65
|
-
"import/no-extraneous-dependencies": [
|
|
66
|
-
"off",
|
|
67
|
-
{
|
|
68
|
-
devDependencies: [
|
|
69
|
-
"**/webpack.config.js",
|
|
70
|
-
"**/svelte.config.js",
|
|
71
|
-
"**/playwright.config.ts",
|
|
72
|
-
"**/playwright.config.js",
|
|
73
|
-
],
|
|
74
|
-
},
|
|
75
|
-
],
|
|
76
|
-
},
|
|
77
|
-
};
|
package/configs/airbnb-mod.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
extends: ["./airbnb-base-mod.js"],
|
|
3
|
-
rules: {
|
|
4
|
-
// modifies airbnb rules for react
|
|
5
|
-
"react/jsx-props-no-spreading": "off",
|
|
6
|
-
"react/jsx-uses-react": "off",
|
|
7
|
-
"react/react-in-jsx-scope": "off",
|
|
8
|
-
"react/forbid-prop-types": "off",
|
|
9
|
-
"react/function-component-definition": [
|
|
10
|
-
2,
|
|
11
|
-
{
|
|
12
|
-
namedComponents: "arrow-function",
|
|
13
|
-
unnamedComponents: "arrow-function",
|
|
14
|
-
},
|
|
15
|
-
],
|
|
16
|
-
},
|
|
17
|
-
};
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
extends: ["./airbnb-base-mod"],
|
|
3
|
-
rules: {
|
|
4
|
-
// modifies airbnb ts default rules
|
|
5
|
-
"lines-between-class-members": "off",
|
|
6
|
-
"@typescript-eslint/lines-between-class-members": "off",
|
|
7
|
-
|
|
8
|
-
// discouraged https://palantir.github.io/tslint/rules/no-use-before-declare/
|
|
9
|
-
"no-use-before-define": "off",
|
|
10
|
-
"@typescript-eslint/no-use-before-define": "off",
|
|
11
|
-
|
|
12
|
-
"dot-notation": "off",
|
|
13
|
-
"@typescript-eslint/dot-notation": "off",
|
|
14
|
-
|
|
15
|
-
"@typescript-eslint/no-namespace": "off",
|
|
16
|
-
"@typescript-eslint/prefer-ts-expect-error": "error",
|
|
17
|
-
"@typescript-eslint/no-misused-promises": [
|
|
18
|
-
"error",
|
|
19
|
-
{
|
|
20
|
-
checksConditionals: false,
|
|
21
|
-
},
|
|
22
|
-
],
|
|
23
|
-
"@typescript-eslint/no-floating-promises": [
|
|
24
|
-
"error",
|
|
25
|
-
{
|
|
26
|
-
ignoreIIFE: true,
|
|
27
|
-
},
|
|
28
|
-
],
|
|
29
|
-
|
|
30
|
-
// no-unsafe-* does not work good
|
|
31
|
-
"@typescript-eslint/no-unsafe-call": "off",
|
|
32
|
-
"@typescript-eslint/no-unsafe-member-access": "off",
|
|
33
|
-
"@typescript-eslint/no-unsafe-return": "off",
|
|
34
|
-
"@typescript-eslint/no-unsafe-argument": "off",
|
|
35
|
-
"@typescript-eslint/no-unsafe-assignment": "off",
|
|
36
|
-
},
|
|
37
|
-
};
|