Skip to content

Commit a1d7194

Browse files
committed
feat: add [import-blacklist] converter #277
1 parent 2cccfd0 commit a1d7194

File tree

4 files changed

+126
-0
lines changed

4 files changed

+126
-0
lines changed

src/rules/converters.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { convertEofline } from "./converters/eofline";
1818
import { convertFileNameCasing } from "./converters/file-name-casing";
1919
import { convertForin } from "./converters/forin";
2020
import { convertFunctionConstructor } from "./converters/function-constructor";
21+
import { convertImportBlacklist } from "./converters/import-blacklist";
2122
import { convertIncrementDecrement } from "./converters/increment-decrement";
2223
import { convertIndent } from "./converters/indent";
2324
import { convertInterfaceName } from "./converters/interface-name";
@@ -154,6 +155,7 @@ export const converters = new Map([
154155
["file-name-casing", convertFileNameCasing],
155156
["forin", convertForin],
156157
["function-constructor", convertFunctionConstructor],
158+
["import-blacklist", convertImportBlacklist],
157159
["increment-decrement", convertIncrementDecrement],
158160
["indent", convertIndent],
159161
["interface-name", convertInterfaceName],
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { RuleConverter } from "../converter";
2+
import { RequireAtLeastOne } from "../../utils";
3+
4+
type ESLintOptionPath = {
5+
name: string;
6+
importNames: string[];
7+
message?: string;
8+
};
9+
type ESLintSimpleOption = string[];
10+
type ESLintComplexOption = RequireAtLeastOne<{
11+
paths: (string | ESLintOptionPath)[];
12+
patterns: string[];
13+
}>;
14+
type ESLintOptions = ESLintSimpleOption | ESLintComplexOption;
15+
16+
export const convertImportBlacklist: RuleConverter = tslintRule => {
17+
const tslintRules = tslintRule.ruleArguments;
18+
let ruleArguments: ESLintOptions = [];
19+
20+
if (tslintRules.every(isString)) {
21+
ruleArguments = tslintRules;
22+
} else {
23+
ruleArguments = [
24+
tslintRules.reduce((rules, rule) => {
25+
if (!Array.isArray(rule)) {
26+
const eslintRule = isString(rule)
27+
? rule
28+
: {
29+
name: Object.keys(rule)[0],
30+
importNames: Object.values(rule)[0] as string[],
31+
};
32+
return { ...rules, paths: [...(rules.paths || []), eslintRule] };
33+
} else if (Array.isArray(rule)) {
34+
return { ...rules, patterns: [...(rules.patterns || []), ...rule] };
35+
}
36+
return rules;
37+
}, {} as ESLintComplexOption),
38+
];
39+
}
40+
return {
41+
rules: [
42+
{
43+
ruleArguments,
44+
ruleName: "no-restricted-imports",
45+
},
46+
],
47+
};
48+
};
49+
50+
function isString(value: string): boolean {
51+
return typeof value === "string";
52+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { convertImportBlacklist } from "../import-blacklist";
2+
3+
describe(convertImportBlacklist, () => {
4+
test.each([
5+
[[], []],
6+
[["rxjs"], ["rxjs"]],
7+
[
8+
["rxjs", "lodash"],
9+
["rxjs", "lodash"],
10+
],
11+
[
12+
[".*\\.temp$", ".*\\.tmp$"],
13+
[".*\\.temp$", ".*\\.tmp$"],
14+
],
15+
[
16+
["moment", "date-fns", ["eslint/*"]],
17+
[{ patterns: ["eslint/*"], paths: ["moment", "date-fns"] }],
18+
],
19+
[
20+
[{ lodash: ["pullAll", "pull"] }],
21+
[
22+
{
23+
paths: [
24+
{
25+
name: "lodash",
26+
importNames: ["pullAll", "pull"],
27+
},
28+
],
29+
},
30+
],
31+
],
32+
[
33+
[
34+
"rxjs",
35+
[".*\\.temp$", ".*\\.tmp$"],
36+
{ lodash: ["pullAll", "pull"] },
37+
{ dummy: ["default"] },
38+
],
39+
[
40+
{
41+
paths: [
42+
"rxjs",
43+
{
44+
name: "lodash",
45+
importNames: ["pullAll", "pull"],
46+
},
47+
{
48+
name: "dummy",
49+
importNames: ["default"],
50+
},
51+
],
52+
patterns: [".*\\.temp$", ".*\\.tmp$"],
53+
},
54+
],
55+
],
56+
] as any[][])("convert %j", (ruleArguments: any[], expected: any[]) => {
57+
const result = convertImportBlacklist({ ruleArguments });
58+
expect(result).toEqual({
59+
rules: [
60+
{
61+
ruleArguments: expected,
62+
ruleName: "no-restricted-imports",
63+
},
64+
],
65+
});
66+
});
67+
});

src/utils.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ export type RemoveErrors<Items> = {
88

99
export type PromiseValue<T> = T extends Promise<infer R> ? R : never;
1010

11+
export type RequireAtLeastOne<T, Keys extends keyof T = keyof T> = Pick<T, Exclude<keyof T, Keys>> &
12+
{
13+
[K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>>;
14+
}[Keys];
15+
1116
export const uniqueFromSources = <T>(...sources: (T | T[] | undefined)[]) => {
1217
const items: T[] = [];
1318

0 commit comments

Comments
 (0)