@croct/eslint-plugin 0.8.0 → 0.8.2

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.
@@ -1,99 +1,117 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.typescript = void 0;
4
- exports.typescript = {
5
- extends: ['plugin:@croct/javascript'],
6
- plugins: [
7
- '@typescript-eslint',
8
- '@croct',
6
+ exports.createTypescriptConfig = createTypescriptConfig;
7
+ const typescript_eslint_1 = __importDefault(require("typescript-eslint"));
8
+ const parser_1 = __importDefault(require("@typescript-eslint/parser"));
9
+ const eslint_plugin_jest_1 = __importDefault(require("eslint-plugin-jest"));
10
+ // @ts-expect-error - no types available
11
+ const eslint_plugin_1 = __importDefault(require("@stylistic/eslint-plugin"));
12
+ const baseRules = {
13
+ 'import-x/export': 'off',
14
+ '@typescript-eslint/array-type': ['error', {
15
+ default: 'array-simple',
16
+ }],
17
+ '@typescript-eslint/prefer-as-const': 'error',
18
+ '@typescript-eslint/adjacent-overload-signatures': 'error',
19
+ '@stylistic/type-annotation-spacing': 'error',
20
+ '@stylistic/semi': ['error', 'always'],
21
+ '@typescript-eslint/strict-boolean-expressions': ['error', {
22
+ allowString: false,
23
+ allowNumber: false,
24
+ allowNullableObject: false,
25
+ }],
26
+ '@typescript-eslint/prefer-optional-chain': 'error',
27
+ 'no-shadow': 'off',
28
+ '@typescript-eslint/no-shadow': ['error', {
29
+ ignoreTypeValueShadow: true,
30
+ ignoreFunctionTypeParameterNameValueShadow: true,
31
+ }],
32
+ '@typescript-eslint/explicit-member-accessibility': [
33
+ 'error',
9
34
  ],
10
- overrides: [
35
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
36
+ '@typescript-eslint/explicit-function-return-type': ['error', { allowExpressions: true }],
37
+ '@typescript-eslint/no-explicit-any': 'off',
38
+ 'no-use-before-define': 'off',
39
+ '@typescript-eslint/no-use-before-define': 'off',
40
+ 'no-unused-expressions': 'off',
41
+ '@typescript-eslint/no-unused-expressions': 'error',
42
+ '@stylistic/indent': ['error', 4, {
43
+ SwitchCase: 1,
44
+ }],
45
+ '@typescript-eslint/no-unused-vars': [
46
+ 'error',
11
47
  {
12
- files: ['**/*.ts', '**/*.tsx'],
13
- extends: ['plugin:@typescript-eslint/recommended'],
14
- parser: '@typescript-eslint/parser',
15
- rules: {
16
- 'import/export': 'off',
17
- '@typescript-eslint/array-type': ['error', {
18
- default: 'array-simple',
19
- }],
20
- '@typescript-eslint/prefer-as-const': 'error',
21
- '@typescript-eslint/adjacent-overload-signatures': 'error',
22
- '@typescript-eslint/type-annotation-spacing': 'error',
23
- '@typescript-eslint/semi': ['error', 'always'],
24
- '@typescript-eslint/strict-boolean-expressions': ['error', {
25
- allowString: false,
26
- allowNumber: false,
27
- allowNullableObject: false,
28
- }],
29
- '@typescript-eslint/prefer-optional-chain': 'error',
30
- 'no-shadow': 'off',
31
- '@typescript-eslint/no-shadow': ['error', {
32
- ignoreTypeValueShadow: true,
33
- ignoreFunctionTypeParameterNameValueShadow: true,
34
- }],
35
- '@typescript-eslint/no-empty-interface': 'off',
36
- '@typescript-eslint/explicit-member-accessibility': [
37
- 'error',
38
- ],
39
- '@typescript-eslint/explicit-module-boundary-types': 'off',
40
- '@typescript-eslint/explicit-function-return-type': ['error'],
41
- '@typescript-eslint/no-explicit-any': 'off',
42
- 'no-use-before-define': 'off',
43
- '@typescript-eslint/no-use-before-define': 'off',
44
- 'no-unused-expressions': 'off',
45
- '@typescript-eslint/no-unused-expressions': 'error',
46
- indent: ['error', 4, {
47
- SwitchCase: 1,
48
- }],
49
- '@typescript-eslint/no-unused-vars': [
50
- 'error',
51
- {
52
- args: 'after-used',
53
- ignoreRestSiblings: true,
48
+ args: 'after-used',
49
+ ignoreRestSiblings: true,
50
+ },
51
+ ],
52
+ 'no-unused-vars': 'off',
53
+ '@typescript-eslint/no-non-null-assertion': 'off',
54
+ '@stylistic/object-curly-spacing': 'error',
55
+ '@stylistic/member-delimiter-style': ['error', {
56
+ multiline: {
57
+ delimiter: 'comma',
58
+ requireLast: true,
59
+ },
60
+ singleline: {
61
+ delimiter: 'comma',
62
+ requireLast: false,
63
+ },
64
+ overrides: {
65
+ interface: {
66
+ singleline: {
67
+ delimiter: 'semi',
54
68
  },
55
- ],
56
- 'no-unused-vars': 'off',
57
- '@typescript-eslint/no-non-null-assertion': 'off',
58
- 'object-curly-spacing': 'off',
59
- '@typescript-eslint/object-curly-spacing': 'error',
60
- '@typescript-eslint/member-delimiter-style': ['error', {
61
- multiline: {
62
- delimiter: 'comma',
63
- requireLast: true,
64
- },
65
- singleline: {
66
- delimiter: 'comma',
67
- requireLast: false,
68
- },
69
- overrides: {
70
- interface: {
71
- singleline: {
72
- delimiter: 'semi',
73
- },
74
- multiline: {
75
- delimiter: 'semi',
76
- },
77
- },
78
- },
79
- }],
80
- 'no-undef': 'off',
81
- '@typescript-eslint/no-namespace': 'off',
69
+ multiline: {
70
+ delimiter: 'semi',
71
+ },
72
+ },
82
73
  },
83
- },
74
+ }],
75
+ 'no-undef': 'off',
76
+ '@typescript-eslint/no-namespace': 'off',
77
+ '@typescript-eslint/restrict-template-expressions': 'off',
78
+ // Disable rules that turn `any` into `unknown`, places where `unknown` is the preferred type
79
+ // have that type already.
80
+ '@typescript-eslint/no-unsafe-argument': 'off',
81
+ '@typescript-eslint/no-unsafe-assignment': 'off',
82
+ '@typescript-eslint/no-unsafe-call': 'off',
83
+ '@typescript-eslint/no-unsafe-enum-comparison': 'off',
84
+ '@typescript-eslint/no-unsafe-member-access': 'off',
85
+ '@typescript-eslint/no-unsafe-return': 'off',
86
+ '@typescript-eslint/no-unsafe-unary-minus': 'off',
87
+ // Breaks with overloaded functions that implement both callback and Promise signatures
88
+ '@typescript-eslint/no-misused-promises': 'off',
89
+ // Doesn't detect classes that implement `toString` method
90
+ '@typescript-eslint/no-base-to-string': 'off',
91
+ // Conflict with TS promise ignore explicitly (void Promise)
92
+ 'no-void': 'off',
93
+ };
94
+ // Factory function to create TypeScript config with the plugin reference
95
+ function createTypescriptConfig(plugin, javascriptConfig) {
96
+ return [
97
+ ...javascriptConfig,
98
+ ...typescript_eslint_1.default.configs.recommendedTypeChecked,
99
+ eslint_plugin_jest_1.default.configs['flat/recommended'],
84
100
  {
85
- files: [
86
- 'src/**/*.test.ts',
87
- 'test/**/*.ts',
88
- ],
89
- extends: ['plugin:jest/recommended'],
90
- plugins: ['jest'],
91
- rules: {
92
- 'no-new-object': 'off',
101
+ name: '@croct/typescript',
102
+ files: ['**/*.ts', '**/*.tsx'],
103
+ plugins: {
104
+ '@stylistic': eslint_plugin_1.default,
105
+ '@croct': plugin,
93
106
  },
94
- env: {
95
- jest: true,
107
+ languageOptions: {
108
+ parser: parser_1.default,
109
+ parserOptions: {
110
+ // Enable type-aware linting
111
+ projectService: true,
112
+ },
96
113
  },
114
+ rules: baseRules,
97
115
  },
98
- ],
99
- };
116
+ ];
117
+ }
package/index.js CHANGED
@@ -1,8 +1,30 @@
1
1
  "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rules = exports.configs = void 0;
2
4
  const rules_1 = require("./rules");
3
- const configs_1 = require("./configs");
4
- const configuration = {
5
+ Object.defineProperty(exports, "rules", { enumerable: true, get: function () { return rules_1.rules; } });
6
+ const javascript_1 = require("./configs/javascript");
7
+ const typescript_1 = require("./configs/typescript");
8
+ const react_1 = require("./configs/react");
9
+ const cypress_1 = require("./configs/cypress");
10
+ // Create the plugin with just the rules first
11
+ const plugin = {
12
+ // Cast from TypeScript Rule Module to ESLint RuleDefinition.
13
+ // Due to variance, TS can't verify the type directly.
5
14
  rules: rules_1.rules,
6
- configs: configs_1.configs,
15
+ configs: {},
7
16
  };
8
- module.exports = configuration;
17
+ // Create configs with the plugin reference
18
+ const javascriptConfig = (0, javascript_1.createJavaScriptConfig)(plugin);
19
+ const typescriptConfig = (0, typescript_1.createTypescriptConfig)(plugin, javascriptConfig);
20
+ const reactConfig = (0, react_1.createReactConfig)(plugin, javascriptConfig);
21
+ const cypressConfig = (0, cypress_1.createCypressConfig)(plugin, javascriptConfig);
22
+ exports.configs = {
23
+ javascript: javascriptConfig,
24
+ typescript: typescriptConfig,
25
+ react: reactConfig,
26
+ cypress: cypressConfig,
27
+ };
28
+ Object.assign(plugin.configs, exports.configs);
29
+ // Export the plugin as default
30
+ exports.default = plugin;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@croct/eslint-plugin",
3
- "version": "0.8.0",
3
+ "version": "0.8.2",
4
4
  "description": "ESLint rules and presets applied to all Croct JavaScript projects.",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -36,20 +36,21 @@
36
36
  "cypress"
37
37
  ],
38
38
  "dependencies": {
39
- "@typescript-eslint/eslint-plugin": "^8.53.0",
39
+ "@eslint-community/eslint-plugin-eslint-comments": "^4.5.0",
40
+ "@stylistic/eslint-plugin": "^5.7.0",
40
41
  "@typescript-eslint/utils": "^8.53.0",
41
42
  "eslint-plugin-cypress": "^5.2.1",
42
- "eslint-plugin-eslint-comments": "^3.2.0",
43
- "eslint-plugin-import": "^2.32.0",
44
43
  "eslint-plugin-import-newlines": "^1.4.0",
44
+ "eslint-plugin-import-x": "^4.16.1",
45
45
  "eslint-plugin-jest": "^29.12.1",
46
46
  "eslint-plugin-jest-dom": "^5.5.0",
47
47
  "eslint-plugin-jsx-a11y": "^6.10.2",
48
48
  "eslint-plugin-newline-destructuring": "^1.2.2",
49
- "eslint-plugin-no-smart-quotes": "^1.4.2",
50
49
  "eslint-plugin-react": "^7.37.5",
51
50
  "eslint-plugin-react-hooks": "^5.2.0",
52
- "eslint-plugin-testing-library": "^7.15.4"
51
+ "eslint-plugin-testing-library": "^7.15.4",
52
+ "globals": "^17.0.0",
53
+ "typescript-eslint": "^8.53.0"
53
54
  },
54
55
  "devDependencies": {
55
56
  "@types/jest": "^29.5.14",
@@ -63,7 +64,7 @@
63
64
  "eslint-plugin-self": "^1.2.1",
64
65
  "jest": "^29.7.0",
65
66
  "ts-jest": "^29.3.4",
66
- "typescript": "~5.8.3"
67
+ "typescript": "~5.9.0"
67
68
  },
68
69
  "peerDependencies": {
69
70
  "@typescript-eslint/parser": ">= 8",
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.argumentSpacing = void 0;
4
+ const utils_1 = require("@typescript-eslint/utils");
4
5
  const createRule_1 = require("../createRule");
5
6
  exports.argumentSpacing = (0, createRule_1.createRule)({
6
7
  name: 'argument-spacing',
@@ -34,8 +35,8 @@ exports.argumentSpacing = (0, createRule_1.createRule)({
34
35
  return;
35
36
  }
36
37
  const lastArgumentFirstToken = sourceCode.getFirstToken(lastArgument);
37
- if ((lastArgument.type !== 'ArrowFunctionExpression'
38
- || lastArgument.body.type === 'BlockStatement')
38
+ if ((lastArgument.type !== utils_1.TSESTree.AST_NODE_TYPES.ArrowFunctionExpression
39
+ || lastArgument.body.type === utils_1.TSESTree.AST_NODE_TYPES.BlockStatement)
39
40
  && firstToken.loc.start.line === lastArgumentFirstToken.loc.start.line) {
40
41
  return;
41
42
  }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.complexExpressionSpacing = void 0;
4
+ const utils_1 = require("@typescript-eslint/utils");
4
5
  const createRule_1 = require("../createRule");
5
6
  exports.complexExpressionSpacing = (0, createRule_1.createRule)({
6
7
  name: 'complex-expression-spacing',
@@ -20,10 +21,10 @@ exports.complexExpressionSpacing = (0, createRule_1.createRule)({
20
21
  const sourceCode = context.getSourceCode();
21
22
  function check(node) {
22
23
  const parentPreviousToken = sourceCode.getTokenBefore(node, {
23
- filter: token => token.type === 'Punctuator',
24
+ filter: token => token.type === utils_1.TSESTree.AST_TOKEN_TYPES.Punctuator,
24
25
  });
25
26
  const parentNextToken = sourceCode.getTokenAfter(node, {
26
- filter: token => token.type === 'Punctuator',
27
+ filter: token => token.type === utils_1.TSESTree.AST_TOKEN_TYPES.Punctuator,
27
28
  });
28
29
  if (parentPreviousToken.loc.end.line === parentNextToken.loc.start.line) {
29
30
  return;
@@ -53,7 +54,7 @@ exports.complexExpressionSpacing = (0, createRule_1.createRule)({
53
54
  return {
54
55
  ArrowFunctionExpression: (node) => {
55
56
  const { body } = node;
56
- if (body.type === 'ConditionalExpression') {
57
+ if (body.type === utils_1.TSESTree.AST_NODE_TYPES.ConditionalExpression) {
57
58
  check(body);
58
59
  }
59
60
  },
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.jsxAttributeSpacing = void 0;
4
+ const utils_1 = require("@typescript-eslint/utils");
4
5
  const createRule_1 = require("../createRule");
5
6
  exports.jsxAttributeSpacing = (0, createRule_1.createRule)({
6
7
  name: 'jsx-attribute-spacing',
@@ -20,12 +21,13 @@ exports.jsxAttributeSpacing = (0, createRule_1.createRule)({
20
21
  const sourceCode = context.getSourceCode();
21
22
  function check(node) {
22
23
  const { value } = node;
23
- if (value?.type !== 'JSXExpressionContainer') {
24
+ if (value?.type !== utils_1.TSESTree.AST_NODE_TYPES.JSXExpressionContainer) {
24
25
  return;
25
26
  }
26
27
  const firstToken = sourceCode.getFirstToken(value.expression);
27
28
  const lastToken = sourceCode.getLastToken(value.expression);
28
- if ((firstToken.type === 'Punctuator' && lastToken.type === 'Punctuator')
29
+ if ((firstToken.type === utils_1.TSESTree.AST_TOKEN_TYPES.Punctuator
30
+ && lastToken.type === utils_1.TSESTree.AST_TOKEN_TYPES.Punctuator)
29
31
  || (firstToken.loc.start.line === lastToken.loc.end.line)) {
30
32
  return;
31
33
  }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.newlinePerChainedCall = void 0;
4
+ const utils_1 = require("@typescript-eslint/utils");
4
5
  const createRule_1 = require("../createRule");
5
6
  const LINEBREAK_MATCHER = /\r\n|[\r\n\u2028\u2029]/u;
6
7
  exports.newlinePerChainedCall = (0, createRule_1.createRule)({
@@ -47,30 +48,30 @@ exports.newlinePerChainedCall = (0, createRule_1.createRule)({
47
48
  return node.object.loc.end.line === node.property.loc.start.line;
48
49
  }
49
50
  function isNotClosingParenToken(token) {
50
- return token.value !== ')' || token.type !== 'Punctuator';
51
+ return token.value !== ')' || token.type !== utils_1.TSESTree.AST_TOKEN_TYPES.Punctuator;
51
52
  }
52
53
  function validateCallExpressionIgnoreDepth(node) {
53
54
  let hasCallExpression = false;
54
- if (node.type === 'CallExpression') {
55
+ if (node.type === utils_1.TSESTree.AST_NODE_TYPES.CallExpression) {
55
56
  hasCallExpression = true;
56
57
  }
57
- if ((node.parent !== undefined)
58
- && node.parent.type !== 'CallExpression'
59
- && node.parent.type !== 'MemberExpression') {
58
+ if (node.parent != null
59
+ && node.parent.type !== utils_1.TSESTree.AST_NODE_TYPES.CallExpression
60
+ && node.parent.type !== utils_1.TSESTree.AST_NODE_TYPES.MemberExpression) {
60
61
  const memberExpressions = [];
61
- let currentNode = (node.type === 'CallExpression'
62
+ let currentNode = ('callee' in node
62
63
  ? node.callee
63
64
  : node);
64
- while (currentNode.type === 'CallExpression'
65
- || currentNode.type === 'MemberExpression') {
66
- if (currentNode.type === 'MemberExpression') {
67
- if (currentNode.property.type === 'Identifier'
65
+ while (currentNode.type === utils_1.TSESTree.AST_NODE_TYPES.CallExpression
66
+ || currentNode.type === utils_1.TSESTree.AST_NODE_TYPES.MemberExpression) {
67
+ if (currentNode.type === utils_1.TSESTree.AST_NODE_TYPES.MemberExpression) {
68
+ if (currentNode.property.type === utils_1.TSESTree.AST_NODE_TYPES.Identifier
68
69
  && !currentNode.computed) {
69
70
  memberExpressions.push(currentNode);
70
71
  }
71
72
  currentNode = currentNode.object;
72
73
  }
73
- else if (currentNode.type === 'CallExpression') {
74
+ else if (currentNode.type === utils_1.TSESTree.AST_NODE_TYPES.CallExpression) {
74
75
  currentNode = currentNode.callee;
75
76
  }
76
77
  }
@@ -80,11 +81,11 @@ exports.newlinePerChainedCall = (0, createRule_1.createRule)({
80
81
  const expressionsOnSameLine = memberExpressions
81
82
  .filter(hasObjectAndPropertyOnSameLine);
82
83
  const rootNode = expressionsOnSameLine[expressionsOnSameLine.length - 1];
83
- if (rootNode.type === 'MemberExpression'
84
- && (rootNode.parent?.type === 'CallExpression'
85
- || rootNode.parent?.type === 'MemberExpression')
86
- && (rootNode.object.type === 'ThisExpression'
87
- || rootNode.object.type === 'Identifier')) {
84
+ if (rootNode.type === utils_1.TSESTree.AST_NODE_TYPES.MemberExpression
85
+ && (rootNode.parent != null && (rootNode.parent.type === utils_1.TSESTree.AST_NODE_TYPES.CallExpression
86
+ || rootNode.parent.type === utils_1.TSESTree.AST_NODE_TYPES.MemberExpression))
87
+ && (rootNode.object.type === utils_1.TSESTree.AST_NODE_TYPES.ThisExpression
88
+ || rootNode.object.type === utils_1.TSESTree.AST_NODE_TYPES.Identifier)) {
88
89
  expressionsOnSameLine.pop();
89
90
  }
90
91
  expressionsOnSameLine.forEach(memberExpression => {
@@ -106,7 +107,7 @@ exports.newlinePerChainedCall = (0, createRule_1.createRule)({
106
107
  }
107
108
  return {
108
109
  CallExpression: (node) => {
109
- if (node.callee?.type === 'MemberExpression') {
110
+ if (node.callee?.type === utils_1.TSESTree.AST_NODE_TYPES.MemberExpression) {
110
111
  validateCallExpressionIgnoreDepth(node);
111
112
  }
112
113
  },