eslint-plugin-oxfmt 0.4.0 → 0.5.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 +26 -1
- package/dist/index.d.mts +3 -1
- package/dist/index.mjs +19 -9
- package/package.json +11 -10
- package/workers/oxfmt.mjs +150 -80
package/README.md
CHANGED
|
@@ -55,6 +55,22 @@ export default [
|
|
|
55
55
|
]
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
+
`recommended` includes `eslint-parser-plain` as `languageOptions.parser` for convenience.
|
|
59
|
+
|
|
60
|
+
If you need parser-agnostic composition (for example to keep `jsonc-eslint-parser` from another config), use the dedicated preset:
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
// eslint.config.mjs
|
|
64
|
+
import pluginOxfmt from 'eslint-plugin-oxfmt'
|
|
65
|
+
|
|
66
|
+
export default [
|
|
67
|
+
{
|
|
68
|
+
...pluginOxfmt.configs.recommendedWithoutParser,
|
|
69
|
+
files: ['**/*.{js,ts,mjs,cjs,jsx,tsx,json,jsonc}'],
|
|
70
|
+
},
|
|
71
|
+
]
|
|
72
|
+
```
|
|
73
|
+
|
|
58
74
|
### Custom Configuration
|
|
59
75
|
|
|
60
76
|
You can customize the formatting options by configuring the rule:
|
|
@@ -156,7 +172,9 @@ When `useConfig` is `true`, the plugin loads config using `load-oxfmt-config`.
|
|
|
156
172
|
- Config discovery order (from `cwd`, walking upward): `.oxfmtrc.json` → `.oxfmtrc.jsonc` → `oxfmt.config.ts`
|
|
157
173
|
- `.editorconfig` support: nearest `.editorconfig` (including section overrides) is merged into the final options
|
|
158
174
|
- `configPath` overrides discovery and directly targets the specified config file
|
|
159
|
-
- ESLint rule options generally take highest priority because inline rule options are merged after loaded config.
|
|
175
|
+
- ESLint rule options generally take highest priority because inline rule options are merged after loaded config.
|
|
176
|
+
- When `useConfig` is `true`, rule-level `overrides` are ignored. Only `overrides` loaded from the resolved oxfmt config file are applied.
|
|
177
|
+
- Rule-level `ignorePatterns` still override config-derived `ignorePatterns` when provided.
|
|
160
178
|
|
|
161
179
|
For detailed behavior, see:
|
|
162
180
|
|
|
@@ -365,6 +383,13 @@ This plugin provides a single rule that formats your code using oxfmt.
|
|
|
365
383
|
|
|
366
384
|
## Integration
|
|
367
385
|
|
|
386
|
+
### Parser Compatibility
|
|
387
|
+
|
|
388
|
+
- `recommended`: forces `eslint-parser-plain` for matched files
|
|
389
|
+
- `recommendedWithoutParser`: parser-agnostic (safe to compose with language-specific parsers)
|
|
390
|
+
|
|
391
|
+
When composing shareable configs, prefer `recommendedWithoutParser` if parser ownership belongs to another preset.
|
|
392
|
+
|
|
368
393
|
### Format on Save in VS Code
|
|
369
394
|
|
|
370
395
|
Add this to your `.vscode/settings.json`:
|
package/dist/index.d.mts
CHANGED
|
@@ -5,6 +5,7 @@ import { Linter, Rule } from "eslint";
|
|
|
5
5
|
interface PluginOxfmt {
|
|
6
6
|
configs: {
|
|
7
7
|
recommended: Linter.Config<Linter.RulesRecord>;
|
|
8
|
+
recommendedWithoutParser: Linter.Config<Linter.RulesRecord>;
|
|
8
9
|
};
|
|
9
10
|
meta: {
|
|
10
11
|
name: string;
|
|
@@ -30,10 +31,11 @@ declare const rules: {
|
|
|
30
31
|
declare const parserPlain: Linter.Parser;
|
|
31
32
|
//#endregion
|
|
32
33
|
//#region src/configs.d.ts
|
|
34
|
+
declare const recommendedWithoutParser: Linter.Config<Linter.RulesRecord>;
|
|
33
35
|
declare const recommended: Linter.Config<Linter.RulesRecord>;
|
|
34
36
|
declare const configs: PluginOxfmt['configs'];
|
|
35
37
|
//#endregion
|
|
36
38
|
//#region src/index.d.ts
|
|
37
39
|
declare const plugin: PluginOxfmt;
|
|
38
40
|
//#endregion
|
|
39
|
-
export { configs, plugin as default, plugin, meta, parserPlain, recommended, rules };
|
|
41
|
+
export { configs, plugin as default, plugin, meta, parserPlain, recommended, recommendedWithoutParser, rules };
|
package/dist/index.mjs
CHANGED
|
@@ -46,20 +46,29 @@ const meta$1 = {
|
|
|
46
46
|
const parserPlain = dist_exports;
|
|
47
47
|
//#endregion
|
|
48
48
|
//#region src/configs.ts
|
|
49
|
-
const
|
|
50
|
-
name: "oxfmt/recommended",
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
const recommendedWithoutParser = {
|
|
50
|
+
name: "oxfmt/recommended-without-parser",
|
|
51
|
+
plugins: {
|
|
52
|
+
/* v8 ignore start */
|
|
53
|
+
get oxfmt() {
|
|
53
54
|
return plugin;
|
|
54
55
|
} },
|
|
55
56
|
rules: { "oxfmt/oxfmt": "error" }
|
|
56
57
|
};
|
|
57
|
-
const
|
|
58
|
+
const recommended = {
|
|
59
|
+
...recommendedWithoutParser,
|
|
60
|
+
name: "oxfmt/recommended",
|
|
61
|
+
languageOptions: { parser: parserPlain }
|
|
62
|
+
};
|
|
63
|
+
const configs = {
|
|
64
|
+
recommended,
|
|
65
|
+
recommendedWithoutParser
|
|
66
|
+
};
|
|
58
67
|
//#endregion
|
|
59
68
|
//#region src/meta.ts
|
|
60
69
|
const meta = {
|
|
61
70
|
name: "eslint-plugin-oxfmt",
|
|
62
|
-
version: "0.
|
|
71
|
+
version: "0.5.0"
|
|
63
72
|
};
|
|
64
73
|
//#endregion
|
|
65
74
|
//#region src/dir.ts
|
|
@@ -550,9 +559,10 @@ const rules = { oxfmt: {
|
|
|
550
559
|
});
|
|
551
560
|
}
|
|
552
561
|
else reportDifferences(context, sourceText, formatResult.code);
|
|
553
|
-
} catch {
|
|
562
|
+
} catch (err) {
|
|
563
|
+
const details = err instanceof Error ? `: ${err.message}` : "";
|
|
554
564
|
context.report({
|
|
555
|
-
message: `Failed to format file: ${context.filename}`,
|
|
565
|
+
message: `Failed to format file: ${context.filename}${details}`,
|
|
556
566
|
loc: {
|
|
557
567
|
end: {
|
|
558
568
|
column: 0,
|
|
@@ -576,4 +586,4 @@ const plugin = {
|
|
|
576
586
|
rules
|
|
577
587
|
};
|
|
578
588
|
//#endregion
|
|
579
|
-
export { configs, plugin as default, plugin, meta, parserPlain, recommended, rules };
|
|
589
|
+
export { configs, plugin as default, plugin, meta, parserPlain, recommended, recommendedWithoutParser, rules };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-oxfmt",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.5.0",
|
|
5
5
|
"description": "An ESLint plugin for formatting code with oxfmt.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"eslint",
|
|
@@ -48,31 +48,32 @@
|
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"generate-differences": "^0.1.1",
|
|
51
|
-
"load-oxfmt-config": "^0.4.
|
|
51
|
+
"load-oxfmt-config": "^0.4.1",
|
|
52
52
|
"picomatch": "^4.0.4",
|
|
53
53
|
"synckit": "^0.11.12"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@ntnyq/eslint-config": "^6.0
|
|
56
|
+
"@ntnyq/eslint-config": "^6.1.0",
|
|
57
57
|
"@types/json-schema": "^7.0.15",
|
|
58
58
|
"@types/node": "^25.6.0",
|
|
59
|
-
"@typescript/native-preview": "^7.0.0-dev.
|
|
59
|
+
"@typescript/native-preview": "^7.0.0-dev.20260429.1",
|
|
60
60
|
"bumpp": "^11.0.1",
|
|
61
|
-
"eslint": "^10.2.
|
|
61
|
+
"eslint": "^10.2.1",
|
|
62
62
|
"eslint-parser-plain": "^0.1.1",
|
|
63
63
|
"eslint-typegen": "^2.3.1",
|
|
64
64
|
"eslint-vitest-rule-tester": "^3.1.0",
|
|
65
65
|
"husky": "^9.1.7",
|
|
66
|
+
"jsonc-eslint-parser": "^3.1.0",
|
|
66
67
|
"nano-staged": "^1.0.2",
|
|
67
68
|
"npm-run-all2": "^8.0.4",
|
|
68
|
-
"oxfmt": "^0.
|
|
69
|
+
"oxfmt": "^0.47.0",
|
|
69
70
|
"show-invisibles": "^0.0.2",
|
|
70
71
|
"tinyglobby": "^0.2.16",
|
|
71
|
-
"tsdown": "^0.21.
|
|
72
|
+
"tsdown": "^0.21.10",
|
|
72
73
|
"tsx": "^4.21.0",
|
|
73
|
-
"typescript": "^6.0.
|
|
74
|
-
"vitest": "^4.1.
|
|
75
|
-
"eslint-plugin-oxfmt": "0.
|
|
74
|
+
"typescript": "^6.0.3",
|
|
75
|
+
"vitest": "^4.1.5",
|
|
76
|
+
"eslint-plugin-oxfmt": "0.5.0"
|
|
76
77
|
},
|
|
77
78
|
"engines": {
|
|
78
79
|
"node": "^20.19.0 || >=22.12.0"
|
package/workers/oxfmt.mjs
CHANGED
|
@@ -20,9 +20,21 @@ import { runAsWorker } from 'synckit'
|
|
|
20
20
|
* @typedef {import('load-oxfmt-config').OxfmtOptions & PluginOptions} Options
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* @typedef {object} WorkerOptions
|
|
25
|
+
* @property {string} cwd Current working directory for resolving rule-relative inputs.
|
|
26
|
+
* @property {string | undefined} configPath Custom path to an oxfmt configuration file.
|
|
27
|
+
* @property {string[] | undefined} ignorePatterns Rule-level ignore patterns.
|
|
28
|
+
* @property {Override[] | undefined} overrides Rule-level override entries.
|
|
29
|
+
* @property {boolean} useConfig Whether config loading is enabled.
|
|
30
|
+
* @property {import('oxfmt').FormatConfig} formatOptions Pure formatter options passed to oxfmt.
|
|
31
|
+
*/
|
|
32
|
+
|
|
23
33
|
/**
|
|
24
34
|
* @typedef {object} ResolvedBaseOptions
|
|
25
|
-
* @property {import('oxfmt').FormatConfig}
|
|
35
|
+
* @property {import('oxfmt').FormatConfig} formatOptions Resolved base formatter options.
|
|
36
|
+
* @property {string[] | undefined} ignorePatterns Resolved ignore patterns from config loading.
|
|
37
|
+
* @property {Override[] | undefined} overrides Resolved overrides from config loading.
|
|
26
38
|
* @property {string} configDir Directory of the resolved config file, used as base for config-derived glob patterns.
|
|
27
39
|
*/
|
|
28
40
|
|
|
@@ -79,17 +91,14 @@ const picomatchCache = new Map()
|
|
|
79
91
|
|
|
80
92
|
/**
|
|
81
93
|
* Apply overrides to the base options based on the filename
|
|
82
|
-
* @param
|
|
83
|
-
* @param cwd - Base directory for glob matching
|
|
94
|
+
* @param relativePath - The file path relative to the glob base directory
|
|
84
95
|
* @param baseOptions - Base format options
|
|
85
96
|
* @param [overrides] - Override configurations
|
|
86
97
|
* @returns - Merged options
|
|
87
98
|
*/
|
|
88
99
|
function applyOverrides(
|
|
89
100
|
/** @type {string} */
|
|
90
|
-
|
|
91
|
-
/** @type {string} */
|
|
92
|
-
cwd,
|
|
101
|
+
relativePath,
|
|
93
102
|
/** @type {import('oxfmt').FormatConfig} */
|
|
94
103
|
baseOptions,
|
|
95
104
|
/** @type {Override[] | undefined} */
|
|
@@ -99,9 +108,6 @@ function applyOverrides(
|
|
|
99
108
|
return baseOptions
|
|
100
109
|
}
|
|
101
110
|
|
|
102
|
-
// Get relative path from cwd and normalize to forward slashes for cross-platform compatibility
|
|
103
|
-
const relativePath = relative(cwd, filename).replace(/\\/g, '/')
|
|
104
|
-
|
|
105
111
|
let mergedOptions = baseOptions
|
|
106
112
|
let hasOverrides = false
|
|
107
113
|
|
|
@@ -171,48 +177,48 @@ function getConfigPathForFile(
|
|
|
171
177
|
|
|
172
178
|
/**
|
|
173
179
|
* Build cache key for merged options per file invocation.
|
|
174
|
-
* The key includes
|
|
175
|
-
* override inputs to avoid stale cache hits.
|
|
180
|
+
* The key only includes data that can affect the final formatter options.
|
|
176
181
|
*
|
|
177
|
-
* @param filename - Current file path.
|
|
178
|
-
* @param cwd - Base directory used for rule-level glob matching.
|
|
179
|
-
* @param configDir - Directory of the resolved config file, used for config-derived glob matching.
|
|
180
182
|
* @param baseOptions - Resolved base options used for formatting.
|
|
181
|
-
* @param
|
|
183
|
+
* @param relativePath - File path relative to the override base directory.
|
|
182
184
|
* @param overrides - Rule-level override entries.
|
|
183
|
-
* @param useConfig - Whether config file loading is enabled.
|
|
184
185
|
* @returns Serialized cache key.
|
|
185
186
|
*/
|
|
186
187
|
function getMergedOptionsCacheKey(
|
|
187
|
-
/** @type {string} */
|
|
188
|
-
filename,
|
|
189
|
-
/** @type {string} */
|
|
190
|
-
cwd,
|
|
191
|
-
/** @type {string} */
|
|
192
|
-
configDir,
|
|
193
188
|
/** @type {import('oxfmt').FormatConfig} */
|
|
194
189
|
baseOptions,
|
|
195
|
-
/** @type {string
|
|
196
|
-
|
|
190
|
+
/** @type {string | undefined} */
|
|
191
|
+
relativePath,
|
|
197
192
|
/** @type {Override[] | undefined} */
|
|
198
193
|
overrides,
|
|
199
|
-
/** @type {boolean} */
|
|
200
|
-
useConfig,
|
|
201
194
|
) {
|
|
195
|
+
const hasOverrides = !!(overrides && overrides.length > 0)
|
|
196
|
+
|
|
202
197
|
return JSON.stringify(
|
|
203
198
|
{
|
|
204
199
|
baseOptions,
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
filename,
|
|
208
|
-
ignorePatterns,
|
|
209
|
-
overrides,
|
|
210
|
-
useConfig,
|
|
200
|
+
overrides: hasOverrides ? overrides : undefined,
|
|
201
|
+
relativePath: hasOverrides ? relativePath : undefined,
|
|
211
202
|
},
|
|
212
203
|
stableReplacer,
|
|
213
204
|
)
|
|
214
205
|
}
|
|
215
206
|
|
|
207
|
+
/**
|
|
208
|
+
* Normalize a file path relative to the provided base directory.
|
|
209
|
+
* @param baseDir - Base directory used for glob evaluation
|
|
210
|
+
* @param filename - Absolute file path
|
|
211
|
+
* @returns - Normalized relative path using forward slashes
|
|
212
|
+
*/
|
|
213
|
+
function getRelativePath(
|
|
214
|
+
/** @type {string} */
|
|
215
|
+
baseDir,
|
|
216
|
+
/** @type {string} */
|
|
217
|
+
filename,
|
|
218
|
+
) {
|
|
219
|
+
return relative(baseDir, filename).replace(/\\/g, '/')
|
|
220
|
+
}
|
|
221
|
+
|
|
216
222
|
/**
|
|
217
223
|
* Build cache key for resolving base formatter options.
|
|
218
224
|
* The key includes file directory and all resolution inputs.
|
|
@@ -248,6 +254,74 @@ function getResolvedBaseOptionsCacheKey(
|
|
|
248
254
|
)
|
|
249
255
|
}
|
|
250
256
|
|
|
257
|
+
/**
|
|
258
|
+
* Validate and normalize worker invocation options.
|
|
259
|
+
* @param options - Raw worker options
|
|
260
|
+
* @returns - Validated worker options
|
|
261
|
+
*/
|
|
262
|
+
function getWorkerOptions(
|
|
263
|
+
/** @type {Options | undefined} */
|
|
264
|
+
options,
|
|
265
|
+
) {
|
|
266
|
+
if (!options || typeof options !== 'object') {
|
|
267
|
+
throw new TypeError('oxfmt worker expected an options object.')
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const {
|
|
271
|
+
configPath,
|
|
272
|
+
cwd,
|
|
273
|
+
ignorePatterns,
|
|
274
|
+
overrides,
|
|
275
|
+
useConfig = true,
|
|
276
|
+
...formatOptions
|
|
277
|
+
} = options
|
|
278
|
+
|
|
279
|
+
if (typeof cwd !== 'string' || cwd.length === 0) {
|
|
280
|
+
throw new TypeError('oxfmt worker requires a non-empty "cwd" option.')
|
|
281
|
+
}
|
|
282
|
+
if (configPath != null && typeof configPath !== 'string') {
|
|
283
|
+
throw new TypeError(
|
|
284
|
+
'oxfmt worker requires "configPath" to be a string when provided.',
|
|
285
|
+
)
|
|
286
|
+
}
|
|
287
|
+
if (ignorePatterns != null && !isStringArray(ignorePatterns)) {
|
|
288
|
+
throw new TypeError(
|
|
289
|
+
'oxfmt worker requires "ignorePatterns" to be an array of strings when provided.',
|
|
290
|
+
)
|
|
291
|
+
}
|
|
292
|
+
if (overrides != null && !Array.isArray(overrides)) {
|
|
293
|
+
throw new TypeError(
|
|
294
|
+
'oxfmt worker requires "overrides" to be an array when provided.',
|
|
295
|
+
)
|
|
296
|
+
}
|
|
297
|
+
if (typeof useConfig !== 'boolean') {
|
|
298
|
+
throw new TypeError(
|
|
299
|
+
'oxfmt worker requires "useConfig" to be a boolean when provided.',
|
|
300
|
+
)
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return {
|
|
304
|
+
configPath,
|
|
305
|
+
cwd,
|
|
306
|
+
formatOptions,
|
|
307
|
+
ignorePatterns,
|
|
308
|
+
overrides,
|
|
309
|
+
useConfig,
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Check whether a value is an array of strings.
|
|
315
|
+
* @param value - Value to validate
|
|
316
|
+
* @returns - Whether the value is a string array
|
|
317
|
+
*/
|
|
318
|
+
function isStringArray(
|
|
319
|
+
/** @type {unknown} */
|
|
320
|
+
value,
|
|
321
|
+
) {
|
|
322
|
+
return Array.isArray(value) && value.every(item => typeof item === 'string')
|
|
323
|
+
}
|
|
324
|
+
|
|
251
325
|
/**
|
|
252
326
|
* Resolve base formatter options for a file and cache the async result.
|
|
253
327
|
*
|
|
@@ -290,7 +364,9 @@ async function resolveBaseOptions(
|
|
|
290
364
|
if (!useConfig) {
|
|
291
365
|
return {
|
|
292
366
|
configDir: cwd,
|
|
293
|
-
|
|
367
|
+
ignorePatterns: undefined,
|
|
368
|
+
overrides: undefined,
|
|
369
|
+
formatOptions: {
|
|
294
370
|
...formatOptions,
|
|
295
371
|
},
|
|
296
372
|
}
|
|
@@ -306,11 +382,15 @@ async function resolveBaseOptions(
|
|
|
306
382
|
configPath: resolvedConfigPath,
|
|
307
383
|
cwd: resolveFromDir,
|
|
308
384
|
})
|
|
385
|
+
const { ignorePatterns, overrides, ...loadedFormatOptions } =
|
|
386
|
+
configOptions ?? {}
|
|
309
387
|
|
|
310
388
|
return {
|
|
311
389
|
configDir,
|
|
312
|
-
|
|
313
|
-
|
|
390
|
+
ignorePatterns,
|
|
391
|
+
overrides,
|
|
392
|
+
formatOptions: {
|
|
393
|
+
...loadedFormatOptions,
|
|
314
394
|
...formatOptions,
|
|
315
395
|
},
|
|
316
396
|
}
|
|
@@ -329,26 +409,19 @@ async function resolveBaseOptions(
|
|
|
329
409
|
|
|
330
410
|
/**
|
|
331
411
|
* Check if a file should be ignored based on ignorePatterns
|
|
332
|
-
* @param
|
|
333
|
-
* @param cwd - Base directory for glob matching
|
|
412
|
+
* @param relativePath - The file path relative to the glob base directory
|
|
334
413
|
* @param [ignorePatterns] - Ignore patterns
|
|
335
414
|
* @returns - Whether the file should be ignored
|
|
336
415
|
*/
|
|
337
416
|
function shouldIgnoreFile(
|
|
338
417
|
/** @type {string} */
|
|
339
|
-
|
|
340
|
-
/** @type {string} */
|
|
341
|
-
cwd,
|
|
342
|
-
/** @type {string[] | undefined} */
|
|
343
|
-
ignorePatterns,
|
|
418
|
+
relativePath,
|
|
419
|
+
/** @type {string[] | undefined} */ ignorePatterns,
|
|
344
420
|
) {
|
|
345
421
|
if (!ignorePatterns || ignorePatterns.length === 0) {
|
|
346
422
|
return false
|
|
347
423
|
}
|
|
348
424
|
|
|
349
|
-
// Get relative path from cwd and normalize to forward slashes for cross-platform compatibility
|
|
350
|
-
const relativePath = relative(cwd, filename).replace(/\\/g, '/')
|
|
351
|
-
|
|
352
425
|
// Check if file matches any ignore pattern
|
|
353
426
|
return getCachedMatcher(ignorePatterns)(relativePath)
|
|
354
427
|
}
|
|
@@ -371,65 +444,62 @@ runAsWorker(
|
|
|
371
444
|
const {
|
|
372
445
|
configPath,
|
|
373
446
|
cwd,
|
|
447
|
+
formatOptions,
|
|
374
448
|
ignorePatterns,
|
|
375
449
|
overrides,
|
|
376
|
-
useConfig
|
|
377
|
-
|
|
378
|
-
} = options
|
|
450
|
+
useConfig,
|
|
451
|
+
} = getWorkerOptions(options)
|
|
379
452
|
|
|
380
|
-
const {
|
|
453
|
+
const {
|
|
454
|
+
configDir,
|
|
455
|
+
formatOptions: baseFormatOptions,
|
|
456
|
+
ignorePatterns: baseIgnorePatterns,
|
|
457
|
+
overrides: baseOverrides,
|
|
458
|
+
} = await resolveBaseOptions(
|
|
381
459
|
filename,
|
|
382
460
|
cwd,
|
|
383
461
|
configPath,
|
|
384
462
|
useConfig,
|
|
385
463
|
formatOptions,
|
|
386
464
|
)
|
|
387
|
-
|
|
388
|
-
const mergedOptionsCacheKey = getMergedOptionsCacheKey(
|
|
389
|
-
filename,
|
|
390
|
-
cwd,
|
|
391
|
-
configDir,
|
|
392
|
-
baseOptions,
|
|
393
|
-
ignorePatterns,
|
|
394
|
-
overrides,
|
|
395
|
-
useConfig,
|
|
396
|
-
)
|
|
397
|
-
|
|
398
|
-
const baseIgnorePatterns = /** @type {string[] | undefined} */ (
|
|
399
|
-
baseOptions.ignorePatterns
|
|
400
|
-
)
|
|
401
465
|
const effectiveIgnorePatterns = ignorePatterns ?? baseIgnorePatterns
|
|
402
466
|
const ignoreBase = ignorePatterns == null ? configDir : cwd
|
|
403
|
-
|
|
404
|
-
|
|
467
|
+
const ignoreRelativePath = effectiveIgnorePatterns?.length
|
|
468
|
+
? getRelativePath(ignoreBase, filename)
|
|
469
|
+
: undefined
|
|
470
|
+
|
|
471
|
+
if (
|
|
472
|
+
ignoreRelativePath &&
|
|
473
|
+
shouldIgnoreFile(ignoreRelativePath, effectiveIgnorePatterns)
|
|
474
|
+
) {
|
|
405
475
|
return { code: sourceText }
|
|
406
476
|
}
|
|
407
477
|
|
|
478
|
+
const effectiveOverrides = useConfig ? baseOverrides : overrides
|
|
479
|
+
const overrideBase = useConfig ? configDir : cwd
|
|
480
|
+
const overrideRelativePath = effectiveOverrides?.length
|
|
481
|
+
? getRelativePath(overrideBase, filename)
|
|
482
|
+
: undefined
|
|
483
|
+
const mergedOptionsCacheKey = getMergedOptionsCacheKey(
|
|
484
|
+
baseFormatOptions,
|
|
485
|
+
overrideRelativePath,
|
|
486
|
+
effectiveOverrides,
|
|
487
|
+
)
|
|
488
|
+
|
|
408
489
|
const cachedMergedOptions = mergedOptionsCache.get(mergedOptionsCacheKey)
|
|
409
490
|
if (cachedMergedOptions) {
|
|
410
491
|
return format(filename, sourceText, cachedMergedOptions)
|
|
411
492
|
}
|
|
412
493
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
)
|
|
416
|
-
|
|
417
|
-
// Apply config-level overrides (relative to config directory)
|
|
418
|
-
let mergedOptions = baseOptions
|
|
419
|
-
if (useConfig && baseOverrides && baseOverrides.length > 0) {
|
|
494
|
+
let mergedOptions = baseFormatOptions
|
|
495
|
+
if (overrideRelativePath && effectiveOverrides?.length) {
|
|
420
496
|
mergedOptions = applyOverrides(
|
|
421
|
-
|
|
422
|
-
configDir,
|
|
497
|
+
overrideRelativePath,
|
|
423
498
|
mergedOptions,
|
|
424
|
-
|
|
499
|
+
effectiveOverrides,
|
|
425
500
|
)
|
|
426
501
|
}
|
|
427
502
|
|
|
428
|
-
// Apply rule-level overrides (relative to ESLint cwd)
|
|
429
|
-
if (overrides && overrides.length > 0) {
|
|
430
|
-
mergedOptions = applyOverrides(filename, cwd, mergedOptions, overrides)
|
|
431
|
-
}
|
|
432
|
-
|
|
433
503
|
mergedOptionsCache.set(mergedOptionsCacheKey, mergedOptions)
|
|
434
504
|
evictCache(mergedOptionsCache)
|
|
435
505
|
|