eslint-plugin-ts-data-forge 0.5.4 → 0.6.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 (48) hide show
  1. package/README.md +1 -0
  2. package/dist/plugin.d.mts +2 -0
  3. package/dist/plugin.d.mts.map +1 -1
  4. package/dist/plugin.mjs +1 -0
  5. package/dist/plugin.mjs.map +1 -1
  6. package/dist/rule-types.d.mts +15 -0
  7. package/dist/rule-types.d.mts.map +1 -1
  8. package/dist/rules/ast-utils.mjs.map +1 -1
  9. package/dist/rules/branded-number-types.mjs.map +1 -1
  10. package/dist/rules/constants.mjs.map +1 -1
  11. package/dist/rules/import-utils.mjs.map +1 -1
  12. package/dist/rules/no-side-effect-import.d.mts +17 -0
  13. package/dist/rules/no-side-effect-import.d.mts.map +1 -0
  14. package/dist/rules/no-side-effect-import.mjs +41 -0
  15. package/dist/rules/no-side-effect-import.mjs.map +1 -0
  16. package/dist/rules/no-unnecessary-type-guard.mjs.map +1 -1
  17. package/dist/rules/prefer-arr-is-array.mjs.map +1 -1
  18. package/dist/rules/prefer-arr-is-bounded-length-array.mjs.map +1 -1
  19. package/dist/rules/prefer-arr-is-fixed-length-array.mjs.map +1 -1
  20. package/dist/rules/prefer-arr-is-max-length-array.mjs.map +1 -1
  21. package/dist/rules/prefer-arr-is-min-length-array.mjs.map +1 -1
  22. package/dist/rules/prefer-arr-is-non-empty.mjs.map +1 -1
  23. package/dist/rules/prefer-arr-sum.mjs.map +1 -1
  24. package/dist/rules/prefer-as-int.mjs.map +1 -1
  25. package/dist/rules/prefer-canonical-array-slicing.mjs.map +1 -1
  26. package/dist/rules/prefer-canonical-length-cast.mjs +1 -1
  27. package/dist/rules/prefer-canonical-length-cast.mjs.map +1 -1
  28. package/dist/rules/prefer-canonical-length-guard.mjs.map +1 -1
  29. package/dist/rules/prefer-comparison-over-nullish-guard.mjs.map +1 -1
  30. package/dist/rules/prefer-is-non-null-object.mjs.map +1 -1
  31. package/dist/rules/prefer-is-record-and-has-key.mjs.map +1 -1
  32. package/dist/rules/prefer-num-safe-parse-float.mjs.map +1 -1
  33. package/dist/rules/prefer-num-safe-parse-int.mjs.map +1 -1
  34. package/dist/rules/prefer-obj-over-entries-round-trip.mjs.map +1 -1
  35. package/dist/rules/prefer-range-for-loop.mjs +1 -1
  36. package/dist/rules/prefer-range-for-loop.mjs.map +1 -1
  37. package/dist/rules/rules.d.mts +1 -0
  38. package/dist/rules/rules.d.mts.map +1 -1
  39. package/dist/rules/rules.mjs +2 -0
  40. package/dist/rules/rules.mjs.map +1 -1
  41. package/package.json +5 -5
  42. package/src/plugin.mts +1 -0
  43. package/src/rule-types.mts +16 -0
  44. package/src/rules/no-side-effect-import.mts +71 -0
  45. package/src/rules/no-side-effect-import.test.mts +85 -0
  46. package/src/rules/prefer-canonical-length-cast.mts +9 -2
  47. package/src/rules/prefer-range-for-loop.mts +1 -1
  48. package/src/rules/rules.mts +2 -0
@@ -0,0 +1,85 @@
1
+ import parser from '@typescript-eslint/parser';
2
+ import { RuleTester } from '@typescript-eslint/rule-tester';
3
+ import dedent from 'dedent';
4
+ import { noSideEffectImport } from './no-side-effect-import.mjs';
5
+
6
+ const tester = new RuleTester({
7
+ languageOptions: {
8
+ parser,
9
+ parserOptions: { ecmaVersion: 2020, sourceType: 'module' },
10
+ },
11
+ });
12
+
13
+ describe('no-side-effect-import', () => {
14
+ tester.run('no-side-effect-import', noSideEffectImport, {
15
+ valid: [
16
+ {
17
+ name: 'accepts a named import',
18
+ code: dedent`
19
+ import { Arr } from 'ts-data-forge';
20
+
21
+ const first = Arr.isNonEmpty(xs) ? xs[0] : undefined;
22
+ `,
23
+ },
24
+ {
25
+ name: 'accepts a namespace import',
26
+ code: dedent`
27
+ import * as tdf from 'ts-data-forge';
28
+
29
+ const sum = tdf.Arr.sum(xs);
30
+ `,
31
+ },
32
+ {
33
+ name: 'leaves other side-effect imports alone',
34
+ code: dedent`
35
+ import './polyfills.mjs';
36
+ import 'ts-data-forge-extras';
37
+ `,
38
+ },
39
+ ],
40
+ invalid: [
41
+ {
42
+ name: 'removes a side-effect-only import',
43
+ code: dedent`
44
+ import 'ts-data-forge';
45
+ `,
46
+ output: '',
47
+ errors: [{ messageId: 'removeSideEffectImport' }],
48
+ },
49
+ {
50
+ name: 'removes it along with its line',
51
+ code: dedent`
52
+ import 'ts-data-forge';
53
+ import { Arr } from 'ts-data-forge';
54
+
55
+ const sum = Arr.sum(xs);
56
+ `,
57
+ output: dedent`
58
+ import { Arr } from 'ts-data-forge';
59
+
60
+ const sum = Arr.sum(xs);
61
+ `,
62
+ errors: [{ messageId: 'removeSideEffectImport' }],
63
+ },
64
+ {
65
+ name: 'removes every side-effect-only import',
66
+ code: dedent`
67
+ import 'ts-data-forge';
68
+ import './polyfills.mjs';
69
+ import 'ts-data-forge';
70
+
71
+ const answer = 42;
72
+ `,
73
+ output: dedent`
74
+ import './polyfills.mjs';
75
+
76
+ const answer = 42;
77
+ `,
78
+ errors: [
79
+ { messageId: 'removeSideEffectImport' },
80
+ { messageId: 'removeSideEffectImport' },
81
+ ],
82
+ },
83
+ ],
84
+ });
85
+ });
@@ -266,12 +266,19 @@ const dropBoundsFix = (
266
266
  rewrite: CastRewrite,
267
267
  ): readonly TSESLint.RuleFix[] =>
268
268
  rewrite.bounds.flatMap((_, index) => {
269
- if (rewrite.keep.includes(index)) return [];
270
-
269
+ // Read before the `includes` below, not after. The strict standard
270
+ // library types `includes` as `searchElement is T` — that is what lets a
271
+ // literal union narrow a wider value — but the predicate applies to the
272
+ // false branch too, and here `keep` is `readonly number[]` against a
273
+ // `number`, so `index` narrows to `never` past the guard and `index + 1`
274
+ // stops type-checking. A false `includes` means "not in this array", not
275
+ // "not of this type".
271
276
  const dropped = node.arguments[index];
272
277
 
273
278
  const next = node.arguments[index + 1];
274
279
 
280
+ if (rewrite.keep.includes(index)) return [];
281
+
275
282
  return dropped === undefined || next === undefined
276
283
  ? []
277
284
  : [fixer.removeRange([dropped.range[0], next.range[0]])];
@@ -110,7 +110,7 @@ export const preferRangeForLoop: TSESLint.RuleModule<MessageIds, Options> = {
110
110
 
111
111
  // Only support positive integer steps
112
112
  if (typeof stepNum === 'number' && stepNum > 0) {
113
- mut_step = stepNum === 1 ? undefined : String(stepNum);
113
+ mut_step = stepNum === 1 ? undefined : stepNum.toString();
114
114
  } else {
115
115
  return;
116
116
  }
@@ -1,4 +1,5 @@
1
1
  import { type ESLintPlugin } from '../types.mjs';
2
+ import { noSideEffectImport } from './no-side-effect-import.mjs';
2
3
  import { noUnnecessaryTypeGuard } from './no-unnecessary-type-guard.mjs';
3
4
  import { preferArrIsArray } from './prefer-arr-is-array.mjs';
4
5
  import { preferArrSum } from './prefer-arr-sum.mjs';
@@ -26,6 +27,7 @@ export const tsDataForgeRules = {
26
27
  'prefer-is-record-and-has-key': preferIsRecordAndHasKey,
27
28
  'prefer-num-safe-parse-int': preferNumSafeParseInt,
28
29
  'prefer-num-safe-parse-float': preferNumSafeParseFloat,
30
+ 'no-side-effect-import': noSideEffectImport,
29
31
  'no-unnecessary-type-guard': noUnnecessaryTypeGuard,
30
32
  'prefer-comparison-over-nullish-guard': preferComparisonOverNullishGuard,
31
33
  'prefer-obj-over-entries-round-trip': preferObjOverEntriesRoundTrip,