eslint-plugin-ts-data-forge 0.6.0 → 0.7.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.
Files changed (77) hide show
  1. package/README.md +1 -0
  2. package/dist/index.mjs +2 -2
  3. package/dist/index.mjs.map +1 -1
  4. package/dist/plugin.d.mts +2 -0
  5. package/dist/plugin.d.mts.map +1 -1
  6. package/dist/plugin.mjs +45 -41
  7. package/dist/plugin.mjs.map +1 -1
  8. package/dist/rule-types.d.mts +15 -0
  9. package/dist/rule-types.d.mts.map +1 -1
  10. package/dist/rule-types.mjs +6 -2
  11. package/dist/rule-types.mjs.map +1 -1
  12. package/dist/rules/ast-utils.mjs +107 -50
  13. package/dist/rules/ast-utils.mjs.map +1 -1
  14. package/dist/rules/branded-number-types.mjs +41 -37
  15. package/dist/rules/branded-number-types.mjs.map +1 -1
  16. package/dist/rules/constants.mjs +2 -4
  17. package/dist/rules/constants.mjs.map +1 -1
  18. package/dist/rules/import-utils.mjs +80 -56
  19. package/dist/rules/import-utils.mjs.map +1 -1
  20. package/dist/rules/index.mjs +2 -2
  21. package/dist/rules/index.mjs.map +1 -1
  22. package/dist/rules/no-side-effect-import.mjs +46 -34
  23. package/dist/rules/no-side-effect-import.mjs.map +1 -1
  24. package/dist/rules/no-unnecessary-type-guard.mjs +376 -265
  25. package/dist/rules/no-unnecessary-type-guard.mjs.map +1 -1
  26. package/dist/rules/prefer-arr-is-array.mjs +64 -52
  27. package/dist/rules/prefer-arr-is-array.mjs.map +1 -1
  28. package/dist/rules/prefer-arr-is-bounded-length-array.mjs +91 -85
  29. package/dist/rules/prefer-arr-is-bounded-length-array.mjs.map +1 -1
  30. package/dist/rules/prefer-arr-is-fixed-length-array.mjs +92 -83
  31. package/dist/rules/prefer-arr-is-fixed-length-array.mjs.map +1 -1
  32. package/dist/rules/prefer-arr-is-max-length-array.mjs +92 -80
  33. package/dist/rules/prefer-arr-is-max-length-array.mjs.map +1 -1
  34. package/dist/rules/prefer-arr-is-min-length-array.mjs +92 -80
  35. package/dist/rules/prefer-arr-is-min-length-array.mjs.map +1 -1
  36. package/dist/rules/prefer-arr-is-non-empty.mjs +85 -77
  37. package/dist/rules/prefer-arr-is-non-empty.mjs.map +1 -1
  38. package/dist/rules/prefer-arr-scan.d.mts +96 -0
  39. package/dist/rules/prefer-arr-scan.d.mts.map +1 -0
  40. package/dist/rules/prefer-arr-scan.mjs +482 -0
  41. package/dist/rules/prefer-arr-scan.mjs.map +1 -0
  42. package/dist/rules/prefer-arr-sum.mjs +176 -132
  43. package/dist/rules/prefer-arr-sum.mjs.map +1 -1
  44. package/dist/rules/prefer-as-int.mjs +77 -71
  45. package/dist/rules/prefer-as-int.mjs.map +1 -1
  46. package/dist/rules/prefer-canonical-array-slicing.mjs +503 -343
  47. package/dist/rules/prefer-canonical-array-slicing.mjs.map +1 -1
  48. package/dist/rules/prefer-canonical-length-cast.mjs +217 -144
  49. package/dist/rules/prefer-canonical-length-cast.mjs.map +1 -1
  50. package/dist/rules/prefer-canonical-length-guard.mjs +160 -109
  51. package/dist/rules/prefer-canonical-length-guard.mjs.map +1 -1
  52. package/dist/rules/prefer-comparison-over-nullish-guard.mjs +89 -71
  53. package/dist/rules/prefer-comparison-over-nullish-guard.mjs.map +1 -1
  54. package/dist/rules/prefer-is-non-null-object.mjs +91 -72
  55. package/dist/rules/prefer-is-non-null-object.mjs.map +1 -1
  56. package/dist/rules/prefer-is-record-and-has-key.mjs +148 -105
  57. package/dist/rules/prefer-is-record-and-has-key.mjs.map +1 -1
  58. package/dist/rules/prefer-num-safe-parse-float.mjs +101 -77
  59. package/dist/rules/prefer-num-safe-parse-float.mjs.map +1 -1
  60. package/dist/rules/prefer-num-safe-parse-int.mjs +103 -81
  61. package/dist/rules/prefer-num-safe-parse-int.mjs.map +1 -1
  62. package/dist/rules/prefer-obj-over-entries-round-trip.mjs +299 -194
  63. package/dist/rules/prefer-obj-over-entries-round-trip.mjs.map +1 -1
  64. package/dist/rules/prefer-range-for-loop.mjs +121 -99
  65. package/dist/rules/prefer-range-for-loop.mjs.map +1 -1
  66. package/dist/rules/rules.d.mts +1 -0
  67. package/dist/rules/rules.d.mts.map +1 -1
  68. package/dist/rules/rules.mjs +19 -20
  69. package/dist/rules/rules.mjs.map +1 -1
  70. package/dist/types.mjs +2 -2
  71. package/dist/types.mjs.map +1 -1
  72. package/package.json +6 -7
  73. package/src/plugin.mts +1 -0
  74. package/src/rule-types.mts +16 -0
  75. package/src/rules/prefer-arr-scan.mts +693 -0
  76. package/src/rules/prefer-arr-scan.test.mts +295 -0
  77. package/src/rules/rules.mts +2 -0
@@ -1,136 +1,180 @@
1
- import { AST_NODE_TYPES } from '@typescript-eslint/utils';
1
+ import { AST_NODE_TYPES, } from '@typescript-eslint/utils';
2
2
  import { Arr, pipe } from 'ts-data-forge';
3
- import { getTsDataForgeImport, getNamedImports, buildImportFixes } from './import-utils.mjs';
4
-
5
- const preferArrSum = {
6
- meta: {
7
- type: "suggestion",
8
- docs: {
9
- description: "Replace `xs.reduce((a, b) => a + b, 0)` with `Arr.sum(xs)` or `Arr.sumBy(xs, fn)` from ts-data-forge."
3
+ import { buildImportFixes, getNamedImports, getTsDataForgeImport, } from './import-utils.mjs';
4
+ export const preferArrSum = {
5
+ meta: {
6
+ type: 'suggestion',
7
+ docs: {
8
+ description: 'Replace `xs.reduce((a, b) => a + b, 0)` with `Arr.sum(xs)` or `Arr.sumBy(xs, fn)` from ts-data-forge.',
9
+ },
10
+ fixable: 'code',
11
+ schema: [],
12
+ messages: {
13
+ useArrSum: 'Replace with `Arr.sum({{arrayName}})` from ts-data-forge.',
14
+ useArrSumBy: 'Replace with `Arr.sumBy({{arrayName}}, {{mapper}})` from ts-data-forge.',
15
+ },
10
16
  },
11
- fixable: "code",
12
- schema: [],
13
- messages: {
14
- useArrSum: "Replace with `Arr.sum({{arrayName}})` from ts-data-forge.",
15
- useArrSumBy: "Replace with `Arr.sumBy({{arrayName}}, {{mapper}})` from ts-data-forge."
16
- }
17
- },
18
- create: (context) => {
19
- const sourceCode = context.sourceCode;
20
- const program = sourceCode.ast;
21
- const tsDataForgeImport = getTsDataForgeImport(program);
22
- const services = context.sourceCode.parserServices;
23
- const mut_nodesToFix = [];
24
- return {
25
- CallExpression: (node) => {
26
- if (node.callee.type !== AST_NODE_TYPES.MemberExpression || node.callee.property.type !== AST_NODE_TYPES.Identifier || node.callee.property.name !== "reduce") {
27
- return;
28
- }
29
- const arrayExpression = node.callee.object;
30
- if (!Arr.isFixedLengthTuple(2, node.arguments)) return;
31
- const reducer = node.arguments[0];
32
- const initialValue = node.arguments[1];
33
- if (initialValue.type !== AST_NODE_TYPES.Literal || initialValue.value !== 0) {
34
- return;
35
- }
36
- if (reducer.type !== AST_NODE_TYPES.ArrowFunctionExpression || !Arr.isFixedLengthTuple(2, reducer.params)) {
37
- return;
38
- }
39
- const [param1, param2] = reducer.params;
40
- if (param1.type !== AST_NODE_TYPES.Identifier || param2.type !== AST_NODE_TYPES.Identifier) {
41
- return;
42
- }
43
- const body = reducer.body;
44
- const checker = services?.program?.getTypeChecker();
45
- if (checker === void 0) return;
46
- if (body.type === AST_NODE_TYPES.BinaryExpression && body.operator === "+" && body.left.type === AST_NODE_TYPES.Identifier && body.left.name === param1.name && body.right.type === AST_NODE_TYPES.Identifier && body.right.name === param2.name) {
47
- const type = pipe(
48
- services?.esTreeNodeToTSNodeMap?.get(arrayExpression)
49
- ).mapNullable((tsNode) => checker.getTypeAtLocation(tsNode)).value;
50
- if (type !== void 0 && // Check if it's an array type or tuple type
51
- (checker.isArrayType(type) || checker.isTupleType(type))) {
52
- const typeArguments = checker.getTypeArguments(
53
- // eslint-disable-next-line total-functions/no-unsafe-type-assertion
54
- type
55
- );
56
- if (Arr.isNonEmpty(typeArguments)) {
57
- const elementType = typeArguments[0];
58
- const numberType = checker.getNumberType();
59
- if (checker.isTypeAssignableTo(elementType, numberType)) {
60
- mut_nodesToFix.push({
61
- node,
62
- arrayExpression,
63
- messageId: "useArrSum"
64
- });
65
- }
66
- }
67
- }
68
- return;
69
- }
70
- if (body.type === AST_NODE_TYPES.BinaryExpression && body.operator === "+" && body.left.type === AST_NODE_TYPES.MemberExpression && body.right.type === AST_NODE_TYPES.MemberExpression) {
71
- const leftObj = body.left.object;
72
- const rightObj = body.right.object;
73
- if (leftObj.type !== AST_NODE_TYPES.Identifier || leftObj.name !== param1.name || rightObj.type !== AST_NODE_TYPES.Identifier || rightObj.name !== param2.name) {
74
- return;
75
- }
76
- const leftProp = body.left.property;
77
- const rightProp = body.right.property;
78
- let mut_propName;
79
- if (leftProp.type === AST_NODE_TYPES.Identifier && !body.left.computed && rightProp.type === AST_NODE_TYPES.Identifier && !body.right.computed && leftProp.name === rightProp.name) {
80
- mut_propName = leftProp.name;
81
- } else if (leftProp.type === AST_NODE_TYPES.Literal && body.left.computed && rightProp.type === AST_NODE_TYPES.Literal && body.right.computed && leftProp.value === rightProp.value && typeof leftProp.value === "string") {
82
- mut_propName = leftProp.value;
83
- }
84
- if (mut_propName === void 0) return;
85
- if (services?.program !== void 0 && services.program !== null) {
86
- const tsLeftProp = services.esTreeNodeToTSNodeMap?.get(body.left);
87
- const tsRightProp = services.esTreeNodeToTSNodeMap?.get(body.right);
88
- if (tsLeftProp !== void 0 && tsRightProp !== void 0) {
89
- const leftPropType = checker.getTypeAtLocation(tsLeftProp);
90
- const rightPropType = checker.getTypeAtLocation(tsRightProp);
91
- const numberType = checker.getNumberType();
92
- if (!checker.isTypeAssignableTo(leftPropType, numberType) || !checker.isTypeAssignableTo(rightPropType, numberType)) {
93
- return;
94
- }
95
- }
96
- }
97
- const mapperParam = param1.name;
98
- const mapper = body.left.computed ? `${mapperParam} => ${mapperParam}['${mut_propName}']` : `${mapperParam} => ${mapperParam}.${mut_propName}`;
99
- mut_nodesToFix.push({
100
- node,
101
- arrayExpression,
102
- messageId: "useArrSumBy",
103
- mapper
104
- });
105
- }
106
- },
107
- "Program:exit": () => {
108
- const namedImports = getNamedImports(tsDataForgeImport);
109
- const hasArrImport = namedImports.includes("Arr");
110
- for (const [index, nodeInfo] of mut_nodesToFix.entries()) {
111
- const arrayText = sourceCode.getText(nodeInfo.arrayExpression);
112
- context.report({
113
- node: nodeInfo.node,
114
- messageId: nodeInfo.messageId,
115
- data: {
116
- arrayName: arrayText,
117
- mapper: nodeInfo.mapper ?? ""
17
+ create: (context) => {
18
+ const sourceCode = context.sourceCode;
19
+ const program = sourceCode.ast;
20
+ const tsDataForgeImport = getTsDataForgeImport(program);
21
+ const services = context.sourceCode.parserServices;
22
+ const mut_nodesToFix = [];
23
+ return {
24
+ CallExpression: (node) => {
25
+
26
+ if (node.callee.type !== AST_NODE_TYPES.MemberExpression ||
27
+ node.callee.property.type !== AST_NODE_TYPES.Identifier ||
28
+ node.callee.property.name !== 'reduce') {
29
+ return;
30
+ }
31
+ const arrayExpression = node.callee.object;
32
+
33
+ if (!Arr.isFixedLengthTuple(2, node.arguments))
34
+ return;
35
+ const reducer = node.arguments[0];
36
+ const initialValue = node.arguments[1];
37
+
38
+ if (initialValue.type !== AST_NODE_TYPES.Literal ||
39
+ initialValue.value !== 0) {
40
+ return;
41
+ }
42
+
43
+ if (reducer.type !== AST_NODE_TYPES.ArrowFunctionExpression ||
44
+ !Arr.isFixedLengthTuple(2, reducer.params)) {
45
+ return;
46
+ }
47
+ const [param1, param2] = reducer.params;
48
+ if (param1.type !== AST_NODE_TYPES.Identifier ||
49
+ param2.type !== AST_NODE_TYPES.Identifier) {
50
+ return;
51
+ }
52
+ const body = reducer.body;
53
+ const checker = services?.program?.getTypeChecker();
54
+ if (checker === undefined)
55
+ return;
56
+
57
+ if (body.type === AST_NODE_TYPES.BinaryExpression &&
58
+ body.operator === '+' &&
59
+ body.left.type === AST_NODE_TYPES.Identifier &&
60
+ body.left.name === param1.name &&
61
+ body.right.type === AST_NODE_TYPES.Identifier &&
62
+ body.right.name === param2.name) {
63
+
64
+ const type = pipe(services?.esTreeNodeToTSNodeMap?.get(arrayExpression)).mapNullable((tsNode) => checker.getTypeAtLocation(tsNode)).value;
65
+ if (type !== undefined &&
66
+ (checker.isArrayType(type) || checker.isTupleType(type))) {
67
+
68
+
69
+ const typeArguments = checker.getTypeArguments(
70
+
71
+ type);
72
+ if (Arr.isNonEmpty(typeArguments)) {
73
+ const elementType = typeArguments[0];
74
+ const numberType = checker.getNumberType();
75
+
76
+ if (checker.isTypeAssignableTo(elementType, numberType)) {
77
+ mut_nodesToFix.push({
78
+ node,
79
+ arrayExpression,
80
+ messageId: 'useArrSum',
81
+ });
82
+ }
83
+ }
84
+ }
85
+ return;
86
+ }
87
+
88
+ if (body.type === AST_NODE_TYPES.BinaryExpression &&
89
+ body.operator === '+' &&
90
+ body.left.type === AST_NODE_TYPES.MemberExpression &&
91
+ body.right.type === AST_NODE_TYPES.MemberExpression) {
92
+ const leftObj = body.left.object;
93
+ const rightObj = body.right.object;
94
+ if (leftObj.type !== AST_NODE_TYPES.Identifier ||
95
+ leftObj.name !== param1.name ||
96
+ rightObj.type !== AST_NODE_TYPES.Identifier ||
97
+ rightObj.name !== param2.name) {
98
+ return;
99
+ }
100
+
101
+ const leftProp = body.left.property;
102
+ const rightProp = body.right.property;
103
+ let mut_propName;
104
+ if (leftProp.type === AST_NODE_TYPES.Identifier &&
105
+ !body.left.computed &&
106
+ rightProp.type === AST_NODE_TYPES.Identifier &&
107
+ !body.right.computed &&
108
+ leftProp.name === rightProp.name) {
109
+ mut_propName = leftProp.name;
110
+ }
111
+ else if (leftProp.type === AST_NODE_TYPES.Literal &&
112
+ body.left.computed &&
113
+ rightProp.type === AST_NODE_TYPES.Literal &&
114
+ body.right.computed &&
115
+ leftProp.value === rightProp.value &&
116
+ typeof leftProp.value === 'string') {
117
+ mut_propName = leftProp.value;
118
+ }
119
+ if (mut_propName === undefined)
120
+ return;
121
+
122
+ if (services?.program !== undefined && services.program !== null) {
123
+ const tsLeftProp = services.esTreeNodeToTSNodeMap?.get(body.left);
124
+ const tsRightProp = services.esTreeNodeToTSNodeMap?.get(body.right);
125
+ if (tsLeftProp !== undefined && tsRightProp !== undefined) {
126
+ const leftPropType = checker.getTypeAtLocation(tsLeftProp);
127
+ const rightPropType = checker.getTypeAtLocation(tsRightProp);
128
+ const numberType = checker.getNumberType();
129
+
130
+ if (!checker.isTypeAssignableTo(leftPropType, numberType) ||
131
+ !checker.isTypeAssignableTo(rightPropType, numberType)) {
132
+ return;
133
+ }
134
+ }
135
+ }
136
+
137
+ const mapperParam = param1.name;
138
+ const mapper = body.left.computed
139
+ ? `${mapperParam} => ${mapperParam}['${mut_propName}']`
140
+ : `${mapperParam} => ${mapperParam}.${mut_propName}`;
141
+ mut_nodesToFix.push({
142
+ node,
143
+ arrayExpression,
144
+ messageId: 'useArrSumBy',
145
+ mapper,
146
+ });
147
+ }
148
+ },
149
+ 'Program:exit': () => {
150
+ const namedImports = getNamedImports(tsDataForgeImport);
151
+ const hasArrImport = namedImports.includes('Arr');
152
+ for (const [index, nodeInfo] of mut_nodesToFix.entries()) {
153
+ const arrayText = sourceCode.getText(nodeInfo.arrayExpression);
154
+ context.report({
155
+ node: nodeInfo.node,
156
+ messageId: nodeInfo.messageId,
157
+ data: {
158
+ arrayName: arrayText,
159
+ mapper: nodeInfo.mapper ?? '',
160
+ },
161
+ fix: (fixer) => {
162
+ const replacement = nodeInfo.messageId === 'useArrSum'
163
+ ? `Arr.sum(${arrayText})`
164
+ : `Arr.sumBy(${arrayText}, ${nodeInfo.mapper})`;
165
+ const importFixes = index === 0 && !hasArrImport
166
+ ? buildImportFixes(fixer, program, tsDataForgeImport, ['Arr'])
167
+ : [];
168
+ return [
169
+ ...importFixes,
170
+ fixer.replaceText(nodeInfo.node, replacement),
171
+ ];
172
+ },
173
+ });
174
+ }
118
175
  },
119
- fix: (fixer) => {
120
- const replacement = nodeInfo.messageId === "useArrSum" ? `Arr.sum(${arrayText})` : `Arr.sumBy(${arrayText}, ${nodeInfo.mapper})`;
121
- const importFixes = index === 0 && !hasArrImport ? buildImportFixes(fixer, program, tsDataForgeImport, ["Arr"]) : [];
122
- return [
123
- ...importFixes,
124
- fixer.replaceText(nodeInfo.node, replacement)
125
- ];
126
- }
127
- });
128
- }
129
- }
130
- };
131
- },
132
- defaultOptions: []
176
+ };
177
+ },
178
+ defaultOptions: [],
133
179
  };
134
-
135
- export { preferArrSum };
136
- //# sourceMappingURL=prefer-arr-sum.mjs.map
180
+ //# sourceMappingURL=prefer-arr-sum.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"prefer-arr-sum.mjs","sources":["../../src/rules/prefer-arr-sum.mts"],"sourcesContent":["import {\n AST_NODE_TYPES,\n type TSESLint,\n type TSESTree,\n} from '@typescript-eslint/utils';\nimport { Arr, pipe } from 'ts-data-forge';\nimport { type TypeReference } from 'typescript';\nimport {\n buildImportFixes,\n getNamedImports,\n getTsDataForgeImport,\n} from './import-utils.mjs';\n\ntype Options = readonly [];\n\ntype MessageIds = 'useArrSum' | 'useArrSumBy';\n\nexport const preferArrSum: TSESLint.RuleModule<MessageIds, Options> = {\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Replace `xs.reduce((a, b) => a + b, 0)` with `Arr.sum(xs)` or `Arr.sumBy(xs, fn)` from ts-data-forge.',\n },\n fixable: 'code',\n schema: [],\n messages: {\n useArrSum: 'Replace with `Arr.sum({{arrayName}})` from ts-data-forge.',\n useArrSumBy:\n 'Replace with `Arr.sumBy({{arrayName}}, {{mapper}})` from ts-data-forge.',\n },\n },\n\n create: (context) => {\n const sourceCode = context.sourceCode;\n\n const program = sourceCode.ast;\n\n const tsDataForgeImport = getTsDataForgeImport(program);\n\n const services = context.sourceCode.parserServices;\n\n const mut_nodesToFix: {\n node: TSESTree.CallExpression;\n arrayExpression: TSESTree.Expression;\n messageId: 'useArrSum' | 'useArrSumBy';\n mapper?: string;\n }[] = [];\n\n return {\n CallExpression: (node) => {\n // Check for xs.reduce(...)\n if (\n node.callee.type !== AST_NODE_TYPES.MemberExpression ||\n node.callee.property.type !== AST_NODE_TYPES.Identifier ||\n node.callee.property.name !== 'reduce'\n ) {\n return;\n }\n\n const arrayExpression = node.callee.object;\n\n // Check if we have 2 arguments: reducer function and initial value 0\n if (!Arr.isFixedLengthTuple(2, node.arguments)) return;\n\n const reducer = node.arguments[0];\n\n const initialValue = node.arguments[1];\n\n // Check initial value is 0\n if (\n initialValue.type !== AST_NODE_TYPES.Literal ||\n initialValue.value !== 0\n ) {\n return;\n }\n\n // Check if reducer is an arrow function with 2 parameters\n if (\n reducer.type !== AST_NODE_TYPES.ArrowFunctionExpression ||\n !Arr.isFixedLengthTuple(2, reducer.params)\n ) {\n return;\n }\n\n const [param1, param2] = reducer.params;\n\n if (\n param1.type !== AST_NODE_TYPES.Identifier ||\n param2.type !== AST_NODE_TYPES.Identifier\n ) {\n return;\n }\n\n const body = reducer.body;\n\n const checker = services?.program?.getTypeChecker();\n\n if (checker === undefined) return;\n\n // Case 1: (a, b) => a + b\n if (\n body.type === AST_NODE_TYPES.BinaryExpression &&\n body.operator === '+' &&\n body.left.type === AST_NODE_TYPES.Identifier &&\n body.left.name === param1.name &&\n body.right.type === AST_NODE_TYPES.Identifier &&\n body.right.name === param2.name\n ) {\n // Check if arrayExpression type is number[] or compatible\n\n const type = pipe(\n services?.esTreeNodeToTSNodeMap?.get(arrayExpression),\n ).mapNullable((tsNode) => checker.getTypeAtLocation(tsNode)).value;\n\n if (\n type !== undefined && // Check if it's an array type or tuple type\n (checker.isArrayType(type) || checker.isTupleType(type))\n ) {\n // Get type arguments using the official API\n // TypeReference has typeArguments that we can access\n const typeArguments = checker.getTypeArguments(\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n type as TypeReference,\n );\n\n if (Arr.isNonEmpty(typeArguments)) {\n const elementType = typeArguments[0];\n\n const numberType = checker.getNumberType();\n\n // Check if element type is assignable to number\n if (checker.isTypeAssignableTo(elementType, numberType)) {\n mut_nodesToFix.push({\n node,\n arrayExpression,\n messageId: 'useArrSum',\n });\n }\n }\n }\n\n return;\n }\n\n // Case 2: (a, b) => a.prop + b.prop or a['prop'] + b['prop']\n if (\n body.type === AST_NODE_TYPES.BinaryExpression &&\n body.operator === '+' &&\n body.left.type === AST_NODE_TYPES.MemberExpression &&\n body.right.type === AST_NODE_TYPES.MemberExpression\n ) {\n const leftObj = body.left.object;\n\n const rightObj = body.right.object;\n\n if (\n leftObj.type !== AST_NODE_TYPES.Identifier ||\n leftObj.name !== param1.name ||\n rightObj.type !== AST_NODE_TYPES.Identifier ||\n rightObj.name !== param2.name\n ) {\n return;\n }\n\n // Check if both access the same property\n const leftProp = body.left.property;\n\n const rightProp = body.right.property;\n\n let mut_propName: string | undefined;\n\n if (\n leftProp.type === AST_NODE_TYPES.Identifier &&\n !body.left.computed &&\n rightProp.type === AST_NODE_TYPES.Identifier &&\n !body.right.computed &&\n leftProp.name === rightProp.name\n ) {\n mut_propName = leftProp.name;\n } else if (\n leftProp.type === AST_NODE_TYPES.Literal &&\n body.left.computed &&\n rightProp.type === AST_NODE_TYPES.Literal &&\n body.right.computed &&\n leftProp.value === rightProp.value &&\n typeof leftProp.value === 'string'\n ) {\n mut_propName = leftProp.value;\n }\n\n if (mut_propName === undefined) return;\n\n // Check if property type is number\n if (services?.program !== undefined && services.program !== null) {\n const tsLeftProp = services.esTreeNodeToTSNodeMap?.get(body.left);\n\n const tsRightProp = services.esTreeNodeToTSNodeMap?.get(body.right);\n\n if (tsLeftProp !== undefined && tsRightProp !== undefined) {\n const leftPropType = checker.getTypeAtLocation(tsLeftProp);\n\n const rightPropType = checker.getTypeAtLocation(tsRightProp);\n\n const numberType = checker.getNumberType();\n\n // Check if property type is assignable to number\n if (\n !checker.isTypeAssignableTo(leftPropType, numberType) ||\n !checker.isTypeAssignableTo(rightPropType, numberType)\n ) {\n return;\n }\n }\n }\n\n // Generate mapper function\n const mapperParam = param1.name;\n\n const mapper = body.left.computed\n ? `${mapperParam} => ${mapperParam}['${mut_propName}']`\n : `${mapperParam} => ${mapperParam}.${mut_propName}`;\n\n mut_nodesToFix.push({\n node,\n arrayExpression,\n messageId: 'useArrSumBy',\n mapper,\n });\n }\n },\n 'Program:exit': () => {\n const namedImports = getNamedImports(tsDataForgeImport);\n\n const hasArrImport = namedImports.includes('Arr');\n\n for (const [index, nodeInfo] of mut_nodesToFix.entries()) {\n const arrayText = sourceCode.getText(nodeInfo.arrayExpression);\n\n context.report({\n node: nodeInfo.node,\n messageId: nodeInfo.messageId,\n data: {\n arrayName: arrayText,\n mapper: nodeInfo.mapper ?? '',\n },\n fix: (fixer) => {\n const replacement =\n nodeInfo.messageId === 'useArrSum'\n ? `Arr.sum(${arrayText})`\n : `Arr.sumBy(${arrayText}, ${nodeInfo.mapper})`;\n\n const importFixes =\n index === 0 && !hasArrImport\n ? buildImportFixes(fixer, program, tsDataForgeImport, ['Arr'])\n : [];\n\n return [\n ...importFixes,\n fixer.replaceText(nodeInfo.node, replacement),\n ];\n },\n });\n }\n },\n };\n },\n defaultOptions: [],\n} as const;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prefer-arr-sum.mjs","sourceRoot":"","sources":["../../src/rules/prefer-arr-sum.mts"],"names":[],"mappings":"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"}
@@ -1,77 +1,83 @@
1
- import { AST_NODE_TYPES } from '@typescript-eslint/utils';
1
+ import { AST_NODE_TYPES, } from '@typescript-eslint/utils';
2
2
  import { brandedNumberTypeNameToFunctionName } from './branded-number-types.mjs';
3
- import { getTsDataForgeImport, getNamedImports, buildImportFixes } from './import-utils.mjs';
3
+ import { buildImportFixes, getNamedImports, getTsDataForgeImport, } from './import-utils.mjs';
4
+ export const preferAsInt = {
5
+ meta: {
6
+ type: 'suggestion',
7
+ docs: {
8
+ description: 'Replace branded number type assertions (e.g., `as Int`) with corresponding functions (e.g., `asInt()`) from ts-data-forge.',
9
+ },
10
+ fixable: 'code',
11
+ schema: [],
12
+ messages: {
13
+ useBrandedNumberCastFunction: 'Replace `as {{typeName}}` with `{{functionName}}()` from ts-data-forge.',
14
+ },
15
+ },
16
+ create: (context) => {
17
+ const sourceCode = context.sourceCode;
18
+ const program = sourceCode.ast;
19
+ const tsDataForgeImport = getTsDataForgeImport(program);
20
+ const mut_nodesToFix = [];
21
+ return {
22
+ TSAsExpression: (node) => {
23
+ const typeInfo = getBrandedNumberTypeInfo(node.typeAnnotation);
24
+ if (typeInfo === undefined)
25
+ return;
26
+ mut_nodesToFix.push({
27
+ node,
28
+ typeName: typeInfo.typeName,
29
+ functionName: typeInfo.functionName,
30
+ });
31
+ },
32
+ 'Program:exit': () => {
33
+ const namedImports = getNamedImports(tsDataForgeImport);
34
+
35
+ const mut_functionNameToNodes = new Map();
36
+ for (const nodeInfo of mut_nodesToFix) {
37
+ const mut_nodes = mut_functionNameToNodes.get(nodeInfo.functionName) ?? [];
38
+ mut_nodes.push(nodeInfo);
39
+ mut_functionNameToNodes.set(nodeInfo.functionName, mut_nodes);
40
+ }
4
41
 
5
- const preferAsInt = {
6
- meta: {
7
- type: "suggestion",
8
- docs: {
9
- description: "Replace branded number type assertions (e.g., `as Int`) with corresponding functions (e.g., `asInt()`) from ts-data-forge."
42
+ for (const [functionName, nodes] of mut_functionNameToNodes) {
43
+ const hasImport = namedImports.includes(functionName);
44
+ for (const [index, { node, typeName }] of nodes.entries()) {
45
+ context.report({
46
+ node,
47
+ messageId: 'useBrandedNumberCastFunction',
48
+ data: {
49
+ typeName,
50
+ functionName,
51
+ },
52
+ fix: (fixer) => {
53
+ const replacement = `${functionName}(${sourceCode.getText(node.expression)})`;
54
+
55
+ const importFixes = index === 0 && !hasImport
56
+ ? buildImportFixes(fixer, program, tsDataForgeImport, [
57
+ functionName,
58
+ ])
59
+ : [];
60
+ return [...importFixes, fixer.replaceText(node, replacement)];
61
+ },
62
+ });
63
+ }
64
+ }
65
+ },
66
+ };
10
67
  },
11
- fixable: "code",
12
- schema: [],
13
- messages: {
14
- useBrandedNumberCastFunction: "Replace `as {{typeName}}` with `{{functionName}}()` from ts-data-forge."
15
- }
16
- },
17
- create: (context) => {
18
- const sourceCode = context.sourceCode;
19
- const program = sourceCode.ast;
20
- const tsDataForgeImport = getTsDataForgeImport(program);
21
- const mut_nodesToFix = [];
22
- return {
23
- TSAsExpression: (node) => {
24
- const typeInfo = getBrandedNumberTypeInfo(node.typeAnnotation);
25
- if (typeInfo === void 0) return;
26
- mut_nodesToFix.push({
27
- node,
28
- typeName: typeInfo.typeName,
29
- functionName: typeInfo.functionName
30
- });
31
- },
32
- "Program:exit": () => {
33
- const namedImports = getNamedImports(tsDataForgeImport);
34
- const mut_functionNameToNodes = /* @__PURE__ */ new Map();
35
- for (const nodeInfo of mut_nodesToFix) {
36
- const mut_nodes = mut_functionNameToNodes.get(nodeInfo.functionName) ?? [];
37
- mut_nodes.push(nodeInfo);
38
- mut_functionNameToNodes.set(nodeInfo.functionName, mut_nodes);
39
- }
40
- for (const [functionName, nodes] of mut_functionNameToNodes) {
41
- const hasImport = namedImports.includes(functionName);
42
- for (const [index, { node, typeName }] of nodes.entries()) {
43
- context.report({
44
- node,
45
- messageId: "useBrandedNumberCastFunction",
46
- data: {
47
- typeName,
48
- functionName
49
- },
50
- fix: (fixer) => {
51
- const replacement = `${functionName}(${sourceCode.getText(node.expression)})`;
52
- const importFixes = index === 0 && !hasImport ? buildImportFixes(fixer, program, tsDataForgeImport, [
53
- functionName
54
- ]) : [];
55
- return [...importFixes, fixer.replaceText(node, replacement)];
56
- }
57
- });
58
- }
59
- }
60
- }
61
- };
62
- },
63
- defaultOptions: []
68
+ defaultOptions: [],
64
69
  };
65
70
  const getBrandedNumberTypeInfo = (typeAnnotation) => {
66
- if (typeAnnotation.type !== AST_NODE_TYPES.TSTypeReference) return void 0;
67
- if (typeAnnotation.typeName.type !== AST_NODE_TYPES.Identifier)
68
- return void 0;
69
- const typeName = typeAnnotation.typeName.name;
70
- if (!brandedNumberTypeNameToFunctionName.has(typeName)) return void 0;
71
- const functionName = brandedNumberTypeNameToFunctionName.get(typeName);
72
- if (functionName === void 0) return void 0;
73
- return { typeName, functionName };
71
+ if (typeAnnotation.type !== AST_NODE_TYPES.TSTypeReference)
72
+ return undefined;
73
+ if (typeAnnotation.typeName.type !== AST_NODE_TYPES.Identifier)
74
+ return undefined;
75
+ const typeName = typeAnnotation.typeName.name;
76
+ if (!brandedNumberTypeNameToFunctionName.has(typeName))
77
+ return undefined;
78
+ const functionName = brandedNumberTypeNameToFunctionName.get(typeName);
79
+ if (functionName === undefined)
80
+ return undefined;
81
+ return { typeName, functionName };
74
82
  };
75
-
76
- export { preferAsInt };
77
- //# sourceMappingURL=prefer-as-int.mjs.map
83
+ //# sourceMappingURL=prefer-as-int.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"prefer-as-int.mjs","sources":["../../src/rules/prefer-as-int.mts"],"sourcesContent":["import {\n AST_NODE_TYPES,\n type TSESLint,\n type TSESTree,\n} from '@typescript-eslint/utils';\nimport { type DeepReadonly } from 'ts-type-forge';\nimport { brandedNumberTypeNameToFunctionName } from './branded-number-types.mjs';\nimport {\n buildImportFixes,\n getNamedImports,\n getTsDataForgeImport,\n} from './import-utils.mjs';\n\ntype Options = readonly [];\n\ntype MessageIds = 'useBrandedNumberCastFunction';\n\nexport const preferAsInt: TSESLint.RuleModule<MessageIds, Options> = {\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Replace branded number type assertions (e.g., `as Int`) with corresponding functions (e.g., `asInt()`) from ts-data-forge.',\n },\n fixable: 'code',\n schema: [],\n messages: {\n useBrandedNumberCastFunction:\n 'Replace `as {{typeName}}` with `{{functionName}}()` from ts-data-forge.',\n },\n },\n\n create: (context) => {\n const sourceCode = context.sourceCode;\n\n const program = sourceCode.ast;\n\n const tsDataForgeImport = getTsDataForgeImport(program);\n\n const mut_nodesToFix: {\n node: TSESTree.TSAsExpression;\n typeName: string;\n functionName: string;\n }[] = [];\n\n return {\n TSAsExpression: (node) => {\n const typeInfo = getBrandedNumberTypeInfo(node.typeAnnotation);\n\n if (typeInfo === undefined) return;\n\n mut_nodesToFix.push({\n node,\n typeName: typeInfo.typeName,\n functionName: typeInfo.functionName,\n });\n },\n 'Program:exit': () => {\n const namedImports = getNamedImports(tsDataForgeImport);\n\n // Group nodes by function name to handle imports efficiently\n const mut_functionNameToNodes = new Map<\n string,\n Readonly<{\n node: TSESTree.TSAsExpression;\n typeName: string;\n functionName: string;\n }>[]\n >();\n\n for (const nodeInfo of mut_nodesToFix) {\n const mut_nodes =\n mut_functionNameToNodes.get(nodeInfo.functionName) ?? [];\n\n mut_nodes.push(nodeInfo);\n\n mut_functionNameToNodes.set(nodeInfo.functionName, mut_nodes);\n }\n\n // Process each group\n for (const [functionName, nodes] of mut_functionNameToNodes) {\n const hasImport = namedImports.includes(functionName);\n\n for (const [index, { node, typeName }] of nodes.entries()) {\n context.report({\n node,\n messageId: 'useBrandedNumberCastFunction',\n data: {\n typeName,\n functionName,\n },\n fix: (fixer) => {\n const replacement = `${functionName}(${sourceCode.getText(node.expression)})`;\n\n // Add import only for the first node of this function and only if not already imported\n const importFixes =\n index === 0 && !hasImport\n ? buildImportFixes(fixer, program, tsDataForgeImport, [\n functionName,\n ])\n : [];\n\n return [...importFixes, fixer.replaceText(node, replacement)];\n },\n });\n }\n }\n },\n };\n },\n defaultOptions: [],\n} as const;\n\nconst getBrandedNumberTypeInfo = (\n typeAnnotation: DeepReadonly<TSESTree.TypeNode>,\n): Readonly<{ typeName: string; functionName: string }> | undefined => {\n if (typeAnnotation.type !== AST_NODE_TYPES.TSTypeReference) return undefined;\n\n if (typeAnnotation.typeName.type !== AST_NODE_TYPES.Identifier)\n return undefined;\n\n const typeName = typeAnnotation.typeName.name;\n\n if (!brandedNumberTypeNameToFunctionName.has(typeName)) return undefined;\n\n const functionName = brandedNumberTypeNameToFunctionName.get(typeName);\n\n if (functionName === undefined) return undefined;\n\n return { typeName, functionName };\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prefer-as-int.mjs","sourceRoot":"","sources":["../../src/rules/prefer-as-int.mts"],"names":[],"mappings":"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"}