]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * IMPORTANT! | |
3 | * | |
4 | * Any changes made to this file must also be made to eslint.config.js. | |
5 | * | |
6 | * Internally, ESLint is using the eslint.config.js file to lint itself. | |
7 | * This file is needed too, because: | |
8 | * | |
9 | * 1. There are tests that expect .eslintrc.js to be present to actually run. | |
10 | * 2. ESLint VS Code extension expects eslintrc config files to be | |
11 | * present to work correctly. | |
12 | * | |
13 | * Once we no longer need to support both eslintrc and flat config, we will | |
14 | * remove this file. | |
15 | */ | |
16 | ||
17 | ||
18 | "use strict"; | |
19 | ||
20 | const path = require("path"); | |
21 | ||
22 | const INTERNAL_FILES = { | |
23 | CLI_ENGINE_PATTERN: "lib/cli-engine/**/*", | |
24 | LINTER_PATTERN: "lib/linter/**/*", | |
25 | RULE_TESTER_PATTERN: "lib/rule-tester/**/*", | |
26 | RULES_PATTERN: "lib/rules/**/*", | |
27 | SOURCE_CODE_PATTERN: "lib/source-code/**/*" | |
28 | }; | |
29 | ||
30 | /** | |
31 | * Resolve an absolute path or glob pattern. | |
32 | * @param {string} pathOrPattern the path or glob pattern. | |
33 | * @returns {string} The resolved path or glob pattern. | |
34 | */ | |
35 | function resolveAbsolutePath(pathOrPattern) { | |
36 | return path.resolve(__dirname, pathOrPattern); | |
37 | } | |
38 | ||
39 | /** | |
40 | * Create an array of `no-restricted-require` entries for ESLint's core files. | |
41 | * @param {string} [pattern] The glob pattern to create the entries for. | |
42 | * @returns {Object[]} The array of `no-restricted-require` entries. | |
43 | */ | |
44 | function createInternalFilesPatterns(pattern = null) { | |
45 | return Object.values(INTERNAL_FILES) | |
46 | .filter(p => p !== pattern) | |
47 | .map(p => ({ | |
48 | name: [ | |
49 | ||
50 | // Disallow all children modules. | |
51 | resolveAbsolutePath(p), | |
52 | ||
53 | // Allow the main `index.js` module. | |
54 | `!${resolveAbsolutePath(p.replace(/\*\*\/\*$/u, "index.js"))}` | |
55 | ] | |
56 | })); | |
57 | } | |
58 | ||
59 | module.exports = { | |
60 | root: true, | |
61 | plugins: [ | |
62 | "eslint-plugin", | |
63 | "internal-rules" | |
64 | ], | |
65 | extends: [ | |
66 | "eslint" | |
67 | ], | |
68 | parserOptions: { | |
69 | ecmaVersion: 2021 | |
70 | }, | |
71 | ||
72 | /* | |
73 | * it fixes eslint-plugin-jsdoc's reports: "Invalid JSDoc tag name "template" jsdoc/check-tag-names" | |
74 | * refs: https://github.com/gajus/eslint-plugin-jsdoc#check-tag-names | |
75 | */ | |
76 | settings: { | |
77 | jsdoc: { | |
78 | mode: "typescript" | |
79 | } | |
80 | }, | |
81 | rules: { | |
82 | "internal-rules/multiline-comment-style": "error" | |
83 | }, | |
84 | overrides: [ | |
85 | { | |
86 | files: ["tools/*.js"], | |
87 | rules: { | |
88 | "no-console": "off" | |
89 | } | |
90 | }, | |
91 | { | |
92 | files: ["lib/rules/*", "tools/internal-rules/*"], | |
93 | excludedFiles: ["index.js"], | |
94 | extends: [ | |
95 | "plugin:eslint-plugin/rules-recommended" | |
96 | ], | |
97 | rules: { | |
98 | "eslint-plugin/no-missing-message-ids": "error", | |
99 | "eslint-plugin/no-unused-message-ids": "error", | |
100 | "eslint-plugin/prefer-message-ids": "error", | |
101 | "eslint-plugin/prefer-placeholders": "error", | |
102 | "eslint-plugin/prefer-replace-text": "error", | |
103 | "eslint-plugin/report-message-format": ["error", "[^a-z].*\\.$"], | |
104 | "eslint-plugin/require-meta-docs-description": ["error", { pattern: "^(Enforce|Require|Disallow)" }], | |
105 | "internal-rules/no-invalid-meta": "error" | |
106 | } | |
107 | }, | |
108 | { | |
109 | files: ["lib/rules/*"], | |
110 | excludedFiles: ["index.js"], | |
111 | rules: { | |
112 | "eslint-plugin/require-meta-docs-url": ["error", { pattern: "https://eslint.org/docs/rules/{{name}}" }] | |
113 | } | |
114 | }, | |
115 | { | |
116 | files: ["tests/lib/rules/*", "tests/tools/internal-rules/*"], | |
117 | extends: [ | |
118 | "plugin:eslint-plugin/tests-recommended" | |
119 | ], | |
120 | rules: { | |
121 | "eslint-plugin/prefer-output-null": "error", | |
122 | "eslint-plugin/test-case-property-ordering": "error", | |
123 | "eslint-plugin/test-case-shorthand-strings": "error" | |
124 | } | |
125 | }, | |
126 | { | |
127 | files: ["tests/**/*"], | |
128 | env: { mocha: true }, | |
129 | rules: { | |
130 | "no-restricted-syntax": ["error", { | |
131 | selector: "CallExpression[callee.object.name='assert'][callee.property.name='doesNotThrow']", | |
132 | message: "`assert.doesNotThrow()` should be replaced with a comment next to the code." | |
133 | }] | |
134 | } | |
135 | }, | |
136 | ||
137 | // Restrict relative path imports | |
138 | { | |
139 | files: ["lib/*"], | |
140 | excludedFiles: ["lib/unsupported-api.js"], | |
141 | rules: { | |
142 | "n/no-restricted-require": ["error", [ | |
143 | ...createInternalFilesPatterns() | |
144 | ]] | |
145 | } | |
146 | }, | |
147 | { | |
148 | files: [INTERNAL_FILES.CLI_ENGINE_PATTERN], | |
149 | rules: { | |
150 | "n/no-restricted-require": ["error", [ | |
151 | ...createInternalFilesPatterns(INTERNAL_FILES.CLI_ENGINE_PATTERN) | |
152 | ]] | |
153 | } | |
154 | }, | |
155 | { | |
156 | files: [INTERNAL_FILES.LINTER_PATTERN], | |
157 | rules: { | |
158 | "n/no-restricted-require": ["error", [ | |
159 | ...createInternalFilesPatterns(INTERNAL_FILES.LINTER_PATTERN), | |
160 | "fs", | |
161 | resolveAbsolutePath("lib/cli-engine/index.js"), | |
162 | resolveAbsolutePath("lib/rule-tester/index.js") | |
163 | ]] | |
164 | } | |
165 | }, | |
166 | { | |
167 | files: [INTERNAL_FILES.RULES_PATTERN], | |
168 | rules: { | |
169 | "n/no-restricted-require": ["error", [ | |
170 | ...createInternalFilesPatterns(INTERNAL_FILES.RULES_PATTERN), | |
171 | "fs", | |
172 | resolveAbsolutePath("lib/cli-engine/index.js"), | |
173 | resolveAbsolutePath("lib/linter/index.js"), | |
174 | resolveAbsolutePath("lib/rule-tester/index.js"), | |
175 | resolveAbsolutePath("lib/source-code/index.js") | |
176 | ]] | |
177 | } | |
178 | }, | |
179 | { | |
180 | files: ["lib/shared/**/*"], | |
181 | rules: { | |
182 | "n/no-restricted-require": ["error", [ | |
183 | ...createInternalFilesPatterns(), | |
184 | resolveAbsolutePath("lib/cli-engine/index.js"), | |
185 | resolveAbsolutePath("lib/linter/index.js"), | |
186 | resolveAbsolutePath("lib/rule-tester/index.js"), | |
187 | resolveAbsolutePath("lib/source-code/index.js") | |
188 | ]] | |
189 | } | |
190 | }, | |
191 | { | |
192 | files: [INTERNAL_FILES.SOURCE_CODE_PATTERN], | |
193 | rules: { | |
194 | "n/no-restricted-require": ["error", [ | |
195 | ...createInternalFilesPatterns(INTERNAL_FILES.SOURCE_CODE_PATTERN), | |
196 | "fs", | |
197 | resolveAbsolutePath("lib/cli-engine/index.js"), | |
198 | resolveAbsolutePath("lib/linter/index.js"), | |
199 | resolveAbsolutePath("lib/rule-tester/index.js"), | |
200 | resolveAbsolutePath("lib/rules/index.js") | |
201 | ]] | |
202 | } | |
203 | }, | |
204 | { | |
205 | files: [INTERNAL_FILES.RULE_TESTER_PATTERN], | |
206 | rules: { | |
207 | "n/no-restricted-require": ["error", [ | |
208 | ...createInternalFilesPatterns(INTERNAL_FILES.RULE_TESTER_PATTERN), | |
209 | resolveAbsolutePath("lib/cli-engine/index.js") | |
210 | ]] | |
211 | } | |
212 | } | |
213 | ] | |
214 | }; |