-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathnode-param-default-wrong-for-options.ts
86 lines (74 loc) · 2.12 KB
/
node-param-default-wrong-for-options.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import { utils } from "../ast/utils";
import { id } from "../ast/identifiers";
import { getters } from "../ast/getters";
export default utils.createRule({
name: utils.getRuleName(module),
meta: {
type: "problem",
docs: {
description:
"`default` for an options-type node parameter must be one of the options.",
recommended: "strict",
},
fixable: "code",
schema: [],
messages: {
chooseOption: "Set one of {{ eligibleOptions }} as default [autofixable]",
setEmptyString: "Set an empty string as default [autofixable]",
},
},
defaultOptions: [],
create(context) {
return {
ObjectExpression(node) {
if (!id.isNodeParameter(node)) return;
if (!id.nodeParam.isOptionsType(node)) return;
const _default = getters.nodeParam.getDefault(node);
if (!_default) return;
const options = getters.nodeParam.getOptions(node);
/**
* if no options but default exists, assume node param is dynamic options,
* regardless of whether `typeOptions.loadOptions` has been specified or not
*/
if (!options && _default.value !== "") {
context.report({
messageId: "setEmptyString",
node: _default.ast,
fix: (fixer) => fixer.replaceText(_default.ast, "default: ''"),
});
}
if (!options) return;
if (
options.hasPropertyPointingToIdentifier || // e.g. `value: myVar`
options.hasPropertyPointingToMemberExpression // e.g. `value: MY_OBJECT.myValue`
) {
return;
}
// @ts-ignore @TODO
const eligibleOptions = options.value.reduce<unknown[]>(
// @ts-ignore @TODO
(acc, option) => {
return acc.push(option.value), acc;
},
[]
);
if (!eligibleOptions.includes(_default.value)) {
const zerothOption = eligibleOptions[0];
const fixed = `default: ${
typeof zerothOption === "string"
? `'${zerothOption}'`
: zerothOption
}`;
context.report({
messageId: "chooseOption",
data: {
eligibleOptions: eligibleOptions.join(" or "),
},
node: _default.ast,
fix: (fixer) => fixer.replaceText(_default.ast, fixed),
});
}
},
};
},
});