Skip to content

Commit dc480b2

Browse files
committed
feat: Add fixer for no-internal.
1 parent b2aa290 commit dc480b2

File tree

3 files changed

+177
-9
lines changed

3 files changed

+177
-9
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ Rules marked with ✅ are recommended and rules marked with 🔧 have fixers.
9696
| [`no-ignored-takewhile-value`](https://github.com/cartant/eslint-plugin-rxjs/blob/main/docs/rules/no-ignored-takewhile-value.md) | Forbids ignoring the value within `takeWhile`. || |
9797
| [`no-implicit-any-catch`](https://github.com/cartant/eslint-plugin-rxjs/blob/main/docs/rules/no-implicit-any-catch.md) | Like the [`no-implicit-any-catch` rule](https://github.com/typescript-eslint/typescript-eslint/pull/2202) in `@typescript-eslint/eslint-plugin`, but for the `catchError` operator instead of `catch` clauses. || 🔧 |
9898
| [`no-index`](https://github.com/cartant/eslint-plugin-rxjs/blob/main/docs/rules/no-index.md) | Forbids the importation from index modules - for the reason, see [this issue](https://github.com/ReactiveX/rxjs/issues/4230). || |
99-
| [`no-internal`](https://github.com/cartant/eslint-plugin-rxjs/blob/main/docs/rules/no-internal.md) | Forbids the importation of internals. || |
99+
| [`no-internal`](https://github.com/cartant/eslint-plugin-rxjs/blob/main/docs/rules/no-internal.md) | Forbids the importation of internals. || 🔧 |
100100
| [`no-nested-subscribe`](https://github.com/cartant/eslint-plugin-rxjs/blob/main/docs/rules/no-nested-subscribe.md) | Forbids the calling of `subscribe` within a `subscribe` callback. || |
101101
| [`no-redundant-notify`](https://github.com/cartant/eslint-plugin-rxjs/blob/main/docs/rules/no-redundant-notify.md) | Forbids redundant notifications from completed or errored observables. || |
102102
| [`no-sharereplay`](https://github.com/cartant/eslint-plugin-rxjs/blob/main/docs/rules/no-sharereplay.md) | Forbids using the `shareReplay` operator. || |

source/rules/no-internal.ts

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
* can be found in the LICENSE file at https://github.com/cartant/eslint-plugin-rxjs
44
*/
55

6-
import { TSESTree as es } from "@typescript-eslint/experimental-utils";
6+
import {
7+
TSESTree as es,
8+
TSESLint as eslint,
9+
} from "@typescript-eslint/experimental-utils";
710
import { ruleCreator } from "../utils";
811

912
const rule = ruleCreator({
@@ -14,23 +17,70 @@ const rule = ruleCreator({
1417
description: "Forbids the importation of internals.",
1518
recommended: "error",
1619
},
17-
fixable: undefined,
20+
fixable: "code",
1821
messages: {
1922
forbidden: "RxJS imports from internal are forbidden.",
23+
suggest: "Import from a non-internal location.",
2024
},
2125
schema: [],
2226
type: "problem",
2327
},
2428
name: "no-internal",
2529
create: (context) => {
30+
function getReplacement(location: string) {
31+
const match = location.match(/^\s*('|")/);
32+
if (!match) {
33+
return undefined;
34+
}
35+
const [, quote] = match;
36+
if (/^['"]rxjs\/internal\/ajax/.test(location)) {
37+
return `${quote}rxjs/ajax${quote}`;
38+
}
39+
if (/^['"]rxjs\/internal\/observable\/dom\/fetch/.test(location)) {
40+
return `${quote}rxjs/fetch${quote}`;
41+
}
42+
if (/^['"]rxjs\/internal\/observable\/dom\/webSocket/i.test(location)) {
43+
return `${quote}rxjs/webSocket${quote}`;
44+
}
45+
if (/^['"]rxjs\/internal\/observable/.test(location)) {
46+
return `${quote}rxjs${quote}`;
47+
}
48+
if (/^['"]rxjs\/internal\/operators/.test(location)) {
49+
return `${quote}rxjs/operators${quote}`;
50+
}
51+
if (/^['"]rxjs\/internal\/scheduled/.test(location)) {
52+
return `${quote}rxjs${quote}`;
53+
}
54+
if (/^['"]rxjs\/internal\/scheduler/.test(location)) {
55+
return `${quote}rxjs${quote}`;
56+
}
57+
if (/^['"]rxjs\/internal\/testing/.test(location)) {
58+
return `${quote}rxjs/testing${quote}`;
59+
}
60+
return undefined;
61+
}
62+
2663
return {
2764
[String.raw`ImportDeclaration Literal[value=/^rxjs\u002finternal/]`]: (
2865
node: es.Literal
2966
) => {
30-
context.report({
31-
messageId: "forbidden",
32-
node,
33-
});
67+
const replacement = getReplacement(node.raw);
68+
if (replacement) {
69+
function fix(fixer: eslint.RuleFixer) {
70+
return fixer.replaceText(node, replacement as string);
71+
}
72+
context.report({
73+
fix,
74+
messageId: "forbidden",
75+
node,
76+
suggest: [{ fix, messageId: "suggest" }],
77+
});
78+
} else {
79+
context.report({
80+
messageId: "forbidden",
81+
node,
82+
});
83+
}
3484
},
3585
};
3686
},

tests/rules/no-internal.ts

Lines changed: 120 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,14 @@ ruleTester({ types: false }).run("no-internal", rule, {
2929
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [forbidden]
3030
import { map } from "rxjs/internal/operators/map";
3131
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [forbidden]
32-
`
32+
`,
33+
{
34+
output: stripIndent`
35+
// internal double quote
36+
import { concat } from "rxjs";
37+
import { map } from "rxjs/operators";
38+
`,
39+
}
3340
),
3441
fromFixture(
3542
stripIndent`
@@ -38,7 +45,118 @@ ruleTester({ types: false }).run("no-internal", rule, {
3845
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [forbidden]
3946
import { map } from 'rxjs/internal/operators/map';
4047
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [forbidden]
41-
`
48+
`,
49+
{
50+
output: stripIndent`
51+
// internal single quote
52+
import { concat } from 'rxjs';
53+
import { map } from 'rxjs/operators';
54+
`,
55+
}
56+
),
57+
fromFixture(
58+
stripIndent`
59+
// internal ajax
60+
import { ajax } from "rxjs/internal/observable/ajax/ajax";
61+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [forbidden]
62+
`,
63+
{
64+
output: stripIndent`
65+
// internal ajax
66+
import { ajax } from "rxjs";
67+
`,
68+
}
69+
),
70+
fromFixture(
71+
stripIndent`
72+
// internal fetch
73+
import { fromFetch } from "rxjs/internal/observable/dom/fetch";
74+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [forbidden]
75+
`,
76+
{
77+
output: stripIndent`
78+
// internal fetch
79+
import { fromFetch } from "rxjs/fetch";
80+
`,
81+
}
82+
),
83+
fromFixture(
84+
stripIndent`
85+
// internal webSocket
86+
import { webSocket } from "rxjs/internal/observable/dom/webSocket";
87+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [forbidden]
88+
`,
89+
{
90+
output: stripIndent`
91+
// internal webSocket
92+
import { webSocket } from "rxjs/webSocket";
93+
`,
94+
}
95+
),
96+
fromFixture(
97+
stripIndent`
98+
// internal observable
99+
import { concat } from "rxjs/internal/observable/concat";
100+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [forbidden]
101+
`,
102+
{
103+
output: stripIndent`
104+
// internal observable
105+
import { concat } from "rxjs";
106+
`,
107+
}
108+
),
109+
fromFixture(
110+
stripIndent`
111+
// internal operator
112+
import { map } from "rxjs/internal/operators/map";
113+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [forbidden]
114+
`,
115+
{
116+
output: stripIndent`
117+
// internal operator
118+
import { map } from "rxjs/operators";
119+
`,
120+
}
121+
),
122+
fromFixture(
123+
stripIndent`
124+
// internal scheduled
125+
import { scheduled } from "rxjs/internal/scheduled/scheduled";
126+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [forbidden]
127+
`,
128+
{
129+
output: stripIndent`
130+
// internal scheduled
131+
import { scheduled } from "rxjs";
132+
`,
133+
}
134+
),
135+
fromFixture(
136+
stripIndent`
137+
// internal scheduler
138+
import { asap } from "rxjs/internal/scheduler/asap";
139+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [forbidden]
140+
`,
141+
{
142+
output: stripIndent`
143+
// internal scheduler
144+
import { asap } from "rxjs";
145+
`,
146+
}
147+
),
148+
fromFixture(
149+
stripIndent`
150+
// internal testing
151+
import { TestScheduler } from "rxjs/internal/testing/TestScheduler";
152+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [forbidden]
153+
`,
154+
{
155+
output: stripIndent`
156+
// internal testing
157+
import { TestScheduler } from "rxjs/testing";
158+
`,
159+
}
42160
),
43161
],
44162
});

0 commit comments

Comments
 (0)