Skip to content

Commit 1b2034b

Browse files
authored
Merge pull request #31 from buildo/create-rule
Use createRule utility for all rules
2 parents 2aa3e80 + 5c60064 commit 1b2034b

11 files changed

+330
-320
lines changed

src/index.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ import { array, record, semigroup } from "fp-ts";
22
import { pipe } from "fp-ts/function";
33

44
const potentialErrors = {
5-
"no-lib-imports": require("./rules/no-lib-imports"),
6-
"no-pipeable": require("./rules/no-pipeable"),
5+
"no-lib-imports": require("./rules/no-lib-imports").default,
6+
"no-pipeable": require("./rules/no-pipeable").default,
77
"no-module-imports": require("./rules/no-module-imports").default,
88
};
99

1010
const suggestions = {
11-
"prefer-traverse": require("./rules/prefer-traverse"),
12-
"no-redundant-flow": require("./rules/no-redundant-flow"),
13-
"prefer-chain": require("./rules/prefer-chain"),
11+
"prefer-traverse": require("./rules/prefer-traverse").default,
12+
"no-redundant-flow": require("./rules/no-redundant-flow").default,
13+
"prefer-chain": require("./rules/prefer-chain").default,
1414
};
1515

1616
export const rules = {

src/rules/no-lib-imports.ts

+45-42
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,49 @@
1-
import { TSESLint } from "@typescript-eslint/experimental-utils";
1+
import { createRule } from "../utils";
22

3-
const messages = {
4-
importNotAllowed:
5-
"Importing from {{ detected }} is not allowed, import from {{ fixed }} instead",
6-
} as const;
7-
type MessageIds = keyof typeof messages;
8-
9-
export const meta: TSESLint.RuleMetaData<MessageIds> = {
10-
type: "problem",
11-
fixable: "code",
12-
schema: [],
13-
messages,
14-
};
15-
16-
export function create(
17-
context: TSESLint.RuleContext<MessageIds, []>
18-
): TSESLint.RuleListener {
19-
return {
20-
ImportDeclaration(node) {
21-
const sourceValue = node.source.value?.toString();
22-
if (sourceValue) {
23-
const forbiddenImportPattern = /^fp-ts\/lib\//;
3+
export default createRule({
4+
name: "no-lib-imports",
5+
meta: {
6+
type: "problem",
7+
fixable: "code",
8+
docs: {
9+
category: "Possible Errors",
10+
description: "Disallow imports from 'fp-ts/lib'",
11+
recommended: "error",
12+
},
13+
schema: [],
14+
messages: {
15+
importNotAllowed:
16+
"Importing from {{ detected }} is not allowed, import from {{ fixed }} instead",
17+
},
18+
},
19+
defaultOptions: [],
20+
create(context) {
21+
return {
22+
ImportDeclaration(node) {
23+
const sourceValue = node.source.value?.toString();
24+
if (sourceValue) {
25+
const forbiddenImportPattern = /^fp-ts\/lib\//;
2426

25-
const fixedImportSource = sourceValue.replace(
26-
forbiddenImportPattern,
27-
"fp-ts/"
28-
);
27+
const fixedImportSource = sourceValue.replace(
28+
forbiddenImportPattern,
29+
"fp-ts/"
30+
);
2931

30-
if (sourceValue.match(forbiddenImportPattern)) {
31-
context.report({
32-
node: node.source,
33-
messageId: "importNotAllowed",
34-
data: {
35-
detected: node.source.value,
36-
fixed: fixedImportSource,
37-
},
38-
fix(fixer) {
39-
return fixer.replaceText(node.source, `"${fixedImportSource}"`);
40-
},
41-
});
32+
if (sourceValue.match(forbiddenImportPattern)) {
33+
context.report({
34+
node: node.source,
35+
messageId: "importNotAllowed",
36+
data: {
37+
detected: node.source.value,
38+
fixed: fixedImportSource,
39+
},
40+
fix(fixer) {
41+
return fixer.replaceText(node.source, `"${fixedImportSource}"`);
42+
},
43+
});
44+
}
4245
}
43-
}
44-
},
45-
};
46-
}
46+
},
47+
};
48+
},
49+
});

src/rules/no-pipeable.ts

+52-52
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,56 @@
1-
import {
2-
ASTUtils,
3-
TSESLint,
4-
TSESTree,
5-
} from "@typescript-eslint/experimental-utils";
1+
import { ASTUtils, TSESTree } from "@typescript-eslint/experimental-utils";
2+
import { createRule } from "../utils";
63

7-
const messages = {
8-
importPipeFromFunction:
9-
"The 'pipeable' module is deprecated. Import 'pipe' from the 'function' module instead",
10-
pipeableIsDeprecated:
11-
"The 'pipeable' module is deprecated and will be removed in future versions of fp-ts",
12-
} as const;
13-
type MessageIds = keyof typeof messages;
14-
15-
export const meta: TSESLint.RuleMetaData<MessageIds> = {
16-
type: "problem",
17-
fixable: "code",
18-
schema: [],
19-
messages,
20-
};
21-
22-
export function create(
23-
context: TSESLint.RuleContext<MessageIds, []>
24-
): TSESLint.RuleListener {
25-
return {
26-
ImportDeclaration(node) {
27-
const sourceValue = ASTUtils.getStringIfConstant(node.source);
28-
if (sourceValue) {
29-
const pipeableSourcePattern = /^fp-ts\/(lib\/)?pipeable/;
4+
export default createRule({
5+
name: "no-pipeable",
6+
meta: {
7+
type: "problem",
8+
fixable: "code",
9+
schema: [],
10+
docs: {
11+
category: "Possible Errors",
12+
description: "Disallow imports from the 'pipeable' module",
13+
recommended: "error",
14+
},
15+
messages: {
16+
importPipeFromFunction:
17+
"The 'pipeable' module is deprecated. Import 'pipe' from the 'function' module instead",
18+
pipeableIsDeprecated:
19+
"The 'pipeable' module is deprecated and will be removed in future versions of fp-ts",
20+
},
21+
},
22+
defaultOptions: [],
23+
create(context) {
24+
return {
25+
ImportDeclaration(node) {
26+
const sourceValue = ASTUtils.getStringIfConstant(node.source);
27+
if (sourceValue) {
28+
const pipeableSourcePattern = /^fp-ts\/(lib\/)?pipeable/;
3029

31-
if (sourceValue.match(pipeableSourcePattern)) {
32-
if (
33-
node.specifiers.find(
34-
(importClause) =>
35-
(importClause as TSESTree.ImportSpecifier).imported?.name ===
36-
"pipe"
37-
)
38-
) {
39-
context.report({
40-
node: node.source,
41-
messageId: "importPipeFromFunction",
42-
fix(fixer) {
43-
return fixer.replaceText(node.source, `"fp-ts/function"`);
44-
},
45-
});
46-
} else {
47-
context.report({
48-
node: node.source,
49-
messageId: "pipeableIsDeprecated",
50-
});
30+
if (sourceValue.match(pipeableSourcePattern)) {
31+
if (
32+
node.specifiers.find(
33+
(importClause) =>
34+
(importClause as TSESTree.ImportSpecifier).imported?.name ===
35+
"pipe"
36+
)
37+
) {
38+
context.report({
39+
node: node.source,
40+
messageId: "importPipeFromFunction",
41+
fix(fixer) {
42+
return fixer.replaceText(node.source, `"fp-ts/function"`);
43+
},
44+
});
45+
} else {
46+
context.report({
47+
node: node.source,
48+
messageId: "pipeableIsDeprecated",
49+
});
50+
}
5151
}
5252
}
53-
}
54-
},
55-
};
56-
}
53+
},
54+
};
55+
},
56+
});

src/rules/no-redundant-flow.ts

+45-43
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,48 @@
1-
import { TSESLint } from "@typescript-eslint/experimental-utils";
2-
import { contextUtils } from "../utils";
1+
import { contextUtils, createRule } from "../utils";
32

4-
const messages = {
5-
redundantFlow: "flow can be removed because it takes only one argument",
6-
removeFlow: "remove flow",
7-
} as const;
8-
type MessageIds = keyof typeof messages;
9-
10-
export const meta: TSESLint.RuleMetaData<MessageIds> = {
11-
type: "suggestion",
12-
fixable: "code",
13-
schema: [],
14-
messages,
15-
};
16-
17-
export function create(
18-
context: TSESLint.RuleContext<MessageIds, []>
19-
): TSESLint.RuleListener {
20-
const { isFlowExpression } = contextUtils(context);
3+
export default createRule({
4+
name: "no-redundant-flow",
5+
meta: {
6+
type: "suggestion",
7+
fixable: "code",
8+
schema: [],
9+
docs: {
10+
category: "Best Practices",
11+
description: "Remove redundant uses of flow",
12+
recommended: "warn",
13+
},
14+
messages: {
15+
redundantFlow: "flow can be removed because it takes only one argument",
16+
removeFlow: "remove flow",
17+
},
18+
},
19+
defaultOptions: [],
20+
create(context) {
21+
const { isFlowExpression } = contextUtils(context);
2122

22-
return {
23-
CallExpression(node) {
24-
if (node.arguments.length === 1 && isFlowExpression(node)) {
25-
context.report({
26-
node,
27-
messageId: "redundantFlow",
28-
suggest: [
29-
{
30-
messageId: "removeFlow",
31-
fix(fixer) {
32-
return [
33-
fixer.removeRange([
34-
node.callee.range[0],
35-
node.callee.range[1] + 1,
36-
]),
37-
fixer.removeRange([node.range[1] - 1, node.range[1]]),
38-
];
23+
return {
24+
CallExpression(node) {
25+
if (node.arguments.length === 1 && isFlowExpression(node)) {
26+
context.report({
27+
node,
28+
messageId: "redundantFlow",
29+
suggest: [
30+
{
31+
messageId: "removeFlow",
32+
fix(fixer) {
33+
return [
34+
fixer.removeRange([
35+
node.callee.range[0],
36+
node.callee.range[1] + 1,
37+
]),
38+
fixer.removeRange([node.range[1] - 1, node.range[1]]),
39+
];
40+
},
3941
},
40-
},
41-
],
42-
});
43-
}
44-
},
45-
};
46-
}
42+
],
43+
});
44+
}
45+
},
46+
};
47+
},
48+
});

0 commit comments

Comments
 (0)