@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.
Files changed (45) hide show
  1. package/README.md +137 -80
  2. package/package.json +37 -43
  3. package/src/configs/cjs.js +45 -0
  4. package/src/configs/esm.js +43 -0
  5. package/src/configs/jest.js +24 -0
  6. package/src/configs/playwright.js +19 -0
  7. package/src/configs/react.js +75 -0
  8. package/src/configs/recommended.js +64 -0
  9. package/src/configs/rules/eslint-core.js +970 -0
  10. package/src/configs/rules/import-x.js +159 -0
  11. package/src/configs/rules/index.js +17 -0
  12. package/src/configs/rules/node.js +10 -0
  13. package/src/configs/rules/react-a11y.js +232 -0
  14. package/src/configs/rules/react-hooks.js +16 -0
  15. package/src/configs/rules/react.js +479 -0
  16. package/src/configs/rules/svelte.js +11 -0
  17. package/src/configs/rules/testing-library.js +74 -0
  18. package/src/configs/rules/typescript.js +228 -0
  19. package/src/configs/svelte.js +48 -0
  20. package/src/configs/vitest.js +36 -0
  21. package/src/index.d.ts +24 -0
  22. package/src/index.js +29 -0
  23. package/src/types/index.ts +52 -0
  24. package/src/utils/compose.js +62 -0
  25. package/src/utils/config.js +22 -0
  26. package/src/utils/merge.js +28 -0
  27. package/configs/airbnb-base-mod.js +0 -77
  28. package/configs/airbnb-mod.js +0 -17
  29. package/configs/airbnb-ts-base-mod.js +0 -37
  30. package/configs/airbnb-ts-mod.js +0 -17
  31. package/configs/env.js +0 -11
  32. package/esm.js +0 -6
  33. package/index.js +0 -10
  34. package/jest.js +0 -25
  35. package/node.js +0 -10
  36. package/overrides/react.js +0 -27
  37. package/overrides/sveltejs.js +0 -25
  38. package/overrides/sveltets.js +0 -32
  39. package/overrides/ts.js +0 -23
  40. package/playwright.js +0 -12
  41. package/react-svelte.js +0 -6
  42. package/react.js +0 -3
  43. package/svelte-js.js +0 -6
  44. package/svelte.js +0 -6
  45. 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
- };
@@ -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
- };