├── .gitattributes ├── .github └── workflows │ ├── ci.yml │ └── release.yml ├── .gitignore ├── .npmrc ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── bin └── index.js ├── eslint.config.ts ├── fixtures ├── input │ ├── astro.astro │ ├── css.css │ ├── html.html │ ├── javascript.js │ ├── jsx.jsx │ ├── markdown.md │ ├── svelte.svelte │ ├── svg.svg │ ├── toml.toml │ ├── tsconfig.json │ ├── tsx.tsx │ ├── typescript.ts │ ├── vue-ts.vue │ ├── vue.vue │ └── xml.xml └── output │ ├── all │ ├── astro.astro │ ├── javascript.js │ ├── jsx.jsx │ ├── markdown.md │ ├── svelte.svelte │ ├── toml.toml │ ├── tsx.tsx │ ├── typescript.ts │ ├── vue-ts.vue │ └── vue.vue │ ├── js │ ├── javascript.js │ ├── jsx.jsx │ ├── markdown.md │ ├── toml.toml │ └── tsx.tsx │ ├── no-markdown-with-formatters │ ├── javascript.js │ ├── markdown.md │ ├── toml.toml │ ├── tsx.tsx │ └── typescript.ts │ ├── no-style │ ├── javascript.js │ ├── jsx.jsx │ ├── toml.toml │ ├── typescript.ts │ ├── vue-ts.vue │ └── vue.vue │ ├── tab-double-quotes │ ├── javascript.js │ ├── jsx.jsx │ ├── markdown.md │ ├── toml.toml │ ├── tsconfig.json │ ├── tsx.tsx │ ├── typescript.ts │ ├── vue-ts.vue │ └── vue.vue │ ├── ts-override │ ├── javascript.js │ ├── jsx.jsx │ ├── markdown.md │ ├── toml.toml │ ├── tsx.tsx │ ├── typescript.ts │ ├── vue-ts.vue │ └── vue.vue │ ├── ts-strict-with-react │ ├── javascript.js │ ├── jsx.jsx │ ├── markdown.md │ ├── toml.toml │ ├── tsx.tsx │ ├── typescript.ts │ ├── vue-ts.vue │ └── vue.vue │ ├── ts-strict │ ├── javascript.js │ ├── jsx.jsx │ ├── markdown.md │ ├── toml.toml │ ├── tsx.tsx │ ├── typescript.ts │ ├── vue-ts.vue │ └── vue.vue │ └── with-formatters │ ├── astro.astro │ ├── css.css │ ├── html.html │ ├── javascript.js │ ├── jsx.jsx │ ├── markdown.md │ ├── svg.svg │ ├── toml.toml │ ├── tsx.tsx │ ├── typescript.ts │ ├── vue-ts.vue │ ├── vue.vue │ └── xml.xml ├── netlify.toml ├── package.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── scripts ├── typegen.ts └── versiongen.ts ├── src ├── cli.ts ├── cli │ ├── constants-generated.ts │ ├── constants.ts │ ├── index.ts │ ├── run.ts │ ├── stages │ │ ├── update-eslint-files.ts │ │ ├── update-package-json.ts │ │ └── update-vscode-settings.ts │ ├── types.ts │ └── utils.ts ├── configs │ ├── astro.ts │ ├── command.ts │ ├── comments.ts │ ├── disables.ts │ ├── formatters.ts │ ├── ignores.ts │ ├── imports.ts │ ├── index.ts │ ├── javascript.ts │ ├── jsdoc.ts │ ├── jsonc.ts │ ├── jsx.ts │ ├── markdown.ts │ ├── node.ts │ ├── perfectionist.ts │ ├── pnpm.ts │ ├── react.ts │ ├── regexp.ts │ ├── solid.ts │ ├── sort.ts │ ├── stylistic.ts │ ├── svelte.ts │ ├── test.ts │ ├── toml.ts │ ├── typescript.ts │ ├── unicorn.ts │ ├── unocss.ts │ ├── vue.ts │ └── yaml.ts ├── factory.ts ├── globs.ts ├── index.ts ├── plugins.ts ├── types.ts ├── utils.ts └── vender │ └── prettier-types.ts ├── test ├── cli.spec.ts ├── fixtures.test.ts └── types.ts ├── tsconfig.json ├── tsdown.config.ts └── vitest.config.ts /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.* text eol=lf 3 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | branches: 10 | - main 11 | 12 | jobs: 13 | lint: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v4 17 | 18 | - name: Install pnpm 19 | uses: pnpm/action-setup@v4 20 | 21 | - name: Set node 22 | uses: actions/setup-node@v4 23 | with: 24 | node-version: lts/* 25 | 26 | - name: Setup 27 | run: npm i -g @antfu/ni 28 | 29 | - name: Install 30 | run: nci 31 | 32 | - name: Build 33 | run: nr build 34 | 35 | - name: Lint 36 | run: nr lint 37 | 38 | - name: Typecheck 39 | run: nr typecheck 40 | 41 | test: 42 | runs-on: ${{ matrix.os }} 43 | 44 | strategy: 45 | matrix: 46 | node: [lts/*] 47 | os: [ubuntu-latest, windows-latest, macos-latest] 48 | fail-fast: false 49 | 50 | steps: 51 | - uses: actions/checkout@v4 52 | 53 | - name: Install pnpm 54 | uses: pnpm/action-setup@v4 55 | 56 | - name: Set node ${{ matrix.node }} 57 | uses: actions/setup-node@v4 58 | with: 59 | node-version: ${{ matrix.node }} 60 | 61 | - name: Setup 62 | run: npm i -g @antfu/ni 63 | 64 | - name: Install 65 | run: nci 66 | 67 | - name: Build 68 | run: nr build 69 | 70 | - name: Test 71 | run: nr test 72 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | 8 | jobs: 9 | release: 10 | permissions: 11 | contents: write 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v4 15 | with: 16 | fetch-depth: 0 17 | 18 | - uses: actions/setup-node@v4 19 | with: 20 | node-version: lts/* 21 | 22 | - run: npx changelogithub 23 | env: 24 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Node template 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # Bower dependency directory (https://bower.io/) 29 | bower_components 30 | 31 | # node-waf configuration 32 | .lock-wscript 33 | 34 | # Compiled binary addons (https://nodejs.org/api/addons.html) 35 | build/Release 36 | 37 | # Dependency directories 38 | node_modules/ 39 | jspm_packages/ 40 | 41 | # TypeScript v1 declaration files 42 | typings/ 43 | 44 | # Optional npm cache directory 45 | .npm 46 | 47 | # Optional eslint cache 48 | .eslintcache 49 | 50 | # Optional REPL history 51 | .node_repl_history 52 | 53 | # Output of 'npm pack' 54 | *.tgz 55 | 56 | # Yarn Integrity file 57 | .yarn-integrity 58 | 59 | # dotenv environment variables file 60 | .env 61 | 62 | # parcel-bundler cache (https://parceljs.org/) 63 | .cache 64 | 65 | # next.js build output 66 | .next 67 | 68 | # nuxt.js build output 69 | .nuxt 70 | 71 | # Nuxt generate 72 | dist 73 | 74 | # Serverless directories 75 | .serverless 76 | 77 | # IDE 78 | .idea 79 | 80 | *.lerna_backup 81 | _fixtures 82 | 83 | .temp 84 | .history 85 | 86 | src/typegen.d.ts 87 | .eslint-config-inspector 88 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | strict-peer-dependencies=false 2 | shamefully-hoist=true 3 | ignore-workspace-root-check=true 4 | shell-emulator=true 5 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | // Disable the default formatter, use eslint instead 3 | "prettier.enable": false, 4 | "editor.formatOnSave": false, 5 | 6 | // Auto fix 7 | "editor.codeActionsOnSave": { 8 | "source.fixAll.eslint": "explicit", 9 | "source.organizeImports": "never" 10 | }, 11 | 12 | "eslint.runtime": "node", 13 | 14 | // Silent the stylistic rules in you IDE, but still auto fix them 15 | "eslint.rules.customizations": [ 16 | { "rule": "style/*", "severity": "off", "fixable": true }, 17 | { "rule": "*-indent", "severity": "off", "fixable": true }, 18 | { "rule": "*-spacing", "severity": "off", "fixable": true }, 19 | { "rule": "*-spaces", "severity": "off", "fixable": true }, 20 | { "rule": "*-order", "severity": "off", "fixable": true }, 21 | { "rule": "*-dangle", "severity": "off", "fixable": true }, 22 | { "rule": "*-newline", "severity": "off", "fixable": true }, 23 | { "rule": "*quotes", "severity": "off", "fixable": true }, 24 | { "rule": "*semi", "severity": "off", "fixable": true } 25 | ], 26 | 27 | // Enable eslint for all supported languages 28 | "eslint.validate": [ 29 | "javascript", 30 | "javascriptreact", 31 | "typescript", 32 | "typescriptreact", 33 | "vue", 34 | "html", 35 | "markdown", 36 | "json", 37 | "json5", 38 | "jsonc", 39 | "yaml", 40 | "toml", 41 | "xml" 42 | ], 43 | 44 | "pair-diff.patterns": [ 45 | { 46 | "source": "./fixtures/output/**/*.*", 47 | "target": "./fixtures/input/" 48 | } 49 | ] 50 | } 51 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-PRESENT Anthony Fu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /bin/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import '../dist/cli.js' 3 | -------------------------------------------------------------------------------- /eslint.config.ts: -------------------------------------------------------------------------------- 1 | import styleMigrate from '@stylistic/eslint-plugin-migrate' 2 | 3 | import { antfu } from './src' 4 | 5 | export default antfu( 6 | { 7 | vue: { 8 | a11y: true, 9 | }, 10 | react: true, 11 | solid: true, 12 | svelte: true, 13 | astro: true, 14 | typescript: true, 15 | formatters: true, 16 | pnpm: true, 17 | type: 'lib', 18 | }, 19 | { 20 | ignores: [ 21 | 'fixtures', 22 | '_fixtures', 23 | '**/constants-generated.ts', 24 | ], 25 | }, 26 | { 27 | files: ['src/**/*.ts'], 28 | rules: { 29 | 'perfectionist/sort-objects': 'error', 30 | }, 31 | }, 32 | { 33 | files: ['src/configs/*.ts'], 34 | plugins: { 35 | 'style-migrate': styleMigrate, 36 | }, 37 | rules: { 38 | 'style-migrate/migrate': ['error', { namespaceTo: 'style' }], 39 | }, 40 | }, 41 | ) 42 | -------------------------------------------------------------------------------- /fixtures/input/astro.astro: -------------------------------------------------------------------------------- 1 | --- 2 | const isJsx = true 3 | const content = "hi!"; 4 | --- 5 | 6 |
7 |
{content}
8 |
9 | {isJsx && ( 10 |

{content}

11 | )} 12 |
13 |
14 | 15 | 16 | 22 | -------------------------------------------------------------------------------- /fixtures/input/css.css: -------------------------------------------------------------------------------- 1 | @media (max-width: 480px) { 2 | .bd-examples {margin-right: -.75rem;margin-left: -.75rem 3 | } 4 | 5 | .bd-examples>[class^="col-"] { 6 | padding-right: .75rem; 7 | padding-left: .75rem; 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /fixtures/input/html.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | My tITlE 6 | 7 | 8 | 9 |

Hello world!
This is HTML5 Boilerplate.

10 | 14 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /fixtures/input/javascript.js: -------------------------------------------------------------------------------- 1 | // This file is generated by ChatGPT 2 | 3 | // eslint-disable-next-line no-console 4 | var log = console.log 5 | 6 | // Define a class using ES6 class syntax 7 | class Person { 8 | constructor(name, age) { 9 | this.name = name; 10 | this.age = age; 11 | } 12 | 13 | // Define a method within the class 14 | sayHello() { 15 | log(`Hello, my name is ${this.name} and I am ${this.age} years old.`); 16 | } 17 | } 18 | 19 | // Create an array of objects 20 | const people = [ 21 | new Person('Alice', 30), 22 | new Person('Bob', 25), 23 | new Person('Charlie', 35) 24 | ]; 25 | 26 | // Use the forEach method to iterate over the array 27 | people.forEach(person => { 28 | person.sayHello(); 29 | }); 30 | 31 | // Use a template literal to create a multiline string 32 | const multilineString = ` 33 | This is a multiline string 34 | that spans multiple lines. 35 | `; 36 | 37 | // Use destructuring assignment to extract values from an object 38 | const { name, age } = people[0]; 39 | log(`First person in the array is ${name} and they are ${age} years old.`, multilineString); 40 | 41 | // Use the spread operator to create a new array 42 | const numbers = [1, 2, 3]; 43 | const newNumbers = [...numbers, 4, 5]; 44 | log(newNumbers); 45 | 46 | // Use a try-catch block for error handling 47 | try { 48 | // Attempt to parse an invalid JSON string 49 | JSON.parse('invalid JSON'); 50 | } catch (error) { 51 | console.error('Error parsing JSON:', error.message); 52 | } 53 | 54 | // Use a ternary conditional operator 55 | const isEven = num => num % 2 === 0; 56 | const number = 7; 57 | log(`${number} is ${isEven(number) ? 'even' : 'odd'}.`); 58 | 59 | // Use a callback function with setTimeout for asynchronous code 60 | setTimeout(() => { 61 | log('This code runs after a delay of 2 seconds.'); 62 | }, 2000); 63 | 64 | let a, b, c, d, foo 65 | 66 | if (a 67 | || b 68 | || c || d 69 | || (d && b) 70 | ) { 71 | foo() 72 | } 73 | -------------------------------------------------------------------------------- /fixtures/input/jsx.jsx: -------------------------------------------------------------------------------- 1 | export function HelloWorld({ 2 | greeting = "hello", greeted = '"World"', silent = false, onMouseOver,}) { 3 | 4 | if(!greeting){ 5 | return null}; 6 | 7 | // TODO: Don't use random in render 8 | let num = Math 9 | .floor (Math.random() * 1E+7).toString() 10 | .replace(/\.\d+/ig, "") 11 | 12 | return
13 | { greeting.slice( 0, 1 ).toUpperCase() + greeting.slice(1).toLowerCase() } 14 | {greeting.endsWith(",") 15 | ? " " : ", " } 16 | 17 | { greeted } 18 | 19 | { (silent)? ".": "!"} 20 |
; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /fixtures/input/markdown.md: -------------------------------------------------------------------------------- 1 | Header 2 | ====== 3 | 4 | _Look,_ code blocks are formatted *too!* 5 | 6 | ```js 7 | // This should be handled by ESLint instead of Prettier 8 | function identity(x) { 9 | if (foo) { 10 | console.log('bar'); 11 | } 12 | } 13 | ``` 14 | 15 | ```css 16 | /* This should be handled by Prettier */ 17 | .foo { color:red;} 18 | ``` 19 | 20 | Pilot|Airport|Hours 21 | --|:--:|--: 22 | John Doe|SKG|1338 23 | Jane Roe|JFK|314 24 | 25 | - - - - - - - - - - - - - - - 26 | 27 | + List 28 | + with a [link] (/to/somewhere) 29 | + and [another one] 30 | 31 | 32 | [another one]: http://example.com 'Example title' 33 | 34 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. 35 | Curabitur consectetur maximus risus, sed maximus tellus tincidunt et. 36 | -------------------------------------------------------------------------------- /fixtures/input/svelte.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 |
6 | 7 |
{@html content}
8 |
-------------------------------------------------------------------------------- /fixtures/input/svg.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fixtures/input/toml.toml: -------------------------------------------------------------------------------- 1 | comma = [ 2 | 1 3 | ,2 4 | ,3, 5 | ] 6 | 7 | [foo] 8 | b = 1 9 | c = "hello" 10 | a = {answer = 42} 11 | 12 | "indent" = [ 13 | 1, 14 | 2 15 | ] 16 | 17 | ['a-table'] 18 | apple.type = "fruit" 19 | orange.type = "fruit" 20 | apple.skin = "thin" 21 | orange.skin = "thick" 22 | 23 | apple.color = "red" 24 | orange.color = "orange" 25 | -------------------------------------------------------------------------------- /fixtures/input/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "module": "ESNext", 5 | "moduleResolution": "Bundler", 6 | "strict": true, 7 | "skipDefaultLibCheck": true, 8 | "skipLibCheck": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /fixtures/input/tsx.tsx: -------------------------------------------------------------------------------- 1 | export function Component1() { 2 | return
; 3 | } 4 | 5 | export function jsx2() { 6 | const props = {a:1, 7 | b:2} 8 | return < a foo= 'bar' bar={`foo` } > 9 |
Inline Text
12 | 13 | Block Text 14 | 15 |
16 | Mixed 17 |
Foo
18 | Text Bar 19 |
20 |

21 | foobarbaz 22 |

23 | 24 | } 25 | -------------------------------------------------------------------------------- /fixtures/input/typescript.ts: -------------------------------------------------------------------------------- 1 | // Define a TypeScript interface 2 | interface Person { 3 | name: string; age: number; 4 | } 5 | 6 | // Create an array of objects with the defined interface 7 | const people: Person[] = [ 8 | { name: 'Alice', age: 30 }, 9 | { name: 'Bob', age: 25 }, 10 | { name: 'Charlie', 11 | age: 35 } 12 | ]; 13 | 14 | // eslint-disable-next-line no-console 15 | var log = console.log 16 | 17 | // Use a for...of loop to iterate over the array 18 | for (const person of people) { 19 | log(`Hello, my name is ${person.name} and I am ${person.age} years old.`); 20 | } 21 | 22 | // Define a generic function 23 | function identity< T >(arg: T): T { 24 | return arg; 25 | } 26 | 27 | // Use the generic function with type inference 28 | const result = identity( 29 | 'TypeScript is awesome'); 30 | log(result); 31 | 32 | // Use optional properties in an interface 33 | interface Car { 34 | make: string; 35 | model?: string; 36 | } 37 | 38 | // Create objects using the interface 39 | const car1: Car = { make: 'Toyota' }; 40 | const car2: Car = { 41 | make: 'Ford', model: 'Focus' }; 42 | 43 | // Use union types 44 | type Fruit = 'apple' | 'banana' | 'orange'; 45 | const favoriteFruit: Fruit = 'apple'; 46 | 47 | // Use a type assertion to tell TypeScript about the type 48 | const inputValue: any = '42'; 49 | const numericValue = inputValue as number; 50 | 51 | // Define a class with access modifiers 52 | class Animal { 53 | private name: string; 54 | constructor(name: string) { 55 | this.name = name; 56 | } 57 | protected makeSound(sound: string) { 58 | log(`${this.name} says ${sound}`); 59 | } 60 | } 61 | 62 | // Extend a class 63 | class Dog extends Animal { 64 | constructor(private alias: string) { 65 | super(alias); 66 | } 67 | bark() { 68 | this.makeSound('Woof!'); 69 | } 70 | } 71 | 72 | const dog = new Dog('Buddy'); 73 | dog.bark(); 74 | 75 | var fn = (): string => { 76 | return 'hello' + 1 77 | } 78 | 79 | log(car1, car2, favoriteFruit, numericValue, fn()) 80 | 81 | // Generator 82 | export function* generator1() { 83 | let id = 0; 84 | while (id < 100) { 85 | yield id++; 86 | } 87 | } 88 | export function * generator2() { 89 | yield* generator1() 90 | } 91 | -------------------------------------------------------------------------------- /fixtures/input/vue-ts.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 22 | 23 | 26 | 27 | 35 | -------------------------------------------------------------------------------- /fixtures/input/vue.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 25 | -------------------------------------------------------------------------------- /fixtures/input/xml.xml: -------------------------------------------------------------------------------- 1 | 2 | Effective Java45.00 3 | Bluetooth Speaker120.00 4 | Clean Code 5 | 33.50 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /fixtures/output/all/astro.astro: -------------------------------------------------------------------------------- 1 | --- 2 | const isJsx = true 3 | const content = 'hi!'; 4 | --- 5 | 6 |
7 |
{content}
8 |
9 | {isJsx && ( 10 |

{content}

11 | )} 12 |
13 |
14 | 15 | 16 | 22 | -------------------------------------------------------------------------------- /fixtures/output/all/javascript.js: -------------------------------------------------------------------------------- 1 | // This file is generated by ChatGPT 2 | 3 | // eslint-disable-next-line no-console 4 | const log = console.log 5 | 6 | // Define a class using ES6 class syntax 7 | class Person { 8 | constructor(name, age) { 9 | this.name = name 10 | this.age = age 11 | } 12 | 13 | // Define a method within the class 14 | sayHello() { 15 | log(`Hello, my name is ${this.name} and I am ${this.age} years old.`) 16 | } 17 | } 18 | 19 | // Create an array of objects 20 | const people = [ 21 | new Person('Alice', 30), 22 | new Person('Bob', 25), 23 | new Person('Charlie', 35), 24 | ] 25 | 26 | // Use the forEach method to iterate over the array 27 | people.forEach((person) => { 28 | person.sayHello() 29 | }) 30 | 31 | // Use a template literal to create a multiline string 32 | const multilineString = ` 33 | This is a multiline string 34 | that spans multiple lines. 35 | ` 36 | 37 | // Use destructuring assignment to extract values from an object 38 | const { name, age } = people[0] 39 | log(`First person in the array is ${name} and they are ${age} years old.`, multilineString) 40 | 41 | // Use the spread operator to create a new array 42 | const numbers = [1, 2, 3] 43 | const newNumbers = [...numbers, 4, 5] 44 | log(newNumbers) 45 | 46 | // Use a try-catch block for error handling 47 | try { 48 | // Attempt to parse an invalid JSON string 49 | JSON.parse('invalid JSON') 50 | } 51 | catch (error) { 52 | console.error('Error parsing JSON:', error.message) 53 | } 54 | 55 | // Use a ternary conditional operator 56 | const isEven = num => num % 2 === 0 57 | const number = 7 58 | log(`${number} is ${isEven(number) ? 'even' : 'odd'}.`) 59 | 60 | // Use a callback function with setTimeout for asynchronous code 61 | setTimeout(() => { 62 | log('This code runs after a delay of 2 seconds.') 63 | }, 2000) 64 | 65 | let a, b, c, d, foo 66 | 67 | if (a 68 | || b 69 | || c || d 70 | || (d && b) 71 | ) { 72 | foo() 73 | } 74 | -------------------------------------------------------------------------------- /fixtures/output/all/jsx.jsx: -------------------------------------------------------------------------------- 1 | export function HelloWorld({ 2 | greeting = 'hello', 3 | greeted = '"World"', 4 | silent = false, 5 | onMouseOver, 6 | }) { 7 | if (!greeting) { 8 | return null 9 | }; 10 | 11 | // TODO: Don't use random in render 12 | const num = Math 13 | .floor (Math.random() * 1e+7) 14 | .toString() 15 | .replace(/\.\d+/g, '') 16 | 17 | return ( 18 |
19 | { greeting.slice(0, 1).toUpperCase() + greeting.slice(1).toLowerCase() } 20 | {greeting.endsWith(',') 21 | ? ' ' 22 | : ", " } 23 | 24 | { greeted } 25 | 26 | { (silent) ? '.' : '!'} 27 |
28 | ) 29 | } 30 | -------------------------------------------------------------------------------- /fixtures/output/all/markdown.md: -------------------------------------------------------------------------------- 1 | Header 2 | ====== 3 | 4 | _Look,_ code blocks are formatted *too!* 5 | 6 | ```js 7 | // This should be handled by ESLint instead of Prettier 8 | function identity(x) { 9 | if (foo) { 10 | console.log('bar') 11 | } 12 | } 13 | ``` 14 | 15 | ```css 16 | /* This should be handled by Prettier */ 17 | .foo { color:red;} 18 | ``` 19 | 20 | Pilot|Airport|Hours 21 | --|:--:|--: 22 | John Doe|SKG|1338 23 | Jane Roe|JFK|314 24 | 25 | - - - - - - - - - - - - - - - 26 | 27 | + List 28 | + with a [link] (/to/somewhere) 29 | + and [another one] 30 | 31 | [another one]: http://example.com 'Example title' 32 | 33 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. 34 | Curabitur consectetur maximus risus, sed maximus tellus tincidunt et. 35 | -------------------------------------------------------------------------------- /fixtures/output/all/svelte.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 |
6 | 7 |
{@html content}
8 |
9 | -------------------------------------------------------------------------------- /fixtures/output/all/toml.toml: -------------------------------------------------------------------------------- 1 | comma = [ 2 | 1, 3 | 2, 4 | 3, 5 | ] 6 | 7 | [foo] 8 | b = 1 9 | c = "hello" 10 | a = { answer = 42 } 11 | indent = [ 12 | 1, 13 | 2 14 | ] 15 | 16 | [a-table] 17 | apple.type = "fruit" 18 | apple.skin = "thin" 19 | apple.color = "red" 20 | 21 | orange.type = "fruit" 22 | orange.skin = "thick" 23 | orange.color = "orange" 24 | -------------------------------------------------------------------------------- /fixtures/output/all/tsx.tsx: -------------------------------------------------------------------------------- 1 | export function Component1() { 2 | return
3 | } 4 | 5 | export function jsx2() { 6 | const props = { a: 1, b: 2 } 7 | return ( 8 | 9 |
14 | Inline Text 15 |
16 | 17 | Block Text 18 | 19 |
20 | Mixed 21 |
Foo
22 | Text 23 | Bar 24 |
25 |

26 | foo 27 | bar 28 | baz 29 |

30 |
31 | ) 32 | } 33 | -------------------------------------------------------------------------------- /fixtures/output/all/typescript.ts: -------------------------------------------------------------------------------- 1 | // Define a TypeScript interface 2 | interface Person { 3 | name: string 4 | age: number 5 | } 6 | 7 | // Create an array of objects with the defined interface 8 | const people: Person[] = [ 9 | { name: 'Alice', age: 30 }, 10 | { name: 'Bob', age: 25 }, 11 | { name: 'Charlie', age: 35 }, 12 | ] 13 | 14 | // eslint-disable-next-line no-console 15 | const log = console.log 16 | 17 | // Use a for...of loop to iterate over the array 18 | for (const person of people) { 19 | log(`Hello, my name is ${person.name} and I am ${person.age} years old.`) 20 | } 21 | 22 | // Define a generic function 23 | function identity(arg: T): T { 24 | return arg 25 | } 26 | 27 | // Use the generic function with type inference 28 | const result = identity( 29 | 'TypeScript is awesome', 30 | ) 31 | log(result) 32 | 33 | // Use optional properties in an interface 34 | interface Car { 35 | make: string 36 | model?: string 37 | } 38 | 39 | // Create objects using the interface 40 | const car1: Car = { make: 'Toyota' } 41 | const car2: Car = { 42 | make: 'Ford', 43 | model: 'Focus', 44 | } 45 | 46 | // Use union types 47 | type Fruit = 'apple' | 'banana' | 'orange' 48 | const favoriteFruit: Fruit = 'apple' 49 | 50 | // Use a type assertion to tell TypeScript about the type 51 | const inputValue: any = '42' 52 | const numericValue = inputValue as number 53 | 54 | // Define a class with access modifiers 55 | class Animal { 56 | private name: string 57 | constructor(name: string) { 58 | this.name = name 59 | } 60 | 61 | protected makeSound(sound: string) { 62 | log(`${this.name} says ${sound}`) 63 | } 64 | } 65 | 66 | // Extend a class 67 | class Dog extends Animal { 68 | constructor(private alias: string) { 69 | super(alias) 70 | } 71 | 72 | bark() { 73 | this.makeSound('Woof!') 74 | } 75 | } 76 | 77 | const dog = new Dog('Buddy') 78 | dog.bark() 79 | 80 | function fn(): string { 81 | return `hello${1}` 82 | } 83 | 84 | log(car1, car2, favoriteFruit, numericValue, fn()) 85 | 86 | // Generator 87 | export function* generator1() { 88 | let id = 0 89 | while (id < 100) { 90 | yield id++ 91 | } 92 | } 93 | export function* generator2() { 94 | yield* generator1() 95 | } 96 | -------------------------------------------------------------------------------- /fixtures/output/all/vue-ts.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 23 | 24 | 27 | 28 | 36 | -------------------------------------------------------------------------------- /fixtures/output/all/vue.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 28 | -------------------------------------------------------------------------------- /fixtures/output/js/javascript.js: -------------------------------------------------------------------------------- 1 | // This file is generated by ChatGPT 2 | 3 | // eslint-disable-next-line no-console 4 | const log = console.log 5 | 6 | // Define a class using ES6 class syntax 7 | class Person { 8 | constructor(name, age) { 9 | this.name = name 10 | this.age = age 11 | } 12 | 13 | // Define a method within the class 14 | sayHello() { 15 | log(`Hello, my name is ${this.name} and I am ${this.age} years old.`) 16 | } 17 | } 18 | 19 | // Create an array of objects 20 | const people = [ 21 | new Person('Alice', 30), 22 | new Person('Bob', 25), 23 | new Person('Charlie', 35), 24 | ] 25 | 26 | // Use the forEach method to iterate over the array 27 | people.forEach((person) => { 28 | person.sayHello() 29 | }) 30 | 31 | // Use a template literal to create a multiline string 32 | const multilineString = ` 33 | This is a multiline string 34 | that spans multiple lines. 35 | ` 36 | 37 | // Use destructuring assignment to extract values from an object 38 | const { name, age } = people[0] 39 | log(`First person in the array is ${name} and they are ${age} years old.`, multilineString) 40 | 41 | // Use the spread operator to create a new array 42 | const numbers = [1, 2, 3] 43 | const newNumbers = [...numbers, 4, 5] 44 | log(newNumbers) 45 | 46 | // Use a try-catch block for error handling 47 | try { 48 | // Attempt to parse an invalid JSON string 49 | JSON.parse('invalid JSON') 50 | } 51 | catch (error) { 52 | console.error('Error parsing JSON:', error.message) 53 | } 54 | 55 | // Use a ternary conditional operator 56 | const isEven = num => num % 2 === 0 57 | const number = 7 58 | log(`${number} is ${isEven(number) ? 'even' : 'odd'}.`) 59 | 60 | // Use a callback function with setTimeout for asynchronous code 61 | setTimeout(() => { 62 | log('This code runs after a delay of 2 seconds.') 63 | }, 2000) 64 | 65 | let a, b, c, d, foo 66 | 67 | if (a 68 | || b 69 | || c || d 70 | || (d && b) 71 | ) { 72 | foo() 73 | } 74 | -------------------------------------------------------------------------------- /fixtures/output/js/jsx.jsx: -------------------------------------------------------------------------------- 1 | export function HelloWorld({ 2 | greeting = 'hello', 3 | greeted = '"World"', 4 | silent = false, 5 | onMouseOver, 6 | }) { 7 | if (!greeting) { 8 | return null 9 | }; 10 | 11 | // TODO: Don't use random in render 12 | const num = Math 13 | .floor (Math.random() * 1e+7) 14 | .toString() 15 | .replace(/\.\d+/g, '') 16 | 17 | return ( 18 |
19 | { greeting.slice(0, 1).toUpperCase() + greeting.slice(1).toLowerCase() } 20 | {greeting.endsWith(',') 21 | ? ' ' 22 | : ", " } 23 | 24 | { greeted } 25 | 26 | { (silent) ? '.' : '!'} 27 |
28 | ) 29 | } 30 | -------------------------------------------------------------------------------- /fixtures/output/js/markdown.md: -------------------------------------------------------------------------------- 1 | Header 2 | ====== 3 | 4 | _Look,_ code blocks are formatted *too!* 5 | 6 | ```js 7 | // This should be handled by ESLint instead of Prettier 8 | function identity(x) { 9 | if (foo) { 10 | console.log('bar') 11 | } 12 | } 13 | ``` 14 | 15 | ```css 16 | /* This should be handled by Prettier */ 17 | .foo { color:red;} 18 | ``` 19 | 20 | Pilot|Airport|Hours 21 | --|:--:|--: 22 | John Doe|SKG|1338 23 | Jane Roe|JFK|314 24 | 25 | - - - - - - - - - - - - - - - 26 | 27 | + List 28 | + with a [link] (/to/somewhere) 29 | + and [another one] 30 | 31 | [another one]: http://example.com 'Example title' 32 | 33 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. 34 | Curabitur consectetur maximus risus, sed maximus tellus tincidunt et. 35 | -------------------------------------------------------------------------------- /fixtures/output/js/toml.toml: -------------------------------------------------------------------------------- 1 | comma = [ 2 | 1, 3 | 2, 4 | 3, 5 | ] 6 | 7 | [foo] 8 | b = 1 9 | c = "hello" 10 | a = { answer = 42 } 11 | indent = [ 12 | 1, 13 | 2 14 | ] 15 | 16 | [a-table] 17 | apple.type = "fruit" 18 | apple.skin = "thin" 19 | apple.color = "red" 20 | 21 | orange.type = "fruit" 22 | orange.skin = "thick" 23 | orange.color = "orange" 24 | -------------------------------------------------------------------------------- /fixtures/output/js/tsx.tsx: -------------------------------------------------------------------------------- 1 | export function Component1() { 2 | return
3 | } 4 | 5 | export function jsx2() { 6 | const props = { a: 1, b: 2 } 7 | return ( 8 | 9 |
14 | Inline Text 15 |
16 | 17 | Block Text 18 | 19 |
20 | Mixed 21 |
Foo
22 | Text 23 | Bar 24 |
25 |

26 | foo 27 | bar 28 | baz 29 |

30 |
31 | ) 32 | } 33 | -------------------------------------------------------------------------------- /fixtures/output/no-markdown-with-formatters/javascript.js: -------------------------------------------------------------------------------- 1 | // This file is generated by ChatGPT 2 | 3 | // eslint-disable-next-line no-console 4 | const log = console.log 5 | 6 | // Define a class using ES6 class syntax 7 | class Person { 8 | constructor(name, age) { 9 | this.name = name 10 | this.age = age 11 | } 12 | 13 | // Define a method within the class 14 | sayHello() { 15 | log(`Hello, my name is ${this.name} and I am ${this.age} years old.`) 16 | } 17 | } 18 | 19 | // Create an array of objects 20 | const people = [ 21 | new Person('Alice', 30), 22 | new Person('Bob', 25), 23 | new Person('Charlie', 35), 24 | ] 25 | 26 | // Use the forEach method to iterate over the array 27 | people.forEach((person) => { 28 | person.sayHello() 29 | }) 30 | 31 | // Use a template literal to create a multiline string 32 | const multilineString = ` 33 | This is a multiline string 34 | that spans multiple lines. 35 | ` 36 | 37 | // Use destructuring assignment to extract values from an object 38 | const { name, age } = people[0] 39 | log(`First person in the array is ${name} and they are ${age} years old.`, multilineString) 40 | 41 | // Use the spread operator to create a new array 42 | const numbers = [1, 2, 3] 43 | const newNumbers = [...numbers, 4, 5] 44 | log(newNumbers) 45 | 46 | // Use a try-catch block for error handling 47 | try { 48 | // Attempt to parse an invalid JSON string 49 | JSON.parse('invalid JSON') 50 | } 51 | catch (error) { 52 | console.error('Error parsing JSON:', error.message) 53 | } 54 | 55 | // Use a ternary conditional operator 56 | const isEven = num => num % 2 === 0 57 | const number = 7 58 | log(`${number} is ${isEven(number) ? 'even' : 'odd'}.`) 59 | 60 | // Use a callback function with setTimeout for asynchronous code 61 | setTimeout(() => { 62 | log('This code runs after a delay of 2 seconds.') 63 | }, 2000) 64 | 65 | let a, b, c, d, foo 66 | 67 | if (a 68 | || b 69 | || c || d 70 | || (d && b) 71 | ) { 72 | foo() 73 | } 74 | -------------------------------------------------------------------------------- /fixtures/output/no-markdown-with-formatters/markdown.md: -------------------------------------------------------------------------------- 1 | # Header 2 | 3 | _Look,_ code blocks are formatted _too!_ 4 | 5 | ```js 6 | // This should be handled by ESLint instead of Prettier 7 | function identity(x) { 8 | if (foo) { 9 | console.log('bar'); 10 | } 11 | } 12 | ``` 13 | 14 | ```css 15 | /* This should be handled by Prettier */ 16 | .foo { color:red;} 17 | ``` 18 | 19 | | Pilot | Airport | Hours | 20 | | -------- | :-----: | ----: | 21 | | John Doe | SKG | 1338 | 22 | | Jane Roe | JFK | 314 | 23 | 24 | --- 25 | 26 | - List 27 | - with a [link] (/to/somewhere) 28 | - and [another one] 29 | 30 | [another one]: http://example.com 'Example title' 31 | 32 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. 33 | Curabitur consectetur maximus risus, sed maximus tellus tincidunt et. 34 | -------------------------------------------------------------------------------- /fixtures/output/no-markdown-with-formatters/toml.toml: -------------------------------------------------------------------------------- 1 | comma = [ 2 | 1, 3 | 2, 4 | 3, 5 | ] 6 | 7 | [foo] 8 | b = 1 9 | c = "hello" 10 | a = { answer = 42 } 11 | indent = [ 12 | 1, 13 | 2 14 | ] 15 | 16 | [a-table] 17 | apple.type = "fruit" 18 | apple.skin = "thin" 19 | apple.color = "red" 20 | 21 | orange.type = "fruit" 22 | orange.skin = "thick" 23 | orange.color = "orange" 24 | -------------------------------------------------------------------------------- /fixtures/output/no-markdown-with-formatters/tsx.tsx: -------------------------------------------------------------------------------- 1 | export function Component1() { 2 | return
3 | } 4 | 5 | export function jsx2() { 6 | const props = { a: 1, b: 2 } 7 | return < a foo= 'bar' bar={`foo` } > 8 |
Inline Text
9 | 10 | Block Text 11 | 12 |
13 | Mixed 14 |
Foo
15 | Text Bar 16 |
17 |

18 | foobarbaz 19 |

20 | 21 | } 22 | -------------------------------------------------------------------------------- /fixtures/output/no-markdown-with-formatters/typescript.ts: -------------------------------------------------------------------------------- 1 | // Define a TypeScript interface 2 | interface Person { 3 | name: string 4 | age: number 5 | } 6 | 7 | // Create an array of objects with the defined interface 8 | const people: Person[] = [ 9 | { name: 'Alice', age: 30 }, 10 | { name: 'Bob', age: 25 }, 11 | { name: 'Charlie', age: 35 }, 12 | ] 13 | 14 | // eslint-disable-next-line no-console 15 | const log = console.log 16 | 17 | // Use a for...of loop to iterate over the array 18 | for (const person of people) { 19 | log(`Hello, my name is ${person.name} and I am ${person.age} years old.`) 20 | } 21 | 22 | // Define a generic function 23 | function identity(arg: T): T { 24 | return arg 25 | } 26 | 27 | // Use the generic function with type inference 28 | const result = identity( 29 | 'TypeScript is awesome', 30 | ) 31 | log(result) 32 | 33 | // Use optional properties in an interface 34 | interface Car { 35 | make: string 36 | model?: string 37 | } 38 | 39 | // Create objects using the interface 40 | const car1: Car = { make: 'Toyota' } 41 | const car2: Car = { 42 | make: 'Ford', 43 | model: 'Focus', 44 | } 45 | 46 | // Use union types 47 | type Fruit = 'apple' | 'banana' | 'orange' 48 | const favoriteFruit: Fruit = 'apple' 49 | 50 | // Use a type assertion to tell TypeScript about the type 51 | const inputValue: any = '42' 52 | const numericValue = inputValue as number 53 | 54 | // Define a class with access modifiers 55 | class Animal { 56 | private name: string 57 | constructor(name: string) { 58 | this.name = name 59 | } 60 | 61 | protected makeSound(sound: string) { 62 | log(`${this.name} says ${sound}`) 63 | } 64 | } 65 | 66 | // Extend a class 67 | class Dog extends Animal { 68 | constructor(private alias: string) { 69 | super(alias) 70 | } 71 | 72 | bark() { 73 | this.makeSound('Woof!') 74 | } 75 | } 76 | 77 | const dog = new Dog('Buddy') 78 | dog.bark() 79 | 80 | function fn(): string { 81 | return `hello${1}` 82 | } 83 | 84 | log(car1, car2, favoriteFruit, numericValue, fn()) 85 | 86 | // Generator 87 | export function* generator1() { 88 | let id = 0 89 | while (id < 100) { 90 | yield id++ 91 | } 92 | } 93 | export function* generator2() { 94 | yield* generator1() 95 | } 96 | -------------------------------------------------------------------------------- /fixtures/output/no-style/javascript.js: -------------------------------------------------------------------------------- 1 | // This file is generated by ChatGPT 2 | 3 | // eslint-disable-next-line no-console 4 | const log = console.log 5 | 6 | // Define a class using ES6 class syntax 7 | class Person { 8 | constructor(name, age) { 9 | this.name = name; 10 | this.age = age; 11 | } 12 | 13 | // Define a method within the class 14 | sayHello() { 15 | log(`Hello, my name is ${this.name} and I am ${this.age} years old.`); 16 | } 17 | } 18 | 19 | // Create an array of objects 20 | const people = [ 21 | new Person('Alice', 30), 22 | new Person('Bob', 25), 23 | new Person('Charlie', 35) 24 | ]; 25 | 26 | // Use the forEach method to iterate over the array 27 | people.forEach(person => { 28 | person.sayHello(); 29 | }); 30 | 31 | // Use a template literal to create a multiline string 32 | const multilineString = ` 33 | This is a multiline string 34 | that spans multiple lines. 35 | `; 36 | 37 | // Use destructuring assignment to extract values from an object 38 | const { name, age } = people[0]; 39 | log(`First person in the array is ${name} and they are ${age} years old.`, multilineString); 40 | 41 | // Use the spread operator to create a new array 42 | const numbers = [1, 2, 3]; 43 | const newNumbers = [...numbers, 4, 5]; 44 | log(newNumbers); 45 | 46 | // Use a try-catch block for error handling 47 | try { 48 | // Attempt to parse an invalid JSON string 49 | JSON.parse('invalid JSON'); 50 | } catch (error) { 51 | console.error('Error parsing JSON:', error.message); 52 | } 53 | 54 | // Use a ternary conditional operator 55 | const isEven = num => num % 2 === 0; 56 | const number = 7; 57 | log(`${number} is ${isEven(number) ? 'even' : 'odd'}.`); 58 | 59 | // Use a callback function with setTimeout for asynchronous code 60 | setTimeout(() => { 61 | log('This code runs after a delay of 2 seconds.'); 62 | }, 2000); 63 | 64 | let a, b, c, d, foo 65 | 66 | if (a 67 | || b 68 | || c || d 69 | || (d && b) 70 | ) { 71 | foo() 72 | } 73 | -------------------------------------------------------------------------------- /fixtures/output/no-style/jsx.jsx: -------------------------------------------------------------------------------- 1 | export function HelloWorld({ 2 | greeting = "hello", greeted = '"World"', silent = false, onMouseOver,}) { 3 | 4 | if(!greeting){ 5 | return null}; 6 | 7 | // TODO: Don't use random in render 8 | const num = Math 9 | .floor (Math.random() * 1e+7).toString() 10 | .replace(/\.\d+/g, "") 11 | 12 | return
13 | { greeting.slice( 0, 1 ).toUpperCase() + greeting.slice(1).toLowerCase() } 14 | {greeting.endsWith(",") 15 | ? " " : ", " } 16 | 17 | { greeted } 18 | 19 | { (silent)? ".": "!"} 20 |
; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /fixtures/output/no-style/toml.toml: -------------------------------------------------------------------------------- 1 | comma = [ 2 | 1, 3 | 2, 4 | 3, 5 | ] 6 | 7 | [foo] 8 | b = 1 9 | c = "hello" 10 | a = {answer = 42} 11 | 12 | "indent" = [ 13 | 1, 14 | 2 15 | ] 16 | 17 | ['a-table'] 18 | apple.type = "fruit" 19 | apple.skin = "thin" 20 | apple.color = "red" 21 | orange.type = "fruit" 22 | orange.skin = "thick" 23 | orange.color = "orange" 24 | -------------------------------------------------------------------------------- /fixtures/output/no-style/typescript.ts: -------------------------------------------------------------------------------- 1 | // Define a TypeScript interface 2 | interface Person { 3 | name: string; age: number; 4 | } 5 | 6 | // Create an array of objects with the defined interface 7 | const people: Person[] = [ 8 | { name: 'Alice', age: 30 }, 9 | { name: 'Bob', age: 25 }, 10 | { name: 'Charlie', 11 | age: 35 } 12 | ]; 13 | 14 | // eslint-disable-next-line no-console 15 | const log = console.log 16 | 17 | // Use a for...of loop to iterate over the array 18 | for (const person of people) { 19 | log(`Hello, my name is ${person.name} and I am ${person.age} years old.`); 20 | } 21 | 22 | // Define a generic function 23 | function identity< T >(arg: T): T { 24 | return arg; 25 | } 26 | 27 | // Use the generic function with type inference 28 | const result = identity( 29 | 'TypeScript is awesome'); 30 | log(result); 31 | 32 | // Use optional properties in an interface 33 | interface Car { 34 | make: string; 35 | model?: string; 36 | } 37 | 38 | // Create objects using the interface 39 | const car1: Car = { make: 'Toyota' }; 40 | const car2: Car = { 41 | make: 'Ford', model: 'Focus' }; 42 | 43 | // Use union types 44 | type Fruit = 'apple' | 'banana' | 'orange'; 45 | const favoriteFruit: Fruit = 'apple'; 46 | 47 | // Use a type assertion to tell TypeScript about the type 48 | const inputValue: any = '42'; 49 | const numericValue = inputValue as number; 50 | 51 | // Define a class with access modifiers 52 | class Animal { 53 | private name: string; 54 | constructor(name: string) { 55 | this.name = name; 56 | } 57 | protected makeSound(sound: string) { 58 | log(`${this.name} says ${sound}`); 59 | } 60 | } 61 | 62 | // Extend a class 63 | class Dog extends Animal { 64 | constructor(private alias: string) { 65 | super(alias); 66 | } 67 | bark() { 68 | this.makeSound('Woof!'); 69 | } 70 | } 71 | 72 | const dog = new Dog('Buddy'); 73 | dog.bark(); 74 | 75 | const fn = (): string => { 76 | return `hello${ 1}` 77 | } 78 | 79 | log(car1, car2, favoriteFruit, numericValue, fn()) 80 | 81 | // Generator 82 | export function* generator1() { 83 | let id = 0; 84 | while (id < 100) { 85 | yield id++; 86 | } 87 | } 88 | export function * generator2() { 89 | yield* generator1() 90 | } 91 | -------------------------------------------------------------------------------- /fixtures/output/no-style/vue-ts.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 23 | 24 | 27 | 28 | 36 | -------------------------------------------------------------------------------- /fixtures/output/no-style/vue.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 28 | -------------------------------------------------------------------------------- /fixtures/output/tab-double-quotes/javascript.js: -------------------------------------------------------------------------------- 1 | // This file is generated by ChatGPT 2 | 3 | // eslint-disable-next-line no-console 4 | const log = console.log 5 | 6 | // Define a class using ES6 class syntax 7 | class Person { 8 | constructor(name, age) { 9 | this.name = name 10 | this.age = age 11 | } 12 | 13 | // Define a method within the class 14 | sayHello() { 15 | log(`Hello, my name is ${this.name} and I am ${this.age} years old.`) 16 | } 17 | } 18 | 19 | // Create an array of objects 20 | const people = [ 21 | new Person("Alice", 30), 22 | new Person("Bob", 25), 23 | new Person("Charlie", 35), 24 | ] 25 | 26 | // Use the forEach method to iterate over the array 27 | people.forEach((person) => { 28 | person.sayHello() 29 | }) 30 | 31 | // Use a template literal to create a multiline string 32 | const multilineString = ` 33 | This is a multiline string 34 | that spans multiple lines. 35 | ` 36 | 37 | // Use destructuring assignment to extract values from an object 38 | const { name, age } = people[0] 39 | log(`First person in the array is ${name} and they are ${age} years old.`, multilineString) 40 | 41 | // Use the spread operator to create a new array 42 | const numbers = [1, 2, 3] 43 | const newNumbers = [...numbers, 4, 5] 44 | log(newNumbers) 45 | 46 | // Use a try-catch block for error handling 47 | try { 48 | // Attempt to parse an invalid JSON string 49 | JSON.parse("invalid JSON") 50 | } 51 | catch (error) { 52 | console.error("Error parsing JSON:", error.message) 53 | } 54 | 55 | // Use a ternary conditional operator 56 | const isEven = num => num % 2 === 0 57 | const number = 7 58 | log(`${number} is ${isEven(number) ? "even" : "odd"}.`) 59 | 60 | // Use a callback function with setTimeout for asynchronous code 61 | setTimeout(() => { 62 | log("This code runs after a delay of 2 seconds.") 63 | }, 2000) 64 | 65 | let a, b, c, d, foo 66 | 67 | if (a 68 | || b 69 | || c || d 70 | || (d && b) 71 | ) { 72 | foo() 73 | } 74 | -------------------------------------------------------------------------------- /fixtures/output/tab-double-quotes/jsx.jsx: -------------------------------------------------------------------------------- 1 | export function HelloWorld({ 2 | greeting = "hello", 3 | greeted = "\"World\"", 4 | silent = false, 5 | onMouseOver, 6 | }) { 7 | if (!greeting) { 8 | return null 9 | }; 10 | 11 | // TODO: Don't use random in render 12 | const num = Math 13 | .floor (Math.random() * 1e+7) 14 | .toString() 15 | .replace(/\.\d+/g, "") 16 | 17 | return ( 18 |
19 | { greeting.slice(0, 1).toUpperCase() + greeting.slice(1).toLowerCase() } 20 | {greeting.endsWith(",") 21 | ? " " 22 | : ", " } 23 | 24 | { greeted } 25 | 26 | { (silent) ? "." : "!"} 27 |
28 | ) 29 | } 30 | -------------------------------------------------------------------------------- /fixtures/output/tab-double-quotes/markdown.md: -------------------------------------------------------------------------------- 1 | Header 2 | ====== 3 | 4 | _Look,_ code blocks are formatted *too!* 5 | 6 | ```js 7 | // This should be handled by ESLint instead of Prettier 8 | function identity(x) { 9 | if (foo) { 10 | console.log("bar") 11 | } 12 | } 13 | ``` 14 | 15 | ```css 16 | /* This should be handled by Prettier */ 17 | .foo { color:red;} 18 | ``` 19 | 20 | Pilot|Airport|Hours 21 | --|:--:|--: 22 | John Doe|SKG|1338 23 | Jane Roe|JFK|314 24 | 25 | - - - - - - - - - - - - - - - 26 | 27 | + List 28 | + with a [link] (/to/somewhere) 29 | + and [another one] 30 | 31 | [another one]: http://example.com 'Example title' 32 | 33 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. 34 | Curabitur consectetur maximus risus, sed maximus tellus tincidunt et. 35 | -------------------------------------------------------------------------------- /fixtures/output/tab-double-quotes/toml.toml: -------------------------------------------------------------------------------- 1 | comma = [ 2 | 1, 3 | 2, 4 | 3, 5 | ] 6 | 7 | [foo] 8 | b = 1 9 | c = "hello" 10 | a = { answer = 42 } 11 | indent = [ 12 | 1, 13 | 2 14 | ] 15 | 16 | [a-table] 17 | apple.type = "fruit" 18 | apple.skin = "thin" 19 | apple.color = "red" 20 | 21 | orange.type = "fruit" 22 | orange.skin = "thick" 23 | orange.color = "orange" 24 | -------------------------------------------------------------------------------- /fixtures/output/tab-double-quotes/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "module": "ESNext", 5 | "moduleResolution": "Bundler", 6 | "strict": true, 7 | "skipDefaultLibCheck": true, 8 | "skipLibCheck": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /fixtures/output/tab-double-quotes/tsx.tsx: -------------------------------------------------------------------------------- 1 | export function Component1() { 2 | return
3 | } 4 | 5 | export function jsx2() { 6 | const props = { a: 1, b: 2 } 7 | return ( 8 | 9 |
14 | Inline Text 15 |
16 | 17 | Block Text 18 | 19 |
20 | Mixed 21 |
Foo
22 | Text 23 | Bar 24 |
25 |

26 | foo 27 | bar 28 | baz 29 |

30 |
31 | ) 32 | } 33 | -------------------------------------------------------------------------------- /fixtures/output/tab-double-quotes/typescript.ts: -------------------------------------------------------------------------------- 1 | // Define a TypeScript interface 2 | interface Person { 3 | name: string 4 | age: number 5 | } 6 | 7 | // Create an array of objects with the defined interface 8 | const people: Person[] = [ 9 | { name: "Alice", age: 30 }, 10 | { name: "Bob", age: 25 }, 11 | { name: "Charlie", age: 35 }, 12 | ] 13 | 14 | // eslint-disable-next-line no-console 15 | const log = console.log 16 | 17 | // Use a for...of loop to iterate over the array 18 | for (const person of people) { 19 | log(`Hello, my name is ${person.name} and I am ${person.age} years old.`) 20 | } 21 | 22 | // Define a generic function 23 | function identity(arg: T): T { 24 | return arg 25 | } 26 | 27 | // Use the generic function with type inference 28 | const result = identity( 29 | "TypeScript is awesome", 30 | ) 31 | log(result) 32 | 33 | // Use optional properties in an interface 34 | interface Car { 35 | make: string 36 | model?: string 37 | } 38 | 39 | // Create objects using the interface 40 | const car1: Car = { make: "Toyota" } 41 | const car2: Car = { 42 | make: "Ford", 43 | model: "Focus", 44 | } 45 | 46 | // Use union types 47 | type Fruit = "apple" | "banana" | "orange" 48 | const favoriteFruit: Fruit = "apple" 49 | 50 | // Use a type assertion to tell TypeScript about the type 51 | const inputValue: any = "42" 52 | const numericValue = inputValue as number 53 | 54 | // Define a class with access modifiers 55 | class Animal { 56 | private name: string 57 | constructor(name: string) { 58 | this.name = name 59 | } 60 | 61 | protected makeSound(sound: string) { 62 | log(`${this.name} says ${sound}`) 63 | } 64 | } 65 | 66 | // Extend a class 67 | class Dog extends Animal { 68 | constructor(private alias: string) { 69 | super(alias) 70 | } 71 | 72 | bark() { 73 | this.makeSound("Woof!") 74 | } 75 | } 76 | 77 | const dog = new Dog("Buddy") 78 | dog.bark() 79 | 80 | function fn(): string { 81 | return `hello${1}` 82 | } 83 | 84 | log(car1, car2, favoriteFruit, numericValue, fn()) 85 | 86 | // Generator 87 | export function* generator1() { 88 | let id = 0 89 | while (id < 100) { 90 | yield id++ 91 | } 92 | } 93 | export function* generator2() { 94 | yield* generator1() 95 | } 96 | -------------------------------------------------------------------------------- /fixtures/output/tab-double-quotes/vue-ts.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 23 | 24 | 27 | 28 | 36 | -------------------------------------------------------------------------------- /fixtures/output/tab-double-quotes/vue.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 28 | -------------------------------------------------------------------------------- /fixtures/output/ts-override/javascript.js: -------------------------------------------------------------------------------- 1 | // This file is generated by ChatGPT 2 | 3 | // eslint-disable-next-line no-console 4 | const log = console.log 5 | 6 | // Define a class using ES6 class syntax 7 | class Person { 8 | constructor(name, age) { 9 | this.name = name 10 | this.age = age 11 | } 12 | 13 | // Define a method within the class 14 | sayHello() { 15 | log(`Hello, my name is ${this.name} and I am ${this.age} years old.`) 16 | } 17 | } 18 | 19 | // Create an array of objects 20 | const people = [ 21 | new Person('Alice', 30), 22 | new Person('Bob', 25), 23 | new Person('Charlie', 35), 24 | ] 25 | 26 | // Use the forEach method to iterate over the array 27 | people.forEach((person) => { 28 | person.sayHello() 29 | }) 30 | 31 | // Use a template literal to create a multiline string 32 | const multilineString = ` 33 | This is a multiline string 34 | that spans multiple lines. 35 | ` 36 | 37 | // Use destructuring assignment to extract values from an object 38 | const { name, age } = people[0] 39 | log(`First person in the array is ${name} and they are ${age} years old.`, multilineString) 40 | 41 | // Use the spread operator to create a new array 42 | const numbers = [1, 2, 3] 43 | const newNumbers = [...numbers, 4, 5] 44 | log(newNumbers) 45 | 46 | // Use a try-catch block for error handling 47 | try { 48 | // Attempt to parse an invalid JSON string 49 | JSON.parse('invalid JSON') 50 | } 51 | catch (error) { 52 | console.error('Error parsing JSON:', error.message) 53 | } 54 | 55 | // Use a ternary conditional operator 56 | const isEven = num => num % 2 === 0 57 | const number = 7 58 | log(`${number} is ${isEven(number) ? 'even' : 'odd'}.`) 59 | 60 | // Use a callback function with setTimeout for asynchronous code 61 | setTimeout(() => { 62 | log('This code runs after a delay of 2 seconds.') 63 | }, 2000) 64 | 65 | let a, b, c, d, foo 66 | 67 | if (a 68 | || b 69 | || c || d 70 | || (d && b) 71 | ) { 72 | foo() 73 | } 74 | -------------------------------------------------------------------------------- /fixtures/output/ts-override/jsx.jsx: -------------------------------------------------------------------------------- 1 | export function HelloWorld({ 2 | greeting = 'hello', 3 | greeted = '"World"', 4 | silent = false, 5 | onMouseOver, 6 | }) { 7 | if (!greeting) { 8 | return null 9 | }; 10 | 11 | // TODO: Don't use random in render 12 | const num = Math 13 | .floor (Math.random() * 1e+7) 14 | .toString() 15 | .replace(/\.\d+/g, '') 16 | 17 | return ( 18 |
19 | { greeting.slice(0, 1).toUpperCase() + greeting.slice(1).toLowerCase() } 20 | {greeting.endsWith(',') 21 | ? ' ' 22 | : ", " } 23 | 24 | { greeted } 25 | 26 | { (silent) ? '.' : '!'} 27 |
28 | ) 29 | } 30 | -------------------------------------------------------------------------------- /fixtures/output/ts-override/markdown.md: -------------------------------------------------------------------------------- 1 | Header 2 | ====== 3 | 4 | _Look,_ code blocks are formatted *too!* 5 | 6 | ```js 7 | // This should be handled by ESLint instead of Prettier 8 | function identity(x) { 9 | if (foo) { 10 | console.log('bar') 11 | } 12 | } 13 | ``` 14 | 15 | ```css 16 | /* This should be handled by Prettier */ 17 | .foo { color:red;} 18 | ``` 19 | 20 | Pilot|Airport|Hours 21 | --|:--:|--: 22 | John Doe|SKG|1338 23 | Jane Roe|JFK|314 24 | 25 | - - - - - - - - - - - - - - - 26 | 27 | + List 28 | + with a [link] (/to/somewhere) 29 | + and [another one] 30 | 31 | [another one]: http://example.com 'Example title' 32 | 33 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. 34 | Curabitur consectetur maximus risus, sed maximus tellus tincidunt et. 35 | -------------------------------------------------------------------------------- /fixtures/output/ts-override/toml.toml: -------------------------------------------------------------------------------- 1 | comma = [ 2 | 1, 3 | 2, 4 | 3, 5 | ] 6 | 7 | [foo] 8 | b = 1 9 | c = "hello" 10 | a = { answer = 42 } 11 | indent = [ 12 | 1, 13 | 2 14 | ] 15 | 16 | [a-table] 17 | apple.type = "fruit" 18 | apple.skin = "thin" 19 | apple.color = "red" 20 | 21 | orange.type = "fruit" 22 | orange.skin = "thick" 23 | orange.color = "orange" 24 | -------------------------------------------------------------------------------- /fixtures/output/ts-override/tsx.tsx: -------------------------------------------------------------------------------- 1 | export function Component1() { 2 | return
3 | } 4 | 5 | export function jsx2() { 6 | const props = { a: 1, b: 2 } 7 | return ( 8 | 9 |
14 | Inline Text 15 |
16 | 17 | Block Text 18 | 19 |
20 | Mixed 21 |
Foo
22 | Text 23 | Bar 24 |
25 |

26 | foo 27 | bar 28 | baz 29 |

30 |
31 | ) 32 | } 33 | -------------------------------------------------------------------------------- /fixtures/output/ts-override/typescript.ts: -------------------------------------------------------------------------------- 1 | // Define a TypeScript interface 2 | type Person = { 3 | name: string 4 | age: number 5 | } 6 | 7 | // Create an array of objects with the defined interface 8 | const people: Person[] = [ 9 | { name: 'Alice', age: 30 }, 10 | { name: 'Bob', age: 25 }, 11 | { name: 'Charlie', age: 35 }, 12 | ] 13 | 14 | // eslint-disable-next-line no-console 15 | const log = console.log 16 | 17 | // Use a for...of loop to iterate over the array 18 | for (const person of people) { 19 | log(`Hello, my name is ${person.name} and I am ${person.age} years old.`) 20 | } 21 | 22 | // Define a generic function 23 | function identity(arg: T): T { 24 | return arg 25 | } 26 | 27 | // Use the generic function with type inference 28 | const result = identity( 29 | 'TypeScript is awesome', 30 | ) 31 | log(result) 32 | 33 | // Use optional properties in an interface 34 | type Car = { 35 | make: string 36 | model?: string 37 | } 38 | 39 | // Create objects using the interface 40 | const car1: Car = { make: 'Toyota' } 41 | const car2: Car = { 42 | make: 'Ford', 43 | model: 'Focus', 44 | } 45 | 46 | // Use union types 47 | type Fruit = 'apple' | 'banana' | 'orange' 48 | const favoriteFruit: Fruit = 'apple' 49 | 50 | // Use a type assertion to tell TypeScript about the type 51 | const inputValue: any = '42' 52 | const numericValue = inputValue as number 53 | 54 | // Define a class with access modifiers 55 | class Animal { 56 | private name: string 57 | constructor(name: string) { 58 | this.name = name 59 | } 60 | 61 | protected makeSound(sound: string) { 62 | log(`${this.name} says ${sound}`) 63 | } 64 | } 65 | 66 | // Extend a class 67 | class Dog extends Animal { 68 | constructor(private alias: string) { 69 | super(alias) 70 | } 71 | 72 | bark() { 73 | this.makeSound('Woof!') 74 | } 75 | } 76 | 77 | const dog = new Dog('Buddy') 78 | dog.bark() 79 | 80 | function fn(): string { 81 | return `hello${1}` 82 | } 83 | 84 | log(car1, car2, favoriteFruit, numericValue, fn()) 85 | 86 | // Generator 87 | export function* generator1() { 88 | let id = 0 89 | while (id < 100) { 90 | yield id++ 91 | } 92 | } 93 | export function* generator2() { 94 | yield* generator1() 95 | } 96 | -------------------------------------------------------------------------------- /fixtures/output/ts-override/vue-ts.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 23 | 24 | 27 | 28 | 36 | -------------------------------------------------------------------------------- /fixtures/output/ts-override/vue.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 28 | -------------------------------------------------------------------------------- /fixtures/output/ts-strict-with-react/javascript.js: -------------------------------------------------------------------------------- 1 | // This file is generated by ChatGPT 2 | 3 | // eslint-disable-next-line no-console 4 | const log = console.log 5 | 6 | // Define a class using ES6 class syntax 7 | class Person { 8 | constructor(name, age) { 9 | this.name = name 10 | this.age = age 11 | } 12 | 13 | // Define a method within the class 14 | sayHello() { 15 | log(`Hello, my name is ${this.name} and I am ${this.age} years old.`) 16 | } 17 | } 18 | 19 | // Create an array of objects 20 | const people = [ 21 | new Person('Alice', 30), 22 | new Person('Bob', 25), 23 | new Person('Charlie', 35), 24 | ] 25 | 26 | // Use the forEach method to iterate over the array 27 | people.forEach((person) => { 28 | person.sayHello() 29 | }) 30 | 31 | // Use a template literal to create a multiline string 32 | const multilineString = ` 33 | This is a multiline string 34 | that spans multiple lines. 35 | ` 36 | 37 | // Use destructuring assignment to extract values from an object 38 | const { name, age } = people[0] 39 | log(`First person in the array is ${name} and they are ${age} years old.`, multilineString) 40 | 41 | // Use the spread operator to create a new array 42 | const numbers = [1, 2, 3] 43 | const newNumbers = [...numbers, 4, 5] 44 | log(newNumbers) 45 | 46 | // Use a try-catch block for error handling 47 | try { 48 | // Attempt to parse an invalid JSON string 49 | JSON.parse('invalid JSON') 50 | } 51 | catch (error) { 52 | console.error('Error parsing JSON:', error.message) 53 | } 54 | 55 | // Use a ternary conditional operator 56 | const isEven = num => num % 2 === 0 57 | const number = 7 58 | log(`${number} is ${isEven(number) ? 'even' : 'odd'}.`) 59 | 60 | // Use a callback function with setTimeout for asynchronous code 61 | setTimeout(() => { 62 | log('This code runs after a delay of 2 seconds.') 63 | }, 2000) 64 | 65 | let a, b, c, d, foo 66 | 67 | if (a 68 | || b 69 | || c || d 70 | || (d && b) 71 | ) { 72 | foo() 73 | } 74 | -------------------------------------------------------------------------------- /fixtures/output/ts-strict-with-react/jsx.jsx: -------------------------------------------------------------------------------- 1 | export function HelloWorld({ 2 | greeting = 'hello', 3 | greeted = '"World"', 4 | silent = false, 5 | onMouseOver, 6 | }) { 7 | if (!greeting) { 8 | return null 9 | }; 10 | 11 | // TODO: Don't use random in render 12 | const num = Math 13 | .floor (Math.random() * 1e+7) 14 | .toString() 15 | .replace(/\.\d+/g, '') 16 | 17 | return ( 18 |
19 | { greeting.slice(0, 1).toUpperCase() + greeting.slice(1).toLowerCase() } 20 | {greeting.endsWith(',') 21 | ? ' ' 22 | : ", " } 23 | 24 | { greeted } 25 | 26 | { (silent) ? '.' : '!'} 27 |
28 | ) 29 | } 30 | -------------------------------------------------------------------------------- /fixtures/output/ts-strict-with-react/markdown.md: -------------------------------------------------------------------------------- 1 | Header 2 | ====== 3 | 4 | _Look,_ code blocks are formatted *too!* 5 | 6 | ```js 7 | // This should be handled by ESLint instead of Prettier 8 | function identity(x) { 9 | if (foo) { 10 | console.log('bar') 11 | } 12 | } 13 | ``` 14 | 15 | ```css 16 | /* This should be handled by Prettier */ 17 | .foo { color:red;} 18 | ``` 19 | 20 | Pilot|Airport|Hours 21 | --|:--:|--: 22 | John Doe|SKG|1338 23 | Jane Roe|JFK|314 24 | 25 | - - - - - - - - - - - - - - - 26 | 27 | + List 28 | + with a [link] (/to/somewhere) 29 | + and [another one] 30 | 31 | [another one]: http://example.com 'Example title' 32 | 33 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. 34 | Curabitur consectetur maximus risus, sed maximus tellus tincidunt et. 35 | -------------------------------------------------------------------------------- /fixtures/output/ts-strict-with-react/toml.toml: -------------------------------------------------------------------------------- 1 | comma = [ 2 | 1, 3 | 2, 4 | 3, 5 | ] 6 | 7 | [foo] 8 | b = 1 9 | c = "hello" 10 | a = { answer = 42 } 11 | indent = [ 12 | 1, 13 | 2 14 | ] 15 | 16 | [a-table] 17 | apple.type = "fruit" 18 | apple.skin = "thin" 19 | apple.color = "red" 20 | 21 | orange.type = "fruit" 22 | orange.skin = "thick" 23 | orange.color = "orange" 24 | -------------------------------------------------------------------------------- /fixtures/output/ts-strict-with-react/tsx.tsx: -------------------------------------------------------------------------------- 1 | export function Component1() { 2 | return
3 | } 4 | 5 | export function jsx2() { 6 | const props = { a: 1, b: 2 } 7 | return ( 8 | 9 |
14 | Inline Text 15 |
16 | 17 | Block Text 18 | 19 |
20 | Mixed 21 |
Foo
22 | Text 23 | Bar 24 |
25 |

26 | foo 27 | bar 28 | baz 29 |

30 |
31 | ) 32 | } 33 | -------------------------------------------------------------------------------- /fixtures/output/ts-strict-with-react/typescript.ts: -------------------------------------------------------------------------------- 1 | // Define a TypeScript interface 2 | interface Person { 3 | name: string 4 | age: number 5 | } 6 | 7 | // Create an array of objects with the defined interface 8 | const people: Person[] = [ 9 | { name: 'Alice', age: 30 }, 10 | { name: 'Bob', age: 25 }, 11 | { name: 'Charlie', age: 35 }, 12 | ] 13 | 14 | // eslint-disable-next-line no-console 15 | const log = console.log 16 | 17 | // Use a for...of loop to iterate over the array 18 | for (const person of people) { 19 | log(`Hello, my name is ${person.name} and I am ${person.age} years old.`) 20 | } 21 | 22 | // Define a generic function 23 | function identity(arg: T): T { 24 | return arg 25 | } 26 | 27 | // Use the generic function with type inference 28 | const result = identity( 29 | 'TypeScript is awesome', 30 | ) 31 | log(result) 32 | 33 | // Use optional properties in an interface 34 | interface Car { 35 | make: string 36 | model?: string 37 | } 38 | 39 | // Create objects using the interface 40 | const car1: Car = { make: 'Toyota' } 41 | const car2: Car = { 42 | make: 'Ford', 43 | model: 'Focus', 44 | } 45 | 46 | // Use union types 47 | type Fruit = 'apple' | 'banana' | 'orange' 48 | const favoriteFruit: Fruit = 'apple' 49 | 50 | // Use a type assertion to tell TypeScript about the type 51 | const inputValue: any = '42' 52 | const numericValue = inputValue as number 53 | 54 | // Define a class with access modifiers 55 | class Animal { 56 | private name: string 57 | constructor(name: string) { 58 | this.name = name 59 | } 60 | 61 | protected makeSound(sound: string) { 62 | log(`${this.name} says ${sound}`) 63 | } 64 | } 65 | 66 | // Extend a class 67 | class Dog extends Animal { 68 | constructor(private alias: string) { 69 | super(alias) 70 | } 71 | 72 | bark() { 73 | this.makeSound('Woof!') 74 | } 75 | } 76 | 77 | const dog = new Dog('Buddy') 78 | dog.bark() 79 | 80 | function fn(): string { 81 | return `hello${1}` 82 | } 83 | 84 | log(car1, car2, favoriteFruit, numericValue, fn()) 85 | 86 | // Generator 87 | export function* generator1() { 88 | let id = 0 89 | while (id < 100) { 90 | yield id++ 91 | } 92 | } 93 | export function* generator2() { 94 | yield* generator1() 95 | } 96 | -------------------------------------------------------------------------------- /fixtures/output/ts-strict-with-react/vue-ts.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 23 | 24 | 27 | 28 | 36 | -------------------------------------------------------------------------------- /fixtures/output/ts-strict-with-react/vue.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 28 | -------------------------------------------------------------------------------- /fixtures/output/ts-strict/javascript.js: -------------------------------------------------------------------------------- 1 | // This file is generated by ChatGPT 2 | 3 | // eslint-disable-next-line no-console 4 | const log = console.log 5 | 6 | // Define a class using ES6 class syntax 7 | class Person { 8 | constructor(name, age) { 9 | this.name = name 10 | this.age = age 11 | } 12 | 13 | // Define a method within the class 14 | sayHello() { 15 | log(`Hello, my name is ${this.name} and I am ${this.age} years old.`) 16 | } 17 | } 18 | 19 | // Create an array of objects 20 | const people = [ 21 | new Person('Alice', 30), 22 | new Person('Bob', 25), 23 | new Person('Charlie', 35), 24 | ] 25 | 26 | // Use the forEach method to iterate over the array 27 | people.forEach((person) => { 28 | person.sayHello() 29 | }) 30 | 31 | // Use a template literal to create a multiline string 32 | const multilineString = ` 33 | This is a multiline string 34 | that spans multiple lines. 35 | ` 36 | 37 | // Use destructuring assignment to extract values from an object 38 | const { name, age } = people[0] 39 | log(`First person in the array is ${name} and they are ${age} years old.`, multilineString) 40 | 41 | // Use the spread operator to create a new array 42 | const numbers = [1, 2, 3] 43 | const newNumbers = [...numbers, 4, 5] 44 | log(newNumbers) 45 | 46 | // Use a try-catch block for error handling 47 | try { 48 | // Attempt to parse an invalid JSON string 49 | JSON.parse('invalid JSON') 50 | } 51 | catch (error) { 52 | console.error('Error parsing JSON:', error.message) 53 | } 54 | 55 | // Use a ternary conditional operator 56 | const isEven = num => num % 2 === 0 57 | const number = 7 58 | log(`${number} is ${isEven(number) ? 'even' : 'odd'}.`) 59 | 60 | // Use a callback function with setTimeout for asynchronous code 61 | setTimeout(() => { 62 | log('This code runs after a delay of 2 seconds.') 63 | }, 2000) 64 | 65 | let a, b, c, d, foo 66 | 67 | if (a 68 | || b 69 | || c || d 70 | || (d && b) 71 | ) { 72 | foo() 73 | } 74 | -------------------------------------------------------------------------------- /fixtures/output/ts-strict/jsx.jsx: -------------------------------------------------------------------------------- 1 | export function HelloWorld({ 2 | greeting = 'hello', 3 | greeted = '"World"', 4 | silent = false, 5 | onMouseOver, 6 | }) { 7 | if (!greeting) { 8 | return null 9 | }; 10 | 11 | // TODO: Don't use random in render 12 | const num = Math 13 | .floor (Math.random() * 1e+7) 14 | .toString() 15 | .replace(/\.\d+/g, '') 16 | 17 | return ( 18 |
19 | { greeting.slice(0, 1).toUpperCase() + greeting.slice(1).toLowerCase() } 20 | {greeting.endsWith(',') 21 | ? ' ' 22 | : ", " } 23 | 24 | { greeted } 25 | 26 | { (silent) ? '.' : '!'} 27 |
28 | ) 29 | } 30 | -------------------------------------------------------------------------------- /fixtures/output/ts-strict/markdown.md: -------------------------------------------------------------------------------- 1 | Header 2 | ====== 3 | 4 | _Look,_ code blocks are formatted *too!* 5 | 6 | ```js 7 | // This should be handled by ESLint instead of Prettier 8 | function identity(x) { 9 | if (foo) { 10 | console.log('bar') 11 | } 12 | } 13 | ``` 14 | 15 | ```css 16 | /* This should be handled by Prettier */ 17 | .foo { color:red;} 18 | ``` 19 | 20 | Pilot|Airport|Hours 21 | --|:--:|--: 22 | John Doe|SKG|1338 23 | Jane Roe|JFK|314 24 | 25 | - - - - - - - - - - - - - - - 26 | 27 | + List 28 | + with a [link] (/to/somewhere) 29 | + and [another one] 30 | 31 | [another one]: http://example.com 'Example title' 32 | 33 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. 34 | Curabitur consectetur maximus risus, sed maximus tellus tincidunt et. 35 | -------------------------------------------------------------------------------- /fixtures/output/ts-strict/toml.toml: -------------------------------------------------------------------------------- 1 | comma = [ 2 | 1, 3 | 2, 4 | 3, 5 | ] 6 | 7 | [foo] 8 | b = 1 9 | c = "hello" 10 | a = { answer = 42 } 11 | indent = [ 12 | 1, 13 | 2 14 | ] 15 | 16 | [a-table] 17 | apple.type = "fruit" 18 | apple.skin = "thin" 19 | apple.color = "red" 20 | 21 | orange.type = "fruit" 22 | orange.skin = "thick" 23 | orange.color = "orange" 24 | -------------------------------------------------------------------------------- /fixtures/output/ts-strict/tsx.tsx: -------------------------------------------------------------------------------- 1 | export function Component1() { 2 | return
3 | } 4 | 5 | export function jsx2() { 6 | const props = { a: 1, b: 2 } 7 | return ( 8 | 9 |
14 | Inline Text 15 |
16 | 17 | Block Text 18 | 19 |
20 | Mixed 21 |
Foo
22 | Text 23 | Bar 24 |
25 |

26 | foo 27 | bar 28 | baz 29 |

30 |
31 | ) 32 | } 33 | -------------------------------------------------------------------------------- /fixtures/output/ts-strict/typescript.ts: -------------------------------------------------------------------------------- 1 | // Define a TypeScript interface 2 | interface Person { 3 | name: string 4 | age: number 5 | } 6 | 7 | // Create an array of objects with the defined interface 8 | const people: Person[] = [ 9 | { name: 'Alice', age: 30 }, 10 | { name: 'Bob', age: 25 }, 11 | { name: 'Charlie', age: 35 }, 12 | ] 13 | 14 | // eslint-disable-next-line no-console 15 | const log = console.log 16 | 17 | // Use a for...of loop to iterate over the array 18 | for (const person of people) { 19 | log(`Hello, my name is ${person.name} and I am ${person.age} years old.`) 20 | } 21 | 22 | // Define a generic function 23 | function identity(arg: T): T { 24 | return arg 25 | } 26 | 27 | // Use the generic function with type inference 28 | const result = identity( 29 | 'TypeScript is awesome', 30 | ) 31 | log(result) 32 | 33 | // Use optional properties in an interface 34 | interface Car { 35 | make: string 36 | model?: string 37 | } 38 | 39 | // Create objects using the interface 40 | const car1: Car = { make: 'Toyota' } 41 | const car2: Car = { 42 | make: 'Ford', 43 | model: 'Focus', 44 | } 45 | 46 | // Use union types 47 | type Fruit = 'apple' | 'banana' | 'orange' 48 | const favoriteFruit: Fruit = 'apple' 49 | 50 | // Use a type assertion to tell TypeScript about the type 51 | const inputValue: any = '42' 52 | const numericValue = inputValue as number 53 | 54 | // Define a class with access modifiers 55 | class Animal { 56 | private name: string 57 | constructor(name: string) { 58 | this.name = name 59 | } 60 | 61 | protected makeSound(sound: string) { 62 | log(`${this.name} says ${sound}`) 63 | } 64 | } 65 | 66 | // Extend a class 67 | class Dog extends Animal { 68 | constructor(private alias: string) { 69 | super(alias) 70 | } 71 | 72 | bark() { 73 | this.makeSound('Woof!') 74 | } 75 | } 76 | 77 | const dog = new Dog('Buddy') 78 | dog.bark() 79 | 80 | function fn(): string { 81 | return `hello${1}` 82 | } 83 | 84 | log(car1, car2, favoriteFruit, numericValue, fn()) 85 | 86 | // Generator 87 | export function* generator1() { 88 | let id = 0 89 | while (id < 100) { 90 | yield id++ 91 | } 92 | } 93 | export function* generator2() { 94 | yield* generator1() 95 | } 96 | -------------------------------------------------------------------------------- /fixtures/output/ts-strict/vue-ts.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 23 | 24 | 27 | 28 | 36 | -------------------------------------------------------------------------------- /fixtures/output/ts-strict/vue.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 28 | -------------------------------------------------------------------------------- /fixtures/output/with-formatters/astro.astro: -------------------------------------------------------------------------------- 1 | --- 2 | const isJsx = true 3 | const content = 'hi!' 4 | --- 5 | 6 |
7 |
{content}
8 |
9 | {isJsx &&

{content}

} 10 |
11 |
12 | 13 | 19 | -------------------------------------------------------------------------------- /fixtures/output/with-formatters/css.css: -------------------------------------------------------------------------------- 1 | @media (max-width: 480px) { 2 | .bd-examples { 3 | margin-right: -0.75rem; 4 | margin-left: -0.75rem; 5 | } 6 | 7 | .bd-examples > [class^='col-'] { 8 | padding-right: 0.75rem; 9 | padding-left: 0.75rem; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /fixtures/output/with-formatters/html.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | My tITlE 6 | 7 | 8 | 9 |

10 | Hello world!
11 | This is HTML5 Boilerplate. 12 |

13 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /fixtures/output/with-formatters/javascript.js: -------------------------------------------------------------------------------- 1 | // This file is generated by ChatGPT 2 | 3 | // eslint-disable-next-line no-console 4 | const log = console.log 5 | 6 | // Define a class using ES6 class syntax 7 | class Person { 8 | constructor(name, age) { 9 | this.name = name 10 | this.age = age 11 | } 12 | 13 | // Define a method within the class 14 | sayHello() { 15 | log(`Hello, my name is ${this.name} and I am ${this.age} years old.`) 16 | } 17 | } 18 | 19 | // Create an array of objects 20 | const people = [ 21 | new Person('Alice', 30), 22 | new Person('Bob', 25), 23 | new Person('Charlie', 35), 24 | ] 25 | 26 | // Use the forEach method to iterate over the array 27 | people.forEach((person) => { 28 | person.sayHello() 29 | }) 30 | 31 | // Use a template literal to create a multiline string 32 | const multilineString = ` 33 | This is a multiline string 34 | that spans multiple lines. 35 | ` 36 | 37 | // Use destructuring assignment to extract values from an object 38 | const { name, age } = people[0] 39 | log(`First person in the array is ${name} and they are ${age} years old.`, multilineString) 40 | 41 | // Use the spread operator to create a new array 42 | const numbers = [1, 2, 3] 43 | const newNumbers = [...numbers, 4, 5] 44 | log(newNumbers) 45 | 46 | // Use a try-catch block for error handling 47 | try { 48 | // Attempt to parse an invalid JSON string 49 | JSON.parse('invalid JSON') 50 | } 51 | catch (error) { 52 | console.error('Error parsing JSON:', error.message) 53 | } 54 | 55 | // Use a ternary conditional operator 56 | const isEven = num => num % 2 === 0 57 | const number = 7 58 | log(`${number} is ${isEven(number) ? 'even' : 'odd'}.`) 59 | 60 | // Use a callback function with setTimeout for asynchronous code 61 | setTimeout(() => { 62 | log('This code runs after a delay of 2 seconds.') 63 | }, 2000) 64 | 65 | let a, b, c, d, foo 66 | 67 | if (a 68 | || b 69 | || c || d 70 | || (d && b) 71 | ) { 72 | foo() 73 | } 74 | -------------------------------------------------------------------------------- /fixtures/output/with-formatters/jsx.jsx: -------------------------------------------------------------------------------- 1 | export function HelloWorld({ 2 | greeting = 'hello', 3 | greeted = '"World"', 4 | silent = false, 5 | onMouseOver, 6 | }) { 7 | if (!greeting) { 8 | return null 9 | }; 10 | 11 | // TODO: Don't use random in render 12 | const num = Math 13 | .floor (Math.random() * 1e+7) 14 | .toString() 15 | .replace(/\.\d+/g, '') 16 | 17 | return ( 18 |
19 | { greeting.slice(0, 1).toUpperCase() + greeting.slice(1).toLowerCase() } 20 | {greeting.endsWith(',') 21 | ? ' ' 22 | : ", " } 23 | 24 | { greeted } 25 | 26 | { (silent) ? '.' : '!'} 27 |
28 | ) 29 | } 30 | -------------------------------------------------------------------------------- /fixtures/output/with-formatters/markdown.md: -------------------------------------------------------------------------------- 1 | # Header 2 | 3 | _Look,_ code blocks are formatted _too!_ 4 | 5 | ```js 6 | // This should be handled by ESLint instead of Prettier 7 | function identity(x) { 8 | if (foo) { 9 | console.log('bar') 10 | } 11 | } 12 | ``` 13 | 14 | ```css 15 | /* This should be handled by Prettier */ 16 | .foo { 17 | color: red; 18 | } 19 | ``` 20 | 21 | | Pilot | Airport | Hours | 22 | | -------- | :-----: | ----: | 23 | | John Doe | SKG | 1338 | 24 | | Jane Roe | JFK | 314 | 25 | 26 | --- 27 | 28 | - List 29 | - with a [link] (/to/somewhere) 30 | - and [another one] 31 | 32 | [another one]: http://example.com 'Example title' 33 | 34 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. 35 | Curabitur consectetur maximus risus, sed maximus tellus tincidunt et. 36 | -------------------------------------------------------------------------------- /fixtures/output/with-formatters/svg.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /fixtures/output/with-formatters/toml.toml: -------------------------------------------------------------------------------- 1 | comma = [ 2 | 1, 3 | 2, 4 | 3, 5 | ] 6 | 7 | [foo] 8 | b = 1 9 | c = "hello" 10 | a = { answer = 42 } 11 | indent = [ 12 | 1, 13 | 2 14 | ] 15 | 16 | [a-table] 17 | apple.type = "fruit" 18 | apple.skin = "thin" 19 | apple.color = "red" 20 | 21 | orange.type = "fruit" 22 | orange.skin = "thick" 23 | orange.color = "orange" 24 | -------------------------------------------------------------------------------- /fixtures/output/with-formatters/tsx.tsx: -------------------------------------------------------------------------------- 1 | export function Component1() { 2 | return
3 | } 4 | 5 | export function jsx2() { 6 | const props = { a: 1, b: 2 } 7 | return ( 8 | 9 |
14 | Inline Text 15 |
16 | 17 | Block Text 18 | 19 |
20 | Mixed 21 |
Foo
22 | Text 23 | Bar 24 |
25 |

26 | foo 27 | bar 28 | baz 29 |

30 |
31 | ) 32 | } 33 | -------------------------------------------------------------------------------- /fixtures/output/with-formatters/typescript.ts: -------------------------------------------------------------------------------- 1 | // Define a TypeScript interface 2 | interface Person { 3 | name: string 4 | age: number 5 | } 6 | 7 | // Create an array of objects with the defined interface 8 | const people: Person[] = [ 9 | { name: 'Alice', age: 30 }, 10 | { name: 'Bob', age: 25 }, 11 | { name: 'Charlie', age: 35 }, 12 | ] 13 | 14 | // eslint-disable-next-line no-console 15 | const log = console.log 16 | 17 | // Use a for...of loop to iterate over the array 18 | for (const person of people) { 19 | log(`Hello, my name is ${person.name} and I am ${person.age} years old.`) 20 | } 21 | 22 | // Define a generic function 23 | function identity(arg: T): T { 24 | return arg 25 | } 26 | 27 | // Use the generic function with type inference 28 | const result = identity( 29 | 'TypeScript is awesome', 30 | ) 31 | log(result) 32 | 33 | // Use optional properties in an interface 34 | interface Car { 35 | make: string 36 | model?: string 37 | } 38 | 39 | // Create objects using the interface 40 | const car1: Car = { make: 'Toyota' } 41 | const car2: Car = { 42 | make: 'Ford', 43 | model: 'Focus', 44 | } 45 | 46 | // Use union types 47 | type Fruit = 'apple' | 'banana' | 'orange' 48 | const favoriteFruit: Fruit = 'apple' 49 | 50 | // Use a type assertion to tell TypeScript about the type 51 | const inputValue: any = '42' 52 | const numericValue = inputValue as number 53 | 54 | // Define a class with access modifiers 55 | class Animal { 56 | private name: string 57 | constructor(name: string) { 58 | this.name = name 59 | } 60 | 61 | protected makeSound(sound: string) { 62 | log(`${this.name} says ${sound}`) 63 | } 64 | } 65 | 66 | // Extend a class 67 | class Dog extends Animal { 68 | constructor(private alias: string) { 69 | super(alias) 70 | } 71 | 72 | bark() { 73 | this.makeSound('Woof!') 74 | } 75 | } 76 | 77 | const dog = new Dog('Buddy') 78 | dog.bark() 79 | 80 | function fn(): string { 81 | return `hello${1}` 82 | } 83 | 84 | log(car1, car2, favoriteFruit, numericValue, fn()) 85 | 86 | // Generator 87 | export function* generator1() { 88 | let id = 0 89 | while (id < 100) { 90 | yield id++ 91 | } 92 | } 93 | export function* generator2() { 94 | yield* generator1() 95 | } 96 | -------------------------------------------------------------------------------- /fixtures/output/with-formatters/vue-ts.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 23 | 24 | 29 | 30 | 39 | -------------------------------------------------------------------------------- /fixtures/output/with-formatters/vue.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 28 | -------------------------------------------------------------------------------- /fixtures/output/with-formatters/xml.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Effective Java 4 | 45.00 5 | 6 | 7 | Bluetooth Speaker 8 | 120.00 9 | 10 | 11 | Clean Code 12 | 33.50 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | publish = ".eslint-config-inspector" 3 | command = "pnpm run build:inspector" 4 | 5 | [build.environment] 6 | NODE_VERSION = "22" 7 | 8 | [[redirects]] 9 | from = "/*" 10 | to = "/index.html" 11 | status = 200 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@antfu/eslint-config", 3 | "type": "module", 4 | "version": "4.13.2", 5 | "packageManager": "pnpm@10.11.0", 6 | "description": "Anthony's ESLint config", 7 | "author": "Anthony Fu (https://github.com/antfu/)", 8 | "license": "MIT", 9 | "funding": "https://github.com/sponsors/antfu", 10 | "homepage": "https://github.com/antfu/eslint-config", 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/antfu/eslint-config.git" 14 | }, 15 | "bugs": { 16 | "url": "https://github.com/antfu/eslint-config/issues" 17 | }, 18 | "keywords": [ 19 | "eslint-config" 20 | ], 21 | "exports": { 22 | ".": "./dist/index.js" 23 | }, 24 | "main": "./dist/index.js", 25 | "types": "./dist/index.d.ts", 26 | "bin": "./bin/index.js", 27 | "files": [ 28 | "bin", 29 | "dist" 30 | ], 31 | "scripts": { 32 | "build": "nr gen && tsdown --clean --dts", 33 | "stub": "tsdown", 34 | "dev": "npx @eslint/config-inspector --config eslint.config.ts", 35 | "build:inspector": "pnpm build && npx @eslint/config-inspector build", 36 | "watch": "tsdown --watch", 37 | "lint": "eslint", 38 | "gen": "tsx scripts/typegen.ts && tsx scripts/versiongen.ts", 39 | "prepack": "nr build", 40 | "release": "bumpp && pnpm publish", 41 | "test": "vitest", 42 | "typecheck": "tsc --noEmit", 43 | "prepare": "simple-git-hooks" 44 | }, 45 | "peerDependencies": { 46 | "@eslint-react/eslint-plugin": "^1.38.4", 47 | "@prettier/plugin-xml": "^3.4.1", 48 | "@unocss/eslint-plugin": ">=0.50.0", 49 | "astro-eslint-parser": "^1.0.2", 50 | "eslint": "^9.10.0", 51 | "eslint-plugin-astro": "^1.2.0", 52 | "eslint-plugin-format": ">=0.1.0", 53 | "eslint-plugin-react-hooks": "^5.2.0", 54 | "eslint-plugin-react-refresh": "^0.4.19", 55 | "eslint-plugin-solid": "^0.14.3", 56 | "eslint-plugin-svelte": ">=2.35.1", 57 | "eslint-plugin-vuejs-accessibility": "^2.4.1", 58 | "prettier-plugin-astro": "^0.14.0", 59 | "prettier-plugin-slidev": "^1.0.5", 60 | "svelte-eslint-parser": ">=0.37.0" 61 | }, 62 | "peerDependenciesMeta": { 63 | "@eslint-react/eslint-plugin": { 64 | "optional": true 65 | }, 66 | "@prettier/plugin-xml": { 67 | "optional": true 68 | }, 69 | "@unocss/eslint-plugin": { 70 | "optional": true 71 | }, 72 | "astro-eslint-parser": { 73 | "optional": true 74 | }, 75 | "eslint-plugin-astro": { 76 | "optional": true 77 | }, 78 | "eslint-plugin-format": { 79 | "optional": true 80 | }, 81 | "eslint-plugin-react-hooks": { 82 | "optional": true 83 | }, 84 | "eslint-plugin-react-refresh": { 85 | "optional": true 86 | }, 87 | "eslint-plugin-solid": { 88 | "optional": true 89 | }, 90 | "eslint-plugin-svelte": { 91 | "optional": true 92 | }, 93 | "eslint-plugin-vuejs-accessibility": { 94 | "optional": true 95 | }, 96 | "prettier-plugin-astro": { 97 | "optional": true 98 | }, 99 | "prettier-plugin-slidev": { 100 | "optional": true 101 | }, 102 | "svelte-eslint-parser": { 103 | "optional": true 104 | } 105 | }, 106 | "dependencies": { 107 | "@antfu/install-pkg": "catalog:prod", 108 | "@clack/prompts": "catalog:prod", 109 | "@eslint-community/eslint-plugin-eslint-comments": "catalog:prod", 110 | "@eslint/markdown": "catalog:prod", 111 | "@stylistic/eslint-plugin": "catalog:prod", 112 | "@typescript-eslint/eslint-plugin": "catalog:prod", 113 | "@typescript-eslint/parser": "catalog:prod", 114 | "@vitest/eslint-plugin": "catalog:prod", 115 | "ansis": "catalog:prod", 116 | "cac": "catalog:prod", 117 | "eslint-config-flat-gitignore": "catalog:prod", 118 | "eslint-flat-config-utils": "catalog:prod", 119 | "eslint-merge-processors": "catalog:prod", 120 | "eslint-plugin-antfu": "catalog:prod", 121 | "eslint-plugin-command": "catalog:prod", 122 | "eslint-plugin-import-x": "catalog:prod", 123 | "eslint-plugin-jsdoc": "catalog:prod", 124 | "eslint-plugin-jsonc": "catalog:prod", 125 | "eslint-plugin-n": "catalog:prod", 126 | "eslint-plugin-no-only-tests": "catalog:prod", 127 | "eslint-plugin-perfectionist": "catalog:prod", 128 | "eslint-plugin-pnpm": "catalog:prod", 129 | "eslint-plugin-regexp": "catalog:prod", 130 | "eslint-plugin-toml": "catalog:prod", 131 | "eslint-plugin-unicorn": "catalog:prod", 132 | "eslint-plugin-unused-imports": "catalog:prod", 133 | "eslint-plugin-vue": "catalog:prod", 134 | "eslint-plugin-yml": "catalog:prod", 135 | "eslint-processor-vue-blocks": "catalog:prod", 136 | "globals": "catalog:prod", 137 | "jsonc-eslint-parser": "catalog:prod", 138 | "local-pkg": "catalog:prod", 139 | "parse-gitignore": "catalog:prod", 140 | "toml-eslint-parser": "catalog:prod", 141 | "vue-eslint-parser": "catalog:prod", 142 | "yaml-eslint-parser": "catalog:prod" 143 | }, 144 | "devDependencies": { 145 | "@antfu/eslint-config": "workspace:*", 146 | "@antfu/ni": "catalog:dev", 147 | "@eslint-react/eslint-plugin": "catalog:peer", 148 | "@eslint/config-inspector": "catalog:dev", 149 | "@prettier/plugin-xml": "catalog:peer", 150 | "@stylistic/eslint-plugin-migrate": "catalog:dev", 151 | "@types/node": "catalog:dev", 152 | "@unocss/eslint-plugin": "catalog:peer", 153 | "astro-eslint-parser": "catalog:peer", 154 | "bumpp": "catalog:dev", 155 | "eslint": "catalog:peer", 156 | "eslint-plugin-astro": "catalog:peer", 157 | "eslint-plugin-format": "catalog:peer", 158 | "eslint-plugin-react-hooks": "catalog:peer", 159 | "eslint-plugin-react-refresh": "catalog:peer", 160 | "eslint-plugin-solid": "catalog:peer", 161 | "eslint-plugin-svelte": "catalog:peer", 162 | "eslint-plugin-vuejs-accessibility": "catalog:peer", 163 | "eslint-typegen": "catalog:dev", 164 | "execa": "catalog:dev", 165 | "jiti": "catalog:dev", 166 | "lint-staged": "catalog:dev", 167 | "pnpm-workspace-yaml": "catalog:dev", 168 | "prettier-plugin-astro": "catalog:peer", 169 | "prettier-plugin-slidev": "catalog:peer", 170 | "simple-git-hooks": "catalog:dev", 171 | "svelte": "catalog:peer", 172 | "svelte-eslint-parser": "catalog:peer", 173 | "tinyglobby": "catalog:dev", 174 | "tsdown": "catalog:dev", 175 | "tsx": "catalog:dev", 176 | "typescript": "catalog:dev", 177 | "vitest": "catalog:dev", 178 | "vue": "catalog:peer" 179 | }, 180 | "simple-git-hooks": { 181 | "pre-commit": "npx lint-staged" 182 | }, 183 | "lint-staged": { 184 | "*": "eslint --fix" 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - fixtures/* 3 | overrides: 4 | '@eslint-community/eslint-utils': ^4.7.0 5 | '@typescript-eslint/utils': ^8.32.1 6 | eslint: ^9.27.0 7 | tsx: ^4.19.4 8 | catalogs: 9 | dev: 10 | '@antfu/ni': ^24.4.0 11 | '@eslint/config-inspector': ^1.0.2 12 | '@stylistic/eslint-plugin-migrate': ^4.2.0 13 | '@types/node': ^22.15.21 14 | bumpp: ^10.1.1 15 | eslint-typegen: ^2.2.0 16 | execa: ^9.5.3 17 | jiti: ^2.4.2 18 | lint-staged: ^16.0.0 19 | pnpm-workspace-yaml: ^0.3.1 20 | simple-git-hooks: ^2.13.0 21 | tinyglobby: ^0.2.13 22 | tsdown: ^0.11.13 23 | tsx: ^4.19.4 24 | typescript: ^5.8.3 25 | vitest: ^3.1.4 26 | peer: 27 | '@eslint-react/eslint-plugin': ^1.49.0 28 | '@prettier/plugin-xml': ^3.4.1 29 | '@unocss/eslint-plugin': ^66.1.2 30 | astro-eslint-parser: ^1.2.2 31 | eslint: ^9.27.0 32 | eslint-plugin-astro: ^1.3.1 33 | eslint-plugin-format: ^1.0.1 34 | eslint-plugin-react-hooks: ^5.2.0 35 | eslint-plugin-react-refresh: ^0.4.20 36 | eslint-plugin-solid: ^0.14.5 37 | eslint-plugin-svelte: ^3.8.2 38 | eslint-plugin-vuejs-accessibility: ^2.4.1 39 | prettier-plugin-astro: ^0.14.1 40 | prettier-plugin-slidev: ^1.0.5 41 | svelte: ^5.32.1 42 | svelte-eslint-parser: ^1.2.0 43 | vue: ^3.5.14 44 | prod: 45 | '@antfu/install-pkg': ^1.1.0 46 | '@clack/prompts': ^0.10.1 47 | '@eslint-community/eslint-plugin-eslint-comments': ^4.5.0 48 | '@eslint/markdown': ^6.4.0 49 | '@stylistic/eslint-plugin': ^4.2.0 50 | '@typescript-eslint/eslint-plugin': ^8.32.1 51 | '@typescript-eslint/parser': ^8.32.1 52 | '@vitest/eslint-plugin': ^1.2.0 53 | ansis: ^4.0.0 54 | cac: ^6.7.14 55 | eslint-config-flat-gitignore: ^2.1.0 56 | eslint-flat-config-utils: ^2.1.0 57 | eslint-merge-processors: ^2.0.0 58 | eslint-plugin-antfu: ^3.1.1 59 | eslint-plugin-command: ^3.2.0 60 | eslint-plugin-import-x: ^4.12.2 61 | eslint-plugin-jsdoc: ^50.6.17 62 | eslint-plugin-jsonc: ^2.20.1 63 | eslint-plugin-n: ^17.18.0 64 | eslint-plugin-no-only-tests: ^3.3.0 65 | eslint-plugin-perfectionist: ^4.13.0 66 | eslint-plugin-pnpm: ^0.3.1 67 | eslint-plugin-regexp: ^2.7.0 68 | eslint-plugin-toml: ^0.12.0 69 | eslint-plugin-unicorn: ^59.0.1 70 | eslint-plugin-unused-imports: ^4.1.4 71 | eslint-plugin-vue: ^10.1.0 72 | eslint-plugin-yml: ^1.18.0 73 | eslint-processor-vue-blocks: ^2.0.0 74 | globals: ^16.1.0 75 | jsonc-eslint-parser: ^2.4.0 76 | local-pkg: ^1.1.1 77 | parse-gitignore: ^2.0.0 78 | toml-eslint-parser: ^0.10.0 79 | vue-eslint-parser: ^10.1.3 80 | yaml-eslint-parser: ^1.3.0 81 | onlyBuiltDependencies: 82 | - esbuild 83 | - simple-git-hooks 84 | - unrs-resolver 85 | -------------------------------------------------------------------------------- /scripts/typegen.ts: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs/promises' 2 | 3 | import { flatConfigsToRulesDTS } from 'eslint-typegen/core' 4 | import { builtinRules } from 'eslint/use-at-your-own-risk' 5 | 6 | import { astro, combine, comments, formatters, imports, javascript, jsdoc, jsonc, jsx, markdown, node, perfectionist, react, regexp, solid, sortPackageJson, stylistic, svelte, test, toml, typescript, unicorn, unocss, vue, yaml } from '../src' 7 | 8 | const configs = await combine( 9 | { 10 | plugins: { 11 | '': { 12 | rules: Object.fromEntries(builtinRules.entries()), 13 | }, 14 | }, 15 | }, 16 | astro(), 17 | comments(), 18 | formatters(), 19 | imports(), 20 | javascript(), 21 | jsx(), 22 | jsdoc(), 23 | jsonc(), 24 | markdown(), 25 | node(), 26 | perfectionist(), 27 | react(), 28 | solid(), 29 | sortPackageJson(), 30 | stylistic(), 31 | svelte(), 32 | test(), 33 | toml(), 34 | regexp(), 35 | typescript(), 36 | unicorn(), 37 | unocss(), 38 | vue(), 39 | yaml(), 40 | ) 41 | 42 | const configNames = configs.map(i => i.name).filter(Boolean) as string[] 43 | 44 | let dts = await flatConfigsToRulesDTS(configs, { 45 | includeAugmentation: false, 46 | }) 47 | 48 | dts += ` 49 | // Names of all the configs 50 | export type ConfigNames = ${configNames.map(i => `'${i}'`).join(' | ')} 51 | ` 52 | 53 | await fs.writeFile('src/typegen.d.ts', dts) 54 | -------------------------------------------------------------------------------- /scripts/versiongen.ts: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs/promises' 2 | import { parsePnpmWorkspaceYaml } from 'pnpm-workspace-yaml' 3 | import { dependenciesMap } from '../src/cli/constants' 4 | 5 | const names = new Set([ 6 | 'eslint', 7 | ...Object.values(dependenciesMap).flat(), 8 | ]) 9 | 10 | const yaml = parsePnpmWorkspaceYaml(await fs.readFile(new URL('../pnpm-workspace.yaml', import.meta.url), 'utf-8')).toJSON() 11 | const catalogs = Object.values({ 12 | default: yaml.catalog || {}, 13 | ...yaml.catalogs, 14 | }) 15 | 16 | const versions = Object.fromEntries(Array.from(names).map((name) => { 17 | const version = catalogs.map(c => c[name]).filter(Boolean)[0] 18 | if (!version) 19 | throw new Error(`Package ${name} not found`) 20 | return [name, version] 21 | }).sort((a, b) => a[0].localeCompare(b[0]))) 22 | 23 | await fs.writeFile(new URL('../src/cli/constants-generated.ts', import.meta.url), `export const versionsMap = ${JSON.stringify(versions, null, 2)}`) 24 | -------------------------------------------------------------------------------- /src/cli.ts: -------------------------------------------------------------------------------- 1 | export * from './cli/index' 2 | -------------------------------------------------------------------------------- /src/cli/constants-generated.ts: -------------------------------------------------------------------------------- 1 | export const versionsMap = { 2 | "@eslint-react/eslint-plugin": "^1.49.0", 3 | "@unocss/eslint-plugin": "^66.1.2", 4 | "astro-eslint-parser": "^1.2.2", 5 | "eslint": "^9.26.0", 6 | "eslint-plugin-astro": "^1.3.1", 7 | "eslint-plugin-format": "^1.0.1", 8 | "eslint-plugin-react-hooks": "^5.2.0", 9 | "eslint-plugin-react-refresh": "^0.4.20", 10 | "eslint-plugin-solid": "^0.14.5", 11 | "eslint-plugin-svelte": "^3.7.0", 12 | "prettier-plugin-astro": "^0.14.1", 13 | "prettier-plugin-slidev": "^1.0.5", 14 | "svelte-eslint-parser": "^1.2.0" 15 | } -------------------------------------------------------------------------------- /src/cli/constants.ts: -------------------------------------------------------------------------------- 1 | import type { ExtraLibrariesOption, FrameworkOption, PromItem } from './types' 2 | 3 | import c from 'ansis' 4 | 5 | export const vscodeSettingsString = ` 6 | // Disable the default formatter, use eslint instead 7 | "prettier.enable": false, 8 | "editor.formatOnSave": false, 9 | 10 | // Auto fix 11 | "editor.codeActionsOnSave": { 12 | "source.fixAll.eslint": "explicit", 13 | "source.organizeImports": "never" 14 | }, 15 | 16 | // Silent the stylistic rules in you IDE, but still auto fix them 17 | "eslint.rules.customizations": [ 18 | { "rule": "style/*", "severity": "off", "fixable": true }, 19 | { "rule": "format/*", "severity": "off", "fixable": true }, 20 | { "rule": "*-indent", "severity": "off", "fixable": true }, 21 | { "rule": "*-spacing", "severity": "off", "fixable": true }, 22 | { "rule": "*-spaces", "severity": "off", "fixable": true }, 23 | { "rule": "*-order", "severity": "off", "fixable": true }, 24 | { "rule": "*-dangle", "severity": "off", "fixable": true }, 25 | { "rule": "*-newline", "severity": "off", "fixable": true }, 26 | { "rule": "*quotes", "severity": "off", "fixable": true }, 27 | { "rule": "*semi", "severity": "off", "fixable": true } 28 | ], 29 | 30 | // Enable eslint for all supported languages 31 | "eslint.validate": [ 32 | "javascript", 33 | "javascriptreact", 34 | "typescript", 35 | "typescriptreact", 36 | "vue", 37 | "html", 38 | "markdown", 39 | "json", 40 | "json5", 41 | "jsonc", 42 | "yaml", 43 | "toml", 44 | "xml", 45 | "gql", 46 | "graphql", 47 | "astro", 48 | "svelte", 49 | "css", 50 | "less", 51 | "scss", 52 | "pcss", 53 | "postcss" 54 | ] 55 | ` 56 | 57 | export const frameworkOptions: PromItem[] = [ 58 | { 59 | label: c.green('Vue'), 60 | value: 'vue', 61 | }, 62 | { 63 | label: c.cyan('React'), 64 | value: 'react', 65 | }, 66 | { 67 | label: c.red('Svelte'), 68 | value: 'svelte', 69 | }, 70 | { 71 | label: c.magenta('Astro'), 72 | value: 'astro', 73 | }, 74 | { 75 | label: c.cyan('Solid'), 76 | value: 'solid', 77 | }, 78 | { 79 | label: c.blue('Slidev'), 80 | value: 'slidev', 81 | }, 82 | ] 83 | 84 | export const frameworks: FrameworkOption[] = frameworkOptions.map(({ value }) => (value)) 85 | 86 | export const extraOptions: PromItem[] = [ 87 | { 88 | hint: 'Use external formatters (Prettier and/or dprint) to format files that ESLint cannot handle yet (.css, .html, etc)', 89 | label: c.red('Formatter'), 90 | value: 'formatter', 91 | }, 92 | { 93 | label: c.cyan('UnoCSS'), 94 | value: 'unocss', 95 | }, 96 | ] 97 | 98 | export const extra: ExtraLibrariesOption[] = extraOptions.map(({ value }) => (value)) 99 | 100 | export const dependenciesMap = { 101 | astro: [ 102 | 'eslint-plugin-astro', 103 | 'astro-eslint-parser', 104 | ], 105 | formatter: [ 106 | 'eslint-plugin-format', 107 | ], 108 | formatterAstro: [ 109 | 'prettier-plugin-astro', 110 | ], 111 | react: [ 112 | '@eslint-react/eslint-plugin', 113 | 'eslint-plugin-react-hooks', 114 | 'eslint-plugin-react-refresh', 115 | ], 116 | slidev: [ 117 | 'prettier-plugin-slidev', 118 | ], 119 | solid: [ 120 | 'eslint-plugin-solid', 121 | ], 122 | svelte: [ 123 | 'eslint-plugin-svelte', 124 | 'svelte-eslint-parser', 125 | ], 126 | unocss: [ 127 | '@unocss/eslint-plugin', 128 | ], 129 | vue: [], 130 | } as const 131 | -------------------------------------------------------------------------------- /src/cli/index.ts: -------------------------------------------------------------------------------- 1 | import process from 'node:process' 2 | 3 | import * as p from '@clack/prompts' 4 | import c from 'ansis' 5 | import { cac } from 'cac' 6 | 7 | import { version } from '../../package.json' 8 | import { run } from './run' 9 | 10 | function header(): void { 11 | console.log('\n') 12 | p.intro(`${c.green`@antfu/eslint-config `}${c.dim`v${version}`}`) 13 | } 14 | 15 | const cli = cac('@antfu/eslint-config') 16 | 17 | cli 18 | .command('', 'Run the initialization or migration') 19 | .option('--yes, -y', 'Skip prompts and use default values', { default: false }) 20 | .option('--template, -t