eslint-plugin-ts-data-forge 0.8.5 → 0.8.6

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 (97) hide show
  1. package/dist/rules/ast-utils.d.mts +0 -32
  2. package/dist/rules/ast-utils.d.mts.map +1 -1
  3. package/dist/rules/ast-utils.mjs +4 -56
  4. package/dist/rules/ast-utils.mjs.map +1 -1
  5. package/dist/rules/no-unnecessary-type-guard.d.mts.map +1 -1
  6. package/dist/rules/no-unnecessary-type-guard.mjs +6 -6
  7. package/dist/rules/no-unnecessary-type-guard.mjs.map +1 -1
  8. package/dist/rules/prefer-arr-is-array.d.mts.map +1 -1
  9. package/dist/rules/prefer-arr-is-array.mjs +7 -5
  10. package/dist/rules/prefer-arr-is-array.mjs.map +1 -1
  11. package/dist/rules/prefer-arr-is-bounded-length-array.d.mts.map +1 -1
  12. package/dist/rules/prefer-arr-is-bounded-length-array.mjs +9 -6
  13. package/dist/rules/prefer-arr-is-bounded-length-array.mjs.map +1 -1
  14. package/dist/rules/prefer-arr-is-fixed-length-array.d.mts.map +1 -1
  15. package/dist/rules/prefer-arr-is-fixed-length-array.mjs +9 -6
  16. package/dist/rules/prefer-arr-is-fixed-length-array.mjs.map +1 -1
  17. package/dist/rules/prefer-arr-is-max-length-array.d.mts.map +1 -1
  18. package/dist/rules/prefer-arr-is-max-length-array.mjs +9 -6
  19. package/dist/rules/prefer-arr-is-max-length-array.mjs.map +1 -1
  20. package/dist/rules/prefer-arr-is-min-length-array.d.mts.map +1 -1
  21. package/dist/rules/prefer-arr-is-min-length-array.mjs +9 -6
  22. package/dist/rules/prefer-arr-is-min-length-array.mjs.map +1 -1
  23. package/dist/rules/prefer-arr-is-non-empty.d.mts.map +1 -1
  24. package/dist/rules/prefer-arr-is-non-empty.mjs +9 -6
  25. package/dist/rules/prefer-arr-is-non-empty.mjs.map +1 -1
  26. package/dist/rules/prefer-arr-scan.d.mts.map +1 -1
  27. package/dist/rules/prefer-arr-scan.mjs +8 -11
  28. package/dist/rules/prefer-arr-scan.mjs.map +1 -1
  29. package/dist/rules/prefer-arr-sum.d.mts.map +1 -1
  30. package/dist/rules/prefer-arr-sum.mjs +8 -6
  31. package/dist/rules/prefer-arr-sum.mjs.map +1 -1
  32. package/dist/rules/prefer-arr-uniq.d.mts.map +1 -1
  33. package/dist/rules/prefer-arr-uniq.mjs +11 -18
  34. package/dist/rules/prefer-arr-uniq.mjs.map +1 -1
  35. package/dist/rules/prefer-as-int.d.mts.map +1 -1
  36. package/dist/rules/prefer-as-int.mjs +6 -8
  37. package/dist/rules/prefer-as-int.mjs.map +1 -1
  38. package/dist/rules/prefer-canonical-array-slicing.d.mts.map +1 -1
  39. package/dist/rules/prefer-canonical-array-slicing.mjs +10 -6
  40. package/dist/rules/prefer-canonical-array-slicing.mjs.map +1 -1
  41. package/dist/rules/prefer-canonical-length-cast.d.mts.map +1 -1
  42. package/dist/rules/prefer-canonical-length-cast.mjs +3 -3
  43. package/dist/rules/prefer-canonical-length-cast.mjs.map +1 -1
  44. package/dist/rules/prefer-canonical-length-guard.d.mts.map +1 -1
  45. package/dist/rules/prefer-canonical-length-guard.mjs +4 -4
  46. package/dist/rules/prefer-canonical-length-guard.mjs.map +1 -1
  47. package/dist/rules/prefer-comparison-over-nullish-guard.d.mts.map +1 -1
  48. package/dist/rules/prefer-comparison-over-nullish-guard.mjs +3 -2
  49. package/dist/rules/prefer-comparison-over-nullish-guard.mjs.map +1 -1
  50. package/dist/rules/prefer-is-non-null-object.d.mts.map +1 -1
  51. package/dist/rules/prefer-is-non-null-object.mjs +5 -5
  52. package/dist/rules/prefer-is-non-null-object.mjs.map +1 -1
  53. package/dist/rules/prefer-is-record-and-has-key.d.mts.map +1 -1
  54. package/dist/rules/prefer-is-record-and-has-key.mjs +5 -5
  55. package/dist/rules/prefer-is-record-and-has-key.mjs.map +1 -1
  56. package/dist/rules/prefer-num-safe-parse-float.d.mts.map +1 -1
  57. package/dist/rules/prefer-num-safe-parse-float.mjs +6 -6
  58. package/dist/rules/prefer-num-safe-parse-float.mjs.map +1 -1
  59. package/dist/rules/prefer-num-safe-parse-int.d.mts.map +1 -1
  60. package/dist/rules/prefer-num-safe-parse-int.mjs +6 -6
  61. package/dist/rules/prefer-num-safe-parse-int.mjs.map +1 -1
  62. package/dist/rules/prefer-obj-over-entries-round-trip.d.mts.map +1 -1
  63. package/dist/rules/prefer-obj-over-entries-round-trip.mjs +9 -12
  64. package/dist/rules/prefer-obj-over-entries-round-trip.mjs.map +1 -1
  65. package/dist/rules/prefer-range-for-loop.d.mts.map +1 -1
  66. package/dist/rules/prefer-range-for-loop.mjs +8 -8
  67. package/dist/rules/prefer-range-for-loop.mjs.map +1 -1
  68. package/package.json +5 -4
  69. package/src/rules/ast-utils.mts +8 -82
  70. package/src/rules/no-unnecessary-type-guard.mts +14 -10
  71. package/src/rules/prefer-arr-is-array.mts +14 -7
  72. package/src/rules/prefer-arr-is-array.test.mts +14 -0
  73. package/src/rules/prefer-arr-is-bounded-length-array.mts +16 -10
  74. package/src/rules/prefer-arr-is-fixed-length-array.mts +17 -11
  75. package/src/rules/prefer-arr-is-max-length-array.mts +17 -11
  76. package/src/rules/prefer-arr-is-min-length-array.mts +17 -11
  77. package/src/rules/prefer-arr-is-non-empty.mts +16 -13
  78. package/src/rules/prefer-arr-scan.mts +24 -19
  79. package/src/rules/prefer-arr-sum.mts +18 -14
  80. package/src/rules/prefer-arr-uniq.mts +24 -28
  81. package/src/rules/prefer-as-int.mts +19 -12
  82. package/src/rules/prefer-canonical-array-slicing.mts +22 -12
  83. package/src/rules/prefer-canonical-length-cast.mts +7 -3
  84. package/src/rules/prefer-canonical-length-guard.mts +9 -4
  85. package/src/rules/prefer-comparison-over-nullish-guard.mts +3 -2
  86. package/src/rules/prefer-comparison-over-nullish-guard.test.mts +16 -0
  87. package/src/rules/prefer-is-non-null-object.mts +11 -7
  88. package/src/rules/prefer-is-record-and-has-key.mts +14 -10
  89. package/src/rules/prefer-num-safe-parse-float.mts +15 -10
  90. package/src/rules/prefer-num-safe-parse-int.mts +15 -13
  91. package/src/rules/prefer-obj-over-entries-round-trip.mts +19 -22
  92. package/src/rules/prefer-range-for-loop.mts +16 -11
  93. package/dist/rules/import-utils.d.mts +0 -30
  94. package/dist/rules/import-utils.d.mts.map +0 -1
  95. package/dist/rules/import-utils.mjs +0 -98
  96. package/dist/rules/import-utils.mjs.map +0 -1
  97. package/src/rules/import-utils.mts +0 -175
@@ -1,7 +1,7 @@
1
1
  import { AST_NODE_TYPES, } from '@typescript-eslint/utils';
2
+ import { buildNamedImportFix, getArgumentText, getImportDeclarations, getNamedImports, skipTypeWrappers, } from 'eslint-rule-forge';
2
3
  import { Arr } from 'ts-data-forge';
3
- import { skipTypeWrappers, toArgumentText } from './ast-utils.mjs';
4
- import { buildImportFixes, getNamedImports, getTsDataForgeImport, } from './import-utils.mjs';
4
+ import { TS_DATA_FORGE_MODULE } from './constants.mjs';
5
5
  export const preferRangeForLoop = {
6
6
  meta: {
7
7
  type: 'suggestion',
@@ -17,7 +17,7 @@ export const preferRangeForLoop = {
17
17
  create: (context) => {
18
18
  const sourceCode = context.sourceCode;
19
19
  const program = sourceCode.ast;
20
- const tsDataForgeImport = getTsDataForgeImport(program);
20
+ const tsDataForgeImports = getImportDeclarations(program, TS_DATA_FORGE_MODULE);
21
21
  const mut_nodesToFix = [];
22
22
  return {
23
23
  ForStatement: (node) => {
@@ -81,14 +81,14 @@ export const preferRangeForLoop = {
81
81
  }
82
82
  else {
83
83
 
84
- mut_step = toArgumentText(node.update.right, sourceCode);
84
+ mut_step = getArgumentText(sourceCode, node.update.right);
85
85
  }
86
86
  }
87
87
  else {
88
88
  return;
89
89
  }
90
- const beginText = toArgumentText(beginExpr, sourceCode);
91
- const endText = toArgumentText(endExpr, sourceCode);
90
+ const beginText = getArgumentText(sourceCode, beginExpr);
91
+ const endText = getArgumentText(sourceCode, endExpr);
92
92
  mut_nodesToFix.push({
93
93
  node,
94
94
  varName,
@@ -98,7 +98,7 @@ export const preferRangeForLoop = {
98
98
  });
99
99
  },
100
100
  'Program:exit': () => {
101
- const namedImports = getNamedImports(tsDataForgeImport);
101
+ const namedImports = getNamedImports(tsDataForgeImports);
102
102
  const hasRangeImport = namedImports.includes('range');
103
103
  for (const [index, { node, varName, begin, end, step },] of mut_nodesToFix.entries()) {
104
104
  context.report({
@@ -116,7 +116,7 @@ export const preferRangeForLoop = {
116
116
  : `${begin}, ${end}, ${step}`;
117
117
  const replacement = `for (const ${varName} of range(${rangeArgs})) ${bodyText}`;
118
118
  const importFixes = index === 0 && !hasRangeImport
119
- ? buildImportFixes(fixer, program, tsDataForgeImport, [
119
+ ? buildNamedImportFix(fixer, program, TS_DATA_FORGE_MODULE, [
120
120
  'range',
121
121
  ])
122
122
  : [];
@@ -1 +1 @@
1
- {"version":3,"file":"prefer-range-for-loop.mjs","sourceRoot":"","sources":["../../src/rules/prefer-range-for-loop.mts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prefer-range-for-loop.mjs","sourceRoot":"","sources":["../../src/rules/prefer-range-for-loop.mts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,GAGf,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,qBAAqB,EACrB,eAAe,EACf,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAMvD,MAAM,CAAC,MAAM,kBAAkB,GAA6C;IAC1E,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE;YACJ,WAAW,EACT,2GAA2G;SAC9G;QACD,OAAO,EAAE,MAAM;QACf,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE;YACR,eAAe,EACb,yFAAyF;SAC5F;KACF;IAED,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE;QAClB,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QAEtC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC;QAE/B,MAAM,kBAAkB,GAAG,qBAAqB,CAC9C,OAAO,EACP,oBAAoB,CACrB,CAAC;QAEF,MAAM,cAAc,GAMd,EAAE,CAAC;QAET,OAAO;YACL,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE;gBACrB,4BAA4B;gBAC5B,IACE,IAAI,CAAC,IAAI,EAAE,IAAI,KAAK,cAAc,CAAC,mBAAmB;oBACtD,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK;oBACxB,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,EAClD,CAAC;oBACD,OAAO;gBACT,CAAC;gBAED,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;gBAE9C,IACE,WAAW,CAAC,EAAE,CAAC,IAAI,KAAK,cAAc,CAAC,UAAU;oBACjD,WAAW,CAAC,IAAI,KAAK,IAAI,EACzB,CAAC;oBACD,OAAO;gBACT,CAAC;gBAED,MAAM,OAAO,GAAG,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC;gBAEpC,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC;gBAEnC,+DAA+D;gBAC/D,mEAAmE;gBACnE,uCAAuC;gBACvC,IACE,IAAI,CAAC,IAAI,EAAE,IAAI,KAAK,cAAc,CAAC,gBAAgB;oBACnD,IAAI,CAAC,IAAI,CAAC,QAAQ,KAAK,GAAG,EAC1B,CAAC;oBACD,OAAO;gBACT,CAAC;gBAED,MAAM,cAAc,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAExD,IACE,cAAc,CAAC,IAAI,KAAK,cAAc,CAAC,UAAU;oBACjD,cAAc,CAAC,IAAI,KAAK,OAAO,EAC/B,CAAC;oBACD,OAAO;gBACT,CAAC;gBAED,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;gBAEhC,+CAA+C;gBAC/C,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;oBACzB,OAAO;gBACT,CAAC;gBAED,IAAI,QAA4B,CAAC;gBAEjC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,cAAc,CAAC,gBAAgB,EAAE,CAAC;oBACzD,aAAa;oBACb,IACE,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,IAAI;wBAC7B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,cAAc,CAAC,UAAU;wBACvD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,OAAO,EACrC,CAAC;wBACD,QAAQ,GAAG,SAAS,CAAC,CAAC,qBAAqB;oBAC7C,CAAC;yBAAM,CAAC;wBACN,OAAO;oBACT,CAAC;gBACH,CAAC;qBAAM,IACL,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,cAAc,CAAC,oBAAoB;oBACxD,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,IAAI;oBAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,UAAU;oBACnD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,EACjC,CAAC;oBACD,YAAY;oBACZ,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBAEtD,IAAI,SAAS,CAAC,IAAI,KAAK,cAAc,CAAC,OAAO,EAAE,CAAC;wBAC9C,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC;wBAEhC,sCAAsC;wBACtC,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;4BAC/C,QAAQ,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;wBAC5D,CAAC;6BAAM,CAAC;4BACN,OAAO;wBACT,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,+BAA+B;wBAC/B,QAAQ,GAAG,eAAe,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBAC5D,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,OAAO;gBACT,CAAC;gBAED,MAAM,SAAS,GAAG,eAAe,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;gBAEzD,MAAM,OAAO,GAAG,eAAe,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;gBAErD,cAAc,CAAC,IAAI,CAAC;oBAClB,IAAI;oBACJ,OAAO;oBACP,KAAK,EAAE,SAAS;oBAChB,GAAG,EAAE,OAAO;oBACZ,IAAI,EAAE,QAAQ;iBACf,CAAC,CAAC;YACL,CAAC;YACD,cAAc,EAAE,GAAG,EAAE;gBACnB,MAAM,YAAY,GAAG,eAAe,CAAC,kBAAkB,CAAC,CAAC;gBAEzD,MAAM,cAAc,GAAG,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;gBAEtD,KAAK,MAAM,CACT,KAAK,EACL,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EACpC,IAAI,cAAc,CAAC,OAAO,EAAE,EAAE,CAAC;oBAC9B,OAAO,CAAC,MAAM,CAAC;wBACb,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI;wBACvB,SAAS,EAAE,iBAAiB;wBAC5B,IAAI,EAAE;4BACJ,OAAO;4BACP,KAAK;4BACL,GAAG;yBACJ;wBACD,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE;4BACb,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;4BAE/C,MAAM,SAAS,GACb,IAAI,KAAK,SAAS;gCAChB,CAAC,CAAC,GAAG,KAAK,KAAK,GAAG,EAAE;gCACpB,CAAC,CAAC,GAAG,KAAK,KAAK,GAAG,KAAK,IAAI,EAAE,CAAC;4BAElC,MAAM,WAAW,GAAG,cAAc,OAAO,aAAa,SAAS,MAAM,QAAQ,EAAE,CAAC;4BAEhF,MAAM,WAAW,GACf,KAAK,KAAK,CAAC,IAAI,CAAC,cAAc;gCAC5B,CAAC,CAAC,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,oBAAoB,EAAE;oCACxD,OAAO;iCACR,CAAC;gCACJ,CAAC,CAAC,EAAE,CAAC;4BAET,OAAO,CAAC,GAAG,WAAW,EAAE,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;wBAChE,CAAC;qBACF,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;IACD,cAAc,EAAE,EAAE;CACV,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-ts-data-forge",
3
- "version": "0.8.5",
3
+ "version": "0.8.6",
4
4
  "private": false,
5
5
  "description": "ESLint rules that steer code toward ts-data-forge idioms.",
6
6
  "keywords": [
@@ -35,6 +35,7 @@
35
35
  ],
36
36
  "dependencies": {
37
37
  "@typescript-eslint/utils": "^8.71.1",
38
+ "eslint-rule-forge": "^0.1.0",
38
39
  "ts-data-forge": "14.7.1",
39
40
  "ts-type-forge": "~9.2.2"
40
41
  },
@@ -42,9 +43,9 @@
42
43
  "@typescript-eslint/parser": "8.71.1",
43
44
  "@typescript-eslint/rule-tester": "8.71.1",
44
45
  "dedent": "1.7.2",
45
- "eslint-config-typed": "5.17.3",
46
- "eslint-plugin-ts-fortress": "1.3.2",
47
- "eslint-plugin-ts-type-forge": "0.8.7",
46
+ "eslint-config-typed": "5.17.4",
47
+ "eslint-plugin-ts-fortress": "1.3.3",
48
+ "eslint-plugin-ts-type-forge": "0.8.8",
48
49
  "prettier": "3.9.9",
49
50
  "prettier-plugin-organize-imports": "4.3.0",
50
51
  "prettier-plugin-packagejson": "3.0.2",
@@ -1,82 +1,21 @@
1
1
  import {
2
2
  AST_NODE_TYPES,
3
+ ASTUtils,
3
4
  type TSESLint,
4
5
  type TSESTree,
5
6
  } from '@typescript-eslint/utils';
7
+ import {
8
+ isTypeWrapper,
9
+ skipTypeWrappers,
10
+ typeWrapperLayers,
11
+ } from 'eslint-rule-forge';
6
12
  import type { DeepReadonly } from 'ts-type-forge';
7
13
 
8
- /**
9
- * `node` with every `as`, `satisfies`, `!` and `<T>` around it taken off: the
10
- * expression whose value it is. A wrapper changes no value, so a rule judges
11
- * syntax on this — `xs.length > (0 as number)` compares with the literal `0`
12
- * — and writes its fix from the original node so the wrapper is kept. A type
13
- * is another matter: see {@link typeWrapperLayers}. See
14
- * `docs/writing-lint-rules.md` at the repository root. A copy of
15
- * `eslint-config-typed`'s `type-wrapper-utils.mts`, since this package is
16
- * published on its own.
17
- */
18
- export const skipTypeWrappers = <N extends TSESTree.Node>(
19
- node: N,
20
- ): N | TSESTree.Expression =>
21
- isTypeWrapper(node) ? skipTypeWrappers(node.expression) : node;
22
-
23
- /**
24
- * `node` and every expression inside the type wrappers around it, outermost
25
- * first: `x as A as B` gives `x as A as B`, `x as A` and `x`.
26
- *
27
- * A conclusion a rule draws from a type — that a guard always holds, that a
28
- * value is an array, that `?? 0` is dead — has to hold for the type of every
29
- * layer. An assertion therefore only ever makes a rule more cautious: one
30
- * that widens (`x as string | null`) is the author saying the value may be
31
- * `null`, and is respected; one that narrows (`x!`, `v as string` on an
32
- * `unknown`) is a claim the checker cannot verify, and the value's own type
33
- * still decides.
34
- */
35
- export const typeWrapperLayers = <N extends TSESTree.Node>(
36
- node: N,
37
- ): readonly (N | TSESTree.Expression)[] =>
38
- isTypeWrapper(node)
39
- ? ([node, ...typeWrapperLayers(node.expression)] as const)
40
- : ([node] as const);
41
-
42
- export const isTypeWrapper = (
43
- node: DeepReadonly<TSESTree.Node>,
44
- ): node is TypeWrapper => TYPE_WRAPPERS.has(node.type);
45
-
46
- export type TypeWrapper =
47
- | TSESTree.TSAsExpression
48
- | TSESTree.TSNonNullExpression
49
- | TSESTree.TSSatisfiesExpression
50
- | TSESTree.TSTypeAssertion;
51
-
52
- const TYPE_WRAPPERS: ReadonlySet<AST_NODE_TYPES> = new Set([
53
- AST_NODE_TYPES.TSAsExpression,
54
- AST_NODE_TYPES.TSNonNullExpression,
55
- AST_NODE_TYPES.TSSatisfiesExpression,
56
- AST_NODE_TYPES.TSTypeAssertion,
57
- ]);
58
-
59
14
  const isIntegerLiteral = (node: DeepReadonly<TSESTree.Expression>): boolean =>
60
15
  node.type === AST_NODE_TYPES.Literal &&
61
16
  typeof node.value === 'number' &&
62
17
  Number.isInteger(node.value);
63
18
 
64
- /**
65
- * The source text of `node` for an argument position. A node's text never
66
- * includes the parentheses the source wrote around it, so a comma (sequence)
67
- * expression gets them back rather than spilling into the next argument.
68
- */
69
- export const toArgumentText = (
70
- // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
71
- node: TSESTree.Node,
72
- // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
73
- sourceCode: TSESLint.SourceCode,
74
- ): string => {
75
- const text = sourceCode.getText(node);
76
-
77
- return node.type === AST_NODE_TYPES.SequenceExpression ? `(${text})` : text;
78
- };
79
-
80
19
  /**
81
20
  * Whether `node` is an array or a tuple at every layer of type wrappers (see
82
21
  * {@link typeWrapperLayers}): a cast does not make a string an array, and the
@@ -135,9 +74,9 @@ export const isIntegerLiteralOrConstant = (
135
74
  // eslint-disable-next-line total-functions/no-unsafe-type-assertion
136
75
  const scope = sourceCode.getScope(node as TSESTree.Node);
137
76
 
138
- const variable = findVariable(scope, node.name);
77
+ const variable = ASTUtils.findVariable(scope, node.name);
139
78
 
140
- if (variable === undefined) {
79
+ if (variable === null) {
141
80
  return false;
142
81
  }
143
82
 
@@ -309,16 +248,3 @@ const isVariableDefinition = (
309
248
  def: TSESLint.Scope.Definition,
310
249
  ): def is TSESLint.Scope.Definition & VariableDefinition =>
311
250
  (def.type as string) === 'Variable';
312
-
313
- const findVariable = (
314
- // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
315
- scope: TSESLint.Scope.Scope,
316
- name: string,
317
- ): TSESLint.Scope.Variable | undefined => {
318
- const variable = scope.set.get(name);
319
-
320
- return (
321
- variable ??
322
- (scope.upper === null ? undefined : findVariable(scope.upper, name))
323
- );
324
- };
@@ -4,15 +4,16 @@ import {
4
4
  type TSESLint,
5
5
  type TSESTree,
6
6
  } from '@typescript-eslint/utils';
7
- import type { DeepReadonly, ReadonlyRecord } from 'ts-type-forge';
8
- import * as ts from 'typescript';
9
- import { typeWrapperLayers } from './ast-utils.mjs';
10
7
  import {
11
8
  buildCalleeResolver,
12
- buildImportFixes,
9
+ buildNamedImportFix,
10
+ getImportDeclarations,
13
11
  getImportedLocalName,
14
- getTsDataForgeImport,
15
- } from './import-utils.mjs';
12
+ typeWrapperLayers,
13
+ } from 'eslint-rule-forge';
14
+ import type { DeepReadonly, ReadonlyRecord } from 'ts-type-forge';
15
+ import * as ts from 'typescript';
16
+ import { TS_DATA_FORGE_MODULE } from './constants.mjs';
16
17
 
17
18
  type Options = readonly [
18
19
  Readonly<{
@@ -169,9 +170,12 @@ export const noUnnecessaryTypeGuard: TSESLint.RuleModule<MessageIds, Options> =
169
170
 
170
171
  const ignored = new Set(options?.ignore);
171
172
 
172
- const tsDataForgeImport = getTsDataForgeImport(program);
173
+ const tsDataForgeImports = getImportDeclarations(
174
+ program,
175
+ TS_DATA_FORGE_MODULE,
176
+ );
173
177
 
174
- const resolveGuard = buildCalleeResolver(tsDataForgeImport);
178
+ const resolveGuard = buildCalleeResolver(tsDataForgeImports);
175
179
 
176
180
  const buildReplaceFix =
177
181
  (
@@ -191,7 +195,7 @@ export const noUnnecessaryTypeGuard: TSESLint.RuleModule<MessageIds, Options> =
191
195
  // alias), rename to its in-scope local name. Otherwise add a new
192
196
  // import and rename to the canonical name.
193
197
  const localName = getImportedLocalName(
194
- tsDataForgeImport,
198
+ tsDataForgeImports,
195
199
  replacement,
196
200
  );
197
201
 
@@ -200,7 +204,7 @@ export const noUnnecessaryTypeGuard: TSESLint.RuleModule<MessageIds, Options> =
200
204
  }
201
205
 
202
206
  return [
203
- ...buildImportFixes(fixer, program, tsDataForgeImport, [
207
+ ...buildNamedImportFix(fixer, program, TS_DATA_FORGE_MODULE, [
204
208
  replacement,
205
209
  ]),
206
210
  fixer.replaceText(propertyNode, replacement),
@@ -3,12 +3,13 @@ import {
3
3
  type TSESLint,
4
4
  type TSESTree,
5
5
  } from '@typescript-eslint/utils';
6
- import { skipTypeWrappers } from './ast-utils.mjs';
7
6
  import {
8
- buildImportFixes,
7
+ buildNamedImportFix,
8
+ getImportDeclarations,
9
9
  getNamedImports,
10
- getTsDataForgeImport,
11
- } from './import-utils.mjs';
10
+ skipTypeWrappers,
11
+ } from 'eslint-rule-forge';
12
+ import { TS_DATA_FORGE_MODULE } from './constants.mjs';
12
13
 
13
14
  type Options = readonly [];
14
15
 
@@ -34,7 +35,10 @@ export const preferArrIsArray: TSESLint.RuleModule<MessageIds, Options> = {
34
35
 
35
36
  const program = sourceCode.ast;
36
37
 
37
- const tsDataForgeImport = getTsDataForgeImport(program);
38
+ const tsDataForgeImports = getImportDeclarations(
39
+ program,
40
+ TS_DATA_FORGE_MODULE,
41
+ );
38
42
 
39
43
  const mut_nodesToFix: TSESTree.CallExpression[] = [];
40
44
 
@@ -48,7 +52,8 @@ export const preferArrIsArray: TSESLint.RuleModule<MessageIds, Options> = {
48
52
  },
49
53
  'Program:exit': () => {
50
54
  // Check if Arr is already imported
51
- const hasArrImport = getNamedImports(tsDataForgeImport).includes('Arr');
55
+ const hasArrImport =
56
+ getNamedImports(tsDataForgeImports).includes('Arr');
52
57
 
53
58
  // Note: We add import only for the first node to avoid conflicts when
54
59
  // multiple fixes try to insert at the same position. This means if the
@@ -70,7 +75,9 @@ export const preferArrIsArray: TSESLint.RuleModule<MessageIds, Options> = {
70
75
  // Add import only for the first node and only if not already imported
71
76
  const importFixes =
72
77
  index === 0 && !hasArrImport
73
- ? buildImportFixes(fixer, program, tsDataForgeImport, ['Arr'])
78
+ ? buildNamedImportFix(fixer, program, TS_DATA_FORGE_MODULE, [
79
+ 'Arr',
80
+ ])
74
81
  : [];
75
82
 
76
83
  return [...importFixes, fixer.replaceText(callee, 'Arr.isArray')];
@@ -33,6 +33,20 @@ ruleTester.run('prefer-arr-is-array', preferArrIsArray, {
33
33
  `,
34
34
  errors: [{ messageId: 'useArrIsArray' }],
35
35
  },
36
+ {
37
+ name: 'Arr imported by a second ts-data-forge declaration is not imported again',
38
+ code: dedent`
39
+ import type { Optional } from 'ts-data-forge';
40
+ import { Arr } from 'ts-data-forge';
41
+ const result = Array.isArray(value);
42
+ `,
43
+ output: dedent`
44
+ import type { Optional } from 'ts-data-forge';
45
+ import { Arr } from 'ts-data-forge';
46
+ const result = Arr.isArray(value);
47
+ `,
48
+ errors: [{ messageId: 'useArrIsArray' }],
49
+ },
36
50
  {
37
51
  name: 'Replace Array.isArray with Arr.isArray when Arr is already imported',
38
52
  code: dedent`
@@ -1,15 +1,16 @@
1
1
  import type { TSESLint, TSESTree } from '@typescript-eslint/utils';
2
+ import {
3
+ buildNamedImportFix,
4
+ getArgumentText,
5
+ getImportDeclarations,
6
+ getNamedImports,
7
+ } from 'eslint-rule-forge';
2
8
  import {
3
9
  isArrayOrTupleExpression,
4
10
  isSameArrayText,
5
11
  parseLengthComparison,
6
- toArgumentText,
7
12
  } from './ast-utils.mjs';
8
- import {
9
- buildImportFixes,
10
- getNamedImports,
11
- getTsDataForgeImport,
12
- } from './import-utils.mjs';
13
+ import { TS_DATA_FORGE_MODULE } from './constants.mjs';
13
14
 
14
15
  type Options = readonly [];
15
16
 
@@ -38,7 +39,10 @@ export const preferArrIsBoundedLengthArray: TSESLint.RuleModule<
38
39
 
39
40
  const program = sourceCode.ast;
40
41
 
41
- const tsDataForgeImport = getTsDataForgeImport(program);
42
+ const tsDataForgeImports = getImportDeclarations(
43
+ program,
44
+ TS_DATA_FORGE_MODULE,
45
+ );
42
46
 
43
47
  const services = context.sourceCode.parserServices;
44
48
 
@@ -95,7 +99,7 @@ export const preferArrIsBoundedLengthArray: TSESLint.RuleModule<
95
99
  });
96
100
  },
97
101
  'Program:exit': () => {
98
- const namedImports = getNamedImports(tsDataForgeImport);
102
+ const namedImports = getNamedImports(tsDataForgeImports);
99
103
 
100
104
  const hasArrImport = namedImports.includes('Arr');
101
105
 
@@ -103,7 +107,7 @@ export const preferArrIsBoundedLengthArray: TSESLint.RuleModule<
103
107
  index,
104
108
  { node, arrayExpression, minExpression, maxExpression },
105
109
  ] of mut_nodesToFix.entries()) {
106
- const arrayText = toArgumentText(arrayExpression, sourceCode);
110
+ const arrayText = getArgumentText(sourceCode, arrayExpression);
107
111
 
108
112
  const minText = sourceCode.getText(minExpression);
109
113
 
@@ -125,7 +129,9 @@ export const preferArrIsBoundedLengthArray: TSESLint.RuleModule<
125
129
 
126
130
  const importFixes =
127
131
  index === 0 && !hasArrImport
128
- ? buildImportFixes(fixer, program, tsDataForgeImport, ['Arr'])
132
+ ? buildNamedImportFix(fixer, program, TS_DATA_FORGE_MODULE, [
133
+ 'Arr',
134
+ ])
129
135
  : [];
130
136
 
131
137
  return [...importFixes, fixer.replaceText(node, replacement)];
@@ -1,16 +1,17 @@
1
1
  import type { TSESLint, TSESTree } from '@typescript-eslint/utils';
2
+ import {
3
+ buildNamedImportFix,
4
+ getArgumentText,
5
+ getImportDeclarations,
6
+ getNamedImports,
7
+ skipTypeWrappers,
8
+ } from 'eslint-rule-forge';
2
9
  import {
3
10
  asLengthAccess,
4
11
  isArrayOrTupleExpression,
5
12
  isIntegerLiteralOrConstant,
6
- skipTypeWrappers,
7
- toArgumentText,
8
13
  } from './ast-utils.mjs';
9
- import {
10
- buildImportFixes,
11
- getNamedImports,
12
- getTsDataForgeImport,
13
- } from './import-utils.mjs';
14
+ import { TS_DATA_FORGE_MODULE } from './constants.mjs';
14
15
 
15
16
  type Options = readonly [];
16
17
 
@@ -39,7 +40,10 @@ export const preferArrIsFixedLengthArray: TSESLint.RuleModule<
39
40
 
40
41
  const program = sourceCode.ast;
41
42
 
42
- const tsDataForgeImport = getTsDataForgeImport(program);
43
+ const tsDataForgeImports = getImportDeclarations(
44
+ program,
45
+ TS_DATA_FORGE_MODULE,
46
+ );
43
47
 
44
48
  const services = context.sourceCode.parserServices;
45
49
 
@@ -94,7 +98,7 @@ export const preferArrIsFixedLengthArray: TSESLint.RuleModule<
94
98
  });
95
99
  },
96
100
  'Program:exit': () => {
97
- const namedImports = getNamedImports(tsDataForgeImport);
101
+ const namedImports = getNamedImports(tsDataForgeImports);
98
102
 
99
103
  const hasArrImport = namedImports.includes('Arr');
100
104
 
@@ -102,7 +106,7 @@ export const preferArrIsFixedLengthArray: TSESLint.RuleModule<
102
106
  index,
103
107
  { node, arrayExpression, lengthExpression, isNegated },
104
108
  ] of mut_nodesToFix.entries()) {
105
- const arrayText = toArgumentText(arrayExpression, sourceCode);
109
+ const arrayText = getArgumentText(sourceCode, arrayExpression);
106
110
 
107
111
  const lengthText = sourceCode.getText(lengthExpression);
108
112
 
@@ -123,7 +127,9 @@ export const preferArrIsFixedLengthArray: TSESLint.RuleModule<
123
127
 
124
128
  const importFixes =
125
129
  index === 0 && !hasArrImport
126
- ? buildImportFixes(fixer, program, tsDataForgeImport, ['Arr'])
130
+ ? buildNamedImportFix(fixer, program, TS_DATA_FORGE_MODULE, [
131
+ 'Arr',
132
+ ])
127
133
  : [];
128
134
 
129
135
  return [...importFixes, fixer.replaceText(node, replacement)];
@@ -1,17 +1,18 @@
1
1
  import type { TSESLint, TSESTree } from '@typescript-eslint/utils';
2
+ import {
3
+ buildNamedImportFix,
4
+ getArgumentText,
5
+ getImportDeclarations,
6
+ getNamedImports,
7
+ skipTypeWrappers,
8
+ } from 'eslint-rule-forge';
2
9
  import {
3
10
  asLengthAccess,
4
11
  isArrayOrTupleExpression,
5
12
  isIntegerLiteralOrConstant,
6
13
  isPartOfBoundedLengthCheck,
7
- skipTypeWrappers,
8
- toArgumentText,
9
14
  } from './ast-utils.mjs';
10
- import {
11
- buildImportFixes,
12
- getNamedImports,
13
- getTsDataForgeImport,
14
- } from './import-utils.mjs';
15
+ import { TS_DATA_FORGE_MODULE } from './constants.mjs';
15
16
 
16
17
  type Options = readonly [];
17
18
 
@@ -40,7 +41,10 @@ export const preferArrIsMaxLengthArray: TSESLint.RuleModule<
40
41
 
41
42
  const program = sourceCode.ast;
42
43
 
43
- const tsDataForgeImport = getTsDataForgeImport(program);
44
+ const tsDataForgeImports = getImportDeclarations(
45
+ program,
46
+ TS_DATA_FORGE_MODULE,
47
+ );
44
48
 
45
49
  const services = context.sourceCode.parserServices;
46
50
 
@@ -99,7 +103,7 @@ export const preferArrIsMaxLengthArray: TSESLint.RuleModule<
99
103
  });
100
104
  },
101
105
  'Program:exit': () => {
102
- const namedImports = getNamedImports(tsDataForgeImport);
106
+ const namedImports = getNamedImports(tsDataForgeImports);
103
107
 
104
108
  const hasArrImport = namedImports.includes('Arr');
105
109
 
@@ -107,7 +111,7 @@ export const preferArrIsMaxLengthArray: TSESLint.RuleModule<
107
111
  index,
108
112
  { node, arrayExpression, lengthExpression },
109
113
  ] of mut_nodesToFix.entries()) {
110
- const arrayText = toArgumentText(arrayExpression, sourceCode);
114
+ const arrayText = getArgumentText(sourceCode, arrayExpression);
111
115
 
112
116
  const lengthText = sourceCode.getText(lengthExpression);
113
117
 
@@ -126,7 +130,9 @@ export const preferArrIsMaxLengthArray: TSESLint.RuleModule<
126
130
 
127
131
  const importFixes =
128
132
  index === 0 && !hasArrImport
129
- ? buildImportFixes(fixer, program, tsDataForgeImport, ['Arr'])
133
+ ? buildNamedImportFix(fixer, program, TS_DATA_FORGE_MODULE, [
134
+ 'Arr',
135
+ ])
130
136
  : [];
131
137
 
132
138
  return [...importFixes, fixer.replaceText(node, replacement)];
@@ -1,17 +1,18 @@
1
1
  import type { TSESLint, TSESTree } from '@typescript-eslint/utils';
2
+ import {
3
+ buildNamedImportFix,
4
+ getArgumentText,
5
+ getImportDeclarations,
6
+ getNamedImports,
7
+ skipTypeWrappers,
8
+ } from 'eslint-rule-forge';
2
9
  import {
3
10
  asLengthAccess,
4
11
  isArrayOrTupleExpression,
5
12
  isIntegerLiteralOrConstant,
6
13
  isPartOfBoundedLengthCheck,
7
- skipTypeWrappers,
8
- toArgumentText,
9
14
  } from './ast-utils.mjs';
10
- import {
11
- buildImportFixes,
12
- getNamedImports,
13
- getTsDataForgeImport,
14
- } from './import-utils.mjs';
15
+ import { TS_DATA_FORGE_MODULE } from './constants.mjs';
15
16
 
16
17
  type Options = readonly [];
17
18
 
@@ -40,7 +41,10 @@ export const preferArrIsMinLengthArray: TSESLint.RuleModule<
40
41
 
41
42
  const program = sourceCode.ast;
42
43
 
43
- const tsDataForgeImport = getTsDataForgeImport(program);
44
+ const tsDataForgeImports = getImportDeclarations(
45
+ program,
46
+ TS_DATA_FORGE_MODULE,
47
+ );
44
48
 
45
49
  const services = context.sourceCode.parserServices;
46
50
 
@@ -99,7 +103,7 @@ export const preferArrIsMinLengthArray: TSESLint.RuleModule<
99
103
  });
100
104
  },
101
105
  'Program:exit': () => {
102
- const namedImports = getNamedImports(tsDataForgeImport);
106
+ const namedImports = getNamedImports(tsDataForgeImports);
103
107
 
104
108
  const hasArrImport = namedImports.includes('Arr');
105
109
 
@@ -107,7 +111,7 @@ export const preferArrIsMinLengthArray: TSESLint.RuleModule<
107
111
  index,
108
112
  { node, arrayExpression, lengthExpression },
109
113
  ] of mut_nodesToFix.entries()) {
110
- const arrayText = toArgumentText(arrayExpression, sourceCode);
114
+ const arrayText = getArgumentText(sourceCode, arrayExpression);
111
115
 
112
116
  const lengthText = sourceCode.getText(lengthExpression);
113
117
 
@@ -126,7 +130,9 @@ export const preferArrIsMinLengthArray: TSESLint.RuleModule<
126
130
 
127
131
  const importFixes =
128
132
  index === 0 && !hasArrImport
129
- ? buildImportFixes(fixer, program, tsDataForgeImport, ['Arr'])
133
+ ? buildNamedImportFix(fixer, program, TS_DATA_FORGE_MODULE, [
134
+ 'Arr',
135
+ ])
130
136
  : [];
131
137
 
132
138
  return [...importFixes, fixer.replaceText(node, replacement)];
@@ -4,16 +4,14 @@ import {
4
4
  type TSESTree,
5
5
  } from '@typescript-eslint/utils';
6
6
  import {
7
- asLengthAccess,
8
- isArrayOrTupleExpression,
9
- skipTypeWrappers,
10
- toArgumentText,
11
- } from './ast-utils.mjs';
12
- import {
13
- buildImportFixes,
7
+ buildNamedImportFix,
8
+ getArgumentText,
9
+ getImportDeclarations,
14
10
  getNamedImports,
15
- getTsDataForgeImport,
16
- } from './import-utils.mjs';
11
+ skipTypeWrappers,
12
+ } from 'eslint-rule-forge';
13
+ import { asLengthAccess, isArrayOrTupleExpression } from './ast-utils.mjs';
14
+ import { TS_DATA_FORGE_MODULE } from './constants.mjs';
17
15
 
18
16
  type Options = readonly [];
19
17
 
@@ -39,7 +37,10 @@ export const preferArrIsNonEmpty: TSESLint.RuleModule<MessageIds, Options> = {
39
37
 
40
38
  const program = sourceCode.ast;
41
39
 
42
- const tsDataForgeImport = getTsDataForgeImport(program);
40
+ const tsDataForgeImports = getImportDeclarations(
41
+ program,
42
+ TS_DATA_FORGE_MODULE,
43
+ );
43
44
 
44
45
  const services = context.sourceCode.parserServices;
45
46
 
@@ -88,7 +89,7 @@ export const preferArrIsNonEmpty: TSESLint.RuleModule<MessageIds, Options> = {
88
89
  });
89
90
  },
90
91
  'Program:exit': () => {
91
- const namedImports = getNamedImports(tsDataForgeImport);
92
+ const namedImports = getNamedImports(tsDataForgeImports);
92
93
 
93
94
  const hasArrImport = namedImports.includes('Arr');
94
95
 
@@ -96,7 +97,7 @@ export const preferArrIsNonEmpty: TSESLint.RuleModule<MessageIds, Options> = {
96
97
  index,
97
98
  { node, arrayExpression },
98
99
  ] of mut_nodesToFix.entries()) {
99
- const arrayText = toArgumentText(arrayExpression, sourceCode);
100
+ const arrayText = getArgumentText(sourceCode, arrayExpression);
100
101
 
101
102
  const originalText = sourceCode.getText(node);
102
103
 
@@ -112,7 +113,9 @@ export const preferArrIsNonEmpty: TSESLint.RuleModule<MessageIds, Options> = {
112
113
 
113
114
  const importFixes =
114
115
  index === 0 && !hasArrImport
115
- ? buildImportFixes(fixer, program, tsDataForgeImport, ['Arr'])
116
+ ? buildNamedImportFix(fixer, program, TS_DATA_FORGE_MODULE, [
117
+ 'Arr',
118
+ ])
116
119
  : [];
117
120
 
118
121
  return [...importFixes, fixer.replaceText(node, replacement)];