@open-turo/eslint-config-typescript 16.0.0-pr-373.8.1.1 → 16.0.0-pr-373.10.1.1

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/eslint.config.mjs CHANGED
@@ -1,3 +1,4 @@
1
1
  import openTuroTypescriptConfig from "./index.mjs";
2
2
 
3
- export default openTuroTypescriptConfig;
3
+ // eslint-disable-next-line import/no-default-export
4
+ export default openTuroTypescriptConfig({ typescript: false });
package/index.cjs CHANGED
@@ -1,15 +1,16 @@
1
- const jestPlugin = require("eslint-plugin-jest");
2
- const nPlugin = require("eslint-plugin-n");
1
+ const eslint = require("@eslint/js");
2
+ const tsParser = require("@typescript-eslint/parser");
3
3
  const importPlugin = require("eslint-plugin-import");
4
+ const jestPlugin = require("eslint-plugin-jest");
4
5
  const jsonPlugin = require("eslint-plugin-json");
5
- const eslint = require("@eslint/js");
6
+ const nPlugin = require("eslint-plugin-n");
6
7
  const perfectionistPlugin = require("eslint-plugin-perfectionist");
7
8
  const prettierPluginRecommended = require("eslint-plugin-prettier/recommended");
8
- const tseslint = require("typescript-eslint");
9
9
  const sonarjsPlugin = require("eslint-plugin-sonarjs");
10
10
  const unicornPlugin = require("eslint-plugin-unicorn");
11
- const tsParser = require("@typescript-eslint/parser");
11
+ const tseslint = require("typescript-eslint");
12
12
 
13
+ const FILES_JS = "**/*.?([cm])js";
13
14
  const FILES_SRC_EXTENSION = "?([cm])[jt]s?(x)";
14
15
  const FILES_TS = "**/*.?([cm])ts";
15
16
  const FILES_TSX = "**/*.?([cm])tsx";
@@ -27,16 +28,19 @@ const typescriptLanguageOptions = () => ({
27
28
  },
28
29
  });
29
30
 
31
+ const javascriptConfig = (ecmaVersion = "latest") =>
32
+ tseslint.config(eslint.configs.recommended, {
33
+ files: [FILES_JS],
34
+ languageOptions: {
35
+ parserOptions: {
36
+ ecmaVersion,
37
+ },
38
+ },
39
+ });
40
+
30
41
  const importConfig = () =>
31
42
  tseslint.config({
32
43
  extends: [importPlugin.flatConfigs.recommended],
33
- settings: {
34
- "import/resolver": {
35
- typescript: {
36
- alwaysTryTypes: true,
37
- },
38
- },
39
- },
40
44
  rules: {
41
45
  "import/default": "off",
42
46
  "import/named": "off",
@@ -48,12 +52,23 @@ const importConfig = () =>
48
52
  ],
49
53
  "import/prefer-default-export": "off",
50
54
  },
55
+ settings: {
56
+ "import/resolver": {
57
+ typescript: {
58
+ alwaysTryTypes: true,
59
+ },
60
+ },
61
+ },
51
62
  });
52
63
 
53
64
  const nPluginConfig = (allowModules = ["@jest/globals", "nock"]) =>
54
65
  tseslint.config({
55
- extends: [nPlugin.configs["flat/recommended"]],
66
+ extends: [
67
+ nPlugin.configs["flat/recommended"],
68
+ nPlugin.configs["flat/mixed-esm-and-cjs"],
69
+ ],
56
70
  rules: {
71
+ "n/no-missing-import": "off",
57
72
  "n/no-unpublished-import": [
58
73
  "error",
59
74
  {
@@ -61,7 +76,6 @@ const nPluginConfig = (allowModules = ["@jest/globals", "nock"]) =>
61
76
  },
62
77
  ],
63
78
  "n/no-unsupported-features/es-syntax": "off",
64
- "n/no-missing-import": "off",
65
79
  },
66
80
  });
67
81
 
@@ -77,10 +91,10 @@ const sonarJsConfig = () =>
77
91
  "sonarjs/no-ignored-exceptions": "off",
78
92
  "sonarjs/no-nested-functions": ["warn", { threshold: 5 }],
79
93
  "sonarjs/no-small-switch": "off",
80
- // Overlaps with @typescript-eslint/prefer-nullish-coalescing
81
- "sonarjs/prefer-nullish-coalescing": "off",
82
94
  // Overlaps with @typescript-eslint/no-unused-vars
83
95
  "sonarjs/no-unused-vars": "off",
96
+ // Overlaps with @typescript-eslint/prefer-nullish-coalescing
97
+ "sonarjs/prefer-nullish-coalescing": "off",
84
98
  // Overlaps with @typescript-eslint/prefer-optional-chain
85
99
  "sonarjs/prefer-optional-chain": "off",
86
100
  // Useful for guarding against prop mutation in React, but too much of a lift as very rarely do we apply readonly/ReadonlyArray<T> to type definitions
@@ -94,11 +108,11 @@ const sonarJsConfig = () =>
94
108
 
95
109
  const typescriptConfig = () =>
96
110
  tseslint.config({
97
- files: [FILES_TS, FILES_TSX],
98
111
  extends: [
99
112
  tseslint.configs.recommendedTypeChecked,
100
113
  importPlugin.flatConfigs.typescript,
101
114
  ],
115
+ files: [FILES_TS, FILES_TSX],
102
116
  languageOptions: typescriptLanguageOptions(),
103
117
  rules: {
104
118
  /**
@@ -138,31 +152,43 @@ const typescriptConfig = () =>
138
152
  },
139
153
  });
140
154
 
141
- const testConfig = () =>
142
- tseslint.config({
155
+ /**
156
+ *
157
+ * @param options Configuration options
158
+ * @param options.typescript Whether to include typescript rules
159
+ * @returns {ConfigArray}
160
+ */
161
+ const testConfig = (options) => {
162
+ const typescriptRules = options.typescript
163
+ ? {
164
+ // this turns the original rule off *only* for test files, for jestPlugin compatibility
165
+ "@typescript-eslint/unbound-method": "off",
166
+ "jest/unbound-method": "error",
167
+ }
168
+ : {};
169
+ return tseslint.config({
170
+ extends: [jestPlugin.configs["flat/recommended"]],
143
171
  files: FILES_TEST,
144
- plugins: { jest: jestPlugin },
145
172
  languageOptions: {
146
173
  globals: jestPlugin.environments.globals.globals,
147
- ...typescriptLanguageOptions(),
174
+ ...(options.typescript ? typescriptLanguageOptions() : {}),
148
175
  },
149
- extends: [jestPlugin.configs["flat/recommended"]],
176
+ plugins: { jest: jestPlugin },
150
177
  rules: {
151
178
  ...jestPlugin.configs["flat/recommended"].rules,
152
- // this turns the original rule off *only* for test files, for jestPlugin compatibility
153
- "@typescript-eslint/unbound-method": "off",
154
- "jest/no-jest-import": "off",
155
- "jest/unbound-method": "error",
179
+ ...typescriptRules,
156
180
  "import/no-extraneous-dependencies": [
157
181
  "error",
158
182
  { devDependencies: FILES_TEST },
159
183
  ],
184
+ "jest/no-jest-import": "off",
160
185
  },
161
186
  });
187
+ };
162
188
 
163
189
  const ignoresConfig = (ignores = []) =>
164
190
  tseslint.config({
165
- ignores: ["**/.yalc", "**/dist"].concat(ignores),
191
+ ignores: ["**/.yalc", "**/dist", ...ignores],
166
192
  });
167
193
 
168
194
  /**
@@ -170,11 +196,15 @@ const ignoresConfig = (ignores = []) =>
170
196
  * @param [options] - Eslint config options
171
197
  * @param [options.allowModules] - List of modules to allow in the n/no-unpublished-import rule
172
198
  * @param [options.ignores] - List of patterns to ignore
199
+ * @param [options.typescript] - Whether to include typescript rules
200
+ * @param [options.ecmaVersion] - The ECMAScript version to use
173
201
  * @returns {ConfigArray}
174
202
  */
175
- module.exports = (options = {}) =>
176
- tseslint.config(
177
- eslint.configs.recommended,
203
+ module.exports = function config(options = {}) {
204
+ const useTypescript =
205
+ options.typescript === undefined ? true : options.typescript;
206
+ return tseslint.config(
207
+ javascriptConfig(options.ecmaVersion),
178
208
  importConfig(),
179
209
  nPluginConfig(options.allowModules),
180
210
  perfectionistPlugin.configs["recommended-alphabetical"],
@@ -182,7 +212,8 @@ module.exports = (options = {}) =>
182
212
  unicornPlugin.configs["flat/recommended"],
183
213
  prettierPluginRecommended,
184
214
  jsonPlugin.configs["recommended"],
185
- typescriptConfig(),
186
- testConfig(),
215
+ useTypescript ? typescriptConfig() : {},
216
+ testConfig({ typescript: useTypescript }),
187
217
  ignoresConfig(options.ignores),
188
218
  );
219
+ };
package/index.mjs CHANGED
@@ -1,3 +1,2 @@
1
- import config from "./index.cjs";
2
-
3
- export default config;
1
+ // eslint-disable-next-line import/no-default-export
2
+ export { default } from "./index.cjs";
package/package.json CHANGED
@@ -54,5 +54,5 @@
54
54
  "access": "public"
55
55
  },
56
56
  "repository": "https://github.com/open-turo/eslint-config-typescript",
57
- "version": "16.0.0-pr-373.8.1.1"
57
+ "version": "16.0.0-pr-373.10.1.1"
58
58
  }
package/recommended.cjs CHANGED
@@ -1,22 +1,8 @@
1
1
  module.exports = {
2
- root: true,
3
2
  env: {
4
3
  es2022: true,
5
4
  jest: true,
6
5
  },
7
- parser: "@typescript-eslint/parser",
8
- plugins: [
9
- "@typescript-eslint",
10
- "eslint-plugin-jest",
11
- "import",
12
- "jest",
13
- "json",
14
- "n",
15
- "perfectionist",
16
- "prettier",
17
- "sonarjs",
18
- "unicorn",
19
- ],
20
6
  extends: [
21
7
  "eslint:recommended",
22
8
  "plugin:@typescript-eslint/recommended-type-checked",
@@ -31,11 +17,6 @@ module.exports = {
31
17
  "plugin:sonarjs/recommended-legacy",
32
18
  "plugin:unicorn/recommended",
33
19
  ],
34
- parserOptions: {
35
- ecmaVersion: "latest",
36
- project: "./tsconfig.json",
37
- sourceType: "module",
38
- },
39
20
  overrides: [
40
21
  {
41
22
  files: ["test/**"],
@@ -47,7 +28,60 @@ module.exports = {
47
28
  },
48
29
  },
49
30
  ],
31
+ parser: "@typescript-eslint/parser",
32
+ parserOptions: {
33
+ ecmaVersion: "latest",
34
+ project: "./tsconfig.json",
35
+ sourceType: "module",
36
+ },
37
+ plugins: [
38
+ "@typescript-eslint",
39
+ "eslint-plugin-jest",
40
+ "import",
41
+ "jest",
42
+ "json",
43
+ "n",
44
+ "perfectionist",
45
+ "prettier",
46
+ "sonarjs",
47
+ "unicorn",
48
+ ],
49
+ root: true,
50
50
  rules: {
51
+ /**
52
+ * {@link https://typescript-eslint.io/rules/consistent-type-imports | TypeScript ESLint: consistent-type-imports docs}
53
+ */
54
+ "@typescript-eslint/consistent-type-imports": [
55
+ "error",
56
+ {
57
+ disallowTypeAnnotations: true,
58
+ fixStyle: "inline-type-imports",
59
+ prefer: "type-imports",
60
+ },
61
+ ],
62
+ /** We do not need to force people to wrap `void`-return implicit arrow returns with braces just for a lint rule. TypeScript alone covers functionality, by the return type being `void`. */
63
+ "@typescript-eslint/no-confusing-void-expression": "off",
64
+ /** Included as part of `strict-type-checked`, but nothing we want to enforce. */
65
+ "@typescript-eslint/no-deprecated": "off",
66
+ /** Prefers `import type {}` syntax over `import { type }` if all imports are type-only */
67
+ "@typescript-eslint/no-import-type-side-effects": "error",
68
+ /** A relatively stylistic rule, downgraded to "off" to limit breaking changes in the update that includes `strict-type-checked`. */
69
+ "@typescript-eslint/no-unnecessary-boolean-literal-compare": "off",
70
+ /** This rule can help us identify syntax that is more defensive than the types suggest. Unfortunately, it may be protecting us from runtime errors where the type definitions are incorrect. As such, it is turned "off", as even "warn" auto-fixes source code. */
71
+ "@typescript-eslint/no-unnecessary-condition": "off",
72
+ /** There is readability benefit to passing in type arguments that match defaults. If defaults change, we may prefer the manual inspection of all the types changed, too. */
73
+ "@typescript-eslint/no-unnecessary-type-arguments": "off",
74
+ /** Errors on generic type parameters that are only used once, even though that helps with return type inference. */
75
+ "@typescript-eslint/no-unnecessary-type-parameters": "off",
76
+ "@typescript-eslint/no-unused-vars": [
77
+ "error",
78
+ {
79
+ // Allow to name unused vars with _
80
+ argsIgnorePattern: "^_",
81
+ },
82
+ ],
83
+ "@typescript-eslint/prefer-ts-expect-error": "error",
84
+ "@typescript-eslint/unbound-method": "error",
51
85
  "import/default": "off",
52
86
  "import/named": "off",
53
87
  "import/namespace": "off",
@@ -59,6 +93,7 @@ module.exports = {
59
93
  "import/prefer-default-export": "off",
60
94
  "jest/no-jest-import": "off",
61
95
  "json/*": "error",
96
+ "n/no-missing-import": "off",
62
97
  "n/no-unpublished-import": [
63
98
  "error",
64
99
  {
@@ -66,7 +101,6 @@ module.exports = {
66
101
  },
67
102
  ],
68
103
  "n/no-unsupported-features/es-syntax": "off",
69
- "n/no-missing-import": "off",
70
104
  // Noisy rule - we may have helpers/methods that we mark as @deprecated but aren't planning to remove in the near future. This rule also significantly adds to eslint running time, which slows down both local development and CI.
71
105
  "sonarjs/deprecation": "off",
72
106
  // This rule is not helpful in TypeScript files, and in JavaScript we often return different types from functions, so this is not a strictness level we want to enforce.
@@ -75,10 +109,10 @@ module.exports = {
75
109
  "sonarjs/no-ignored-exceptions": "off",
76
110
  "sonarjs/no-nested-functions": ["warn", { threshold: 5 }],
77
111
  "sonarjs/no-small-switch": "off",
78
- // Overlaps with @typescript-eslint/prefer-nullish-coalescing
79
- "sonarjs/prefer-nullish-coalescing": "off",
80
112
  // Overlaps with @typescript-eslint/no-unused-vars
81
113
  "sonarjs/no-unused-vars": "off",
114
+ // Overlaps with @typescript-eslint/prefer-nullish-coalescing
115
+ "sonarjs/prefer-nullish-coalescing": "off",
82
116
  // Overlaps with @typescript-eslint/prefer-optional-chain
83
117
  "sonarjs/prefer-optional-chain": "off",
84
118
  // Useful for guarding against prop mutation in React, but too much of a lift as very rarely do we apply readonly/ReadonlyArray<T> to type definitions
@@ -87,40 +121,6 @@ module.exports = {
87
121
  "sonarjs/todo-tag": "off",
88
122
  // A useful rule to consider for libraries to better document (and export) type definitions, but noisy in app usages (especially around redux type definitions)
89
123
  "sonarjs/use-type-alias": "off",
90
- /**
91
- * {@link https://typescript-eslint.io/rules/consistent-type-imports | TypeScript ESLint: consistent-type-imports docs}
92
- */
93
- "@typescript-eslint/consistent-type-imports": [
94
- "error",
95
- {
96
- disallowTypeAnnotations: true,
97
- fixStyle: "inline-type-imports",
98
- prefer: "type-imports",
99
- },
100
- ],
101
- /** We do not need to force people to wrap `void`-return implicit arrow returns with braces just for a lint rule. TypeScript alone covers functionality, by the return type being `void`. */
102
- "@typescript-eslint/no-confusing-void-expression": "off",
103
- /** Included as part of `strict-type-checked`, but nothing we want to enforce. */
104
- "@typescript-eslint/no-deprecated": "off",
105
- /** Prefers `import type {}` syntax over `import { type }` if all imports are type-only */
106
- "@typescript-eslint/no-import-type-side-effects": "error",
107
- /** A relatively stylistic rule, downgraded to "off" to limit breaking changes in the update that includes `strict-type-checked`. */
108
- "@typescript-eslint/no-unnecessary-boolean-literal-compare": "off",
109
- /** This rule can help us identify syntax that is more defensive than the types suggest. Unfortunately, it may be protecting us from runtime errors where the type definitions are incorrect. As such, it is turned "off", as even "warn" auto-fixes source code. */
110
- "@typescript-eslint/no-unnecessary-condition": "off",
111
- /** There is readability benefit to passing in type arguments that match defaults. If defaults change, we may prefer the manual inspection of all the types changed, too. */
112
- "@typescript-eslint/no-unnecessary-type-arguments": "off",
113
- /** Errors on generic type parameters that are only used once, even though that helps with return type inference. */
114
- "@typescript-eslint/no-unnecessary-type-parameters": "off",
115
- "@typescript-eslint/no-unused-vars": [
116
- "error",
117
- {
118
- // Allow to name unused vars with _
119
- argsIgnorePattern: "^_",
120
- },
121
- ],
122
- "@typescript-eslint/prefer-ts-expect-error": "error",
123
- "@typescript-eslint/unbound-method": "error",
124
124
  },
125
125
  settings: {
126
126
  "import/parsers": {
package/test/test.spec.js CHANGED
@@ -1,46 +1,52 @@
1
1
  import { loadESLint } from "eslint";
2
- import { fileURLToPath } from "node:url";
3
- import path from "node:path";
4
2
 
5
3
  describe("validate config", () => {
6
- test.each(["./index.mjs", "./index.cjs", "./recommended.cjs"])(
7
- `load config file in ESLint to validate all rules are correct for %s`,
8
- async (config) => {
9
- const testFileName = "test.js";
10
- const useFlatConfig = !config.includes("recommended");
4
+ const testFileName = "test.js";
5
+ const code = `const foo = 1;\nconsole.log(foo);\n`;
6
+ const parserOptions = {
7
+ projectService: {
8
+ allowDefaultProject: [testFileName],
9
+ },
10
+ };
11
+
12
+ test("the legacy recommended config is correct", async () => {
13
+ const ESLint = await loadESLint({
14
+ useFlatConfig: false,
15
+ });
16
+ const linter = new ESLint({
17
+ overrideConfig: {
18
+ parserOptions,
19
+ },
20
+ overrideConfigFile: "./recommended.cjs",
21
+ });
22
+ const messages = await linter.lintText(code, {
23
+ filePath: testFileName,
24
+ });
25
+ expect(messages[0].messages).toEqual([]);
26
+ expect(messages[0].errorCount).toEqual(0);
27
+ });
28
+
29
+ test.each(["index.mjs", "index.cjs"])(
30
+ `the flat config is correct for %s`,
31
+ async (configFile) => {
11
32
  const ESLint = await loadESLint({
12
- useFlatConfig,
33
+ useFlatConfig: true,
13
34
  });
35
+ const { default: config } = await import(`../${configFile}`);
14
36
  const linter = new ESLint({
15
- // cwd: cwd,
16
- overrideConfigFile: config,
17
- overrideConfig: useFlatConfig
18
- ? [
19
- {
20
- files: [testFileName],
21
- languageOptions: {
22
- parserOptions: {
23
- projectService: {
24
- allowDefaultProject: [testFileName],
25
- },
26
- },
27
- },
28
- },
29
- ]
30
- : {
31
- parserOptions: {
32
- projectService: {
33
- allowDefaultProject: [testFileName],
34
- },
35
- },
37
+ baseConfig: config(),
38
+ overrideConfig: [
39
+ {
40
+ files: [testFileName],
41
+ languageOptions: {
42
+ parserOptions,
36
43
  },
44
+ },
45
+ ],
46
+ });
47
+ const messages = await linter.lintText(code, {
48
+ filePath: testFileName,
37
49
  });
38
- const messages = await linter.lintText(
39
- `const foo = 1;\nconsole.log(foo);\n`,
40
- {
41
- filePath: testFileName,
42
- },
43
- );
44
50
  expect(messages[0].messages).toEqual([]);
45
51
  expect(messages[0].errorCount).toEqual(0);
46
52
  },