eslint-plugin-ts-data-forge 0.5.3 → 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.
- package/README.md +1 -0
- package/dist/plugin.d.mts +2 -0
- package/dist/plugin.d.mts.map +1 -1
- package/dist/plugin.mjs +1 -0
- package/dist/plugin.mjs.map +1 -1
- package/dist/rule-types.d.mts +15 -0
- package/dist/rule-types.d.mts.map +1 -1
- package/dist/rules/ast-utils.mjs.map +1 -1
- package/dist/rules/branded-number-types.mjs.map +1 -1
- package/dist/rules/constants.mjs.map +1 -1
- package/dist/rules/import-utils.mjs.map +1 -1
- package/dist/rules/no-side-effect-import.d.mts +17 -0
- package/dist/rules/no-side-effect-import.d.mts.map +1 -0
- package/dist/rules/no-side-effect-import.mjs +41 -0
- package/dist/rules/no-side-effect-import.mjs.map +1 -0
- package/dist/rules/no-unnecessary-type-guard.mjs.map +1 -1
- package/dist/rules/prefer-arr-is-array.mjs.map +1 -1
- package/dist/rules/prefer-arr-is-bounded-length-array.mjs.map +1 -1
- package/dist/rules/prefer-arr-is-fixed-length-array.mjs.map +1 -1
- package/dist/rules/prefer-arr-is-max-length-array.mjs.map +1 -1
- package/dist/rules/prefer-arr-is-min-length-array.mjs.map +1 -1
- package/dist/rules/prefer-arr-is-non-empty.mjs.map +1 -1
- package/dist/rules/prefer-arr-sum.mjs.map +1 -1
- package/dist/rules/prefer-as-int.mjs.map +1 -1
- package/dist/rules/prefer-canonical-array-slicing.mjs.map +1 -1
- package/dist/rules/prefer-canonical-length-cast.mjs +1 -1
- package/dist/rules/prefer-canonical-length-cast.mjs.map +1 -1
- package/dist/rules/prefer-canonical-length-guard.mjs.map +1 -1
- package/dist/rules/prefer-comparison-over-nullish-guard.mjs.map +1 -1
- package/dist/rules/prefer-is-non-null-object.mjs.map +1 -1
- package/dist/rules/prefer-is-record-and-has-key.mjs.map +1 -1
- package/dist/rules/prefer-num-safe-parse-float.mjs.map +1 -1
- package/dist/rules/prefer-num-safe-parse-int.mjs.map +1 -1
- package/dist/rules/prefer-obj-over-entries-round-trip.mjs.map +1 -1
- package/dist/rules/prefer-range-for-loop.mjs +1 -1
- package/dist/rules/prefer-range-for-loop.mjs.map +1 -1
- package/dist/rules/rules.d.mts +1 -0
- package/dist/rules/rules.d.mts.map +1 -1
- package/dist/rules/rules.mjs +2 -0
- package/dist/rules/rules.mjs.map +1 -1
- package/package.json +8 -8
- package/src/plugin.mts +1 -0
- package/src/rule-types.mts +16 -0
- package/src/rules/no-side-effect-import.mts +71 -0
- package/src/rules/no-side-effect-import.test.mts +85 -0
- package/src/rules/prefer-canonical-length-cast.mts +9 -2
- package/src/rules/prefer-range-for-loop.mts +1 -1
- 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
|
-
|
|
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 :
|
|
113
|
+
mut_step = stepNum === 1 ? undefined : stepNum.toString();
|
|
114
114
|
} else {
|
|
115
115
|
return;
|
|
116
116
|
}
|
package/src/rules/rules.mts
CHANGED
|
@@ -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,
|