├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .github ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── add-to-project.yaml │ └── ci.yml ├── .gitignore ├── .releaserc.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── commitlint.config.js ├── get-node-supported-versions.sh ├── lefthook.yml ├── package-lock.json ├── package.json ├── renovate.json ├── src ├── index.ts └── test │ ├── export.ts │ └── validate-config.ts └── tsconfig.json /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | indent_style = space 7 | indent_size = 2 8 | 9 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | /lib 2 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | overrides: [ 3 | { 4 | files: ['*.js', '*.ts'], 5 | extends: 'eslint-config-standard-with-typescript', 6 | parserOptions: { 7 | project: './tsconfig.json' 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /.github/workflows/add-to-project.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | pull_request: 3 | types: [opened] 4 | issues: 5 | types: [opened] 6 | 7 | jobs: 8 | add-to-project: 9 | uses: standard/.github/.github/workflows/add-to-project.yaml@master 10 | secrets: inherit 11 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | on: 2 | pull_request: {} 3 | push: {} 4 | 5 | jobs: 6 | publish: 7 | needs: ci 8 | if: github.ref == 'refs/heads/master' 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: navikt/github-app-token-generator@v1 12 | id: get-token 13 | with: 14 | app-id: ${{ secrets.BOT_APP_ID }} 15 | private-key: ${{ secrets.BOT_PRIVATE_KEY }} 16 | - uses: actions/checkout@v4 17 | with: 18 | persist-credentials: false # for later steps to use a different authentication 19 | - uses: actions/setup-node@v4 20 | with: 21 | node-version: latest 22 | - run: npm ci 23 | - run: npx semantic-release 24 | env: 25 | GITHUB_TOKEN: ${{ steps.get-token.outputs.token }} 26 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 27 | # The ci-matrix job ends up as multiple jobs and therefore as multiple checks. 28 | # Each check's name ends up with the node version appended. 29 | # If we were to use those checks as required checks, we would have to occasionally bump them. 30 | # This job allows us to have a single check that we don't have to bump. 31 | ci: 32 | needs: ci-matrix 33 | runs-on: ubuntu-latest 34 | steps: 35 | - run: exit 0 36 | ci-matrix: 37 | needs: get-supported-node-versions 38 | runs-on: ubuntu-latest 39 | strategy: 40 | matrix: 41 | node-version: ${{ fromJson(needs.get-supported-node-versions.outputs.versions) }} 42 | steps: 43 | - uses: actions/checkout@v4 44 | with: 45 | fetch-depth: 0 # for commit linting 46 | - uses: actions/setup-node@v4 47 | with: 48 | node-version: ${{ matrix.node-version }} 49 | - run: npm --global install npm@latest 50 | - run: npm ci 51 | - uses: wagoid/commitlint-github-action@v5 52 | - run: npm test 53 | get-supported-node-versions: 54 | runs-on: ubuntu-latest 55 | steps: 56 | - uses: actions/checkout@v4 57 | - id: get 58 | run: | 59 | set -euxo pipefail 60 | active_versions=$(bash get-node-supported-versions.sh) 61 | echo "active=$active_versions" >> "$GITHUB_OUTPUT" 62 | outputs: 63 | versions: ${{ steps.get.outputs.active }} 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /lib 3 | -------------------------------------------------------------------------------- /.releaserc.yml: -------------------------------------------------------------------------------- 1 | extends: semantic-release-standard 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/standard/eslint-config-standard/60d408b04723fb7cd743f6be7c5c01bb3f729139/CHANGELOG.md -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Feross Aboukhadijeh 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | 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, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # eslint-config-standard [![CI][ci-image]][ci-url] [![npm][npm-image]][npm-url] [![downloads][downloads-image]][downloads-url] [![javascript style guide][standard-image]][standard-url] 2 | 3 | [ci-image]: https://github.com/standard/eslint-config-standard/actions/workflows/ci.yml/badge.svg?branch=master 4 | [ci-url]: https://github.com/standard/eslint-config-standard/actions/workflows/ci.yml 5 | [npm-image]: https://img.shields.io/npm/v/eslint-config-standard.svg 6 | [npm-url]: https://npmjs.org/package/eslint-config-standard 7 | [downloads-image]: https://img.shields.io/npm/dm/eslint-config-standard.svg 8 | [downloads-url]: https://npmjs.org/package/eslint-config-standard 9 | [standard-image]: https://img.shields.io/badge/code_style-standard-brightgreen.svg 10 | [standard-url]: https://standardjs.com 11 | 12 | #### The ESLint config of [JavaScript Standard Style](http://standardjs.com) 13 | 14 | [![JavaScript Style Guide - Standard Style](https://cdn.rawgit.com/standard/standard/master/badge.svg)](http://standardjs.com) 15 | 16 | This module is for advanced users. You probably want to use [`standard`](http://standardjs.com) instead :) 17 | 18 | ## Usage 19 | 20 | This package exports [a flat ESLint configuration](https://eslint.org/docs/latest/use/configure/configuration-files-new). 21 | 22 | ```bash 23 | npm install --save-dev eslint eslint-config-standard 24 | ``` 25 | 26 | 27 | Example `eslint.config.js`: 28 | ```js 29 | const standard = require('eslint-config-standard') 30 | 31 | module.exports = [ 32 | standard, 33 | { 34 | // your overrides here 35 | } 36 | ] 37 | ``` 38 | 39 | ### Looking for something easier than this? 40 | 41 | The easiest way to use JavaScript Standard Style to check your code is to use the 42 | [`standard`](http://standardjs.com) package. This comes with a global 43 | Node command line program (`standard`) that you can run or add to your `npm test` script 44 | to quickly check your style. 45 | 46 | ## Badge 47 | 48 | Use this in one of your projects? Include one of these badges in your readme to 49 | let people know that your code is using the standard style. 50 | 51 | [![js-standard-style](https://cdn.rawgit.com/standard/standard/master/badge.svg)](http://standardjs.com) 52 | 53 | ```markdown 54 | [![js-standard-style](https://cdn.rawgit.com/standard/standard/master/badge.svg)](http://standardjs.com) 55 | ``` 56 | 57 | [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com) 58 | 59 | ```markdown 60 | [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com) 61 | ``` 62 | 63 | ## Learn more 64 | 65 | For the full listing of rules, editor plugins, FAQs, and more, visit the main 66 | [JavaScript Standard Style repo](http://standardjs.com). 67 | 68 | ## License 69 | 70 | MIT. Copyright (c) [Feross Aboukhadijeh](http://feross.org). 71 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { extends: ['standard'] } 2 | -------------------------------------------------------------------------------- /get-node-supported-versions.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euxo pipefail 3 | url=https://raw.githubusercontent.com/nodejs/Release/master/schedule.json 4 | release_schedule=$(curl -s $url) 5 | today=$(date "+%Y-%m-%d") 6 | active_versions=$(echo $release_schedule | jq -s "[ .[] | to_entries[] | select(.value.start <= \"$today\" and .value.end >= \"$today\") | .key[1:] ]") 7 | echo $active_versions 8 | -------------------------------------------------------------------------------- /lefthook.yml: -------------------------------------------------------------------------------- 1 | commit-msg: 2 | commands: 3 | commitlint: 4 | run: npx --no-install commitlint --edit 5 | pre-commit: 6 | commands: 7 | test: 8 | run: npm run test 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-config-standard", 3 | "description": "JavaScript Standard Style - ESLint Shareable Config", 4 | "version": "17.1.0", 5 | "author": { 6 | "name": "Feross Aboukhadijeh", 7 | "email": "feross@feross.org", 8 | "url": "https://feross.org" 9 | }, 10 | "bugs": { 11 | "url": "https://github.com/standard/eslint-config-standard/issues" 12 | }, 13 | "engines": { 14 | "node": ">=12.0.0" 15 | }, 16 | "files": [ 17 | "CHANGELOG.md", 18 | "LICENSE", 19 | "README.md", 20 | "lib/index.d.ts", 21 | "lib/index.js" 22 | ], 23 | "devDependencies": { 24 | "@arkweid/lefthook": "0.7.7", 25 | "@commitlint/cli": "18.6.1", 26 | "@commitlint/config-conventional": "18.6.3", 27 | "@types/eslint": "8.44.8", 28 | "ava": "6.1.3", 29 | "commitlint-config-standard": "github:standard/commitlint-config-standard", 30 | "editorconfig-checker": "5.1.8", 31 | "eslint": "8.55.0", 32 | "eslint-config-standard-with-typescript": "42.0.0", 33 | "eslint-plugin-import": "2.30.0", 34 | "eslint-plugin-n": "16.6.2", 35 | "eslint-plugin-promise": "6.6.0", 36 | "npm-run-all": "4.1.5", 37 | "semantic-release": "22.0.12", 38 | "semantic-release-standard": "github:standard/semantic-release", 39 | "tsconfigs": "5.0.0", 40 | "typescript": "5.5.4" 41 | }, 42 | "homepage": "https://github.com/standard/eslint-config-standard", 43 | "keywords": [ 44 | "JavaScript Standard Style", 45 | "check", 46 | "checker", 47 | "code", 48 | "code checker", 49 | "code linter", 50 | "code standards", 51 | "code style", 52 | "enforce", 53 | "eslint", 54 | "eslintconfig", 55 | "hint", 56 | "jscs", 57 | "jshint", 58 | "lint", 59 | "policy", 60 | "quality", 61 | "simple", 62 | "standard", 63 | "standard style", 64 | "style", 65 | "style checker", 66 | "style linter", 67 | "verify" 68 | ], 69 | "license": "MIT", 70 | "main": "lib/index.js", 71 | "types": "lib/index.d.ts", 72 | "peerDependencies": { 73 | "eslint": "^8.0.1" 74 | }, 75 | "repository": { 76 | "type": "git", 77 | "url": "git://github.com/standard/eslint-config-standard.git" 78 | }, 79 | "scripts": { 80 | "clean-artifacts": "git clean lib -X --force", 81 | "editorconfig": "editorconfig-checker", 82 | "compile": "tsc", 83 | "lint": "eslint .", 84 | "unit": "ava", 85 | "test": "run-s clean-artifacts editorconfig compile lint unit" 86 | }, 87 | "funding": [ 88 | { 89 | "type": "github", 90 | "url": "https://github.com/sponsors/feross" 91 | }, 92 | { 93 | "type": "patreon", 94 | "url": "https://www.patreon.com/feross" 95 | }, 96 | { 97 | "type": "consulting", 98 | "url": "https://feross.org/support" 99 | } 100 | ], 101 | "dependencies": { 102 | "globals": "13.24.0", 103 | "eslint-plugin-import": "2.30.0", 104 | "eslint-plugin-n": "16.6.2", 105 | "eslint-plugin-promise": "6.6.0" 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["github>standard/renovate-config:renovate.json5"], 3 | "packageRules": [ 4 | { 5 | "matchDepTypes": ["peerDependencies", "engines"], 6 | "enabled": false 7 | } 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | /*! eslint-config-standard. MIT License. Feross Aboukhadijeh */ 2 | 3 | import { type Linter } from 'eslint' 4 | 5 | // @ts-expect-error missing type 6 | import pluginN from 'eslint-plugin-n' 7 | // @ts-expect-error missing type 8 | import * as pluginImport from 'eslint-plugin-import' 9 | // @ts-expect-error missing type 10 | import pluginPromise from 'eslint-plugin-promise' 11 | import globals from 'globals' 12 | 13 | const config: Linter.FlatConfig = { 14 | languageOptions: { 15 | ecmaVersion: 2022, 16 | sourceType: 'module', 17 | 18 | parserOptions: { 19 | ecmaFeatures: { jsx: true } 20 | }, 21 | 22 | globals: { 23 | ...globals.es2021, 24 | ...globals.node, 25 | // @ts-expect-error @types/eslint seems to be incomplete 26 | document: 'readonly', 27 | // @ts-expect-error @types/eslint seems to be incomplete 28 | navigator: 'readonly', 29 | // @ts-expect-error @types/eslint seems to be incomplete 30 | window: 'readonly' 31 | } 32 | }, 33 | 34 | plugins: { 35 | n: pluginN, 36 | promise: pluginPromise, 37 | import: pluginImport 38 | }, 39 | 40 | rules: { 41 | 'no-var': 'warn', 42 | 'object-shorthand': ['warn', 'properties'], 43 | 44 | 'accessor-pairs': ['error', { setWithoutGet: true, enforceForClassMembers: true }], 45 | 'array-bracket-spacing': ['error', 'never'], 46 | 'array-callback-return': ['error', { 47 | allowImplicit: false, 48 | checkForEach: false 49 | }], 50 | 'arrow-spacing': ['error', { before: true, after: true }], 51 | 'block-spacing': ['error', 'always'], 52 | 'brace-style': ['error', '1tbs', { allowSingleLine: true }], 53 | camelcase: ['error', { 54 | allow: ['^UNSAFE_'], 55 | properties: 'never', 56 | ignoreGlobals: true 57 | }], 58 | 'comma-dangle': ['error', { 59 | arrays: 'never', 60 | objects: 'never', 61 | imports: 'never', 62 | exports: 'never', 63 | functions: 'never' 64 | }], 65 | 'comma-spacing': ['error', { before: false, after: true }], 66 | 'comma-style': ['error', 'last'], 67 | 'computed-property-spacing': ['error', 'never', { enforceForClassMembers: true }], 68 | 'constructor-super': 'error', 69 | curly: ['error', 'multi-line'], 70 | 'default-case-last': 'error', 71 | 'dot-location': ['error', 'property'], 72 | 'dot-notation': ['error', { allowKeywords: true }], 73 | 'eol-last': 'error', 74 | eqeqeq: ['error', 'always', { null: 'ignore' }], 75 | 'func-call-spacing': ['error', 'never'], 76 | 'generator-star-spacing': ['error', { before: true, after: true }], 77 | indent: ['error', 2, { 78 | SwitchCase: 1, 79 | VariableDeclarator: 1, 80 | outerIIFEBody: 1, 81 | MemberExpression: 1, 82 | FunctionDeclaration: { parameters: 1, body: 1 }, 83 | FunctionExpression: { parameters: 1, body: 1 }, 84 | CallExpression: { arguments: 1 }, 85 | ArrayExpression: 1, 86 | ObjectExpression: 1, 87 | ImportDeclaration: 1, 88 | flatTernaryExpressions: false, 89 | ignoreComments: false, 90 | ignoredNodes: [ 91 | 'TemplateLiteral *', 92 | 'JSXElement', 93 | 'JSXElement > *', 94 | 'JSXAttribute', 95 | 'JSXIdentifier', 96 | 'JSXNamespacedName', 97 | 'JSXMemberExpression', 98 | 'JSXSpreadAttribute', 99 | 'JSXExpressionContainer', 100 | 'JSXOpeningElement', 101 | 'JSXClosingElement', 102 | 'JSXFragment', 103 | 'JSXOpeningFragment', 104 | 'JSXClosingFragment', 105 | 'JSXText', 106 | 'JSXEmptyExpression', 107 | 'JSXSpreadChild' 108 | ], 109 | offsetTernaryExpressions: true 110 | }], 111 | 'key-spacing': ['error', { beforeColon: false, afterColon: true }], 112 | 'keyword-spacing': ['error', { before: true, after: true }], 113 | 'lines-between-class-members': ['error', 'always', { exceptAfterSingleLine: true }], 114 | 'multiline-ternary': ['error', 'always-multiline'], 115 | 'new-cap': ['error', { newIsCap: true, capIsNew: false, properties: true }], 116 | 'new-parens': 'error', 117 | 'no-array-constructor': 'error', 118 | 'no-async-promise-executor': 'error', 119 | 'no-caller': 'error', 120 | 'no-case-declarations': 'error', 121 | 'no-class-assign': 'error', 122 | 'no-compare-neg-zero': 'error', 123 | 'no-cond-assign': 'error', 124 | 'no-const-assign': 'error', 125 | 'no-constant-condition': ['error', { checkLoops: false }], 126 | 'no-control-regex': 'error', 127 | 'no-debugger': 'error', 128 | 'no-delete-var': 'error', 129 | 'no-dupe-args': 'error', 130 | 'no-dupe-class-members': 'error', 131 | 'no-dupe-keys': 'error', 132 | 'no-duplicate-case': 'error', 133 | 'no-useless-backreference': 'error', 134 | 'no-empty': ['error', { allowEmptyCatch: true }], 135 | 'no-empty-character-class': 'error', 136 | 'no-empty-pattern': 'error', 137 | 'no-eval': 'error', 138 | 'no-ex-assign': 'error', 139 | 'no-extend-native': 'error', 140 | 'no-extra-bind': 'error', 141 | 'no-extra-boolean-cast': 'error', 142 | 'no-extra-parens': ['error', 'functions'], 143 | 'no-fallthrough': 'error', 144 | 'no-floating-decimal': 'error', 145 | 'no-func-assign': 'error', 146 | 'no-global-assign': 'error', 147 | 'no-implied-eval': 'error', 148 | 'no-import-assign': 'error', 149 | 'no-invalid-regexp': 'error', 150 | 'no-irregular-whitespace': 'error', 151 | 'no-iterator': 'error', 152 | 'no-labels': ['error', { allowLoop: false, allowSwitch: false }], 153 | 'no-lone-blocks': 'error', 154 | 'no-loss-of-precision': 'error', 155 | 'no-misleading-character-class': 'error', 156 | 'no-prototype-builtins': 'error', 157 | 'no-useless-catch': 'error', 158 | 'no-mixed-operators': ['error', { 159 | groups: [ 160 | ['==', '!=', '===', '!==', '>', '>=', '<', '<='], 161 | ['&&', '||'], 162 | ['in', 'instanceof'] 163 | ], 164 | allowSamePrecedence: true 165 | }], 166 | 'no-mixed-spaces-and-tabs': 'error', 167 | 'no-multi-spaces': 'error', 168 | 'no-multi-str': 'error', 169 | 'no-multiple-empty-lines': ['error', { max: 1, maxBOF: 0, maxEOF: 0 }], 170 | 'no-new': 'error', 171 | 'no-new-func': 'error', 172 | 'no-new-object': 'error', 173 | 'no-new-symbol': 'error', 174 | 'no-new-wrappers': 'error', 175 | 'no-obj-calls': 'error', 176 | 'no-octal': 'error', 177 | 'no-octal-escape': 'error', 178 | 'no-proto': 'error', 179 | 'no-redeclare': ['error', { builtinGlobals: false }], 180 | 'no-regex-spaces': 'error', 181 | 'no-return-assign': ['error', 'except-parens'], 182 | 'no-self-assign': ['error', { props: true }], 183 | 'no-self-compare': 'error', 184 | 'no-sequences': 'error', 185 | 'no-shadow-restricted-names': 'error', 186 | 'no-sparse-arrays': 'error', 187 | 'no-tabs': 'error', 188 | 'no-template-curly-in-string': 'error', 189 | 'no-this-before-super': 'error', 190 | 'no-throw-literal': 'error', 191 | 'no-trailing-spaces': 'error', 192 | 'no-undef': 'error', 193 | 'no-undef-init': 'error', 194 | 'no-unexpected-multiline': 'error', 195 | 'no-unmodified-loop-condition': 'error', 196 | 'no-unneeded-ternary': ['error', { defaultAssignment: false }], 197 | 'no-unreachable': 'error', 198 | 'no-unreachable-loop': 'error', 199 | 'no-unsafe-finally': 'error', 200 | 'no-unsafe-negation': 'error', 201 | 'no-unused-expressions': ['error', { 202 | allowShortCircuit: true, 203 | allowTernary: true, 204 | allowTaggedTemplates: true 205 | }], 206 | 'no-unused-vars': ['error', { 207 | args: 'none', 208 | caughtErrors: 'none', 209 | ignoreRestSiblings: true, 210 | vars: 'all' 211 | }], 212 | 'no-use-before-define': ['error', { functions: false, classes: false, variables: false }], 213 | 'no-useless-call': 'error', 214 | 'no-useless-computed-key': 'error', 215 | 'no-useless-constructor': 'error', 216 | 'no-useless-escape': 'error', 217 | 'no-useless-rename': 'error', 218 | 'no-useless-return': 'error', 219 | 'no-void': 'error', 220 | 'no-whitespace-before-property': 'error', 221 | 'no-with': 'error', 222 | 'object-curly-newline': ['error', { multiline: true, consistent: true }], 223 | 'object-curly-spacing': ['error', 'always'], 224 | 'object-property-newline': ['error', { allowMultiplePropertiesPerLine: true }], 225 | 'one-var': ['error', { initialized: 'never' }], 226 | 'operator-linebreak': ['error', 'after', { overrides: { '?': 'before', ':': 'before', '|>': 'before' } }], 227 | 'padded-blocks': ['error', { blocks: 'never', switches: 'never', classes: 'never' }], 228 | 'prefer-const': ['error', { destructuring: 'all' }], 229 | 'prefer-promise-reject-errors': 'error', 230 | 'prefer-regex-literals': ['error', { disallowRedundantWrapping: true }], 231 | 'quote-props': ['error', 'as-needed'], 232 | quotes: ['error', 'single', { avoidEscape: true, allowTemplateLiterals: false }], 233 | 'rest-spread-spacing': ['error', 'never'], 234 | semi: ['error', 'never'], 235 | 'semi-spacing': ['error', { before: false, after: true }], 236 | 'space-before-blocks': ['error', 'always'], 237 | 'space-before-function-paren': ['error', 'always'], 238 | 'space-in-parens': ['error', 'never'], 239 | 'space-infix-ops': 'error', 240 | 'space-unary-ops': ['error', { words: true, nonwords: false }], 241 | 'spaced-comment': ['error', 'always', { 242 | line: { markers: ['*package', '!', '/', ',', '='] }, 243 | block: { balanced: true, markers: ['*package', '!', ',', ':', '::', 'flow-include'], exceptions: ['*'] } 244 | }], 245 | 'symbol-description': 'error', 246 | 'template-curly-spacing': ['error', 'never'], 247 | 'template-tag-spacing': ['error', 'never'], 248 | 'unicode-bom': ['error', 'never'], 249 | 'use-isnan': ['error', { 250 | enforceForSwitchCase: true, 251 | enforceForIndexOf: true 252 | }], 253 | 'valid-typeof': ['error', { requireStringLiterals: true }], 254 | 'wrap-iife': ['error', 'any', { functionPrototypeMethods: true }], 255 | 'yield-star-spacing': ['error', 'both'], 256 | yoda: ['error', 'never'], 257 | 258 | 'import/export': 'error', 259 | 'import/first': 'error', 260 | 'import/no-absolute-path': ['error', { esmodule: true, commonjs: true, amd: false }], 261 | 'import/no-duplicates': 'error', 262 | 'import/no-named-default': 'error', 263 | 'import/no-webpack-loader-syntax': 'error', 264 | 265 | 'n/handle-callback-err': ['error', '^(err|error)$'], 266 | 'n/no-callback-literal': 'error', 267 | 'n/no-deprecated-api': 'error', 268 | 'n/no-exports-assign': 'error', 269 | 'n/no-new-require': 'error', 270 | 'n/no-path-concat': 'error', 271 | 'n/process-exit-as-throw': 'error', 272 | 273 | 'promise/param-names': 'error' 274 | } 275 | } 276 | 277 | export default config 278 | -------------------------------------------------------------------------------- /src/test/export.ts: -------------------------------------------------------------------------------- 1 | import actual from '..' 2 | import test from 'ava' 3 | 4 | // @ts-expect-error missing type 5 | import pluginN from 'eslint-plugin-n' 6 | // @ts-expect-error missing type 7 | import * as pluginImport from 'eslint-plugin-import' 8 | // @ts-expect-error missing type 9 | import pluginPromise from 'eslint-plugin-promise' 10 | import globals from 'globals' 11 | 12 | test('export equality', function (t) { 13 | const expected = { 14 | languageOptions: { 15 | ecmaVersion: 2022, 16 | sourceType: 'module', 17 | 18 | parserOptions: { 19 | ecmaFeatures: { jsx: true } 20 | }, 21 | 22 | globals: { 23 | ...globals.es2021, 24 | ...globals.node, 25 | document: 'readonly', 26 | navigator: 'readonly', 27 | window: 'readonly' 28 | } 29 | }, 30 | 31 | plugins: { 32 | n: pluginN, 33 | promise: pluginPromise, 34 | import: pluginImport 35 | }, 36 | 37 | rules: { 38 | 'no-var': 'warn', 39 | 'object-shorthand': ['warn', 'properties'], 40 | 41 | 'accessor-pairs': ['error', { setWithoutGet: true, enforceForClassMembers: true }], 42 | 'array-bracket-spacing': ['error', 'never'], 43 | 'array-callback-return': ['error', { 44 | allowImplicit: false, 45 | checkForEach: false 46 | }], 47 | 'arrow-spacing': ['error', { before: true, after: true }], 48 | 'block-spacing': ['error', 'always'], 49 | 'brace-style': ['error', '1tbs', { allowSingleLine: true }], 50 | camelcase: ['error', { 51 | allow: ['^UNSAFE_'], 52 | properties: 'never', 53 | ignoreGlobals: true 54 | }], 55 | 'comma-dangle': ['error', { 56 | arrays: 'never', 57 | objects: 'never', 58 | imports: 'never', 59 | exports: 'never', 60 | functions: 'never' 61 | }], 62 | 'comma-spacing': ['error', { before: false, after: true }], 63 | 'comma-style': ['error', 'last'], 64 | 'computed-property-spacing': ['error', 'never', { enforceForClassMembers: true }], 65 | 'constructor-super': 'error', 66 | curly: ['error', 'multi-line'], 67 | 'default-case-last': 'error', 68 | 'dot-location': ['error', 'property'], 69 | 'dot-notation': ['error', { allowKeywords: true }], 70 | 'eol-last': 'error', 71 | eqeqeq: ['error', 'always', { null: 'ignore' }], 72 | 'func-call-spacing': ['error', 'never'], 73 | 'generator-star-spacing': ['error', { before: true, after: true }], 74 | indent: ['error', 2, { 75 | SwitchCase: 1, 76 | VariableDeclarator: 1, 77 | outerIIFEBody: 1, 78 | MemberExpression: 1, 79 | FunctionDeclaration: { parameters: 1, body: 1 }, 80 | FunctionExpression: { parameters: 1, body: 1 }, 81 | CallExpression: { arguments: 1 }, 82 | ArrayExpression: 1, 83 | ObjectExpression: 1, 84 | ImportDeclaration: 1, 85 | flatTernaryExpressions: false, 86 | ignoreComments: false, 87 | ignoredNodes: [ 88 | 'TemplateLiteral *', 89 | 'JSXElement', 90 | 'JSXElement > *', 91 | 'JSXAttribute', 92 | 'JSXIdentifier', 93 | 'JSXNamespacedName', 94 | 'JSXMemberExpression', 95 | 'JSXSpreadAttribute', 96 | 'JSXExpressionContainer', 97 | 'JSXOpeningElement', 98 | 'JSXClosingElement', 99 | 'JSXFragment', 100 | 'JSXOpeningFragment', 101 | 'JSXClosingFragment', 102 | 'JSXText', 103 | 'JSXEmptyExpression', 104 | 'JSXSpreadChild' 105 | ], 106 | offsetTernaryExpressions: true 107 | }], 108 | 'key-spacing': ['error', { beforeColon: false, afterColon: true }], 109 | 'keyword-spacing': ['error', { before: true, after: true }], 110 | 'lines-between-class-members': ['error', 'always', { exceptAfterSingleLine: true }], 111 | 'multiline-ternary': ['error', 'always-multiline'], 112 | 'new-cap': ['error', { newIsCap: true, capIsNew: false, properties: true }], 113 | 'new-parens': 'error', 114 | 'no-array-constructor': 'error', 115 | 'no-async-promise-executor': 'error', 116 | 'no-caller': 'error', 117 | 'no-case-declarations': 'error', 118 | 'no-class-assign': 'error', 119 | 'no-compare-neg-zero': 'error', 120 | 'no-cond-assign': 'error', 121 | 'no-const-assign': 'error', 122 | 'no-constant-condition': ['error', { checkLoops: false }], 123 | 'no-control-regex': 'error', 124 | 'no-debugger': 'error', 125 | 'no-delete-var': 'error', 126 | 'no-dupe-args': 'error', 127 | 'no-dupe-class-members': 'error', 128 | 'no-dupe-keys': 'error', 129 | 'no-duplicate-case': 'error', 130 | 'no-useless-backreference': 'error', 131 | 'no-empty': ['error', { allowEmptyCatch: true }], 132 | 'no-empty-character-class': 'error', 133 | 'no-empty-pattern': 'error', 134 | 'no-eval': 'error', 135 | 'no-ex-assign': 'error', 136 | 'no-extend-native': 'error', 137 | 'no-extra-bind': 'error', 138 | 'no-extra-boolean-cast': 'error', 139 | 'no-extra-parens': ['error', 'functions'], 140 | 'no-fallthrough': 'error', 141 | 'no-floating-decimal': 'error', 142 | 'no-func-assign': 'error', 143 | 'no-global-assign': 'error', 144 | 'no-implied-eval': 'error', 145 | 'no-import-assign': 'error', 146 | 'no-invalid-regexp': 'error', 147 | 'no-irregular-whitespace': 'error', 148 | 'no-iterator': 'error', 149 | 'no-labels': ['error', { allowLoop: false, allowSwitch: false }], 150 | 'no-lone-blocks': 'error', 151 | 'no-loss-of-precision': 'error', 152 | 'no-misleading-character-class': 'error', 153 | 'no-prototype-builtins': 'error', 154 | 'no-useless-catch': 'error', 155 | 'no-mixed-operators': ['error', { 156 | groups: [ 157 | ['==', '!=', '===', '!==', '>', '>=', '<', '<='], 158 | ['&&', '||'], 159 | ['in', 'instanceof'] 160 | ], 161 | allowSamePrecedence: true 162 | }], 163 | 'no-mixed-spaces-and-tabs': 'error', 164 | 'no-multi-spaces': 'error', 165 | 'no-multi-str': 'error', 166 | 'no-multiple-empty-lines': ['error', { max: 1, maxBOF: 0, maxEOF: 0 }], 167 | 'no-new': 'error', 168 | 'no-new-func': 'error', 169 | 'no-new-object': 'error', 170 | 'no-new-symbol': 'error', 171 | 'no-new-wrappers': 'error', 172 | 'no-obj-calls': 'error', 173 | 'no-octal': 'error', 174 | 'no-octal-escape': 'error', 175 | 'no-proto': 'error', 176 | 'no-redeclare': ['error', { builtinGlobals: false }], 177 | 'no-regex-spaces': 'error', 178 | 'no-return-assign': ['error', 'except-parens'], 179 | 'no-self-assign': ['error', { props: true }], 180 | 'no-self-compare': 'error', 181 | 'no-sequences': 'error', 182 | 'no-shadow-restricted-names': 'error', 183 | 'no-sparse-arrays': 'error', 184 | 'no-tabs': 'error', 185 | 'no-template-curly-in-string': 'error', 186 | 'no-this-before-super': 'error', 187 | 'no-throw-literal': 'error', 188 | 'no-trailing-spaces': 'error', 189 | 'no-undef': 'error', 190 | 'no-undef-init': 'error', 191 | 'no-unexpected-multiline': 'error', 192 | 'no-unmodified-loop-condition': 'error', 193 | 'no-unneeded-ternary': ['error', { defaultAssignment: false }], 194 | 'no-unreachable': 'error', 195 | 'no-unreachable-loop': 'error', 196 | 'no-unsafe-finally': 'error', 197 | 'no-unsafe-negation': 'error', 198 | 'no-unused-expressions': ['error', { 199 | allowShortCircuit: true, 200 | allowTernary: true, 201 | allowTaggedTemplates: true 202 | }], 203 | 'no-unused-vars': ['error', { 204 | args: 'none', 205 | caughtErrors: 'none', 206 | ignoreRestSiblings: true, 207 | vars: 'all' 208 | }], 209 | 'no-use-before-define': ['error', { functions: false, classes: false, variables: false }], 210 | 'no-useless-call': 'error', 211 | 'no-useless-computed-key': 'error', 212 | 'no-useless-constructor': 'error', 213 | 'no-useless-escape': 'error', 214 | 'no-useless-rename': 'error', 215 | 'no-useless-return': 'error', 216 | 'no-void': 'error', 217 | 'no-whitespace-before-property': 'error', 218 | 'no-with': 'error', 219 | 'object-curly-newline': ['error', { multiline: true, consistent: true }], 220 | 'object-curly-spacing': ['error', 'always'], 221 | 'object-property-newline': ['error', { allowMultiplePropertiesPerLine: true }], 222 | 'one-var': ['error', { initialized: 'never' }], 223 | 'operator-linebreak': ['error', 'after', { overrides: { '?': 'before', ':': 'before', '|>': 'before' } }], 224 | 'padded-blocks': ['error', { blocks: 'never', switches: 'never', classes: 'never' }], 225 | 'prefer-const': ['error', { destructuring: 'all' }], 226 | 'prefer-promise-reject-errors': 'error', 227 | 'prefer-regex-literals': ['error', { disallowRedundantWrapping: true }], 228 | 'quote-props': ['error', 'as-needed'], 229 | quotes: ['error', 'single', { avoidEscape: true, allowTemplateLiterals: false }], 230 | 'rest-spread-spacing': ['error', 'never'], 231 | semi: ['error', 'never'], 232 | 'semi-spacing': ['error', { before: false, after: true }], 233 | 'space-before-blocks': ['error', 'always'], 234 | 'space-before-function-paren': ['error', 'always'], 235 | 'space-in-parens': ['error', 'never'], 236 | 'space-infix-ops': 'error', 237 | 'space-unary-ops': ['error', { words: true, nonwords: false }], 238 | 'spaced-comment': ['error', 'always', { 239 | line: { markers: ['*package', '!', '/', ',', '='] }, 240 | block: { balanced: true, markers: ['*package', '!', ',', ':', '::', 'flow-include'], exceptions: ['*'] } 241 | }], 242 | 'symbol-description': 'error', 243 | 'template-curly-spacing': ['error', 'never'], 244 | 'template-tag-spacing': ['error', 'never'], 245 | 'unicode-bom': ['error', 'never'], 246 | 'use-isnan': ['error', { 247 | enforceForSwitchCase: true, 248 | enforceForIndexOf: true 249 | }], 250 | 'valid-typeof': ['error', { requireStringLiterals: true }], 251 | 'wrap-iife': ['error', 'any', { functionPrototypeMethods: true }], 252 | 'yield-star-spacing': ['error', 'both'], 253 | yoda: ['error', 'never'], 254 | 255 | 'import/export': 'error', 256 | 'import/first': 'error', 257 | 'import/no-absolute-path': ['error', { esmodule: true, commonjs: true, amd: false }], 258 | 'import/no-duplicates': 'error', 259 | 'import/no-named-default': 'error', 260 | 'import/no-webpack-loader-syntax': 'error', 261 | 262 | 'n/handle-callback-err': ['error', '^(err|error)$'], 263 | 'n/no-callback-literal': 'error', 264 | 'n/no-deprecated-api': 'error', 265 | 'n/no-exports-assign': 'error', 266 | 'n/no-new-require': 'error', 267 | 'n/no-path-concat': 'error', 268 | 'n/process-exit-as-throw': 'error', 269 | 270 | 'promise/param-names': 'error' 271 | } 272 | } 273 | 274 | t.deepEqual(actual, expected) 275 | }) 276 | -------------------------------------------------------------------------------- /src/test/validate-config.ts: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | // @ts-expect-error missing type 3 | import { FlatESLint } from 'eslint/use-at-your-own-risk' 4 | import config from '../index' 5 | 6 | const eslint = new FlatESLint({ 7 | overrideConfigFile: true, 8 | baseConfig: config 9 | }) 10 | 11 | test('load config in eslint to validate all rule syntax is correct', async function (t) { 12 | const code = 'const foo = 1\nconst bar = function () {}\nbar(foo)\n' 13 | const [lintResult] = await eslint.lintText(code) 14 | t.is(lintResult.errorCount, 0) 15 | }) 16 | 17 | test('ensure we allow top level await', async function (t) { 18 | const code = 'const foo = await 1\nconst bar = function () {}\nawait bar(foo)\n' 19 | const [lintResult] = await eslint.lintText(code) 20 | t.is(lintResult.errorCount, 0) 21 | }) 22 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfigs/nodejs-module", 3 | "compilerOptions": { 4 | "outDir": "lib" 5 | }, 6 | "include": [ 7 | ".eslintrc.js", 8 | "commitlint.config.js", 9 | "src/**/*.ts" 10 | ] 11 | } 12 | 13 | --------------------------------------------------------------------------------