eslint-plugin-th-rules 1.13.0 → 1.13.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/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## [1.13.1](https://github.com/tomerh2001/eslint-plugin-th-rules/compare/v1.13.0...v1.13.1) (2024-08-19)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * Update named-functions rule to enforce named function declarations ([e2c9b5d](https://github.com/tomerh2001/eslint-plugin-th-rules/commit/e2c9b5d5f96030278b2900adbf940363c4648bdd))
7
+
1
8
  # [1.13.0](https://github.com/tomerh2001/eslint-plugin-th-rules/compare/v1.12.0...v1.13.0) (2024-08-19)
2
9
 
3
10
 
package/README.md CHANGED
@@ -20,7 +20,7 @@ This repository contains custom ESLint rules to enhance code quality and consist
20
20
 
21
21
  | Name              | Description | 💼 | 🔧 |
22
22
  | :--------------------------------------------------- | :------------------------------------------------------------------------------- | :---------------------------------- | :- |
23
- | [named-functions](docs/rules/named-functions.md) | Enforce top-level functions to be named functions | ✅ ![badge-recommended-typescript][] | 🔧 |
23
+ | [named-functions](docs/rules/named-functions.md) | Enforce top-level functions to be named function declarations | ✅ ![badge-recommended-typescript][] | 🔧 |
24
24
  | [no-comments](docs/rules/no-comments.md) | Disallow comments except for specified allowed patterns. | ✅ ![badge-recommended-typescript][] | 🔧 |
25
25
  | [no-default-export](docs/rules/no-default-export.md) | Convert unnamed default exports to named default exports based on the file name. | ✅ ![badge-recommended-typescript][] | 🔧 |
26
26
  | [no-destructuring](docs/rules/no-destructuring.md) | Disallow destructuring that does not meet certain conditions | ✅ ![badge-recommended-typescript][] | |
package/bun.lockb CHANGED
Binary file
@@ -1,4 +1,4 @@
1
- # Enforce top-level functions to be named functions (`th-rules/named-functions`)
1
+ # Enforce top-level functions to be named function declarations (`th-rules/named-functions`)
2
2
 
3
3
  💼 This rule is enabled in the following configs: ✅ `recommended`, `recommended-typescript`.
4
4
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-th-rules",
3
- "version": "1.13.0",
3
+ "version": "1.13.1",
4
4
  "description": "A List of custom ESLint rules created by Tomer Horowitz",
5
5
  "keywords": [
6
6
  "eslint",
@@ -2,7 +2,7 @@ module.exports = {
2
2
  meta: {
3
3
  type: 'problem',
4
4
  docs: {
5
- description: 'Enforce top-level functions to be named functions',
5
+ description: 'Enforce top-level functions to be named function declarations',
6
6
  url: 'https://github.com/tomerh2001/eslint-plugin-th-rules/blob/main/docs/rules/named-functions.md',
7
7
  },
8
8
  fixable: 'code',
@@ -10,34 +10,40 @@ module.exports = {
10
10
  },
11
11
 
12
12
  create(context) {
13
- function reportAndFix(node, name) {
13
+ function reportAndFix(node, varName) {
14
14
  context.report({
15
15
  node,
16
16
  message: 'Top-level functions must be named function declarations.',
17
17
  fix(fixer) {
18
- if (node.type === 'FunctionExpression' && node.parent.type === 'VariableDeclarator') {
19
- // Convert to a function declaration
20
- const sourceCode = context.getSourceCode();
21
- const varName = node.parent.id.name;
18
+ const sourceCode = context.getSourceCode();
19
+
20
+ if (node.type === 'ArrowFunctionExpression') {
21
+ // Convert arrow function to a named function declaration
22
22
  const functionBody = sourceCode.getText(node.body);
23
23
  const functionParams = sourceCode.getText(node.params);
24
24
  const asyncKeyword = node.async ? 'async ' : '';
25
- const generatorKeyword = node.generator ? '*' : '';
26
25
 
27
- const functionDeclaration = `${asyncKeyword}function ${generatorKeyword}${varName}(${functionParams}) ${functionBody}`;
28
- return fixer.replaceText(node.parent.parent, functionDeclaration);
26
+ let functionDeclaration;
27
+
28
+ if (node.body.type === 'BlockStatement') {
29
+ functionDeclaration = `${asyncKeyword}function ${varName}(${functionParams}) ${functionBody}`;
30
+ } else {
31
+ // For concise body (single expression)
32
+ functionDeclaration = `${asyncKeyword}function ${varName}(${functionParams}) { return ${functionBody}; }`;
33
+ }
34
+
35
+ return fixer.replaceText(node.parent, functionDeclaration);
29
36
  }
30
37
 
31
38
  if (node.type === 'FunctionExpression') {
32
- // Convert to a function declaration
33
- const sourceCode = context.getSourceCode();
39
+ // Convert anonymous function expression to named function declaration
34
40
  const functionBody = sourceCode.getText(node.body);
35
41
  const functionParams = sourceCode.getText(node.params);
36
42
  const asyncKeyword = node.async ? 'async ' : '';
37
43
  const generatorKeyword = node.generator ? '*' : '';
38
44
 
39
- const functionDeclaration = `${asyncKeyword}function ${generatorKeyword}${name}(${functionParams}) ${functionBody}`;
40
- return fixer.replaceText(node, functionDeclaration);
45
+ const functionDeclaration = `${asyncKeyword}function ${generatorKeyword}${varName}(${functionParams}) ${functionBody}`;
46
+ return fixer.replaceText(node.parent, functionDeclaration);
41
47
  }
42
48
 
43
49
  return null;
@@ -47,31 +53,29 @@ module.exports = {
47
53
 
48
54
  return {
49
55
  Program(programNode) {
50
- const topLevelNodes = programNode.body;
51
-
52
- topLevelNodes.forEach((node) => {
53
- if (node.type === 'FunctionDeclaration') {
54
- // Skip if already a named function declaration
55
- return;
56
+ programNode.body.forEach((node) => {
57
+ // Handle VariableDeclaration (e.g. const function_ = () => {})
58
+ if (node.type === 'VariableDeclaration') {
59
+ node.declarations.forEach((declaration) => {
60
+ // Ensure that declaration.init is defined and that it's a function expression or arrow function
61
+ if (
62
+ declaration.init &&
63
+ (declaration.init.type === 'ArrowFunctionExpression' || declaration.init.type === 'FunctionExpression')
64
+ ) {
65
+ const varName = declaration.id.name;
66
+ reportAndFix(declaration.init, varName);
67
+ }
68
+ });
56
69
  }
57
70
 
58
- if (
59
- node.type === 'FunctionExpression' ||
60
- (node.type === 'VariableDeclaration' && node.declarations[0].init?.type === 'FunctionExpression')
61
- ) {
62
- // Force it to be a named function declaration
63
- if (node.type === 'VariableDeclaration') {
64
- const varName = node.declarations[0].id.name;
65
- reportAndFix(node.declarations[0].init, varName);
66
- } else {
67
- reportAndFix(node, 'Anonymous');
68
- }
71
+ // Handle anonymous top-level function declarations
72
+ if (node.type === 'FunctionDeclaration' && !node.id) {
73
+ reportAndFix(node, 'Anonymous');
69
74
  }
70
75
 
76
+ // Handle ExpressionStatement for top-level arrow function (though uncommon)
71
77
  if (node.type === 'ExpressionStatement' && node.expression.type === 'ArrowFunctionExpression') {
72
- // Convert arrow functions into named function declarations
73
- const varName = node.expression.id ? node.expression.id.name : 'Anonymous';
74
- reportAndFix(node.expression, varName);
78
+ reportAndFix(node.expression, 'Anonymous');
75
79
  }
76
80
  });
77
81
  },
@@ -3,7 +3,7 @@
3
3
  const path = require('node:path');
4
4
 
5
5
  const meta = {
6
- type: 'suggestion',
6
+ type: 'problem',
7
7
  docs: {
8
8
  description: 'Convert unnamed default exports to named default exports based on the file name.',
9
9
  url: 'https://github.com/tomerh2001/eslint-plugin-th-rules/blob/main/docs/rules/no-default-export.md'