@fullstacksjs/eslint-config 7.2.0 → 8.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -10
- package/bin/lib/askWhenConfigExists.js +51 -0
- package/bin/lib/createOptions.js +1 -1
- package/bin/lib/generateFile.js +1 -1
- package/bin/lib/getUserInput.js +1 -1
- package/bin/lib/tasks.js +6 -3
- package/package.json +16 -15
- package/rules/jest.js +2 -1
- package/rules/react.js +2 -2
- package/rules/storybook.js +17 -0
- package/rules/strict.js +1 -1
- package/rules/typescript.js +1 -1
- package/storybook.js +9 -0
- package/nextjs.js +0 -24
package/README.md
CHANGED
|
@@ -58,16 +58,6 @@ Just extend from `@fullstacksjs`:
|
|
|
58
58
|
|
|
59
59
|
It reads your root `package.json` dependencies and includes necessary rules.
|
|
60
60
|
|
|
61
|
-
## NextJS
|
|
62
|
-
|
|
63
|
-
[NextJS](https://nextjs.org/) config is subset of base config which is compatible with builtin NextJS eslint config.
|
|
64
|
-
|
|
65
|
-
```json
|
|
66
|
-
{
|
|
67
|
-
"extends": ["@fullstacksjs/eslint-config/nextjs"]
|
|
68
|
-
}
|
|
69
|
-
```
|
|
70
|
-
|
|
71
61
|
## Advanced Usage
|
|
72
62
|
|
|
73
63
|
```jsonc
|
|
@@ -79,6 +69,7 @@ It reads your root `package.json` dependencies and includes necessary rules.
|
|
|
79
69
|
"@fullstacksjs/eslint-config/typescript",
|
|
80
70
|
"@fullstacksjs/eslint-config/strict",
|
|
81
71
|
"@fullstacksjs/eslint-config/cypress",
|
|
72
|
+
"@fullstacksjs/eslint-config/storybook",
|
|
82
73
|
"@fullstacksjs/eslint-config/esm", // for native ESM modules
|
|
83
74
|
"@fullstacksjs/eslint-config/typecheck" // ⚠️ Needs configurations (not included in default config)
|
|
84
75
|
]
|
|
@@ -116,6 +107,7 @@ If you need more advanced `typescript-eslint` rules, then you can extend from `"
|
|
|
116
107
|
* eslint-plugin-fp
|
|
117
108
|
* eslint-plugin-node
|
|
118
109
|
* eslint-plugin-promise
|
|
110
|
+
* eslint-plugin-storybook
|
|
119
111
|
|
|
120
112
|
That's all. Feel free to use 💛
|
|
121
113
|
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const { readFile } = require('fs/promises');
|
|
2
|
+
const inquirer = require('inquirer');
|
|
3
|
+
|
|
4
|
+
const isObject = x => typeof x === 'object' && !Array.isArray(x) && x !== null;
|
|
5
|
+
|
|
6
|
+
// TODO: add this function to the toolbox
|
|
7
|
+
const merge = (obj, obj2) =>
|
|
8
|
+
Object.entries(obj)
|
|
9
|
+
.concat(Object.entries(obj2))
|
|
10
|
+
.reduce((acc, [key, value]) => {
|
|
11
|
+
const accValue = acc[key];
|
|
12
|
+
return Array.isArray(accValue) && Array.isArray(value)
|
|
13
|
+
? { ...acc, [key]: accValue.concat(value) }
|
|
14
|
+
: isObject(accValue) && isObject(value)
|
|
15
|
+
? { ...acc, [key]: merge(accValue, value) }
|
|
16
|
+
: { ...acc, [key]: value };
|
|
17
|
+
}, {});
|
|
18
|
+
|
|
19
|
+
const Choice = {
|
|
20
|
+
noConfig: 'noConfig',
|
|
21
|
+
overwrite: 'overwrite',
|
|
22
|
+
extend: 'extend',
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const askWhenConfigExists = async eslintrc => {
|
|
26
|
+
const file = await readFile('.eslintrc.json').catch(() => null);
|
|
27
|
+
if (file === null) return eslintrc;
|
|
28
|
+
|
|
29
|
+
const currentConfig = JSON.parse(file);
|
|
30
|
+
const isConfiguredBefore = eslintrc?.extends.every(c => currentConfig?.extends?.includes(c));
|
|
31
|
+
if (isConfiguredBefore) return currentConfig;
|
|
32
|
+
|
|
33
|
+
const { choice } = await inquirer.prompt({
|
|
34
|
+
type: 'list',
|
|
35
|
+
name: 'choice',
|
|
36
|
+
message: 'config found',
|
|
37
|
+
choices: [
|
|
38
|
+
{
|
|
39
|
+
value: 'overwrite',
|
|
40
|
+
name: 'overwrite the current config completely',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
value: 'extend',
|
|
44
|
+
name: 'extend the fullstacks config alongside current config',
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
});
|
|
48
|
+
return choice === Choice.extend ? merge(currentConfig, eslintrc) : eslintrc;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
module.exports = askWhenConfigExists;
|
package/bin/lib/createOptions.js
CHANGED
|
@@ -12,7 +12,7 @@ async function createOptions() {
|
|
|
12
12
|
const optionsFromArgs = { technology: args.t };
|
|
13
13
|
const userInput = isTechnologyInArgv ? optionsFromArgs : await getUserInput();
|
|
14
14
|
|
|
15
|
-
if (userInput.
|
|
15
|
+
if (userInput.technology === 'ts') {
|
|
16
16
|
requiredPackages.push('typescript');
|
|
17
17
|
}
|
|
18
18
|
|
package/bin/lib/generateFile.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { writeFile } = require('fs/promises');
|
|
2
2
|
|
|
3
3
|
function createFileTask(eslintrc, ctx, task) {
|
|
4
|
-
return writeFile('.eslintrc', JSON.stringify(eslintrc, null, 2))
|
|
4
|
+
return writeFile('.eslintrc.json', JSON.stringify(eslintrc, null, 2))
|
|
5
5
|
.then(() => {
|
|
6
6
|
task.title = `.eslintrc - Successfully Generated.`;
|
|
7
7
|
})
|
package/bin/lib/getUserInput.js
CHANGED
package/bin/lib/tasks.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
const Listr = require('listr');
|
|
2
2
|
const util = require('util');
|
|
3
|
+
const askWhenConfigExists = require('./askWhenConfigExists');
|
|
3
4
|
const exec = util.promisify(require('child_process').exec);
|
|
4
5
|
const createFileTask = require('./generateFile');
|
|
5
6
|
|
|
6
|
-
function createTasks({ packages, eslintrc }) {
|
|
7
|
+
async function createTasks({ packages, eslintrc }) {
|
|
7
8
|
const installTasks = packages.map(pkg => ({
|
|
8
9
|
title: `Installing ${pkg}`,
|
|
9
10
|
task: (ctx, task) => exec(`npm i -D ${pkg}`).then(() => (task.title = `${pkg} Installed`)),
|
|
10
11
|
}));
|
|
11
12
|
|
|
13
|
+
const config = await askWhenConfigExists(eslintrc);
|
|
14
|
+
|
|
12
15
|
return new Listr(
|
|
13
16
|
[
|
|
14
17
|
{
|
|
@@ -16,8 +19,8 @@ function createTasks({ packages, eslintrc }) {
|
|
|
16
19
|
task: () => new Listr(installTasks, { exitOnError: true }),
|
|
17
20
|
},
|
|
18
21
|
{
|
|
19
|
-
title: 'Generating .eslintrc file',
|
|
20
|
-
task: (ctx, task) => createFileTask(
|
|
22
|
+
title: 'Generating .eslintrc.json file',
|
|
23
|
+
task: (ctx, task) => createFileTask(config, ctx, task),
|
|
21
24
|
},
|
|
22
25
|
],
|
|
23
26
|
{ exitOnError: false },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fullstacksjs/eslint-config",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.1.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "fullstacks <fullstacksjs@gmail.com>",
|
|
6
6
|
"description": "fullstacks eslint config",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"index.js",
|
|
22
22
|
"jest.js",
|
|
23
23
|
"cypress.js",
|
|
24
|
-
"
|
|
24
|
+
"storybook.js",
|
|
25
25
|
"react.js",
|
|
26
26
|
"typescript.js",
|
|
27
27
|
"typecheck.js",
|
|
@@ -42,38 +42,39 @@
|
|
|
42
42
|
"main": "index.js",
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@frontendmonster/utils": "0.3.11",
|
|
45
|
-
"@typescript-eslint/eslint-plugin": "5.
|
|
46
|
-
"@typescript-eslint/parser": "5.
|
|
45
|
+
"@typescript-eslint/eslint-plugin": "5.10.2",
|
|
46
|
+
"@typescript-eslint/parser": "5.10.2",
|
|
47
47
|
"eslint-config-prettier": "8.3.0",
|
|
48
48
|
"eslint-import-resolver-typescript": "2.5.0",
|
|
49
49
|
"eslint-plugin-cypress": "2.12.1",
|
|
50
50
|
"eslint-plugin-fp": "2.3.0",
|
|
51
|
-
"eslint-plugin-import": "2.25.
|
|
52
|
-
"eslint-plugin-jest": "
|
|
51
|
+
"eslint-plugin-import": "2.25.4",
|
|
52
|
+
"eslint-plugin-jest": "26.1.0",
|
|
53
53
|
"eslint-plugin-jest-formatting": "3.1.0",
|
|
54
54
|
"eslint-plugin-jsx-a11y": "6.5.1",
|
|
55
55
|
"eslint-plugin-node": "11.1.0",
|
|
56
56
|
"eslint-plugin-prettier": "4.0.0",
|
|
57
57
|
"eslint-plugin-promise": "6.0.0",
|
|
58
|
-
"eslint-plugin-react": "7.
|
|
58
|
+
"eslint-plugin-react": "7.28.0",
|
|
59
59
|
"eslint-plugin-react-hooks": "4.3.0",
|
|
60
60
|
"eslint-plugin-simple-import-sort": "7.0.0",
|
|
61
|
+
"eslint-plugin-storybook": "0.5.6",
|
|
62
|
+
"inquirer": "8.2.0",
|
|
63
|
+
"listr": "0.14.3",
|
|
61
64
|
"lodash.has": "4.5.2",
|
|
62
|
-
"read-pkg-up": "7.0.1"
|
|
65
|
+
"read-pkg-up": "7.0.1",
|
|
66
|
+
"yargs": "17.3.1"
|
|
63
67
|
},
|
|
64
68
|
"devDependencies": {
|
|
65
|
-
"eslint": "8.
|
|
66
|
-
"eslint-find-rules": "4.
|
|
69
|
+
"eslint": "8.8.0",
|
|
70
|
+
"eslint-find-rules": "4.1.0",
|
|
67
71
|
"husky": "7.0.4",
|
|
68
|
-
"
|
|
69
|
-
"lint-staged": "12.1.2",
|
|
70
|
-
"listr": "0.14.3",
|
|
72
|
+
"lint-staged": "12.3.3",
|
|
71
73
|
"np": "7.6.0",
|
|
72
74
|
"npm-run-all": "4.1.5",
|
|
73
75
|
"pinst": "2.1.6",
|
|
74
76
|
"prettier": "2.5.1",
|
|
75
|
-
"typescript": "4.5.
|
|
76
|
-
"yargs": "17.3.1"
|
|
77
|
+
"typescript": "4.5.5"
|
|
77
78
|
},
|
|
78
79
|
"peerDependencies": {
|
|
79
80
|
"cypress": ">=8",
|
package/rules/jest.js
CHANGED
|
@@ -7,6 +7,7 @@ module.exports = {
|
|
|
7
7
|
'jest/no-alias-methods': 'off',
|
|
8
8
|
'jest/no-commented-out-tests': 'warn',
|
|
9
9
|
'jest/no-conditional-expect': 'error',
|
|
10
|
+
'jest/no-conditional-in-test': 'error',
|
|
10
11
|
'jest/no-deprecated-functions': 'error',
|
|
11
12
|
'jest/no-disabled-tests': 'warn',
|
|
12
13
|
'jest/no-done-callback': 'warn',
|
|
@@ -16,7 +17,6 @@ module.exports = {
|
|
|
16
17
|
'jest/no-focused-tests': 'error',
|
|
17
18
|
'jest/no-hooks': 'off',
|
|
18
19
|
'jest/no-identical-title': 'error',
|
|
19
|
-
'jest/no-if': 'error',
|
|
20
20
|
'jest/no-interpolation-in-snapshots': 'error',
|
|
21
21
|
'jest/no-jasmine-globals': 'off',
|
|
22
22
|
'jest/no-jest-import': 'error',
|
|
@@ -34,6 +34,7 @@ module.exports = {
|
|
|
34
34
|
'jest/prefer-hooks-on-top': 'error',
|
|
35
35
|
'jest/prefer-inline-snapshots': 'off',
|
|
36
36
|
'jest/prefer-lowercase-title': 'off',
|
|
37
|
+
'jest/prefer-snapshot-hint': 'warn',
|
|
37
38
|
'jest/prefer-spy-on': 'off',
|
|
38
39
|
'jest/prefer-strict-equal': 'off',
|
|
39
40
|
'jest/prefer-to-be-null': 'off',
|
package/rules/react.js
CHANGED
|
@@ -10,7 +10,7 @@ module.exports = {
|
|
|
10
10
|
'react/forbid-elements': 'off',
|
|
11
11
|
'react/forbid-foreign-prop-types': 'error',
|
|
12
12
|
'react/forbid-prop-types': 'off',
|
|
13
|
-
'react/function-component-definition': '
|
|
13
|
+
'react/function-component-definition': ['warn', { namedComponents: 'arrow-function', unnamedComponents: 'arrow-function' }],
|
|
14
14
|
'react/jsx-boolean-value': 'off',
|
|
15
15
|
'react/jsx-child-element-spacing': 'warn',
|
|
16
16
|
'react/jsx-curly-brace-presence': ['warn', { props: 'never', children: 'ignore' }],
|
|
@@ -68,10 +68,10 @@ module.exports = {
|
|
|
68
68
|
'react/no-unused-state': 'error',
|
|
69
69
|
'react/no-will-update-set-state': 'error',
|
|
70
70
|
'react/prefer-es6-class': 'off',
|
|
71
|
+
'react/prefer-exact-props': 'off',
|
|
71
72
|
'react/prefer-read-only-props': 'off',
|
|
72
73
|
'react/prefer-stateless-function': 'off',
|
|
73
74
|
'react/prop-types': 'off',
|
|
74
|
-
'react/prefer-exact-props': 'off',
|
|
75
75
|
'react/react-in-jsx-scope': 'off', // jsx automatic runtime
|
|
76
76
|
'react/require-default-props': 'off',
|
|
77
77
|
'react/require-optimization': 'off',
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
rules: {
|
|
3
|
+
'storybook/await-interactions': 'error',
|
|
4
|
+
'storybook/context-in-play-function': 'error',
|
|
5
|
+
'storybook/default-exports': 'error',
|
|
6
|
+
'storybook/hierarchy-separator': 'warn',
|
|
7
|
+
'storybook/no-redundant-story-name': 'warn',
|
|
8
|
+
'storybook/prefer-pascal-case': 'warn',
|
|
9
|
+
'storybook/story-exports': 'error',
|
|
10
|
+
'storybook/use-storybook-expect': 'error',
|
|
11
|
+
'storybook/use-storybook-testing-library': 'error',
|
|
12
|
+
|
|
13
|
+
'storybook/csf-component': 'warn',
|
|
14
|
+
'storybook/no-stories-of': 'warn',
|
|
15
|
+
'storybook/no-title-property-in-meta': 'warn',
|
|
16
|
+
},
|
|
17
|
+
};
|
package/rules/strict.js
CHANGED
package/rules/typescript.js
CHANGED
package/storybook.js
ADDED
package/nextjs.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
plugins: ['prettier', 'simple-import-sort', 'promise', 'node', 'fp'],
|
|
3
|
-
parserOptions: {
|
|
4
|
-
ecmaVersion: 2020,
|
|
5
|
-
sourceType: 'module',
|
|
6
|
-
requireConfigFile: false,
|
|
7
|
-
},
|
|
8
|
-
env: {
|
|
9
|
-
browser: true,
|
|
10
|
-
es6: true,
|
|
11
|
-
node: true,
|
|
12
|
-
},
|
|
13
|
-
extends: [
|
|
14
|
-
'./rules/base',
|
|
15
|
-
'./rules/es2015',
|
|
16
|
-
'./rules/forbidden',
|
|
17
|
-
'./rules/style',
|
|
18
|
-
'./rules/variables',
|
|
19
|
-
'./rules/fp',
|
|
20
|
-
'./rules/promise',
|
|
21
|
-
'./rules/node',
|
|
22
|
-
'prettier',
|
|
23
|
-
],
|
|
24
|
-
};
|