Skip to content

Commit 910aeb6

Browse files
authoredSep 2, 2022
feat!: bump eslint, node and prettier versions, add types support (#508)
1 parent 21d87ab commit 910aeb6

18 files changed

+4559
-3155
lines changed
 

‎.changeset/config.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"$schema": "https://unpkg.com/@changesets/config@1.6.0/schema.json",
2+
"$schema": "https://unpkg.com/@changesets/config/schema.json",
33
"changelog": [
44
"@changesets/changelog-github",
55
{

‎.changeset/old-plants-exist.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'eslint-plugin-prettier': major
3+
---
4+
5+
feat!: bump peer eslint to ">=8.0.0" and node to "^14.18.0 || >=16.0.0"

‎.changeset/orange-eyes-brush.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"eslint-plugin-prettier": major
3+
---
4+
5+
feat!: upgrade to prettier v3

‎.changeset/pre.json

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"mode": "pre",
3+
"tag": "alpha",
4+
"initialVersions": {
5+
"eslint-plugin-prettier": "4.2.2"
6+
},
7+
"changesets": []
8+
}

‎.changeset/quiet-cups-pull.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"eslint-plugin-prettier": minor
3+
---
4+
5+
feat: add typings support

‎.eslintrc.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
"@1stg",
88
"plugin:eslint-plugin/recommended"
99
],
10+
"parserOptions": {
11+
"project": null
12+
},
1013
"rules": {
1114
"eslint-plugin/report-message-format": [
1215
"error",
@@ -28,7 +31,8 @@
2831
{
2932
"files": "test/*.js",
3033
"rules": {
31-
"no-magic-numbers": "off"
34+
"no-magic-numbers": "off",
35+
"unicorn/prefer-top-level-await": "off"
3236
}
3337
}
3438
]

‎.github/FUNDING.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
github:
22
- JounQin
33
- 1stG
4-
- rxts
5-
- unts
4+
- rx-ts
5+
- un-ts
66
patreon: 1stG
77
open_collective: prettier
88
custom:

‎.github/workflows/ci.yml

+3-9
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,14 @@ on:
88

99
jobs:
1010
ci:
11-
name: 'Test: Node ${{ matrix.node-version }} - ESLint ${{ matrix.eslint-version }}'
11+
name: Lint and Test on Node ${{ matrix.node-version }}
1212
runs-on: ubuntu-latest
1313
strategy:
1414
matrix:
15-
eslint-version:
16-
- 7
17-
- 8
1815
node-version:
19-
- 12
2016
- 14
2117
- 16
18+
- 18
2219

2320
steps:
2421
- uses: actions/checkout@v3
@@ -29,11 +26,8 @@ jobs:
2926
node-version: ${{ matrix.node-version }}
3027
cache: yarn
3128

32-
- name: Use ESLint ${{ matrix.eslint-version }}
33-
run: yarn upgrade eslint@${{ matrix.eslint-version }} --ignore-engines
34-
3529
- name: Install
36-
run: yarn --frozen-lockfile --ignore-engines
30+
run: yarn --frozen-lockfile
3731

3832
- name: Test
3933
run: yarn mocha

‎.remarkrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"plugins": [
3-
"@1stg/remark-config"
3+
"@1stg/preset"
44
]
55
}

‎README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ If you’re fixing large of amounts of previously unformatted code, consider tem
139139

140140
- An object with the following options
141141

142-
- `usePrettierrc`: Enables loading of the Prettier configuration file, (default: `true`). May be useful if you are using multiple tools that conflict with each other, or do not wish to mix your ESLint settings with your Prettier configuration.
142+
- `usePrettierrc`: Enables loading of the Prettier configuration file, (default: `true`). May be useful if you are using multiple tools that conflict with each other, or do not wish to mix your ESLint settings with your Prettier configuration. And also, it is possible to run prettier without loading the prettierrc config file [via the CLI's --no-config option](https://prettier.io/docs/en/cli.html#--no-config) or through the API by [calling prettier.format() without passing through the options generated by calling resolveConfig](https://prettier.io/docs/en/api.html#prettierresolveconfigfilepath--options).
143143

144144
```json
145145
{

‎eslint-plugin-prettier.d.ts

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { ESLint } from 'eslint';
2+
3+
declare const eslintPluginPrettier: ESLint.Plugin;
4+
5+
export = eslintPluginPrettier;

‎eslint-plugin-prettier.js

+57-132
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@
33
* @author Andres Suarez
44
*/
55

6+
// @ts-check
7+
8+
/**
9+
* @typedef {import('eslint').AST.Range} Range
10+
* @typedef {import('eslint').AST.SourceLocation} SourceLocation
11+
* @typedef {import('eslint').ESLint.Plugin} Plugin
12+
* @typedef {import('prettier').FileInfoOptions} FileInfoOptions
13+
* @typedef {import('prettier').Options & { onDiskFilepath: string, parserPath: string, usePrettierrc?: boolean }} Options
14+
*/
15+
616
'use strict';
717

818
// ------------------------------------------------------------------------------
@@ -26,9 +36,9 @@ const { INSERT, DELETE, REPLACE } = generateDifferences;
2636

2737
// Lazily-loaded Prettier.
2838
/**
29-
* @type {import('prettier')}
39+
* @type {(source: string, options: Options, fileInfoOptions: FileInfoOptions) => string}
3040
*/
31-
let prettier;
41+
let prettierFormat;
3242

3343
// ------------------------------------------------------------------------------
3444
// Rule Definition
@@ -43,7 +53,7 @@ let prettier;
4353
*/
4454
function reportDifference(context, difference) {
4555
const { operation, offset, deleteText = '', insertText = '' } = difference;
46-
const range = [offset, offset + deleteText.length];
56+
const range = /** @type {Range} */ ([offset, offset + deleteText.length]);
4757
const [start, end] = range.map(index =>
4858
context.getSourceCode().getLocFromIndex(index),
4959
);
@@ -63,7 +73,10 @@ function reportDifference(context, difference) {
6373
// Module Definition
6474
// ------------------------------------------------------------------------------
6575

66-
module.exports = {
76+
/**
77+
* @type {Plugin}
78+
*/
79+
const eslintPluginPrettier = {
6780
configs: {
6881
recommended: {
6982
extends: ['prettier'],
@@ -112,7 +125,10 @@ module.exports = {
112125
create(context) {
113126
const usePrettierrc =
114127
!context.options[1] || context.options[1].usePrettierrc !== false;
115-
const eslintFileInfoOptions =
128+
/**
129+
* @type {FileInfoOptions}
130+
*/
131+
const fileInfoOptions =
116132
(context.options[1] && context.options[1].fileInfoOptions) || {};
117133
const sourceCode = context.getSourceCode();
118134
const filepath = context.getFilename();
@@ -125,134 +141,19 @@ module.exports = {
125141
const source = sourceCode.text;
126142

127143
return {
128-
// eslint-disable-next-line sonarjs/cognitive-complexity
129144
Program() {
130-
if (!prettier) {
145+
if (!prettierFormat) {
131146
// Prettier is expensive to load, so only load it if needed.
132-
prettier = require('prettier');
147+
prettierFormat = require('synckit').createSyncFn(
148+
require.resolve('./worker'),
149+
);
133150
}
134151

152+
/**
153+
* @type {{}}
154+
*/
135155
const eslintPrettierOptions = context.options[0] || {};
136156

137-
const prettierRcOptions = usePrettierrc
138-
? prettier.resolveConfig.sync(onDiskFilepath, {
139-
editorconfig: true,
140-
})
141-
: null;
142-
143-
const { ignored, inferredParser } = prettier.getFileInfo.sync(
144-
onDiskFilepath,
145-
{
146-
resolveConfig: false,
147-
withNodeModules: false,
148-
ignorePath: '.prettierignore',
149-
plugins: prettierRcOptions ? prettierRcOptions.plugins : null,
150-
...eslintFileInfoOptions,
151-
},
152-
);
153-
154-
// Skip if file is ignored using a .prettierignore file
155-
if (ignored) {
156-
return;
157-
}
158-
159-
const initialOptions = {};
160-
161-
// ESLint supports processors that let you extract and lint JS
162-
// fragments within a non-JS language. In the cases where prettier
163-
// supports the same language as a processor, we want to process
164-
// the provided source code as javascript (as ESLint provides the
165-
// rules with fragments of JS) instead of guessing the parser
166-
// based off the filename. Otherwise, for instance, on a .md file we
167-
// end up trying to run prettier over a fragment of JS using the
168-
// markdown parser, which throws an error.
169-
// Processors may set virtual filenames for these extracted blocks.
170-
// If they do so then we want to trust the file extension they
171-
// provide, and no override is needed.
172-
// If the processor does not set any virtual filename (signified by
173-
// `filepath` and `onDiskFilepath` being equal) AND we can't
174-
// infer the parser from the filename, either because no filename
175-
// was provided or because there is no parser found for the
176-
// filename, use javascript.
177-
// This is added to the options first, so that
178-
// prettierRcOptions and eslintPrettierOptions can still override
179-
// the parser.
180-
//
181-
// `parserBlocklist` should contain the list of prettier parser
182-
// names for file types where:
183-
// * Prettier supports parsing the file type
184-
// * There is an ESLint processor that extracts JavaScript snippets
185-
// from the file type.
186-
if (filepath === onDiskFilepath) {
187-
// The following list means the plugin process source into js content
188-
// but with same filename, so we need to change the parser to `babel`
189-
// by default.
190-
// Related ESLint plugins are:
191-
// 1. `eslint-plugin-graphql` (replacement: `@graphql-eslint/eslint-plugin`)
192-
// 2. `eslint-plugin-html`
193-
// 3. `eslint-plugin-markdown@1` (replacement: `eslint-plugin-markdown@2+`)
194-
// 4. `eslint-plugin-svelte3` (replacement: `eslint-plugin-svelte@2+`)
195-
const parserBlocklist = [null, 'markdown', 'html'];
196-
197-
let inferParserToBabel = parserBlocklist.includes(inferredParser);
198-
199-
switch (inferredParser) {
200-
// it could be processed by `@graphql-eslint/eslint-plugin` or `eslint-plugin-graphql`
201-
case 'graphql': {
202-
if (
203-
// for `eslint-plugin-graphql`, see https://github.com/apollographql/eslint-plugin-graphql/blob/master/src/index.js#L416
204-
source.startsWith('ESLintPluginGraphQLFile`')
205-
) {
206-
inferParserToBabel = true;
207-
}
208-
break;
209-
}
210-
// it could be processed by `@ota-meshi/eslint-plugin-svelte`, `eslint-plugin-svelte` or `eslint-plugin-svelte3`
211-
case 'svelte': {
212-
// The `source` would be modified by `eslint-plugin-svelte3`
213-
if (!context.parserPath.includes('svelte-eslint-parser')) {
214-
// We do not support `eslint-plugin-svelte3`,
215-
// the users should run `prettier` on `.svelte` files manually
216-
return;
217-
}
218-
}
219-
}
220-
221-
if (inferParserToBabel) {
222-
initialOptions.parser = 'babel';
223-
}
224-
} else {
225-
// Similar to https://github.com/prettier/stylelint-prettier/pull/22
226-
// In all of the following cases ESLint extracts a part of a file to
227-
// be formatted and there exists a prettier parser for the whole file.
228-
// If you're interested in prettier you'll want a fully formatted file so
229-
// you're about to run prettier over the whole file anyway.
230-
// Therefore running prettier over just the style section is wasteful, so
231-
// skip it.
232-
const parserBlocklist = [
233-
'babel',
234-
'babylon',
235-
'flow',
236-
'typescript',
237-
'vue',
238-
'markdown',
239-
'html',
240-
'mdx',
241-
'angular',
242-
'svelte',
243-
];
244-
if (parserBlocklist.includes(inferredParser)) {
245-
return;
246-
}
247-
}
248-
249-
const prettierOptions = {
250-
...initialOptions,
251-
...prettierRcOptions,
252-
...eslintPrettierOptions,
253-
filepath,
254-
};
255-
256157
// prettier.format() may throw a SyntaxError if it cannot parse the
257158
// source code it is given. Usually for JS files this isn't a
258159
// problem as ESLint will report invalid syntax before trying to
@@ -261,29 +162,51 @@ module.exports = {
261162
// files throw an error if they contain unclosed elements, such as
262163
// `<template><div></template>. In this case report an error at the
263164
// point at which parsing failed.
165+
/**
166+
* @type {string}
167+
*/
264168
let prettierSource;
265169
try {
266-
prettierSource = prettier.format(source, prettierOptions);
170+
prettierSource = prettierFormat(
171+
source,
172+
{
173+
...eslintPrettierOptions,
174+
filepath,
175+
onDiskFilepath,
176+
parserPath: context.parserPath,
177+
usePrettierrc,
178+
},
179+
fileInfoOptions,
180+
);
267181
} catch (err) {
268182
if (!(err instanceof SyntaxError)) {
269183
throw err;
270184
}
271185

272186
let message = 'Parsing error: ' + err.message;
273187

188+
const error =
189+
/** @type {SyntaxError & {codeFrame: string; loc: SourceLocation}} */ (
190+
err
191+
);
192+
274193
// Prettier's message contains a codeframe style preview of the
275194
// invalid code and the line/column at which the error occurred.
276195
// ESLint shows those pieces of information elsewhere already so
277196
// remove them from the message
278-
if (err.codeFrame) {
279-
message = message.replace(`\n${err.codeFrame}`, '');
197+
if (error.codeFrame) {
198+
message = message.replace(`\n${error.codeFrame}`, '');
280199
}
281-
if (err.loc) {
200+
if (error.loc) {
282201
message = message.replace(/ \(\d+:\d+\)$/, '');
283202
}
284203

285-
context.report({ message, loc: err.loc });
204+
context.report({ message, loc: error.loc });
205+
206+
return;
207+
}
286208

209+
if (prettierSource == null) {
287210
return;
288211
}
289212

@@ -300,3 +223,5 @@ module.exports = {
300223
},
301224
},
302225
};
226+
227+
module.exports = eslintPluginPrettier;

‎package.json

+31-55
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,20 @@
44
"description": "Runs prettier as an eslint rule",
55
"repository": "git+https://github.com/prettier/eslint-plugin-prettier.git",
66
"homepage": "https://github.com/prettier/eslint-plugin-prettier#readme",
7-
"funding": "https://opencollective.com/prettier",
87
"author": "Teddy Katz",
98
"contributors": [
109
"JounQin (https://github.com/JounQin) <admin@1stg.me>"
1110
],
11+
"funding": "https://opencollective.com/prettier",
1212
"license": "MIT",
13+
"packageManager": "yarn@1.22.19",
1314
"engines": {
14-
"node": ">=12.0.0"
15+
"node": "^14.18.0 || >=16.0.0"
1516
},
1617
"main": "eslint-plugin-prettier.js",
18+
"types": "eslint-plugin-prettier.d.ts",
1719
"files": [
20+
"eslint-plugin-prettier.d.ts",
1821
"eslint-plugin-prettier.js"
1922
],
2023
"keywords": [
@@ -26,16 +29,20 @@
2629
"scripts": {
2730
"format": "yarn prettier '**/*.{js,json,md,yml}' --write && yarn lint --fix",
2831
"lint": "eslint . --cache -f friendly --max-warnings 10",
29-
"prepare": "patch-package && simple-git-hooks && yarn-deduplicate --strategy fewer || exit 0",
32+
"prepare": "simple-git-hooks && yarn-deduplicate --strategy fewer || exit 0",
3033
"prerelease": "yarn format && yarn test",
3134
"release": "changeset publish",
3235
"test": "yarn lint && mocha"
3336
},
3437
"peerDependencies": {
35-
"eslint": ">=7.28.0",
36-
"prettier": ">=2.0.0"
38+
"@types/eslint": ">=8.0.0",
39+
"eslint": ">=8.0.0",
40+
"prettier": ">=3.0.0"
3741
},
3842
"peerDependenciesMeta": {
43+
"@types/eslint": {
44+
"optional": true
45+
},
3946
"eslint-config-prettier": {
4047
"optional": true
4148
}
@@ -44,60 +51,29 @@
4451
"prettier-linter-helpers": "^1.0.0"
4552
},
4653
"devDependencies": {
47-
"@1stg/common-config": "~3.0.0",
48-
"@1stg/eslint-config": "~3.0.0",
49-
"@changesets/changelog-github": "^0.4.5",
50-
"@changesets/cli": "^2.23.1",
51-
"@graphql-eslint/eslint-plugin": "^2.5.0",
52-
"@typescript-eslint/parser": "^5.30.5",
54+
"@1stg/common-config": "^7.1.1",
55+
"@changesets/changelog-github": "^0.4.6",
56+
"@changesets/cli": "^2.24.4",
57+
"@graphql-eslint/eslint-plugin": "^3.10.7",
58+
"@types/eslint": "^8.4.6",
59+
"@types/prettier": "^2.7.0",
60+
"@types/prettier-linter-helpers": "^1.0.1",
61+
"@typescript-eslint/parser": "^5.36.1",
5362
"eslint-config-prettier": "^8.5.0",
54-
"eslint-mdx": "^1.17.1",
55-
"eslint-plugin-eslint-plugin": "^4.4.0",
56-
"eslint-plugin-mdx": "^1.17.1",
63+
"eslint-mdx": "^2.0.2",
64+
"eslint-plugin-eslint-plugin": "^5.0.6",
65+
"eslint-plugin-mdx": "^2.0.2",
5766
"eslint-plugin-self": "^1.2.1",
58-
"eslint-plugin-svelte": "~2.1.0",
59-
"eslint-plugin-utils": "^0.1.0",
60-
"graphql": "^16.5.0",
61-
"mocha": "^9.2.2",
62-
"patch-package": "^6.4.7",
67+
"eslint-plugin-svelte": "^2.7.0",
68+
"eslint-plugin-svelte3": "^4.0.0",
69+
"graphql": "^16.6.0",
70+
"mocha": "^10.0.0",
6371
"svelte": "^3.49.0",
64-
"vue-eslint-parser": "^8.3.0"
72+
"vue-eslint-parser": "^9.0.3",
73+
"yarn-deduplicate": "^6.0.0"
6574
},
6675
"resolutions": {
67-
"@babel/traverse": "^7.18.5",
6876
"eslint-plugin-prettier": "link:.",
69-
"prettier": "^2.7.1"
70-
},
71-
"donate": {
72-
"recipients": [
73-
{
74-
"name": "unts",
75-
"platform": "opencollective",
76-
"address": "https://opencollective.com/unts",
77-
"weight": 60
78-
},
79-
{
80-
"name": "rxts",
81-
"platform": "opencollective",
82-
"address": "https://opencollective.com/rxts",
83-
"weight": 20
84-
},
85-
{
86-
"name": "1stG",
87-
"email": "i@1stg.me",
88-
"weight": 20,
89-
"platforms": [
90-
{
91-
"platform": "opencollective",
92-
"address": "https://opencollective.com/1stG"
93-
},
94-
{
95-
"platform": "patreon",
96-
"address": "https://www.patreon.com/1stG"
97-
}
98-
]
99-
}
100-
]
101-
},
102-
"packageManager": "yarn@1.22.19"
77+
"prettier": "^3.0.0-alpha.0"
78+
}
10379
}

‎patches/@1stg+lint-staged+1.7.5.patch

-13
This file was deleted.

‎patches/@pkgr+utils+2.2.0.patch

-21
This file was deleted.

‎test/prettier.js

+12-9
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
// Requirements
1515
// ------------------------------------------------------------------------------
1616

17-
const assert = require('assert');
18-
const fs = require('fs');
19-
const path = require('path');
17+
const assert = require('node:assert');
18+
const fs = require('node:fs');
19+
const path = require('node:path');
2020

2121
const { ESLint, RuleTester } = require('eslint');
2222

@@ -31,7 +31,7 @@ const rule = eslintPluginPrettier.rules.prettier;
3131
const eslint = new ESLint({
3232
baseConfig: {
3333
parserOptions: {
34-
ecmaVersion: 2021,
34+
ecmaVersion: 'latest',
3535
ecmaFeatures: {
3636
jsx: true,
3737
},
@@ -184,7 +184,9 @@ atGraphqlEslintRuleTester.run('@graphql-eslint/eslint-plugin', rule, {
184184
// `newRuleTester({processor: require('eslint-plugin-graphql').processor['.graphql']})
185185
// and then pass in pure graphql into the code value.
186186
const eslintPluginGraphqlRuleTester = new RuleTester({
187-
parserOptions: { ecmaVersion: 2015 },
187+
parserOptions: {
188+
ecmaVersion: 'latest',
189+
},
188190
});
189191

190192
eslintPluginGraphqlRuleTester.run('eslint-plugin-graphql', rule, {
@@ -199,7 +201,10 @@ eslintPluginGraphqlRuleTester.run('eslint-plugin-graphql', rule, {
199201

200202
const mdxRuleTester = new RuleTester({
201203
parser: require.resolve('eslint-mdx'),
202-
parserOptions: require('eslint-mdx').DEFAULT_PARSER_OPTIONS,
204+
parserOptions: {
205+
sourceType: 'module',
206+
ecmaVersion: 'latest',
207+
},
203208
});
204209

205210
mdxRuleTester.run('eslint-plugin-mdx', rule, {
@@ -309,9 +314,7 @@ runFixture('eslint-plugin-svelte3/*.svelte', [[], []]);
309314
function loadInvalidFixture(name) {
310315
const filename = path.join(__dirname, 'invalid', name + '.txt');
311316
const src = fs.readFileSync(filename, 'utf8');
312-
const sections = src
313-
.split(/^[A-Z]+:\n/m)
314-
.map(x => x.replace(/(?=\n)\n$/, ''));
317+
const sections = src.split(/^[A-Z]+:\n/m).map(x => x.replace(/\n$/, ''));
315318
const item = {
316319
code: sections[1],
317320
output: sections[2],

‎worker.js

+161
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
// @ts-check
2+
3+
/**
4+
* @typedef {import('prettier').FileInfoOptions} FileInfoOptions
5+
* @typedef {import('prettier').Options & { onDiskFilepath: string, parserPath: string, usePrettierrc?: boolean }} Options
6+
*/
7+
8+
const { runAsWorker } = require('synckit');
9+
10+
/**
11+
* @type {typeof import('prettier')}
12+
*/
13+
let prettier;
14+
15+
runAsWorker(
16+
/**
17+
* @param {string} source - The source code to format.
18+
* @param {Options} options - The prettier options.
19+
* @param {FileInfoOptions} eslintFileInfoOptions - The file info options.
20+
* @returns {Promise<string | undefined>} The formatted source code.
21+
*/
22+
async (
23+
source,
24+
{
25+
filepath,
26+
onDiskFilepath,
27+
parserPath,
28+
usePrettierrc,
29+
...eslintPrettierOptions
30+
},
31+
eslintFileInfoOptions,
32+
// eslint-disable-next-line sonarjs/cognitive-complexity
33+
) => {
34+
if (!prettier) {
35+
prettier = await import('prettier');
36+
}
37+
38+
const prettierRcOptions = usePrettierrc
39+
? await prettier.resolveConfig(onDiskFilepath, {
40+
editorconfig: true,
41+
})
42+
: null;
43+
44+
const { ignored, inferredParser } = await prettier.getFileInfo(
45+
onDiskFilepath,
46+
{
47+
resolveConfig: false,
48+
withNodeModules: false,
49+
ignorePath: '.prettierignore',
50+
plugins: /** @type {string[] | undefined} */ (
51+
prettierRcOptions ? prettierRcOptions.plugins : null
52+
),
53+
...eslintFileInfoOptions,
54+
},
55+
);
56+
57+
// Skip if file is ignored using a .prettierignore file
58+
if (ignored) {
59+
return;
60+
}
61+
62+
const initialOptions = {};
63+
64+
// ESLint supports processors that let you extract and lint JS
65+
// fragments within a non-JS language. In the cases where prettier
66+
// supports the same language as a processor, we want to process
67+
// the provided source code as javascript (as ESLint provides the
68+
// rules with fragments of JS) instead of guessing the parser
69+
// based off the filename. Otherwise, for instance, on a .md file we
70+
// end up trying to run prettier over a fragment of JS using the
71+
// markdown parser, which throws an error.
72+
// Processors may set virtual filenames for these extracted blocks.
73+
// If they do so then we want to trust the file extension they
74+
// provide, and no override is needed.
75+
// If the processor does not set any virtual filename (signified by
76+
// `filepath` and `onDiskFilepath` being equal) AND we can't
77+
// infer the parser from the filename, either because no filename
78+
// was provided or because there is no parser found for the
79+
// filename, use javascript.
80+
// This is added to the options first, so that
81+
// prettierRcOptions and eslintPrettierOptions can still override
82+
// the parser.
83+
//
84+
// `parserBlocklist` should contain the list of prettier parser
85+
// names for file types where:
86+
// * Prettier supports parsing the file type
87+
// * There is an ESLint processor that extracts JavaScript snippets
88+
// from the file type.
89+
if (filepath === onDiskFilepath) {
90+
// The following list means the plugin process source into js content
91+
// but with same filename, so we need to change the parser to `babel`
92+
// by default.
93+
// Related ESLint plugins are:
94+
// 1. `eslint-plugin-graphql` (replacement: `@graphql-eslint/eslint-plugin`)
95+
// 2. `eslint-plugin-html`
96+
// 3. `eslint-plugin-markdown@1` (replacement: `eslint-plugin-markdown@2+`)
97+
// 4. `eslint-plugin-svelte3` (replacement: `eslint-plugin-svelte@2+`)
98+
const parserBlocklist = [null, 'markdown', 'html'];
99+
100+
let inferParserToBabel = parserBlocklist.includes(inferredParser);
101+
102+
switch (inferredParser) {
103+
// it could be processed by `@graphql-eslint/eslint-plugin` or `eslint-plugin-graphql`
104+
case 'graphql': {
105+
if (
106+
// for `eslint-plugin-graphql`, see https://github.com/apollographql/eslint-plugin-graphql/blob/master/src/index.js#L416
107+
source.startsWith('ESLintPluginGraphQLFile`')
108+
) {
109+
inferParserToBabel = true;
110+
}
111+
break;
112+
}
113+
// it could be processed by `@ota-meshi/eslint-plugin-svelte`, `eslint-plugin-svelte` or `eslint-plugin-svelte3`
114+
case 'svelte': {
115+
// The `source` would be modified by `eslint-plugin-svelte3`
116+
if (!parserPath.includes('svelte-eslint-parser')) {
117+
// We do not support `eslint-plugin-svelte3`,
118+
// the users should run `prettier` on `.svelte` files manually
119+
return;
120+
}
121+
}
122+
}
123+
124+
if (inferParserToBabel) {
125+
initialOptions.parser = 'babel';
126+
}
127+
} else {
128+
// Similar to https://github.com/prettier/stylelint-prettier/pull/22
129+
// In all of the following cases ESLint extracts a part of a file to
130+
// be formatted and there exists a prettier parser for the whole file.
131+
// If you're interested in prettier you'll want a fully formatted file so
132+
// you're about to run prettier over the whole file anyway.
133+
// Therefore running prettier over just the style section is wasteful, so
134+
// skip it.
135+
const parserBlocklist = [
136+
'babel',
137+
'babylon',
138+
'flow',
139+
'typescript',
140+
'vue',
141+
'markdown',
142+
'html',
143+
'mdx',
144+
'angular',
145+
'svelte',
146+
];
147+
if (parserBlocklist.includes(/** @type {string} */ (inferredParser))) {
148+
return;
149+
}
150+
}
151+
152+
const prettierOptions = {
153+
...initialOptions,
154+
...prettierRcOptions,
155+
...eslintPrettierOptions,
156+
filepath,
157+
};
158+
159+
return prettier.format(source, prettierOptions);
160+
},
161+
);

‎yarn.lock

+4,257-2,910
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.