├── .editorconfig
├── .eslintrc
├── .gitattributes
├── .github
└── FUNDING.yml
├── .gitignore
├── .ncurc
├── .npmignore
├── .npmrc
├── .prettierignore
├── .prettierrc
├── .snyk
├── LICENSE
├── README.md
├── configs.js
├── docs
├── typescript.md
└── vue.md
├── index.js
├── lib
├── is-module-available.js
├── loaded.js
├── loggers.js
├── missing.js
└── utils.js
├── package.json
└── rules
├── array-func.js
├── ava.js
├── chai-expect.js
├── chai-friendly.js
├── const-case.js
├── cypress.js
├── eslint-comments.js
├── fsa.js
├── html.js
├── jasmine.js
├── jest-async.js
├── jest-dom.js
├── jest.js
├── json-format.js
├── json.js
├── lodash-fp.js
├── lodash.js
├── markdown.js
├── mocha-cleanup.js
├── mocha.js
├── no-constructor-bind.js
├── no-secrets.js
├── no-unsanitized.js
├── no-use-extend-native.js
├── optimize-regex.js
├── pii.js
├── prettier.js
├── promise.js
├── qunit.js
├── ramda.js
├── react-redux.js
├── redux-saga.js
├── security.js
├── simple-import-sort.js
├── sonarjs.js
├── switch-case.js
├── test-overrides.js
├── testing-library.js
├── unicorn.js
└── xss.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | trim_trailing_whitespace = true
7 | insert_final_newline = true
8 | # editorconfig-tools is unable to ignore longs strings or urls
9 | max_line_length = null
10 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["airbnb", "./index.js"],
3 | "rules": {
4 | "security/detect-non-literal-fs-filename": 0,
5 | "unicorn/prevent-abbreviations": 0,
6 | "unicorn/prefer-module": 0,
7 | "unicorn/prefer-node-protocol": 0
8 | },
9 | "env": {
10 | "es6": true,
11 | "node": true
12 | },
13 | "parserOptions": {
14 | "ecmaVersion": 6,
15 | "sourceType": "module",
16 | "ecmaFeatures": {
17 | "generators": false,
18 | "objectLiteralDuplicateProperties": false
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 | *.js text eol=lf
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | # github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | # patreon: # Replace with a single Patreon username
5 | # open_collective: # Replace with a single Open Collective username
6 | # ko_fi: # Replace with a single Ko-fi username
7 | # tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | # community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | # liberapay: # Replace with a single Liberapay username
10 | # issuehunt: # Replace with a single IssueHunt username
11 | # otechie: # Replace with a single Otechie username
12 | # custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
14 | github: davidjbradshaw
15 | custom: ['https://www.buymeacoffee.com/davidjbradshaw']
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (https://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # TypeScript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | # next.js build output
61 | .next
62 |
--------------------------------------------------------------------------------
/.ncurc:
--------------------------------------------------------------------------------
1 | {
2 | "reject": ["arrify","read-pkg-up"]
3 | }
4 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .coveralls.yml
3 | .idea
4 | node_modules
5 | bin
6 | docs
7 | example
8 | test
9 | spec
10 | src
11 | npm-debug.log
12 | bower_components
13 | bower.json
14 | gruntfile.js
15 | karma.conf.js
16 | test-main.js
17 | coverage*
18 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | package-lock=false
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | package.json
2 | node_modules
3 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 80,
3 | "tabWidth": 2,
4 | "useTabs": false,
5 | "semi": false,
6 | "singleQuote": true,
7 | "trailingComma": "es5",
8 | "bracketSpacing": true,
9 | "jsxBracketSameLine": false
10 | }
11 |
--------------------------------------------------------------------------------
/.snyk:
--------------------------------------------------------------------------------
1 | # Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
2 | version: v1.14.1
3 | ignore: {}
4 | # patches apply the minimum changes required to fix a vulnerability
5 | patch:
6 | SNYK-JS-LODASH-567746:
7 | - lodash:
8 | patched: '2020-06-06T17:07:42.550Z'
9 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 - 2020 David J. Bradshaw
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |

3 |
4 | # eslint-config-adjunct
5 | _A reasonable collection of *plugins* to use alongside your main esLint configuration_
6 |
7 |
8 | This config is designed to be used alongside any of the major esLint configs, such as [airbnb](https://github.com/airbnb/javascript), [standard](https://github.com/standard/eslint-config-standard) or [eslint:recommended](https://eslint.org/docs/rules/). It provides a range of useful plugins that are often too time-consuming to setup and provides an easy way to install just the plugins you need, based on your project's dependencies.
9 |
10 | ## Install
11 |
12 | To install this config, run the following command.
13 |
14 | ```sh
15 | npm install eslint-config-adjunct --save-dev
16 | ```
17 |
18 | ## Configure
19 |
20 | Extend your `.eslintrc`, with `adjunct`, which should be the last item in the `extends` array. For example if your using `eslint-config-airbnb` as your main rule set, your `.eslintrc` should look like the following. For more advanced use cases see the example configurations for [TypeScript](https://github.com/davidjbradshaw/eslint-config-adjunct/blob/master/docs/typescript.md) and [Vue](https://github.com/davidjbradshaw/eslint-config-adjunct/blob/master/docs/vue.md).
21 |
22 | ```json
23 | {
24 | "extends": ["airbnb", "adjunct"]
25 | }
26 | ```
27 |
28 | You can now include `html`, `json` and `markdown` in the list of files passed to `eslint` to lint any JavaScript contained.
29 |
30 | ```json
31 | {
32 | "scripts": {
33 | "eslint": "eslint --color --ext .html,.js,.json,.jsx,.md *.* src",
34 | "eslint:fix": "npm run eslint -- --fix"
35 | }
36 | }
37 | ```
38 |
39 | ## Install Dependencies
40 |
41 | After you have configured `eslint` to include this package, the first time you run `eslint` it will output the `npm` command to install the dependencies required for your project. Cut'n'paste this command into the console, and you are then ready to start linting.
42 |
43 | ## Plugins
44 |
45 | ### Code Quality
46 |
47 | These two plugins provide a range of code quality rules:
48 |
49 | - [eslint-plugin-sonarjs](https://github.com/SonarSource/eslint-plugin-sonarjs)
50 | - [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn)
51 |
52 | ### Langauges
53 |
54 | The following plugins expand esLint to work with json files, and lint JavaScript contiained in HTML and MarkDown:
55 |
56 | - [eslint-plugin-html](https://github.com/BenoitZugmeyer/eslint-plugin-html)
57 | - [eslint-plugin-json](https://github.com/azeemba/eslint-plugin-json)
58 | - [eslint-plugin-markdown](https://github.com/eslint/eslint-plugin-markdown)
59 |
60 | _When linting code snippets in Markdown files, a few [rules](https://github.com/davidjbradshaw/eslint-config-adjunct/blob/master/rules/markdown.js#L3) relating to globals and unused vars are disabled._
61 |
62 | ### Library Plugins
63 |
64 | These plugins will be loaded in based on your project `dependencies` in `package.json`. If a supported library is part of your project then it's related esLint plugins will be loaded. The following packages are supported:
65 |
66 | - [eslint-plugin-fsa](https://github.com/joseph-galindo/eslint-plugin-fsa)
67 | - [eslint-plugin-lodash](https://github.com/wix/eslint-plugin-lodash)
68 | - [eslint-plugin-lodash-fp](https://github.com/jfmengels/eslint-plugin-lodash-fp)
69 | - [eslint-plugin-ramda](https://github.com/ramda/eslint-plugin-ramda)
70 | - [eslint-plugin-react-redux](https://github.com/DianaSuvorova/eslint-plugin-react-redux#readme)
71 | - [eslint-plugin-redux-saga](https://github.com/pke/eslint-plugin-redux-saga)
72 |
73 | ### Practices
74 |
75 | The following esLint plugins enforce good coding practices:
76 |
77 | - [eslint-plugin-const-case](https://github.com/k03mad/eslint-plugin-const-case#readme)
78 | - [eslint-plugin-array-func](https://github.com/freaktechnik/eslint-plugin-array-func)
79 | - [eslint-plugin-eslint-comments](https://github.com/mysticatea/eslint-plugin-eslint-comments)
80 | - [eslint-plugin-no-constructor-bind](https://github.com/markalfred/eslint-plugin-no-constructor-bind)
81 | - [eslint-plugin-no-use-extend-native](https://github.com/dustinspecker/eslint-plugin-no-use-extend-native)
82 | - [eslint-plugin-optimize-regex](https://github.com/BrainMaestro/eslint-plugin-optimize-regex)
83 | - [eslint-plugin-promise](https://github.com/xjamundx/eslint-plugin-promise)
84 | - [eslint-plugin-simple-import-sort](https://github.com/lydell/eslint-plugin-simple-import-sort)
85 | - [eslint-plugin-switch-case](https://github.com/lukeapage/eslint-plugin-switch-case)
86 |
87 | ### Prettier
88 |
89 | If prettier is installed, any rules that may conflict with Prettier will be disabled. The plugin should read you Prettier config from your project's root.
90 |
91 | - [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier)
92 |
93 | The prettier configs for different eslint plugins are also automatically included based on which eslint plugins have been installed into your project.
94 |
95 | ### Security
96 |
97 | These plugins add code security rules to esLint:
98 |
99 | - [eslint-plugin-no-secrets](https://github.com/nickdeis/eslint-plugin-no-secrets)
100 | - [eslint-plugin-no-unsanitized](https://github.com/mozilla/eslint-plugin-no-unsanitized)
101 | - [eslint-plugin-pii](https://github.com/shiva-hack/eslint-plugin-pii)
102 | - [eslint-plugin-security](https://github.com/nodesecurity/eslint-plugin-security)
103 | - [eslint-plugin-xss](https://github.com/Rantanen/eslint-plugin-xss)
104 |
105 | ### Test Libraries
106 |
107 | Test plugins are loaded based on which testing tools you have listed in `devDependencies` of `package.json`. The following test plugins are supported:
108 |
109 | - [eslint-plugin-ava](https://github.com/avajs/eslint-plugin-ava)
110 | - [eslint-plugin-chai-expect](https://github.com/turbo87/eslint-plugin-chai-expect)
111 | - [eslint-plugin-chai-friendly](https://github.com/ihordiachenko/eslint-plugin-chai-friendly)
112 | - [eslint-plugin-cypress](https://github.com/cypress-io/eslint-plugin-cypress)
113 | - [eslint-plugin-jasmine](https://github.com/tlvince/eslint-plugin-jasmine)
114 | - [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest)
115 | - [eslint-plugin-jest-async](https://www.npmjs.com/package/eslint-plugin-jest-async)
116 | - [eslint-plugin-mocha](https://github.com/lo1tuma/eslint-plugin-mocha)
117 | - [eslint-plugin-mocha-cleanup](https://github.com/onechiporenko/eslint-plugin-mocha-cleanup/)
118 | - [eslint-plugin-qunit](https://github.com/platinumazure/eslint-plugin-qunit)
119 | - [eslint-plugin-testing-library](https://github.com/testing-library/eslint-plugin-testing-library)
120 |
121 | _For test files a few [rules](https://github.com/davidjbradshaw/eslint-config-adjunct/blob/master/rules/test-overrides.js) are turned off, to better to support normal unit test code styles._
122 |
123 | ## Rules
124 |
125 | In the most part the default rules are used for the plugins listed above, with the following exceptions.
126 |
127 | ### Switch-Case
128 |
129 | Adds the `fallthrough: 'never'` option to the `newline-between-switch-case` rule.
130 |
131 | ```js
132 | // Good
133 |
134 | switch (foo) {
135 | case 1:
136 | something()
137 | break
138 |
139 | case 2:
140 | case 3:
141 | somethingElse()
142 | break
143 |
144 | default:
145 | defaultThing()
146 | }
147 | ```
148 |
149 | ### Disabled rules
150 |
151 | The following rules are disabled due to them being considered unduly restrictive or unhelpful.
152 |
153 | - jest/no-disabled-tests
154 | - react-redux/prefer-separate-component-file
155 | - redux-saga/no-unhandled-errors
156 | - lodash/prefer over native rules
157 | - lodash-fp/use-fp
158 | - unicorn/no-array-for-each
159 | - unicorn/no-fn-reference-in-iterator
160 | - unicorn/no-array-for-each
161 | - unicorn/no-reduce
162 | - unicorn/no-null
163 | - unicorn/prefer-number-properties
164 | - unicorn/prefer-optional-catch-binding
165 | - unicorn/prevent-abbreviations
166 |
167 | The following rules are disabled due to clashing with other plugins
168 |
169 | - array-func/prefer-array-from
170 | - import/order
171 | - sort-imports
172 |
173 | ## License
174 |
175 | Copyright © 2019-21 [David J. Bradshaw](https://github.com/davidjbradshaw).
176 | Licensed under the [MIT License](LICENSE).
177 |
--------------------------------------------------------------------------------
/configs.js:
--------------------------------------------------------------------------------
1 | const { hasAnyDep } = require('./lib/utils')
2 | const isModuleAvailable = require('./lib/is-module-available')
3 |
4 | // Base rules
5 | const rules = [
6 | // 'array-func',
7 | 'const-case',
8 | 'eslint-comments',
9 | 'html',
10 | 'json',
11 | // 'json-format',
12 | 'markdown',
13 | 'no-constructor-bind',
14 | 'no-use-extend-native',
15 | 'optimize-regex',
16 | 'promise',
17 | 'simple-import-sort',
18 | 'sonarjs',
19 | 'switch-case',
20 | 'unicorn',
21 |
22 | // Security Rules
23 | 'no-secrets',
24 | 'no-unsanitized',
25 | 'pii',
26 | 'security',
27 | 'xss',
28 | ]
29 |
30 | // Optionals rules besed on project dependencies
31 | const depRules = [
32 | ['redux', 'fsa'],
33 | 'lodash',
34 | ['lodash', 'lodash-fp'],
35 | 'ramda',
36 | 'react-redux',
37 | 'redux-saga',
38 | ]
39 |
40 | const testRules = [
41 | 'ava',
42 | ['chai', 'chai-expect'],
43 | ['chai', 'chai-friendly'],
44 | 'cypress',
45 | 'jasmine',
46 | 'jest',
47 | ['jest', 'jest-async'],
48 | 'jest-dom',
49 | ['@testing-library/jest-dom', 'jest-dom'],
50 | 'mocha',
51 | ['mocha', 'mocha-cleanup'],
52 | 'qunit',
53 | ['grunt-contrib-qunit', 'qunit'],
54 | ['@testing-library/dom', 'testing-library'],
55 | ]
56 |
57 | depRules.forEach((depRule) => {
58 | const rule = typeof depRule === 'string' ? [depRule, depRule] : depRule
59 | if (hasAnyDep(rule[0])) rules.push(rule[1])
60 | })
61 |
62 | testRules.forEach((depRule) => {
63 | const rule = typeof depRule === 'string' ? [depRule, depRule] : depRule
64 | if (isModuleAvailable(rule[0])) rules.push(rule[1])
65 | })
66 |
67 | if (hasAnyDep('prettier')) rules.push('prettier')
68 |
69 | // Extra required optional packages
70 | const extraInstallPackage = [['prettier', 'eslint-config-prettier']]
71 |
72 | module.exports = { rules, extraInstallPackage }
73 |
--------------------------------------------------------------------------------
/docs/typescript.md:
--------------------------------------------------------------------------------
1 | ## TypeScript
2 |
3 | All of the packages in _eslint-config-adjuct_ should work with TypeScript. The following is an example config using the AirBnB ruleset with Adjunct and TypeScript-Eslint.
4 |
5 | ```json
6 | {
7 | "extends": [
8 | "plugin:@typescript-eslint/recommended",
9 | "plugin:@typescript-eslint/recommended-requiring-type-checking",
10 | "airbnb-typescript",
11 | "airbnb/hooks",
12 | "adjunct"
13 | ],
14 | "parserOptions": {
15 | "project": "./tsconfig.json"
16 | }
17 | }
18 | ```
19 |
--------------------------------------------------------------------------------
/docs/vue.md:
--------------------------------------------------------------------------------
1 | ## Vue
2 |
3 | Example Vue configuration with AirBnB rules.
4 |
5 | ```js
6 | module.exports = {
7 | root: true,
8 | env: {
9 | node: true,
10 | },
11 | extends: [
12 | 'plugin:vue/recommended',
13 | '@vue/airbnb',
14 | '@vue/typescript/recommended',
15 | 'adjunct',
16 | ],
17 | rules: {
18 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
19 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
20 | },
21 | };
22 | ```
23 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | const checkMissing = require('./lib/missing')
2 | const showLoaded = require('./lib/loaded')
3 | const { rules, extraInstallPackage } = require('./configs')
4 |
5 | // Workaround VS Code trying to run this file twice!
6 | if (!global.hasAdjunctLoaded) {
7 | checkMissing(rules, extraInstallPackage)
8 | showLoaded(rules, [])
9 |
10 | // Disable some rules in unit tests
11 | rules.push('test-overrides') // eslint-disable-line unicorn/no-array-push-push
12 | global.hasAdjunctLoaded = true
13 | }
14 |
15 | module.exports = {
16 | extends: rules.map((plugin) =>
17 | require.resolve(`./rules/${plugin.split('@')[0]}`)
18 | ),
19 | }
20 |
--------------------------------------------------------------------------------
/lib/is-module-available.js:
--------------------------------------------------------------------------------
1 | module.exports = function isModuleAvailable(name) {
2 | try {
3 | require.resolve(name)
4 | return true
5 | } catch (error) {
6 | return false
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/lib/loaded.js:
--------------------------------------------------------------------------------
1 | const { consoleLog, consolePlugin } = require('./loggers')
2 | const { hasAnyDep } = require('./utils')
3 |
4 | module.exports = function showLoaded(rules, extraInstallPackage) {
5 | const installed = [...rules]
6 |
7 | extraInstallPackage.forEach(([dep, package_]) => {
8 | if (hasAnyDep(dep)) {
9 | installed.push(package_)
10 | }
11 | })
12 |
13 | consoleLog('\neslint-config-adjunct loaded the following packages:\n')
14 | installed.forEach((plugin) => consolePlugin(plugin))
15 | }
16 |
--------------------------------------------------------------------------------
/lib/loggers.js:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line unicorn/no-useless-undefined
2 | const noop = () => undefined
3 |
4 | const consolePrefix = (prefix) =>
5 | // eslint-disable-next-line no-console
6 | process.env.NO_LOGS ? noop : (file) => console.log(`${prefix}${file}`)
7 |
8 | const consolePlugin = consolePrefix(' eslint-plugin-')
9 | const consoleConfig = consolePrefix(' eslint-config-')
10 | const consoleLog = consolePrefix('')
11 |
12 | module.exports = {
13 | consolePlugin,
14 | consoleConfig,
15 | consoleLog,
16 | }
17 |
--------------------------------------------------------------------------------
/lib/missing.js:
--------------------------------------------------------------------------------
1 | const { equals, indexOf, pipe, when } = require('ramda')
2 |
3 | const { hasAnyDep } = require('./utils')
4 | const isModuleAvailable = require('./is-module-available')
5 | const { consoleLog } = require('./loggers')
6 |
7 | const moduleNotAvailable = (pkg) => !isModuleAvailable(pkg.split('@')[0])
8 |
9 | const atLatest = when(pipe(indexOf('@'), equals(-1)), (pkg) => `${pkg}@latest`)
10 |
11 | module.exports = function checkMissing(rules, extraInstallPackage) {
12 | const notInstalled = rules
13 | .map((plugin) => `eslint-plugin-${plugin}`)
14 | .filter((pkg) => moduleNotAvailable(pkg))
15 |
16 | extraInstallPackage.forEach(([dep, pkg]) => {
17 | if (hasAnyDep(dep) && moduleNotAvailable(pkg)) {
18 | notInstalled.push(pkg)
19 | }
20 | })
21 |
22 | if (notInstalled.length === 0) return
23 |
24 | const s = notInstalled.length === 1 ? '' : 's'
25 |
26 | consoleLog(`\nOops! Something went wrong! :(
27 |
28 | EsLint-config-adjunct could not find the following package${s}
29 |
30 | ${notInstalled.join('\n ')}
31 |
32 | To install the missing package${s}, please run the following command:
33 |
34 | npm install ${notInstalled.map((pkg) => atLatest(pkg)).join(' ')} --save-dev
35 |
36 | `)
37 |
38 | process.exit(1) // eslint-disable-line unicorn/no-process-exit
39 | }
40 |
--------------------------------------------------------------------------------
/lib/utils.js:
--------------------------------------------------------------------------------
1 | // From kcd-scripts
2 |
3 | const fs = require('fs')
4 | const path = require('path')
5 | const rimraf = require('rimraf')
6 | const mkdirp = require('mkdirp')
7 | const arrify = require('arrify')
8 | const has = require('lodash/has')
9 | const readPkgUp = require('read-pkg-up')
10 | const { cosmiconfigSync } = require('cosmiconfig')
11 |
12 | const { packageJson: package_, path: packagePath } = readPkgUp.sync({
13 | cwd: fs.realpathSync(process.cwd()),
14 | })
15 |
16 | const appDirectory = path.dirname(packagePath)
17 |
18 | const fromRoot = (...p) => path.join(appDirectory, ...p)
19 | const hasFile = (...p) => fs.existsSync(fromRoot(...p))
20 |
21 | const hasPackageProperty = (properties) =>
22 | arrify(properties).some((property) => has(package_, property)) // eslint-disable-line lodash-fp/no-extraneous-function-wrapping
23 |
24 | const hasPackageSubProperty = (packageProperty) => (properties) =>
25 | hasPackageProperty(arrify(properties).map((p) => `${packageProperty}.${p}`))
26 |
27 | const hasScript = hasPackageSubProperty('scripts')
28 | const hasPeerDep = hasPackageSubProperty('peerDependencies')
29 | const hasDep = hasPackageSubProperty('dependencies')
30 | const hasDevelopmentDep = hasPackageSubProperty('devDependencies')
31 | const hasAnyDep = (arguments_) =>
32 | [hasDep, hasDevelopmentDep, hasPeerDep].some((fn) => fn(arguments_))
33 |
34 | function environmentIsSet(name) {
35 | return (
36 | process.env.hasOwnProperty(name) && // eslint-disable-line no-prototype-builtins
37 | process.env[name] &&
38 | process.env[name] !== 'undefined'
39 | )
40 | }
41 |
42 | function parseEnvironment(name, def) {
43 | if (environmentIsSet(name)) {
44 | try {
45 | return JSON.parse(process.env[name])
46 | } catch (error) {
47 | return process.env[name]
48 | }
49 | }
50 | return def
51 | }
52 |
53 | function uniq(array) {
54 | return [...new Set(array)]
55 | }
56 |
57 | function writeExtraEntry(name, { cjs, esm }, clean = true) {
58 | if (clean) {
59 | rimraf.sync(fromRoot(name))
60 | }
61 | mkdirp.sync(fromRoot(name))
62 |
63 | const packageJson = fromRoot(`${name}/package.json`)
64 | const entryDir = fromRoot(name)
65 |
66 | fs.writeFileSync(
67 | packageJson,
68 | JSON.stringify(
69 | {
70 | main: path.relative(entryDir, cjs),
71 | 'jsnext:main': path.relative(entryDir, esm),
72 | module: path.relative(entryDir, esm),
73 | },
74 | null,
75 | 2
76 | )
77 | )
78 | }
79 |
80 | function hasLocalConfig(moduleName, searchOptions = {}) {
81 | const explorerSync = cosmiconfigSync(moduleName, searchOptions)
82 | const result = explorerSync.search(packagePath)
83 |
84 | return result !== null
85 | }
86 |
87 | module.exports = {
88 | appDirectory,
89 | fromRoot,
90 | hasFile,
91 | hasLocalConfig,
92 | hasPkgProp: hasPackageProperty,
93 | hasScript,
94 | hasAnyDep,
95 | parseEnv: parseEnvironment,
96 | pkg: package_,
97 | uniq,
98 | writeExtraEntry,
99 | }
100 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "eslint-config-adjunct",
3 | "version": "4.13.0",
4 | "type": "commonjs",
5 | "author": "David J. Bradshaw",
6 | "license": "MIT",
7 | "description": "A reasonable collection of plugins to use alongside your main esLint configuration",
8 | "funding": {
9 | "type": "github",
10 | "url": "https://github.com/sponsors/davidjbradshaw"
11 | },
12 | "repository": {
13 | "type": "git",
14 | "url": "https://github.com/davidjbradshaw/eslint-config-adjunct.git"
15 | },
16 | "main": "index.js",
17 | "scripts": {
18 | "ci-test": "npm run test",
19 | "eslint": "eslint --color --ext .html,js,json,jsx,md *.* rules lib docs",
20 | "eslint:fix": "npm run eslint --fix",
21 | "prepublishOnly": "npm run test",
22 | "postpublish": "PACKAGE_VERSION=$(cat package.json | grep \\\"version\\\" | head -1 | awk -F: '{ print $2 }' | sed 's/[\",]//g' | tr -d '[[:space:]]') && git tag v$PACKAGE_VERSION && git push --tags",
23 | "test": "npm run eslint && eslint-find-rules -d --no-core"
24 | },
25 | "keywords": [
26 | "airbnb",
27 | "config",
28 | "eslint",
29 | "eslintconfig",
30 | "javascript",
31 | "standard",
32 | "styleguide"
33 | ],
34 | "dependencies": {
35 | "@eslint/eslintrc": "^3.0.1",
36 | "arrify": "^2.0.1",
37 | "cosmiconfig": "^9.0.0",
38 | "lodash": "^4.17.21",
39 | "mkdirp": "^3.0.1",
40 | "path": "^0.12.7",
41 | "ramda": "^0.29.1",
42 | "read-pkg-up": "7.0.1",
43 | "rimraf": "^5.0.5",
44 | "url": "^0.11.3"
45 | },
46 | "devDependencies": {
47 | "@testing-library/dom": "^9.3.4",
48 | "@testing-library/jest-dom": "^6.4.2",
49 | "@typescript-eslint/eslint-plugin": "^7.0.1",
50 | "ava": "^6.1.1",
51 | "babel-eslint": "^10.1.0",
52 | "chai": "^5.1.0",
53 | "cypress": "^13.6.4",
54 | "eslint": "^8.56.0",
55 | "eslint-config-airbnb": "^19.0.4",
56 | "eslint-config-prettier": "^9.1.0",
57 | "eslint-find-rules": "^4.1.0",
58 | "eslint-plugin-ava": "^14.0.0",
59 | "eslint-plugin-chai-expect": "^3.0.0",
60 | "eslint-plugin-chai-friendly": "^0.7.4",
61 | "eslint-plugin-const-case": "^1.2.2",
62 | "eslint-plugin-cypress": "^2.15.1",
63 | "eslint-plugin-eslint-comments": "^3.2.0",
64 | "eslint-plugin-fsa": "^1.0.12",
65 | "eslint-plugin-html": "^8.0.0",
66 | "eslint-plugin-jasmine": "^4.1.3",
67 | "eslint-plugin-jest": "^27.8.0",
68 | "eslint-plugin-jest-async": "^1.0.3",
69 | "eslint-plugin-jest-dom": "^5.1.0",
70 | "eslint-plugin-json": "^3.1.0",
71 | "eslint-plugin-lodash": "^7.4.0",
72 | "eslint-plugin-lodash-fp": "^2.2.0-a1",
73 | "eslint-plugin-markdown": "^3.0.1",
74 | "eslint-plugin-mocha": "^10.2.0",
75 | "eslint-plugin-mocha-cleanup": "^1.11.3",
76 | "eslint-plugin-no-constructor-bind": "^2.0.4",
77 | "eslint-plugin-no-secrets": "^0.8.9",
78 | "eslint-plugin-no-unsanitized": "^4.0.2",
79 | "eslint-plugin-no-use-extend-native": "^0.5.0",
80 | "eslint-plugin-optimize-regex": "^1.2.1",
81 | "eslint-plugin-pii": "^1.0.2",
82 | "eslint-plugin-prettier": "^5.1.3",
83 | "eslint-plugin-promise": "^6.1.1",
84 | "eslint-plugin-qunit": "^8.1.1",
85 | "eslint-plugin-ramda": "^2.5.1",
86 | "eslint-plugin-react-redux": "^4.1.0",
87 | "eslint-plugin-redux-saga": "^1.3.2",
88 | "eslint-plugin-security": "^2.1.0",
89 | "eslint-plugin-simple-import-sort": "^12.0.0",
90 | "eslint-plugin-sonarjs": "^0.24.0",
91 | "eslint-plugin-switch-case": "^1.1.2",
92 | "eslint-plugin-testing-library": "^6.2.0",
93 | "eslint-plugin-unicorn": "^51.0.1",
94 | "eslint-plugin-xss": "^0.1.12",
95 | "husky": "^9.0.11",
96 | "in-publish": "^2.0.1",
97 | "jasmine": "^5.1.0",
98 | "jest": "^29.7.0",
99 | "jest-dom": "^4.0.0",
100 | "lint-staged": "^15.2.2",
101 | "lodash-fp": "^0.10.4",
102 | "mocha": "^10.3.0",
103 | "prettier": "^3.2.5",
104 | "prettier-cli": "^0.1.0",
105 | "qunit": "^2.20.0",
106 | "react": "^18.2.0",
107 | "react-redux": "^9.1.0",
108 | "redux": "^5.0.1",
109 | "redux-saga": "^1.3.0",
110 | "safe-publish-latest": "^2.0.0",
111 | "snyk": "^1.1279.0",
112 | "testing-library": "0.0.2"
113 | },
114 | "engines": {
115 | "node": ">= 6.5"
116 | },
117 | "snyk": false
118 | }
119 |
--------------------------------------------------------------------------------
/rules/array-func.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['array-func'],
3 | // extends: ['plugin:array-func/recommended'],
4 | rules: {
5 | // Rule disabled due to clash with Unicorn
6 | 'array-func/prefer-array-from': 'off',
7 |
8 | // Rules not in recommended config
9 | 'array-func/prefer-flat': 0,
10 | 'array-func/prefer-flat-map': 0,
11 |
12 | // Rules in recommended config
13 | 'array-func/from-map': 'error',
14 | 'array-func/no-unnecessary-this-arg': 'error',
15 | 'array-func/avoid-reverse': 'error',
16 | },
17 | }
18 |
--------------------------------------------------------------------------------
/rules/ava.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['plugin:ava/recommended'],
3 | }
4 |
--------------------------------------------------------------------------------
/rules/chai-expect.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['plugin:chai-expect/recommended'],
3 | }
4 |
--------------------------------------------------------------------------------
/rules/chai-friendly.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['plugin:chai-friendly/recommended'],
3 | }
4 |
--------------------------------------------------------------------------------
/rules/const-case.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['const-case'],
3 | rules: { 'const-case/uppercase': 'error' },
4 | }
5 |
--------------------------------------------------------------------------------
/rules/cypress.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | 'cypress/globals': true,
4 | },
5 | extends: ['plugin:cypress/recommended'],
6 | plugins: ['cypress'],
7 | rules: {
8 | // Rules not in recommmend config
9 | 'cypress/assertion-before-screenshot': 0,
10 | 'cypress/no-force': 0,
11 | 'cypress/require-data-selectors': 0,
12 | },
13 | }
14 |
--------------------------------------------------------------------------------
/rules/eslint-comments.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['plugin:eslint-comments/recommended'],
3 | plugins: ['eslint-comments'],
4 | rules: {
5 | // Rules are not in recommended config
6 | 'eslint-comments/no-restricted-disable': 0,
7 | 'eslint-comments/no-unused-disable': 0,
8 | 'eslint-comments/no-use': 0,
9 | 'eslint-comments/require-description': 0,
10 | },
11 | }
12 |
--------------------------------------------------------------------------------
/rules/fsa.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['plugin:fsa/recommended'],
3 | plugins: ['fsa'],
4 | }
5 |
--------------------------------------------------------------------------------
/rules/html.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['html'],
3 | }
4 |
--------------------------------------------------------------------------------
/rules/jasmine.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | jasmine: true,
4 | },
5 | extends: ['plugin:jasmine/recommended'],
6 | plugins: ['jasmine'],
7 | rules: {
8 | 'jasmine/valid-expect': 0,
9 | },
10 | }
11 |
--------------------------------------------------------------------------------
/rules/jest-async.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['jest-async'],
3 | rules: {
4 | 'jest-async/expect-return': 'error',
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/rules/jest-dom.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['plugin:jest-dom/recommended'],
3 | }
4 |
--------------------------------------------------------------------------------
/rules/jest.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | jest: true,
4 | },
5 | extends: ['plugin:jest/recommended', 'plugin:jest/style'],
6 | overrides: [
7 | {
8 | files: ['setupJest.js'],
9 | rules: {
10 | 'import/no-extraneous-dependencies': 'off',
11 | },
12 | },
13 | ],
14 | plugins: ['jest'],
15 | rules: {
16 | 'jest/no-disabled-tests': 'off',
17 |
18 | // Not included in jest/recommended
19 | 'jest/consistent-test-it': 0,
20 | 'jest/lowercase-name': 0,
21 | 'jest/no-conditional-expect': 0,
22 | 'jest/no-deprecated-functions': 0,
23 | 'jest/no-duplicate-hooks': 0,
24 | 'jest/no-expect-resolves': 0,
25 | 'jest/no-hooks': 0,
26 | // 'jest/no-if': 0, deprecaded
27 | 'jest/no-interpolation-in-snapshots': 0,
28 | 'jest/no-large-snapshots': 0,
29 | 'jest/no-restricted-matchers': 0,
30 | 'jest/no-test-return-statement': 0,
31 | 'jest/no-truthy-falsy': 0,
32 | 'jest/prefer-called-with': 0,
33 | 'jest/prefer-expect-assertions': 0,
34 | 'jest/prefer-hooks-on-top': 0,
35 | 'jest/prefer-inline-snapshots': 0,
36 | 'jest/prefer-spy-on': 0,
37 | 'jest/prefer-strict-equal': 0,
38 | 'jest/prefer-todo': 0,
39 | 'jest/require-to-throw-message': 0,
40 | 'jest/require-top-level-describe': 0,
41 | 'jest/unbound-method': 0,
42 | 'jest/valid-title': 0,
43 | },
44 | }
45 |
--------------------------------------------------------------------------------
/rules/json-format.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['json-format'],
3 | settings: {
4 | 'json/sort-package-json': [
5 | 'name',
6 | 'version',
7 | 'author',
8 | 'contributors',
9 | 'license',
10 | 'private',
11 | 'description',
12 | 'homepage',
13 | 'funding',
14 | 'bugs',
15 | 'repository',
16 | 'files',
17 | 'sideEffects',
18 | 'main',
19 | 'umd:main',
20 | 'unpkg',
21 | 'module',
22 | 'source',
23 | 'jsnext:main',
24 | 'browser',
25 | 'types',
26 | 'typings',
27 | 'style',
28 | 'example',
29 | 'examplestyle',
30 | 'assets',
31 | 'bin',
32 | 'man',
33 | 'directories',
34 | 'workspaces',
35 | 'scripts',
36 | 'betterScripts',
37 | 'husky',
38 | 'pre-commit',
39 | 'commitlint',
40 | 'lint-staged',
41 | 'config',
42 | 'keywords',
43 | 'nodemonConfig',
44 | 'browserify',
45 | 'babel',
46 | 'browserslist',
47 | 'xo',
48 | 'prettier',
49 | 'eslintConfig',
50 | 'eslintIgnore',
51 | 'stylelint',
52 | 'jest',
53 | 'dependencies',
54 | 'devDependencies',
55 | 'peerDependencies',
56 | 'bundledDependencies',
57 | 'bundleDependencies',
58 | 'optionalDependencies',
59 | 'flat',
60 | 'resolutions',
61 | 'engines',
62 | 'engineStrict',
63 | 'os',
64 | 'cpu',
65 | 'preferGlobal',
66 | 'publishConfig',
67 | ],
68 | 'json/ignore-files': ['**/package-lock.json'],
69 | 'json/json-with-comments-files': ['**/tsconfig.json', '.vscode/**'],
70 | },
71 | }
72 |
--------------------------------------------------------------------------------
/rules/json.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['plugin:json/recommended-with-comments'],
3 | overrides: [
4 | {
5 | files: ['**.json'],
6 | plugins: ['json'],
7 | rules: {
8 | 'comma-dangle': 0,
9 | 'no-var': 0,
10 | 'no-unused-vars': 0,
11 | quotes: 0,
12 | 'quote-props': 0,
13 | semi: 0,
14 | },
15 | },
16 | ],
17 | rules: {
18 | // Not included in json/recommended-with-comments
19 | 'json/colon-expected': 0,
20 | 'json/comma-expected': 0,
21 | 'json/comma-or-close-backet-expected': 0,
22 | 'json/comma-or-close-brace-expected': 0,
23 | 'json/comment-not-permitted': 0,
24 | 'json/duplicate-key': 0,
25 | 'json/enum-value-mismatch': 0,
26 | 'json/invalid-character': 0,
27 | 'json/invalid-escape-character': 0,
28 | 'json/invalid-unicode': 0,
29 | 'json/json': 0,
30 | 'json/property-expected': 0,
31 | 'json/schema-resolve-error': 0,
32 | 'json/trailing-comma': 0,
33 | 'json/undefined': 0,
34 | 'json/unexpected-end-of-comment': 0,
35 | 'json/unexpected-end-of-number': 0,
36 | 'json/unexpected-end-of-string': 0,
37 | 'json/unknown': 0,
38 | 'json/value-expected': 0,
39 | },
40 | }
41 |
--------------------------------------------------------------------------------
/rules/lodash-fp.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['plugin:lodash-fp/recommended'],
3 | plugins: ['lodash-fp'],
4 | rules: {
5 | 'lodash-fp/use-fp': 0,
6 | },
7 | }
8 |
--------------------------------------------------------------------------------
/rules/lodash.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['lodash'],
3 | rules: {
4 | // Possible Errors
5 | 'lodash/callback-binding': 2,
6 | 'lodash/collection-method-value': 2,
7 | 'lodash/collection-return': 2,
8 | 'lodash/no-double-unwrap': 2,
9 | 'lodash/no-extra-args': 2,
10 | 'lodash/no-unbound-this': 2,
11 | 'lodash/unwrap': 2,
12 |
13 | // Disable stylistic rules = Use prettier
14 | 'lodash/chain-style': [2, 'as-needed'],
15 | 'lodash/chaining': 2,
16 | 'lodash/collection-ordering': 2,
17 | 'lodash/consistent-compose': [2, 'flow'],
18 | 'lodash/identity-shorthand': [2, 'always'],
19 | 'lodash/import-scope': [2],
20 | 'lodash/matches-prop-shorthand': [2, 'always'],
21 | 'lodash/matches-shorthand': [2, 'always', 3],
22 | 'lodash/no-commit': 2,
23 | 'lodash/path-style': [2, 'string'],
24 | 'lodash/prefer-compact': 2,
25 | 'lodash/prefer-filter': [2, 3],
26 | 'lodash/prefer-find': 2,
27 | 'lodash/prefer-flat-map': 2,
28 | 'lodash/prefer-immutable-method': 2,
29 | 'lodash/prefer-invoke-map': 2,
30 | 'lodash/prefer-map': 2,
31 | 'lodash/prefer-noop': 2,
32 | 'lodash/prefer-reject': [2, 3],
33 | 'lodash/prefer-thru': 2,
34 | 'lodash/prefer-wrapper-method': 2,
35 | 'lodash/preferred-alias': 2,
36 | 'lodash/prop-shorthand': [2, 'always'],
37 |
38 | // Prefer over Native - DISABLED
39 | 'lodash/prefer-constant': 0,
40 | 'lodash/prefer-get': 0,
41 | 'lodash/prefer-includes': 0,
42 | 'lodash/prefer-is-nil': 0,
43 | 'lodash/prefer-lodash-chain': 0,
44 | 'lodash/prefer-lodash-method': 0,
45 | 'lodash/prefer-lodash-typecheck': 0,
46 | 'lodash/prefer-matches': 0,
47 | 'lodash/prefer-over-quantifier': 0,
48 | 'lodash/prefer-some': 0,
49 | 'lodash/prefer-startswith': 0,
50 | 'lodash/prefer-times': 0,
51 | },
52 | }
53 |
--------------------------------------------------------------------------------
/rules/markdown.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['markdown'],
3 | overrides: [
4 | {
5 | files: ['*.md', '**/*.md'],
6 | processor: 'markdown/markdown',
7 | },
8 | {
9 | files: ['*.md/*.js', '**/*.md/*.js'],
10 | rules: {
11 | 'global-require': 'off',
12 | 'import/no-unresolved': 'off',
13 | 'import/order': 'off',
14 | 'no-undef': 'off',
15 | 'no-console': 'off',
16 | 'no-unused-vars': 'off',
17 | 'prefer-reflect': 'off',
18 | strict: 'off',
19 | },
20 | },
21 | ],
22 | }
23 |
--------------------------------------------------------------------------------
/rules/mocha-cleanup.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['plugin:mocha-cleanup/recommended-no-limits'],
3 | plugins: ['mocha-cleanup'],
4 | rules: {
5 | // Rules are not in recommended config
6 | 'mocha-cleanup/asserts-limit': 0,
7 | 'mocha-cleanup/complexity-it': 0,
8 | 'mocha-cleanup/disallow-stub-window': 0,
9 | 'mocha-cleanup/disallowed-usage': 0,
10 | },
11 | }
12 |
--------------------------------------------------------------------------------
/rules/mocha.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['plugin:mocha/recommended'],
3 | plugins: ['mocha'],
4 | }
5 |
--------------------------------------------------------------------------------
/rules/no-constructor-bind.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['no-constructor-bind'],
3 | rules: {
4 | 'no-constructor-bind/no-constructor-bind': 'error',
5 | 'no-constructor-bind/no-constructor-state': 'error',
6 | },
7 | }
8 |
--------------------------------------------------------------------------------
/rules/no-secrets.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | overrides: [
3 | {
4 | plugins: ['no-secrets'],
5 | rules: {
6 | 'no-secrets/no-secrets': 'error',
7 | },
8 | files: ['*', '*/**'],
9 | excludedFiles: [
10 | 'package.json',
11 | '**/package.json',
12 | 'package-lock.json',
13 | '**/package-lock.json',
14 | 'tsconfig.json',
15 | '**/tsconfig.json',
16 | ],
17 | },
18 | ],
19 | }
20 |
--------------------------------------------------------------------------------
/rules/no-unsanitized.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['no-unsanitized'],
3 | rules: {
4 | 'no-unsanitized/method': 'error',
5 | 'no-unsanitized/property': 'error',
6 | },
7 | }
8 |
--------------------------------------------------------------------------------
/rules/no-use-extend-native.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['no-use-extend-native'],
3 | rules: {
4 | 'no-use-extend-native/no-use-extend-native': 'error',
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/rules/optimize-regex.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['optimize-regex'],
3 | rules: {
4 | 'optimize-regex/optimize-regex': 'warn',
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/rules/pii.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['plugin:pii/recommended'],
3 | rules: {
4 | 'pii/no-dob': 0, // Buggy rule
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/rules/prettier.js:
--------------------------------------------------------------------------------
1 | const { hasAnyDep } = require('../lib/utils')
2 | const { consoleConfig } = require('../lib/loggers')
3 | const isModuleAvailable = require('../lib/is-module-available')
4 |
5 | const configs = ['prettier']
6 |
7 | const optionalConfigs = [
8 | ['@typescript-eslint/eslint-plugin', 'prettier/@typescript-eslint'],
9 | 'babel',
10 | 'flowtype',
11 | 'react',
12 | ['eslint-config-standard', 'prettier/standard'],
13 | 'vue',
14 | 'unicorn',
15 | ]
16 |
17 | optionalConfigs.forEach((optConfig) => {
18 | const config =
19 | typeof optConfig === 'string'
20 | ? [`eslint-plugin-${optConfig}`, `prettier/${optConfig}`]
21 | : optConfig
22 |
23 | if (hasAnyDep(config[0]) && isModuleAvailable(config[1]))
24 | configs.push(config[1])
25 | })
26 |
27 | if (!global.hasAdjunctPrettierLoaded) {
28 | configs.map((config) => consoleConfig(config))
29 | global.hasAdjunctPrettierLoaded = true
30 | }
31 |
32 | module.exports = {
33 | extends: configs,
34 | plugins: ['prettier'],
35 | rules: {
36 | 'prettier/prettier': 'error',
37 | },
38 | overrides: [
39 | {
40 | files: ['**.md', '**.json'],
41 | rules: {
42 | 'prettier/prettier': 'off',
43 | },
44 | },
45 | ],
46 | }
47 |
--------------------------------------------------------------------------------
/rules/promise.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['plugin:promise/recommended'],
3 | plugins: ['promise'],
4 | rules: {
5 | 'promise/prefer-await-to-callbacks': 'off',
6 | 'promise/prefer-await-to-then': 'off',
7 | },
8 | }
9 |
--------------------------------------------------------------------------------
/rules/qunit.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['qunit'],
3 | extends: ['plugin:qunit/recommended'],
4 | }
5 |
--------------------------------------------------------------------------------
/rules/ramda.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['plugin:ramda/recommended'],
3 | plugins: ['ramda'],
4 | }
5 |
--------------------------------------------------------------------------------
/rules/react-redux.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['plugin:react-redux/recommended'],
3 | plugins: ['react-redux'],
4 | rules: {
5 | 'react-redux/prefer-separate-component-file': 'off',
6 | 'react-redux/mapStateToProps-prefer-selectors': 'off',
7 | },
8 | }
9 |
--------------------------------------------------------------------------------
/rules/redux-saga.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['plugin:redux-saga/recommended'],
3 | plugins: ['redux-saga'],
4 | rules: {
5 | 'redux-saga/no-unhandled-errors': 'off',
6 | },
7 | }
8 |
--------------------------------------------------------------------------------
/rules/security.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['security'],
3 | extends: ['plugin:security/recommended-legacy'],
4 | rules: {
5 | 'security/detect-object-injection': 0,
6 | },
7 | }
8 |
--------------------------------------------------------------------------------
/rules/simple-import-sort.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['simple-import-sort'],
3 | rules: {
4 | 'simple-import-sort/imports': 'error',
5 | 'simple-import-sort/exports': 'error',
6 | 'sort-imports': 'off',
7 | 'import/order': 'off',
8 | },
9 | }
10 |
--------------------------------------------------------------------------------
/rules/sonarjs.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['sonarjs'],
3 | extends: ['plugin:sonarjs/recommended'],
4 | overrides: [
5 | {
6 | files: ['**.md', '**.json'],
7 | rules: {
8 | 'sonarjs/no-duplicate-string': 'off',
9 | },
10 | },
11 | ],
12 | }
13 |
--------------------------------------------------------------------------------
/rules/switch-case.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['plugin:switch-case/recommended'],
3 | plugins: ['switch-case'],
4 | rules: {
5 | 'switch-case/newline-between-switch-case': [
6 | 'error',
7 | 'always',
8 | { fallthrough: 'never' },
9 | ],
10 | },
11 | }
12 |
--------------------------------------------------------------------------------
/rules/test-overrides.js:
--------------------------------------------------------------------------------
1 | require('../lib/loggers').consoleLog(' eslint-test-overrides\n')
2 |
3 | module.exports = {
4 | overrides: [
5 | {
6 | files: [
7 | '*.spec.js',
8 | '*.spec.ts',
9 | '*.spec.jsx',
10 | '*.spec.tsx',
11 | '*.test.js',
12 | '*.test.ts',
13 | '*.test.jsx',
14 | '*.test.tsx',
15 | '**/tests/**',
16 | '**/test/**',
17 | '**/__test__/**',
18 | '**/__tests__/**',
19 | ],
20 | rules: {
21 | 'func-names': 'off',
22 | 'global-require': 'off',
23 | 'no-shadow': 'off',
24 | 'max-lines': 'off',
25 | 'max-nested-callbacks': 'off',
26 | 'max-statements': 'off',
27 | 'promise/always-return': 'off',
28 | 'promise/no-callback-in-promise': 'off',
29 | 'security/detect-non-literal-regexp': 'off',
30 | 'sonarjs/no-duplicate-string': 'off',
31 | 'sonarjs/no-identical-functions': 'off',
32 | },
33 | },
34 | ],
35 | }
36 |
--------------------------------------------------------------------------------
/rules/testing-library.js:
--------------------------------------------------------------------------------
1 | const isModuleAvailable = require('../lib/is-module-available')
2 | const { consoleLog } = require('../lib/loggers')
3 |
4 | let ruleset = ''
5 |
6 | switch (true) {
7 | case isModuleAvailable('react'):
8 | ruleset = 'react'
9 | break
10 |
11 | case isModuleAvailable('vue'):
12 | ruleset = 'vue'
13 | break
14 |
15 | default:
16 | ruleset = 'recommended'
17 | }
18 |
19 | consoleLog(` eslint-plugin-testing-library/${ruleset}`)
20 |
21 | module.exports = {
22 | extends: [`plugin:testing-library/${ruleset}`],
23 | rules: {
24 | // Not included in jest/recommended
25 | 'testing-library/await-fire-event': 0,
26 | 'testing-library/consistent-data-testid': 0,
27 | 'testing-library/no-debug': 0,
28 | 'testing-library/no-dom-import': 0,
29 | 'testing-library/no-manual-cleanup': 0,
30 | 'testing-library/no-render-in-setup': 0,
31 | 'testing-library/no-await-sync-events': 0,
32 | 'testing-library/no-wait-for-empty-callback': 0,
33 | 'testing-library/no-wait-for-snapshot': 0,
34 | 'testing-library/prefer-explicit-assert': 0,
35 | 'testing-library/prefer-presence-queries': 0,
36 | 'testing-library/prefer-screen-queries': 0,
37 | 'testing-library/prefer-wait-for': 0,
38 | },
39 | }
40 |
--------------------------------------------------------------------------------
/rules/unicorn.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['plugin:unicorn/recommended'],
3 | rules: {
4 | 'unicorn/expiring-todo-comments': 0,
5 | 'unicorn/filename-case': 0,
6 | 'unicorn/no-array-for-each': 0,
7 | 'unicorn/no-null': 0,
8 | 'unicorn/prefer-number-properties': 0,
9 | 'unicorn/prefer-optional-catch-binding': 0,
10 | 'unicorn/prevent-abbreviations': 0,
11 | 'unicorn/switch-case-braces': ['error', 'avoid'],
12 | },
13 | }
14 |
--------------------------------------------------------------------------------
/rules/xss.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['plugin:xss/recommended'],
3 | }
4 |
--------------------------------------------------------------------------------