@fullstacksjs/eslint-config 8.10.0 → 8.11.0

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/cypress.js CHANGED
@@ -1,13 +1,15 @@
1
+ const { exts } = require('./utils');
2
+
1
3
  /** @type { import('eslint').Linter.Config } */
2
4
  module.exports = {
3
5
  overrides: [
4
6
  {
5
- files: ['**/cypress/**/*.+(js|jsx)', '**/cypress/**/*.+(ts|tsx)'],
6
- plugins: ['cypress'],
7
+ files: [`**/cypress/**/*.${exts}`, `**/*.cy.+${exts}`],
8
+ plugins: ['jest', 'jest-formatting', 'cypress'],
7
9
  env: {
8
10
  'cypress/globals': true,
9
11
  },
10
- extends: ['./rules/cypress'],
12
+ extends: ['./rules/test', './rules/cypress'],
11
13
  },
12
14
  ],
13
15
  };
package/esm.js CHANGED
@@ -1,13 +1,13 @@
1
1
  /** @type { import('eslint').Linter.Config } */
2
2
  module.exports = {
3
3
  rules: {
4
- 'import/extensions': 'off',
4
+ 'import/extensions': ['error', { mjs: 'ignorePackages' }],
5
5
  },
6
6
  overrides: [
7
7
  {
8
8
  files: ['*.ts', '*.tsx'],
9
9
  rules: {
10
- 'import/no-unresolved': [2, { ignore: ['.js$'], caseSensitiveStrict: true }],
10
+ 'import/no-unresolved': ['error', { ignore: ['.js$'], caseSensitiveStrict: true }],
11
11
  },
12
12
  },
13
13
  ],
package/jest.js CHANGED
@@ -1,4 +1,5 @@
1
- const exts = '+(js|jsx|ts|tsx)';
1
+ const { exts } = require('./utils');
2
+
2
3
  const dirs = '+(test|tests|__test__|__tests__|spec|specs)';
3
4
 
4
5
  /** @type { import('eslint').Linter.Config } */
@@ -10,7 +11,7 @@ module.exports = {
10
11
  env: {
11
12
  'jest/globals': true,
12
13
  },
13
- extends: ['./rules/jest', './rules/jest-format'],
14
+ extends: ['./rules/test', './rules/jest'],
14
15
  },
15
16
  ],
16
17
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fullstacksjs/eslint-config",
3
- "version": "8.10.0",
3
+ "version": "8.11.0",
4
4
  "license": "MIT",
5
5
  "author": "fullstacks <fullstacksjs@gmail.com>",
6
6
  "description": "fullstacks eslint config",
@@ -11,24 +11,22 @@
11
11
  "publishConfig": {
12
12
  "registry": "https://registry.npmjs.org"
13
13
  },
14
- "bin": {
15
- "fullstacksjs-eslint": "./bin/index.js"
16
- },
17
14
  "files": [
18
- "bin",
19
- "rules",
20
15
  "base.js",
16
+ "bin",
17
+ "cypress.js",
18
+ "esm.js",
19
+ "graphql.js",
21
20
  "index.js",
22
21
  "jest.js",
23
22
  "nextjs.js",
24
- "cypress.js",
25
- "storybook.js",
26
23
  "packages.js",
27
- "graphql.js",
28
24
  "react.js",
29
- "typescript.js",
25
+ "rules",
26
+ "storybook.js",
30
27
  "typecheck.js",
31
- "esm.js"
28
+ "typescript.js",
29
+ "utils.js"
32
30
  ],
33
31
  "scripts": {
34
32
  "lint": "eslint .",
@@ -40,7 +38,7 @@
40
38
  "check-rules:graphql": "eslint-find-rules --no-core --deprecated --unused ./tests/graphql.js",
41
39
  "check-rules:storybook": "eslint-find-rules --no-core --deprecated --unused ./tests/storybook.js",
42
40
  "spell": "cspell ./* --no-progress",
43
- "test": "npm-run-all --parallel check-rules:* && npm run spell",
41
+ "test": "npm-run-all --parallel check-rules:*",
44
42
  "prepublishOnly": "pinst --disable",
45
43
  "postpublish": "pinst --enable",
46
44
  "pre-commit": "npm run test && lint-staged"
@@ -52,7 +50,7 @@
52
50
  "@typescript-eslint/eslint-plugin": "5.46.1",
53
51
  "@typescript-eslint/parser": "5.46.1",
54
52
  "eslint-config-prettier": "8.5.0",
55
- "eslint-import-resolver-typescript": "3.5.2",
53
+ "eslint-import-resolver-typescript": "3.5.3",
56
54
  "eslint-plugin-cypress": "2.12.1",
57
55
  "eslint-plugin-fp": "2.3.0",
58
56
  "eslint-plugin-import": "2.26.0",
@@ -72,17 +70,17 @@
72
70
  "@semantic-release/github": "8.0.7",
73
71
  "@semantic-release/npm": "9.0.1",
74
72
  "@semantic-release/release-notes-generator": "10.0.3",
75
- "cspell": "6.17.0",
73
+ "cspell": "6.19.2",
76
74
  "eslint": "8.29.0",
77
75
  "eslint-find-rules": "4.1.0",
78
- "husky": "8.0.2",
76
+ "husky": "8.0.3",
79
77
  "lint-staged": "13.1.0",
80
- "np": "7.6.2",
78
+ "np": "7.6.3",
81
79
  "npm-run-all": "4.1.5",
82
80
  "pinst": "3.0.0",
83
- "prettier": "2.8.1",
81
+ "prettier": "2.8.3",
84
82
  "semantic-release": "19.0.5",
85
- "typescript": "4.9.4"
83
+ "typescript": "4.9.5"
86
84
  },
87
85
  "peerDependencies": {
88
86
  "cypress": ">=8",
package/rules/cypress.js CHANGED
@@ -6,10 +6,5 @@ module.exports = {
6
6
  'cypress/no-force': 'warn',
7
7
  'cypress/no-async-tests': 'error',
8
8
  'cypress/no-pause': 'error',
9
-
10
- // other modules
11
- 'max-lines-per-function': ['off'],
12
- '@typescript-eslint/method-signature-style': ['off'],
13
- '@typescript-eslint/no-namespace ': ['off'],
14
9
  },
15
10
  };
package/rules/jest.js CHANGED
@@ -10,14 +10,10 @@ module.exports = {
10
10
  'jest/no-commented-out-tests': 'warn',
11
11
  'jest/no-conditional-expect': 'error',
12
12
  'jest/no-conditional-in-test': 'error',
13
- 'jest/no-disabled-tests': 'warn',
14
13
  'jest/no-done-callback': 'warn',
15
- 'jest/no-duplicate-hooks': 'off',
16
14
  'jest/no-expect-resolves': 'off',
17
15
  'jest/no-export': 'error',
18
- 'jest/no-focused-tests': 'error',
19
16
  'jest/no-hooks': 'off',
20
- 'jest/no-identical-title': 'error',
21
17
  'jest/no-interpolation-in-snapshots': 'error',
22
18
  'jest/no-jasmine-globals': 'off',
23
19
  'jest/no-large-snapshots': ['warn', { maxSize: 300 }],
@@ -61,7 +57,6 @@ module.exports = {
61
57
 
62
58
  ...packages.ifAnyDep('typescript', () => ({
63
59
  '@typescript-eslint/unbound-method': 'off',
64
- 'jest/unbound-method': 'error',
65
60
  })),
66
61
 
67
62
  // conflicts
@@ -0,0 +1,50 @@
1
+ module.exports = [
2
+ {
3
+ selector: 'default',
4
+ format: ['camelCase'],
5
+ },
6
+ {
7
+ selector: 'function',
8
+ format: ['camelCase', 'PascalCase'],
9
+ },
10
+ // variables, CONSTANTS, ReactComponents
11
+ {
12
+ selector: 'variable',
13
+ format: ['camelCase', 'UPPER_CASE', 'PascalCase'],
14
+ },
15
+ {
16
+ selector: 'parameter',
17
+ format: ['camelCase', 'PascalCase'],
18
+ leadingUnderscore: 'allowSingleOrDouble',
19
+ },
20
+ {
21
+ selector: 'memberLike',
22
+ format: null,
23
+ },
24
+ {
25
+ selector: 'memberLike',
26
+ modifiers: ['static'],
27
+ format: ['camelCase', 'PascalCase'],
28
+ leadingUnderscore: 'allow',
29
+ },
30
+ {
31
+ selector: 'memberLike',
32
+ modifiers: ['private'],
33
+ format: ['camelCase'],
34
+ leadingUnderscore: 'allow',
35
+ },
36
+ {
37
+ selector: 'typeLike',
38
+ format: ['PascalCase'],
39
+ },
40
+ {
41
+ selector: 'enumMember',
42
+ format: ['PascalCase'],
43
+ },
44
+ // disallow I prefix for interfaces
45
+ {
46
+ selector: 'interface',
47
+ format: ['PascalCase'],
48
+ custom: { regex: '^I[A-Z]', match: false },
49
+ },
50
+ ];
package/rules/test.js ADDED
@@ -0,0 +1,31 @@
1
+ const packages = require('../packages');
2
+
3
+ module.exports = {
4
+ rules: {
5
+ 'jest/no-duplicate-hooks': 'error',
6
+ 'jest/no-disabled-tests': 'error',
7
+ 'jest/no-focused-tests': 'error',
8
+ 'jest/no-identical-title': 'error',
9
+
10
+ // formatting
11
+ 'jest-formatting/padding-around-after-all-blocks': 'warn',
12
+ 'jest-formatting/padding-around-after-each-blocks': 'warn',
13
+ 'jest-formatting/padding-around-all': 'warn',
14
+ 'jest-formatting/padding-around-before-all-blocks': 'warn',
15
+ 'jest-formatting/padding-around-before-each-blocks': 'warn',
16
+ 'jest-formatting/padding-around-describe-blocks': 'warn',
17
+ 'jest-formatting/padding-around-expect-groups': 'warn',
18
+ 'jest-formatting/padding-around-test-blocks': 'warn',
19
+
20
+ // other modules
21
+ 'max-lines-per-function': 'off',
22
+ ...packages.ifAnyDep('react', () => ({
23
+ 'react/jsx-no-constructed-context-values': 'off',
24
+ })),
25
+ ...packages.ifAnyDep('typescript', () => ({
26
+ '@typescript-eslint/method-signature-style': 'off',
27
+ '@typescript-eslint/no-namespace ': 'off',
28
+ '@typescript-eslint/unbound-method': 'off',
29
+ })),
30
+ },
31
+ };
@@ -4,14 +4,18 @@ module.exports = {
4
4
  '@typescript-eslint/consistent-type-exports': 'warn',
5
5
  '@typescript-eslint/dot-notation': [
6
6
  'warn',
7
- { allowPrivateClassPropertyAccess: false, allowProtectedClassPropertyAccess: false, allowIndexSignaturePropertyAccess: true },
7
+ {
8
+ allowPrivateClassPropertyAccess: false,
9
+ allowProtectedClassPropertyAccess: false,
10
+ allowIndexSignaturePropertyAccess: true,
11
+ },
8
12
  ],
9
13
  '@typescript-eslint/no-confusing-void-expression': ['warn', { ignoreArrowShorthand: true, ignoreVoidOperator: true }],
10
14
  '@typescript-eslint/no-floating-promises': ['error', { ignoreVoid: true }],
11
15
  '@typescript-eslint/no-for-in-array': 'error',
12
16
  '@typescript-eslint/no-implied-eval': 'error',
13
17
  '@typescript-eslint/no-meaningless-void-operator': ['warn', { checkNever: false }],
14
- '@typescript-eslint/no-misused-promises': 'error',
18
+ '@typescript-eslint/no-misused-promises': ['warn', { checksVoidReturn: { attributes: false } }],
15
19
  '@typescript-eslint/no-redundant-type-constituents': 'warn',
16
20
  '@typescript-eslint/no-throw-literal': 'error',
17
21
  '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error',
@@ -47,45 +51,13 @@ module.exports = {
47
51
  '@typescript-eslint/unbound-method': ['error', { ignoreStatic: true }],
48
52
  '@typescript-eslint/naming-convention': [
49
53
  'warn',
50
- {
51
- selector: 'default',
52
- format: ['camelCase'],
53
- },
54
- // variables, CONSTANTS, ReactComponents
55
- {
56
- selector: 'variable',
57
- format: ['camelCase', 'UPPER_CASE', 'PascalCase'],
58
- },
59
- {
60
- selector: 'parameter',
61
- format: ['camelCase'],
62
- leadingUnderscore: 'allow',
63
- },
64
- {
65
- selector: 'memberLike',
66
- modifiers: ['private'],
67
- format: ['camelCase'],
68
- leadingUnderscore: 'allow',
69
- },
70
- {
71
- selector: 'typeLike',
72
- format: ['PascalCase'],
73
- },
74
- // disallow I prefix for interfaces
75
- {
76
- selector: 'interface',
77
- format: ['PascalCase'],
78
- custom: {
79
- regex: '^I[A-Z]',
80
- match: false,
81
- },
82
- },
83
- // force use is/should/has ... for boolean variables
54
+ ...require('./naming-convention'), // eslint-disable-line node/global-require
55
+ // force use is/should/has for boolean variables
84
56
  {
85
57
  selector: 'variable',
86
58
  types: ['boolean'],
87
- format: ['camelCase'],
88
- prefix: ['is', 'should', 'has', 'can', 'did', 'will', 'enable'],
59
+ format: ['PascalCase'],
60
+ prefix: ['is', 'should', 'has', 'can', 'did', 'will', 'enable', 'loading'],
89
61
  },
90
62
  ],
91
63
 
@@ -30,57 +30,7 @@ module.exports = {
30
30
  '@typescript-eslint/member-naming': 'off',
31
31
  '@typescript-eslint/member-ordering': 'off',
32
32
  '@typescript-eslint/method-signature-style': ['warn', 'property'],
33
- '@typescript-eslint/naming-convention': [
34
- 'warn',
35
- {
36
- selector: 'default',
37
- format: ['camelCase'],
38
- },
39
- {
40
- selector: 'function',
41
- format: ['camelCase', 'PascalCase'],
42
- },
43
- // variables, CONSTANTS, ReactComponents
44
- {
45
- selector: 'variable',
46
- format: ['camelCase', 'UPPER_CASE', 'PascalCase'],
47
- },
48
- {
49
- selector: 'parameter',
50
- format: ['camelCase', 'PascalCase'],
51
- leadingUnderscore: 'allowSingleOrDouble',
52
- },
53
- {
54
- selector: 'memberLike',
55
- format: null,
56
- },
57
- {
58
- selector: 'memberLike',
59
- modifiers: ['static'],
60
- format: ['camelCase', 'PascalCase'],
61
- leadingUnderscore: 'allow',
62
- },
63
- {
64
- selector: 'memberLike',
65
- modifiers: ['private'],
66
- format: ['camelCase'],
67
- leadingUnderscore: 'allow',
68
- },
69
- {
70
- selector: 'typeLike',
71
- format: ['PascalCase'],
72
- },
73
- {
74
- selector: 'enumMember',
75
- format: ['PascalCase'],
76
- },
77
- // disallow I prefix for interfaces
78
- {
79
- selector: 'interface',
80
- format: ['PascalCase'],
81
- custom: { regex: '^I[A-Z]', match: false },
82
- },
83
- ],
33
+ '@typescript-eslint/naming-convention': ['warn', ...require('./naming-convention')], // eslint-disable-line node/global-require
84
34
  '@typescript-eslint/no-array-constructor': 'error',
85
35
  '@typescript-eslint/no-base-to-string': 'off', // false negative
86
36
  '@typescript-eslint/no-confusing-non-null-assertion': 'error',
package/storybook.js CHANGED
@@ -3,7 +3,7 @@ module.exports = {
3
3
  overrides: [
4
4
  {
5
5
  plugins: ['storybook'],
6
- files: ['*.stories.+(ts|tsx|js|jsx|mjs|cjs)', '*.story.+(ts|tsx|js|jsx|mjs|cjs)'],
6
+ files: ['*.stories.+(ts|tsx|js|jsx|mjs|cjs|mdx)', '*.story.+(ts|tsx|js|jsx|mjs|cjs|mdx)'],
7
7
  extends: ['./rules/storybook.js'],
8
8
  },
9
9
  ],
package/typecheck.js CHANGED
@@ -3,7 +3,7 @@ module.exports = {
3
3
  overrides: [
4
4
  {
5
5
  files: ['*.ts', '*.tsx'],
6
- extends: ['./rules/typescript-requiring-type-checking.js'],
6
+ extends: ['./rules/typecheck.js'],
7
7
  },
8
8
  ],
9
9
  };
package/utils.js ADDED
@@ -0,0 +1 @@
1
+ module.exports.exts = '+(js|jsx|mjs|cjs|ts|tsx|mts|cts)';
package/bin/index.js DELETED
@@ -1,9 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const createOptions = require('./lib/createOptions');
4
- const createTasks = require('./lib/tasks');
5
-
6
- createOptions()
7
- .then(createTasks)
8
- .then(tasks => tasks.run())
9
- .catch(() => {});
@@ -1,51 +0,0 @@
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;
@@ -1,25 +0,0 @@
1
- const getUserInput = require('./getUserInput');
2
- const args = require('./parseArgs');
3
-
4
- const eslintrcConfig = {
5
- extends: ['@fullstacksjs'],
6
- };
7
-
8
- const requiredPackages = ['@fullstacksjs/eslint-config', 'eslint', 'prettier'];
9
-
10
- async function createOptions() {
11
- const isTechnologyInArgv = args.t != null;
12
- const optionsFromArgs = { technology: args.t };
13
- const userInput = isTechnologyInArgv ? optionsFromArgs : await getUserInput();
14
-
15
- if (userInput.technology === 'ts') {
16
- requiredPackages.push('typescript');
17
- }
18
-
19
- return {
20
- eslintrc: eslintrcConfig,
21
- packages: requiredPackages,
22
- };
23
- }
24
-
25
- module.exports = createOptions;
@@ -1,15 +0,0 @@
1
- const { writeFile } = require('fs/promises');
2
-
3
- function createFileTask(eslintrc, ctx, task) {
4
- return writeFile('.eslintrc.json', JSON.stringify(eslintrc, null, 2))
5
- .then(() => {
6
- task.title = `.eslintrc - Successfully Generated.`;
7
- })
8
- .catch(() => {
9
- ctx.isEslintrc = false;
10
- task.title = `Generating .eslintrc file`;
11
- throw Error("Couldn't create file");
12
- });
13
- }
14
-
15
- module.exports = createFileTask;
@@ -1,24 +0,0 @@
1
- const inquirer = require('inquirer');
2
-
3
- function getUserInput() {
4
- return inquirer.prompt([
5
- {
6
- type: 'list',
7
- name: 'technology',
8
- message: 'which technology are you using?',
9
- choices: [
10
- {
11
- value: 'ts',
12
- name: 'ESLint alongside TypeScript',
13
- },
14
- {
15
- value: 'js',
16
- name: 'ESLint for JavaScript development',
17
- },
18
- ],
19
- default: 'js',
20
- },
21
- ]);
22
- }
23
-
24
- module.exports = getUserInput;
@@ -1,12 +0,0 @@
1
- const yargs = require('yargs');
2
-
3
- const args = yargs(process.argv.slice(2))
4
- .alias('t', 'technology')
5
- .describe('t', 'Which technology are you using')
6
- .choices('t', ['ts', 'js'])
7
- .usage('Usage: $0 [-t ts|js]')
8
- .example('$0 - ts')
9
- .help('h')
10
- .alias('h', 'help').argv;
11
-
12
- module.exports = args;
package/bin/lib/tasks.js DELETED
@@ -1,30 +0,0 @@
1
- const Listr = require('listr');
2
- const util = require('util');
3
- const askWhenConfigExists = require('./askWhenConfigExists');
4
- const exec = util.promisify(require('child_process').exec);
5
- const createFileTask = require('./generateFile');
6
-
7
- async function createTasks({ packages, eslintrc }) {
8
- const installTasks = packages.map(pkg => ({
9
- title: `Installing ${pkg}`,
10
- task: (ctx, task) => exec(`npm i -D ${pkg}`).then(() => (task.title = `${pkg} Installed`)),
11
- }));
12
-
13
- const config = await askWhenConfigExists(eslintrc);
14
-
15
- return new Listr(
16
- [
17
- {
18
- title: 'Installing dependencies using npm',
19
- task: () => new Listr(installTasks, { exitOnError: true }),
20
- },
21
- {
22
- title: 'Generating .eslintrc.json file',
23
- task: (ctx, task) => createFileTask(config, ctx, task),
24
- },
25
- ],
26
- { exitOnError: false },
27
- );
28
- }
29
-
30
- module.exports = createTasks;
@@ -1,12 +0,0 @@
1
- module.exports = {
2
- rules: {
3
- 'jest-formatting/padding-around-after-all-blocks': 'warn',
4
- 'jest-formatting/padding-around-after-each-blocks': 'warn',
5
- 'jest-formatting/padding-around-all': 'warn',
6
- 'jest-formatting/padding-around-before-all-blocks': 'warn',
7
- 'jest-formatting/padding-around-before-each-blocks': 'warn',
8
- 'jest-formatting/padding-around-describe-blocks': 'warn',
9
- 'jest-formatting/padding-around-expect-groups': 'warn',
10
- 'jest-formatting/padding-around-test-blocks': 'warn',
11
- },
12
- };