eslint-plugin-ts-data-forge 0.8.6 → 0.10.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 (70) hide show
  1. package/README.md +21 -19
  2. package/dist/plugin.d.mts +4 -0
  3. package/dist/plugin.d.mts.map +1 -1
  4. package/dist/plugin.mjs +2 -0
  5. package/dist/plugin.mjs.map +1 -1
  6. package/dist/rule-types.d.mts +31 -1
  7. package/dist/rule-types.d.mts.map +1 -1
  8. package/dist/rule-types.mjs.map +1 -1
  9. package/dist/rules/ast-utils.d.mts +21 -2
  10. package/dist/rules/ast-utils.d.mts.map +1 -1
  11. package/dist/rules/ast-utils.mjs +51 -4
  12. package/dist/rules/ast-utils.mjs.map +1 -1
  13. package/dist/rules/constants.d.mts +2 -0
  14. package/dist/rules/constants.d.mts.map +1 -1
  15. package/dist/rules/constants.mjs +9 -0
  16. package/dist/rules/constants.mjs.map +1 -1
  17. package/dist/rules/mutable-result.d.mts +10 -0
  18. package/dist/rules/mutable-result.d.mts.map +1 -0
  19. package/dist/rules/mutable-result.mjs +145 -0
  20. package/dist/rules/mutable-result.mjs.map +1 -0
  21. package/dist/rules/prefer-arr-generate.d.mts +57 -0
  22. package/dist/rules/prefer-arr-generate.d.mts.map +1 -0
  23. package/dist/rules/prefer-arr-generate.mjs +588 -0
  24. package/dist/rules/prefer-arr-generate.mjs.map +1 -0
  25. package/dist/rules/prefer-arr-uniq.d.mts.map +1 -1
  26. package/dist/rules/prefer-arr-uniq.mjs +2 -149
  27. package/dist/rules/prefer-arr-uniq.mjs.map +1 -1
  28. package/dist/rules/prefer-canonical-array-slicing.d.mts.map +1 -1
  29. package/dist/rules/prefer-canonical-array-slicing.mjs +47 -28
  30. package/dist/rules/prefer-canonical-array-slicing.mjs.map +1 -1
  31. package/dist/rules/prefer-is-non-null-object.d.mts.map +1 -1
  32. package/dist/rules/prefer-is-non-null-object.mjs +110 -40
  33. package/dist/rules/prefer-is-non-null-object.mjs.map +1 -1
  34. package/dist/rules/prefer-is-record-and-has-key.d.mts.map +1 -1
  35. package/dist/rules/prefer-is-record-and-has-key.mjs +102 -45
  36. package/dist/rules/prefer-is-record-and-has-key.mjs.map +1 -1
  37. package/dist/rules/prefer-pipe-map-nullable.d.mts +24 -0
  38. package/dist/rules/prefer-pipe-map-nullable.d.mts.map +1 -0
  39. package/dist/rules/prefer-pipe-map-nullable.mjs +266 -0
  40. package/dist/rules/prefer-pipe-map-nullable.mjs.map +1 -0
  41. package/dist/rules/prefer-range-for-loop.d.mts.map +1 -1
  42. package/dist/rules/prefer-range-for-loop.mjs +97 -16
  43. package/dist/rules/prefer-range-for-loop.mjs.map +1 -1
  44. package/dist/rules/rules.d.mts +2 -0
  45. package/dist/rules/rules.d.mts.map +1 -1
  46. package/dist/rules/rules.mjs +4 -0
  47. package/dist/rules/rules.mjs.map +1 -1
  48. package/package.json +11 -11
  49. package/src/plugin.mts +2 -0
  50. package/src/rule-types.mts +33 -1
  51. package/src/rules/ast-utils.mts +72 -5
  52. package/src/rules/constants.mts +12 -0
  53. package/src/rules/mutable-result.mts +204 -0
  54. package/src/rules/prefer-arr-generate.mts +918 -0
  55. package/src/rules/prefer-arr-generate.test.mts +967 -0
  56. package/src/rules/prefer-arr-is-bounded-length-array.test.mts +19 -0
  57. package/src/rules/prefer-arr-is-max-length-array.test.mts +8 -0
  58. package/src/rules/prefer-arr-is-min-length-array.test.mts +8 -0
  59. package/src/rules/prefer-arr-uniq.mts +2 -207
  60. package/src/rules/prefer-canonical-array-slicing.mts +57 -40
  61. package/src/rules/prefer-canonical-array-slicing.test.mts +55 -0
  62. package/src/rules/prefer-is-non-null-object.mts +160 -57
  63. package/src/rules/prefer-is-non-null-object.test.mts +138 -0
  64. package/src/rules/prefer-is-record-and-has-key.mts +148 -67
  65. package/src/rules/prefer-is-record-and-has-key.test.mts +118 -23
  66. package/src/rules/prefer-pipe-map-nullable.mts +391 -0
  67. package/src/rules/prefer-pipe-map-nullable.test.mts +470 -0
  68. package/src/rules/prefer-range-for-loop.mts +142 -21
  69. package/src/rules/prefer-range-for-loop.test.mts +127 -5
  70. package/src/rules/rules.mts +4 -0
package/README.md CHANGED
@@ -66,25 +66,27 @@ export default [
66
66
 
67
67
  ## Rules
68
68
 
69
- | Rule | Description |
70
- | -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
71
- | `prefer-canonical-array-slicing` | Unify non-mutating array add/remove patterns into `Arr.tail`/`skip`/`take`/etc. |
72
- | `prefer-canonical-length-guard` | Normalize array-length checks to the canonical `Arr` guard (`xs.length > 0` → `Arr.isNonEmpty`, `Arr.isFixedLengthArray(0, xs)` → `Arr.isEmpty`, `Arr.isFixedLengthTuple(0, xs)` → `Arr.isEmptyTuple`, …). |
73
- | `prefer-canonical-length-cast` | Normalize a degenerate `Arr` length cast to the canonical one (`Arr.asMinLengthArray(1, xs)` → `Arr.asNonEmptyArray(xs)`, `Arr.asBoundedLengthArray(n, n, xs)` → `Arr.asFixedLengthArray(n, xs)`, …). |
74
- | `prefer-arr-is-array` | Replace `Array.isArray` with `Arr.isArray`. |
75
- | `prefer-arr-scan` | Report an accumulated value rebuilt for every element (`xs.map((_, i) => f(...xs.slice(0, i + 1)))`, or a `reduce` that appends to its accumulator) and point at `Arr.scan`. Fixes the `reduce` form. |
76
- | `prefer-arr-sum` | Replace `xs.reduce((a, b) => a + b, 0)` with `Arr.sum(xs)` / `Arr.sumBy(xs, fn)`. |
77
- | `prefer-arr-uniq` | Replace `Array.from(new Set(xs))` / `[...new Set(xs)]` with `Arr.uniq(xs)` when `xs` is an array of primitives (type-aware). Suggests instead of fixing when the result is used as a mutable array. |
78
- | `prefer-as-int` | Replace branded-number assertions (`x as Int`) with `asInt(x)`-style casts. |
79
- | `prefer-is-non-null-object` | Replace `typeof u === 'object' && u !== null` with `isNonNullObject(u)`. |
80
- | `prefer-range-for-loop` | Replace C-style `for` loops with `for (const i of range(begin, end))`. |
81
- | `prefer-is-record-and-has-key` | Replace `Object.hasOwn(obj, key)` / `key in obj` with `isRecord(obj) && hasKey(…)`. |
82
- | `prefer-num-safe-parse-int` | Replace `parseInt(x, 10)` with `Result.unwrapOkOr(Num.safeParseInt(x), NaN)`. |
83
- | `prefer-num-safe-parse-float` | Replace `parseFloat(x)` / `Number(x)` with `Num.safeParseFloat`-based parsing. |
84
- | `no-unnecessary-type-guard` | Flag `ts-data-forge` type-guard calls that do no narrowing (type-aware). |
85
- | `prefer-comparison-over-nullish-guard` | Prefer direct `=== null` / `!== undefined` over `isNull` / `isNotUndefined` calls. |
86
- | `prefer-obj-over-entries-round-trip` | Replace an `Object.fromEntries(Object.entries(o).map/filter/flatMap(…))` round trip with `Obj.map` / `Obj.filter` / `Obj.filterMap`. |
87
- | `no-side-effect-import` | Remove a side-effect-only `import 'ts-data-forge';`; the package declares `sideEffects: false`, so it binds no name and does nothing. |
69
+ | Rule | Description |
70
+ | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
71
+ | `prefer-canonical-array-slicing` | Unify non-mutating array add/remove patterns into `Arr.tail`/`skip`/`take`/etc. |
72
+ | `prefer-canonical-length-guard` | Normalize array-length checks to the canonical `Arr` guard (`xs.length > 0` → `Arr.isNonEmpty`, `Arr.isFixedLengthArray(0, xs)` → `Arr.isEmpty`, `Arr.isFixedLengthTuple(0, xs)` → `Arr.isEmptyTuple`, …). |
73
+ | `prefer-canonical-length-cast` | Normalize a degenerate `Arr` length cast to the canonical one (`Arr.asMinLengthArray(1, xs)` → `Arr.asNonEmptyArray(xs)`, `Arr.asBoundedLengthArray(n, n, xs)` → `Arr.asFixedLengthArray(n, xs)`, …). |
74
+ | `prefer-arr-generate` | Replace the filter-and-map idiom `xs.flatMap((x) => (cond ? [f(x)] : []))` with a `for…of` loop in `Arr.generate` (type-aware). Suggests instead of fixing when the result is used as a mutable array, when a type annotation, a type wrapper or a comment would be dropped, when the receiver relies on a narrowing the generator function would not see, or when it is a `filter()` call. |
75
+ | `prefer-arr-is-array` | Replace `Array.isArray` with `Arr.isArray`. |
76
+ | `prefer-arr-scan` | Report an accumulated value rebuilt for every element (`xs.map((_, i) => f(...xs.slice(0, i + 1)))`, or a `reduce` that appends to its accumulator) and point at `Arr.scan`. Fixes the `reduce` form. |
77
+ | `prefer-arr-sum` | Replace `xs.reduce((a, b) => a + b, 0)` with `Arr.sum(xs)` / `Arr.sumBy(xs, fn)`. |
78
+ | `prefer-arr-uniq` | Replace `Array.from(new Set(xs))` / `[...new Set(xs)]` with `Arr.uniq(xs)` when `xs` is an array of primitives (type-aware). Suggests instead of fixing when the result is used as a mutable array. |
79
+ | `prefer-as-int` | Replace branded-number assertions (`x as Int`) with `asInt(x)`-style casts. |
80
+ | `prefer-is-non-null-object` | Replace `typeof u === 'object' && u !== null` with `isNonNullObject(u)`. |
81
+ | `prefer-range-for-loop` | Replace C-style `for` loops with `for (const i of range(begin, end))`. |
82
+ | `prefer-is-record-and-has-key` | Replace `Object.hasOwn(obj, key)` / `key in obj` with `isRecord(obj) && hasKey(…)`. |
83
+ | `prefer-num-safe-parse-int` | Replace `parseInt(x, 10)` with `Result.unwrapOkOr(Num.safeParseInt(x), NaN)`. |
84
+ | `prefer-num-safe-parse-float` | Replace `parseFloat(x)` / `Number(x)` with `Num.safeParseFloat`-based parsing. |
85
+ | `no-unnecessary-type-guard` | Flag `ts-data-forge` type-guard calls that do no narrowing (type-aware). |
86
+ | `prefer-comparison-over-nullish-guard` | Prefer direct `=== null` / `!== undefined` over `isNull` / `isNotUndefined` calls. |
87
+ | `prefer-obj-over-entries-round-trip` | Replace an `Object.fromEntries(Object.entries(o).map/filter/flatMap(…))` round trip with `Obj.map` / `Obj.filter` / `Obj.filterMap`. |
88
+ | `prefer-pipe-map-nullable` | Replace `pipe(x).map(mapNullable(fn))` with `pipe(x).mapNullable(fn)`. Suggests instead of fixing when an inline function's inferred result type has a literal or tuple part (which `mapNullable`'s `const` type parameter keeps and `Pipe.mapNullable` widens), or when a comment or type assertion would be dropped. |
89
+ | `no-side-effect-import` | Remove a side-effect-only `import 'ts-data-forge';`; the package declares `sideEffects: false`, so it binds no name and does nothing. |
88
90
 
89
91
  ## License
90
92
 
package/dist/plugin.d.mts CHANGED
@@ -7,6 +7,7 @@ export declare const eslintPluginTsDataForge: {
7
7
  readonly 'prefer-canonical-array-slicing': import("@typescript-eslint/utils/ts-eslint").RuleModule<"preferCanonicalArraySlicing", readonly [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
8
8
  readonly 'prefer-canonical-length-guard': import("@typescript-eslint/utils/ts-eslint").RuleModule<"useCanonicalGuard" | "useIsBoundedLengthArray" | "useIsFixedLengthArray" | "useIsMaxLengthArray" | "useIsMinLengthArray" | "useIsNonEmpty", readonly [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
9
9
  readonly 'prefer-canonical-length-cast': import("@typescript-eslint/utils/ts-eslint").RuleModule<"useCanonicalCast", readonly [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
10
+ readonly 'prefer-arr-generate': import("@typescript-eslint/utils/ts-eslint").RuleModule<"suggestArrGenerate" | "useArrGenerate", readonly [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
10
11
  readonly 'prefer-arr-is-array': import("@typescript-eslint/utils/ts-eslint").RuleModule<"useArrIsArray", readonly [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
11
12
  readonly 'prefer-arr-scan': import("@typescript-eslint/utils/ts-eslint").RuleModule<"preferArrScanAccumulate" | "preferArrScanPrefix", readonly [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
12
13
  readonly 'prefer-arr-sum': import("@typescript-eslint/utils/ts-eslint").RuleModule<"useArrSum" | "useArrSumBy", readonly [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
@@ -23,6 +24,7 @@ export declare const eslintPluginTsDataForge: {
23
24
  }> | undefined)?], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
24
25
  readonly 'prefer-comparison-over-nullish-guard': import("@typescript-eslint/utils/ts-eslint").RuleModule<"preferComparison", readonly [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
25
26
  readonly 'prefer-obj-over-entries-round-trip': import("@typescript-eslint/utils/ts-eslint").RuleModule<"useObjFilter" | "useObjFilterMap" | "useObjMap", readonly [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
27
+ readonly 'prefer-pipe-map-nullable': import("@typescript-eslint/utils/ts-eslint").RuleModule<"suggestMapNullable" | "useMapNullable", readonly [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
26
28
  };
27
29
  readonly configs: {
28
30
  /** Enables every rule of this plugin at `error`. */
@@ -35,6 +37,7 @@ export declare const eslintPluginTsDataForge: {
35
37
  readonly 'ts-data-forge/prefer-canonical-array-slicing': 'error';
36
38
  readonly 'ts-data-forge/prefer-canonical-length-cast': 'error';
37
39
  readonly 'ts-data-forge/prefer-canonical-length-guard': 'error';
40
+ readonly 'ts-data-forge/prefer-arr-generate': 'error';
38
41
  readonly 'ts-data-forge/prefer-arr-is-array': 'error';
39
42
  readonly 'ts-data-forge/prefer-arr-scan': 'error';
40
43
  readonly 'ts-data-forge/prefer-arr-sum': 'error';
@@ -49,6 +52,7 @@ export declare const eslintPluginTsDataForge: {
49
52
  readonly 'ts-data-forge/no-unnecessary-type-guard': 'error';
50
53
  readonly 'ts-data-forge/prefer-comparison-over-nullish-guard': 'error';
51
54
  readonly 'ts-data-forge/prefer-obj-over-entries-round-trip': 'error';
55
+ readonly 'ts-data-forge/prefer-pipe-map-nullable': 'error';
52
56
  };
53
57
  };
54
58
  };
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.mts","sourceRoot":"","sources":["../src/plugin.mts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAoB,YAAY,EAAE,MAAM,aAAa,CAAC;AAgDlE,eAAO,MAAM,uBAAuB;;iBAEhC,IAAI,EAAE,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;QAInC,oDAAoD;iBACpD,WAAW;2BAtBP,2BAA2B;;yBAQ3B,eAAe,EAAI,YAAY;;;yEA/BW,OAAO;uEACT,OAAO;wEACN,OAAO;8DACjB,OAAO;0DACX,OAAO;yDACR,OAAO;0DACN,OAAO;wDACT,OAAO;oEACK,OAAO;gEACX,OAAO;uEACA,OAAO;oEACV,OAAO;sEACL,OAAO;gEACb,OAAO;oEACH,OAAO;+EACI,OAAO;6EACT,OAAO;;;;CA+B5B,CAAC"}
1
+ {"version":3,"file":"plugin.d.mts","sourceRoot":"","sources":["../src/plugin.mts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAoB,YAAY,EAAE,MAAM,aAAa,CAAC;AAkDlE,eAAO,MAAM,uBAAuB;;iBAEhC,IAAI,EAAE,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;QAInC,oDAAoD;iBACpD,WAAW;2BAtBP,2BAA2B;;yBAQ3B,eAAe,EAAI,YAAY;;;yEAjCW,OAAO;uEACT,OAAO;wEACN,OAAO;8DACjB,OAAO;8DACP,OAAO;0DACX,OAAO;yDACR,OAAO;0DACN,OAAO;wDACT,OAAO;oEACK,OAAO;gEACX,OAAO;uEACA,OAAO;oEACV,OAAO;sEACL,OAAO;gEACb,OAAO;oEACH,OAAO;+EACI,OAAO;6EACT,OAAO;mEACjB,OAAO;;;;CA+BlB,CAAC"}
package/dist/plugin.mjs CHANGED
@@ -10,6 +10,7 @@ const recommendedRules = {
10
10
  'ts-data-forge/prefer-canonical-array-slicing': 'error',
11
11
  'ts-data-forge/prefer-canonical-length-cast': 'error',
12
12
  'ts-data-forge/prefer-canonical-length-guard': 'error',
13
+ 'ts-data-forge/prefer-arr-generate': 'error',
13
14
  'ts-data-forge/prefer-arr-is-array': 'error',
14
15
  'ts-data-forge/prefer-arr-scan': 'error',
15
16
  'ts-data-forge/prefer-arr-sum': 'error',
@@ -24,6 +25,7 @@ const recommendedRules = {
24
25
  'ts-data-forge/no-unnecessary-type-guard': 'error',
25
26
  'ts-data-forge/prefer-comparison-over-nullish-guard': 'error',
26
27
  'ts-data-forge/prefer-obj-over-entries-round-trip': 'error',
28
+ 'ts-data-forge/prefer-pipe-map-nullable': 'error',
27
29
  };
28
30
  const recommendedConfig = {
29
31
  name: 'ts-data-forge/recommended',
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.mjs","sourceRoot":"","sources":["../src/plugin.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGrD;;;;;;GAMG;AACH,MAAM,gBAAgB,GAAG;IACvB,8CAA8C,EAAE,OAAO;IACvD,4CAA4C,EAAE,OAAO;IACrD,6CAA6C,EAAE,OAAO;IACtD,mCAAmC,EAAE,OAAO;IAC5C,+BAA+B,EAAE,OAAO;IACxC,8BAA8B,EAAE,OAAO;IACvC,+BAA+B,EAAE,OAAO;IACxC,6BAA6B,EAAE,OAAO;IACtC,yCAAyC,EAAE,OAAO;IAClD,qCAAqC,EAAE,OAAO;IAC9C,4CAA4C,EAAE,OAAO;IACrD,yCAAyC,EAAE,OAAO;IAClD,2CAA2C,EAAE,OAAO;IACpD,qCAAqC,EAAE,OAAO;IAC9C,yCAAyC,EAAE,OAAO;IAClD,oDAAoD,EAAE,OAAO;IAC7D,kDAAkD,EAAE,OAAO;CAI5D,CAAC;AAEF,MAAM,iBAAiB,GAAG;IACxB,IAAI,EAAE,2BAA2B;IACjC,OAAO,EAAE;QACP,uEAAuE;QACvE,yEAAyE;QACzE,wEAAwE;QACxE,mDAAmD;QACnD,0EAA0E;QAC1E,wDAAwD;QACxD,IAAI,eAAe;YACjB,OAAO,uBAAuB,CAAC;QACjC,CAAC;KACF;IACD,KAAK,EAAE,gBAAgB;CACY,CAAC;AAEtC,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,IAAI,EAAE;QACJ,IAAI,EAAE,6BAA6B;KACpC;IACD,KAAK,EAAE,gBAAgB;IACvB,OAAO,EAAE;QACP,oDAAoD;QACpD,WAAW,EAAE,iBAAiB;KAC/B;CAC8B,CAAC"}
1
+ {"version":3,"file":"plugin.mjs","sourceRoot":"","sources":["../src/plugin.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGrD;;;;;;GAMG;AACH,MAAM,gBAAgB,GAAG;IACvB,8CAA8C,EAAE,OAAO;IACvD,4CAA4C,EAAE,OAAO;IACrD,6CAA6C,EAAE,OAAO;IACtD,mCAAmC,EAAE,OAAO;IAC5C,mCAAmC,EAAE,OAAO;IAC5C,+BAA+B,EAAE,OAAO;IACxC,8BAA8B,EAAE,OAAO;IACvC,+BAA+B,EAAE,OAAO;IACxC,6BAA6B,EAAE,OAAO;IACtC,yCAAyC,EAAE,OAAO;IAClD,qCAAqC,EAAE,OAAO;IAC9C,4CAA4C,EAAE,OAAO;IACrD,yCAAyC,EAAE,OAAO;IAClD,2CAA2C,EAAE,OAAO;IACpD,qCAAqC,EAAE,OAAO;IAC9C,yCAAyC,EAAE,OAAO;IAClD,oDAAoD,EAAE,OAAO;IAC7D,kDAAkD,EAAE,OAAO;IAC3D,wCAAwC,EAAE,OAAO;CAIlD,CAAC;AAEF,MAAM,iBAAiB,GAAG;IACxB,IAAI,EAAE,2BAA2B;IACjC,OAAO,EAAE;QACP,uEAAuE;QACvE,yEAAyE;QACzE,wEAAwE;QACxE,mDAAmD;QACnD,0EAA0E;QAC1E,wDAAwD;QACxD,IAAI,eAAe;YACjB,OAAO,uBAAuB,CAAC;QACjC,CAAC;KACF;IACD,KAAK,EAAE,gBAAgB;CACY,CAAC;AAEtC,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,IAAI,EAAE;QACJ,IAAI,EAAE,6BAA6B;KACpC;IACD,KAAK,EAAE,gBAAgB;IACvB,OAAO,EAAE;QACP,oDAAoD;QACpD,WAAW,EAAE,iBAAiB;KAC/B;CAC8B,CAAC"}
@@ -50,6 +50,20 @@ declare namespace PreferCanonicalLengthGuard {
50
50
  declare namespace PreferCanonicalLengthCast {
51
51
  type RuleEntry = Linter.StringSeverity;
52
52
  }
53
+ /**
54
+ * @description Replace the filter-and-map idiom `xs.flatMap((x) => (cond ? [f(x)] : []))` with a loop in `Arr.generate` from ts-data-forge.
55
+ *
56
+ * ```md
57
+ * | key | value |
58
+ * | :--------- | :--------- |
59
+ * | type | suggestion |
60
+ * | deprecated | false |
61
+ * | fixable | code |
62
+ * ```
63
+ */
64
+ declare namespace PreferArrGenerate {
65
+ type RuleEntry = Linter.StringSeverity;
66
+ }
53
67
  /**
54
68
  * @description Replace `Array.isArray` with `Arr.isArray` from ts-data-forge.
55
69
  *
@@ -121,7 +135,7 @@ declare namespace PreferAsInt {
121
135
  type RuleEntry = Linter.StringSeverity;
122
136
  }
123
137
  /**
124
- * @description Replace `typeof u === "object" && u !== null` with `isNonNullObject(u)` from ts-data-forge.
138
+ * @description Replace `typeof u === "object" && u !== null`, in either order and anywhere in an `&&` chain, with `isNonNullObject(u)` from ts-data-forge.
125
139
  *
126
140
  * ```md
127
141
  * | key | value |
@@ -268,10 +282,25 @@ declare namespace PreferComparisonOverNullishGuard {
268
282
  declare namespace PreferObjOverEntriesRoundTrip {
269
283
  type RuleEntry = Linter.StringSeverity;
270
284
  }
285
+ /**
286
+ * @description Replace `pipe(x).map(mapNullable(fn))` with `pipe(x).mapNullable(fn)`.
287
+ *
288
+ * ```md
289
+ * | key | value |
290
+ * | :--------- | :--------- |
291
+ * | type | suggestion |
292
+ * | deprecated | false |
293
+ * | fixable | code |
294
+ * ```
295
+ */
296
+ declare namespace PreferPipeMapNullable {
297
+ type RuleEntry = Linter.StringSeverity;
298
+ }
271
299
  export type EslintTsDataForgeRules = Readonly<{
272
300
  'ts-data-forge/prefer-canonical-array-slicing': PreferCanonicalArraySlicing.RuleEntry;
273
301
  'ts-data-forge/prefer-canonical-length-guard': PreferCanonicalLengthGuard.RuleEntry;
274
302
  'ts-data-forge/prefer-canonical-length-cast': PreferCanonicalLengthCast.RuleEntry;
303
+ 'ts-data-forge/prefer-arr-generate': PreferArrGenerate.RuleEntry;
275
304
  'ts-data-forge/prefer-arr-is-array': PreferArrIsArray.RuleEntry;
276
305
  'ts-data-forge/prefer-arr-scan': PreferArrScan.RuleEntry;
277
306
  'ts-data-forge/prefer-arr-sum': PreferArrSum.RuleEntry;
@@ -286,6 +315,7 @@ export type EslintTsDataForgeRules = Readonly<{
286
315
  'ts-data-forge/no-unnecessary-type-guard': NoUnnecessaryTypeGuard.RuleEntry;
287
316
  'ts-data-forge/prefer-comparison-over-nullish-guard': PreferComparisonOverNullishGuard.RuleEntry;
288
317
  'ts-data-forge/prefer-obj-over-entries-round-trip': PreferObjOverEntriesRoundTrip.RuleEntry;
318
+ 'ts-data-forge/prefer-pipe-map-nullable': PreferPipeMapNullable.RuleEntry;
289
319
  }>;
290
320
  export type EslintTsDataForgeRulesOption = Readonly<{
291
321
  'ts-data-forge/no-unnecessary-type-guard': NoUnnecessaryTypeGuard.Options;
@@ -1 +1 @@
1
- {"version":3,"file":"rule-types.d.mts","sourceRoot":"","sources":["../src/rule-types.mts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rule-types.d.mts","sourceRoot":"","sources":["../src/rule-types.mts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"rule-types.mjs","sourceRoot":"","sources":["../src/rule-types.mts"],"names":[],"mappings":"AAAA,oBAAoB;AAOpB,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAyU3C,8EAA8E;AAC9E,8DAA8D;AAC9D,UAAU,CAGR,GAAG,CAAC,CAAC"}
1
+ {"version":3,"file":"rule-types.mjs","sourceRoot":"","sources":["../src/rule-types.mts"],"names":[],"mappings":"AAAA,oBAAoB;AAOpB,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAyW3C,8EAA8E;AAC9E,8DAA8D;AAC9D,UAAU,CAGR,GAAG,CAAC,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { type TSESLint, type TSESTree } from '@typescript-eslint/utils';
2
2
  import type { DeepReadonly } from 'ts-type-forge';
3
+ import type * as ts from 'typescript';
3
4
  /**
4
5
  * Whether `node` is an array or a tuple at every layer of type wrappers (see
5
6
  * {@link typeWrapperLayers}): a cast does not make a string an array, and the
@@ -33,21 +34,39 @@ type LengthComparison = Readonly<{
33
34
  * Parses a `<array>.length <op> <bound>` comparison (in either operand order)
34
35
  * into its array expression, integer-literal/`const` `bound`, and whether it is
35
36
  * a lower (`min`) or upper (`max`) length bound. Returns `undefined` for
36
- * anything else. The length and the bound are read through type wrappers; the
37
+ * anything else. The comparison, the length and the bound are read through
38
+ * type wrappers; the
37
39
  * `bound` returned is the literal or constant underneath, since a wrapper such
38
40
  * as `as number` would only widen the length a guard narrows to.
39
41
  *
40
42
  * - `xs.length >= n` / `n <= xs.length` → `min`
41
43
  * - `xs.length <= n` / `n >= xs.length` → `max`
42
44
  */
43
- export declare const parseLengthComparison: (node: TSESTree.Expression, sourceCode: TSESLint.SourceCode) => LengthComparison | undefined;
45
+ export declare const parseLengthComparison: (wrapped: TSESTree.Expression, sourceCode: TSESLint.SourceCode) => LengthComparison | undefined;
44
46
  /**
45
47
  * `true` when `node` is one operand of an `a && b` whose other operand is the
46
48
  * complementary length bound (`min` vs `max`) on the same array — i.e. the two
47
49
  * together form the `Arr.isBoundedLengthArray` pattern handled by
48
50
  * `prefer-arr-is-bounded-length-array`. The single-bound rules skip such
49
51
  * operands so the bounded rule rewrites the whole `&&` instead of the parts.
52
+ * A comparison wrapped as a whole (`(xs.length >= 1 satisfies boolean) && …`)
53
+ * is still the operand.
50
54
  */
51
55
  export declare const isPartOfBoundedLengthCheck: (node: TSESTree.BinaryExpression, sourceCode: TSESLint.SourceCode) => boolean;
56
+ /**
57
+ * Whether `node`, read through its type wrappers, is the identifier `name`:
58
+ * `Number`, `(Number as NumberConstructor)` and `Number!` are the same object.
59
+ */
60
+ export declare const isIdentifierNamed: (node: TSESTree.Node, name: string) => boolean;
61
+ /**
62
+ * Whether `holds` is true of the type of every layer of type wrappers around
63
+ * `node` (see {@link typeWrapperLayers}), outermost to innermost; `false`
64
+ * without type information. A widening cast (`s as string | number`) is the
65
+ * author saying the value may be more than it is, and is respected; a
66
+ * narrowing one (`s!`, `v as unknown as string`) cannot vouch for what the
67
+ * value's own type does not, and the fix, which keeps the wrapper, has to
68
+ * type-check at every layer too.
69
+ */
70
+ export declare const typeHoldsAtEveryLayer: (sourceCode: TSESLint.SourceCode, node: TSESTree.Node, holds: (type: ts.Type, typeChecker: ts.TypeChecker) => boolean) => boolean;
52
71
  export {};
53
72
  //# sourceMappingURL=ast-utils.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ast-utils.d.mts","sourceRoot":"","sources":["../../src/rules/ast-utils.mts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,QAAQ,EACd,MAAM,0BAA0B,CAAC;AAMlC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAOlD;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,aAEzB,QAAQ,CAAC,UAAU,CAAC,gBAAgB,CAAC,QAEzC,QAAQ,CAAC,UAAU,KACxB,OAkBF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,0BAA0B,SAC/B,YAAY,CAAC,QAAQ,CAAC,UAAU,CAAC,cAE3B,QAAQ,CAAC,UAAU,KAC9B,OA0CF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,SAEnB,QAAQ,CAAC,UAAU,KACxB,QAAQ,CAAC,gBAAgB,GAAG,SAS9B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,eAAe,MAEvB,QAAQ,CAAC,UAAU,KAEnB,QAAQ,CAAC,UAAU,cAEV,QAAQ,CAAC,UAAU,KAC9B,OAEsC,CAAC;AAE1C,KAAK,gBAAgB,GAAG,QAAQ,CAAC;IAC/B,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC;IAC3B,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC;IAC3B,IAAI,EAAE,KAAK,GAAG,KAAK,CAAC;CACrB,CAAC,CAAC;AAEH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,SAE1B,QAAQ,CAAC,UAAU,cAEb,QAAQ,CAAC,UAAU,KAC9B,gBAAgB,GAAG,SAqCrB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,SAE/B,QAAQ,CAAC,gBAAgB,cAEnB,QAAQ,CAAC,UAAU,KAC9B,OA4BF,CAAC"}
1
+ {"version":3,"file":"ast-utils.d.mts","sourceRoot":"","sources":["../../src/rules/ast-utils.mts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,QAAQ,EACd,MAAM,0BAA0B,CAAC;AAMlC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAOtC;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,aAEzB,QAAQ,CAAC,UAAU,CAAC,gBAAgB,CAAC,QAEzC,QAAQ,CAAC,UAAU,KACxB,OAkBF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,0BAA0B,SAC/B,YAAY,CAAC,QAAQ,CAAC,UAAU,CAAC,cAE3B,QAAQ,CAAC,UAAU,KAC9B,OA0CF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,SAEnB,QAAQ,CAAC,UAAU,KACxB,QAAQ,CAAC,gBAAgB,GAAG,SAS9B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,eAAe,MAEvB,QAAQ,CAAC,UAAU,KAEnB,QAAQ,CAAC,UAAU,cAEV,QAAQ,CAAC,UAAU,KAC9B,OAEsC,CAAC;AAE1C,KAAK,gBAAgB,GAAG,QAAQ,CAAC;IAC/B,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC;IAC3B,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC;IAC3B,IAAI,EAAE,KAAK,GAAG,KAAK,CAAC;CACrB,CAAC,CAAC;AAEH;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,qBAAqB,YAEvB,QAAQ,CAAC,UAAU,cAEhB,QAAQ,CAAC,UAAU,KAC9B,gBAAgB,GAAG,SAuCrB,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,0BAA0B,SAE/B,QAAQ,CAAC,gBAAgB,cAEnB,QAAQ,CAAC,UAAU,KAC9B,OA8BF,CAAC;AAuBF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,SAEtB,QAAQ,CAAC,IAAI,QACb,MAAM,KACX,OAMF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,eAEpB,QAAQ,CAAC,UAAU,QAEzB,QAAQ,CAAC,IAAI,SAEZ,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,CAAC,WAAW,KAAK,OAAO,KAC7D,OAgBF,CAAC"}
@@ -106,11 +106,13 @@ sourceCode) => sourceCode.getText(skipTypeWrappers(a)) ===
106
106
 
107
107
 
108
108
 
109
+
109
110
  export const parseLengthComparison = (
110
111
 
111
- node,
112
+ wrapped,
112
113
 
113
114
  sourceCode) => {
115
+ const node = skipTypeWrappers(wrapped);
114
116
  if (node.type !== AST_NODE_TYPES.BinaryExpression ||
115
117
  (node.operator !== '>=' && node.operator !== '<=')) {
116
118
  return undefined;
@@ -142,13 +144,16 @@ sourceCode) => {
142
144
 
143
145
 
144
146
 
147
+
148
+
145
149
  export const isPartOfBoundedLengthCheck = (
146
150
 
147
151
  node,
148
152
 
149
153
  sourceCode) => {
150
- const { parent } = node;
151
- if (parent.type !== AST_NODE_TYPES.LogicalExpression ||
154
+ const operand = outermostTypeWrapper(node);
155
+ const { parent } = operand;
156
+ if (parent?.type !== AST_NODE_TYPES.LogicalExpression ||
152
157
  parent.operator !== '&&') {
153
158
  return false;
154
159
  }
@@ -156,7 +161,7 @@ sourceCode) => {
156
161
  if (self === undefined) {
157
162
  return false;
158
163
  }
159
- const sibling = parent.left === node ? parent.right : parent.left;
164
+ const sibling = parent.left === operand ? parent.right : parent.left;
160
165
  const other = parseLengthComparison(sibling, sourceCode);
161
166
  if (other === undefined) {
162
167
  return false;
@@ -164,7 +169,49 @@ sourceCode) => {
164
169
  return (self.kind !== other.kind &&
165
170
  isSameArrayText(self.array, other.array, sourceCode));
166
171
  };
172
+
173
+ const outermostTypeWrapper = (
174
+
175
+ node) => node.parent !== undefined && isTypeWrapper(node.parent)
176
+ ? outermostTypeWrapper(node.parent)
177
+ : node;
167
178
  const isVariableDefinition = (
168
179
 
169
180
  def) => def.type === 'Variable';
181
+
182
+
183
+
184
+
185
+ export const isIdentifierNamed = (
186
+
187
+ node, name) => {
188
+ const unwrapped = skipTypeWrappers(node);
189
+ return (unwrapped.type === AST_NODE_TYPES.Identifier && unwrapped.name === name);
190
+ };
191
+
192
+
193
+
194
+
195
+
196
+
197
+
198
+
199
+
200
+ export const typeHoldsAtEveryLayer = (
201
+
202
+ sourceCode,
203
+
204
+ node,
205
+
206
+ holds) => {
207
+ const services = sourceCode.parserServices;
208
+ const checker = services?.program?.getTypeChecker();
209
+ if (checker === undefined) {
210
+ return false;
211
+ }
212
+ return typeWrapperLayers(node).every((layer) => {
213
+ const tsNode = services?.esTreeNodeToTSNodeMap?.get(layer);
214
+ return (tsNode !== undefined && holds(checker.getTypeAtLocation(tsNode), checker));
215
+ });
216
+ };
170
217
  //# sourceMappingURL=ast-utils.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ast-utils.mjs","sourceRoot":"","sources":["../../src/rules/ast-utils.mts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ast-utils.mjs","sourceRoot":"","sources":["../../src/rules/ast-utils.mts"],"names":[],"mappings":"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"}
@@ -1,2 +1,4 @@
1
1
  export declare const TS_DATA_FORGE_MODULE = "ts-data-forge";
2
+ /** The type flags of every primitive type but `void`. */
3
+ export declare const primitiveTypeFlags: number;
2
4
  //# sourceMappingURL=constants.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.mts","sourceRoot":"","sources":["../../src/rules/constants.mts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,kBAAkB,CAAC"}
1
+ {"version":3,"file":"constants.d.mts","sourceRoot":"","sources":["../../src/rules/constants.mts"],"names":[],"mappings":"AAEA,eAAO,MAAM,oBAAoB,kBAAkB,CAAC;AAEpD,yDAAyD;AACzD,eAAO,MAAM,kBAAkB,QAOP,CAAC"}
@@ -1,2 +1,11 @@
1
+ import * as ts from 'typescript';
1
2
  export const TS_DATA_FORGE_MODULE = 'ts-data-forge';
3
+
4
+ export const primitiveTypeFlags = ts.TypeFlags.StringLike |
5
+ ts.TypeFlags.NumberLike |
6
+ ts.TypeFlags.BigIntLike |
7
+ ts.TypeFlags.BooleanLike |
8
+ ts.TypeFlags.ESSymbolLike |
9
+ ts.TypeFlags.Null |
10
+ ts.TypeFlags.Undefined;
2
11
  //# sourceMappingURL=constants.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.mjs","sourceRoot":"","sources":["../../src/rules/constants.mts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,oBAAoB,GAAG,eAAe,CAAC"}
1
+ {"version":3,"file":"constants.mjs","sourceRoot":"","sources":["../../src/rules/constants.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,MAAM,CAAC,MAAM,oBAAoB,GAAG,eAAe,CAAC;AAEpD,yDAAyD;AACzD,MAAM,CAAC,MAAM,kBAAkB,GAC7B,EAAE,CAAC,SAAS,CAAC,UAAU;IACvB,EAAE,CAAC,SAAS,CAAC,UAAU;IACvB,EAAE,CAAC,SAAS,CAAC,UAAU;IACvB,EAAE,CAAC,SAAS,CAAC,WAAW;IACxB,EAAE,CAAC,SAAS,CAAC,YAAY;IACzB,EAAE,CAAC,SAAS,CAAC,IAAI;IACjB,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { type TSESLint, type TSESTree } from '@typescript-eslint/utils';
2
+ import * as ts from 'typescript';
3
+ /**
4
+ * Whether the code around `node` visibly relies on the result being a mutable
5
+ * array, so that swapping in the readonly array `Arr.uniq` or `Arr.generate`
6
+ * returns would not compile. Looks at `node` itself and, when it initializes a variable without a
7
+ * type annotation, at every read of that variable.
8
+ */
9
+ export declare const needsMutableResult: (sourceCode: TSESLint.SourceCode, checker: ts.TypeChecker, getTsNode: (esNode: TSESTree.Node) => ts.Node | undefined, node: TSESTree.Node) => boolean;
10
+ //# sourceMappingURL=mutable-result.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutable-result.d.mts","sourceRoot":"","sources":["../../src/rules/mutable-result.mts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,QAAQ,EACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAGjC;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,eAEjB,QAAQ,CAAC,UAAU,WAEtB,EAAE,CAAC,WAAW,aAEZ,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,KAAK,EAAE,CAAC,IAAI,GAAG,SAAS,QAEnD,QAAQ,CAAC,IAAI,KAClB,OA+BF,CAAC"}
@@ -0,0 +1,145 @@
1
+ import { AST_NODE_TYPES, } from '@typescript-eslint/utils';
2
+ import * as ts from 'typescript';
3
+ import { primitiveTypeFlags } from './constants.mjs';
4
+
5
+
6
+
7
+
8
+
9
+
10
+ export const needsMutableResult = (
11
+
12
+ sourceCode,
13
+
14
+ checker,
15
+
16
+ getTsNode,
17
+
18
+ node) => {
19
+ const outer = outermostTypePreservingWrapper(node);
20
+ if (isUsedAsMutable(checker, getTsNode, outer)) {
21
+ return true;
22
+ }
23
+ const parent = outer.parent;
24
+ if (parent?.type !== AST_NODE_TYPES.VariableDeclarator ||
25
+ parent.init !== outer ||
26
+ parent.id.type !== AST_NODE_TYPES.Identifier ||
27
+ parent.id.typeAnnotation !== undefined) {
28
+ return false;
29
+ }
30
+ const [variable] = sourceCode.getDeclaredVariables(parent);
31
+ return (variable?.references.some((reference) => reference.init !== true &&
32
+ isUsedAsMutable(checker, getTsNode, outermostTypePreservingWrapper(reference.identifier))) ?? false);
33
+ };
34
+
35
+
36
+
37
+
38
+
39
+
40
+ const outermostTypePreservingWrapper = (
41
+
42
+ node) => {
43
+ const { parent } = node;
44
+ return parent !== undefined &&
45
+ (parent.type === AST_NODE_TYPES.TSNonNullExpression ||
46
+ parent.type === AST_NODE_TYPES.TSSatisfiesExpression) &&
47
+ parent.expression === node
48
+ ? outermostTypePreservingWrapper(parent)
49
+ : node;
50
+ };
51
+ const isUsedAsMutable = (
52
+
53
+ checker,
54
+
55
+ getTsNode,
56
+
57
+ node) => {
58
+ const parent = node.parent;
59
+ if (parent?.type === AST_NODE_TYPES.MemberExpression &&
60
+ parent.object === node) {
61
+
62
+ if (!parent.computed &&
63
+ parent.property.type === AST_NODE_TYPES.Identifier &&
64
+ mutatingMethods.has(parent.property.name)) {
65
+ return true;
66
+ }
67
+
68
+ const grandParent = parent.parent;
69
+ return ((grandParent.type === AST_NODE_TYPES.AssignmentExpression &&
70
+ grandParent.left === parent) ||
71
+ grandParent.type === AST_NODE_TYPES.UpdateExpression ||
72
+ (grandParent.type === AST_NODE_TYPES.UnaryExpression &&
73
+ grandParent.operator === 'delete'));
74
+ }
75
+
76
+
77
+ const tsNode = getTsNode(node);
78
+ if (tsNode === undefined) {
79
+ return false;
80
+ }
81
+ if (!ts.isExpression(tsNode)) {
82
+ return false;
83
+ }
84
+ const expectedType = getDeclaredParameterType(checker, tsNode) ??
85
+ checker.getContextualType(tsNode);
86
+ return (expectedType !== undefined && isMutableArrayOnly(checker, expectedType));
87
+ };
88
+
89
+
90
+
91
+
92
+
93
+
94
+
95
+
96
+ const getDeclaredParameterType = (
97
+
98
+ checker,
99
+
100
+ argument) => {
101
+ const call = argument.parent;
102
+ if (!ts.isCallExpression(call) && !ts.isNewExpression(call)) {
103
+ return undefined;
104
+ }
105
+ const index = call.arguments?.indexOf(argument) ?? -1;
106
+ if (index === -1) {
107
+ return undefined;
108
+ }
109
+ const declaration = checker.getResolvedSignature(call)?.getDeclaration();
110
+ const parameter = declaration?.parameters[index];
111
+
112
+
113
+ return parameter === undefined || parameter.dotDotDotToken !== undefined
114
+ ? undefined
115
+ : checker.getTypeAtLocation(parameter);
116
+ };
117
+
118
+
119
+
120
+
121
+
122
+ const isMutableArrayOnly = (
123
+
124
+ checker,
125
+
126
+ type) => {
127
+ const members = type.isUnion() ? type.types : [type];
128
+ return (members.every((t) =>
129
+
130
+ (t.flags & primitiveTypeFlags) !== 0 ||
131
+ (checker.isArrayType(t) && t.getSymbol()?.getName() === 'Array')) && members.some((t) => (t.flags & primitiveTypeFlags) === 0));
132
+ };
133
+
134
+ const mutatingMethods = new Set([
135
+ 'copyWithin',
136
+ 'fill',
137
+ 'pop',
138
+ 'push',
139
+ 'reverse',
140
+ 'shift',
141
+ 'sort',
142
+ 'splice',
143
+ 'unshift',
144
+ ]);
145
+ //# sourceMappingURL=mutable-result.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutable-result.mjs","sourceRoot":"","sources":["../../src/rules/mutable-result.mts"],"names":[],"mappings":"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"}