-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
/
ConfigEslint.tsx
101 lines (91 loc) · 2.88 KB
/
ConfigEslint.tsx
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import React, { useCallback, useEffect, useState } from 'react';
import { shallowEqual } from '../lib/shallowEqual';
import type { ConfigModel, EslintRC, RuleDetails, RuleEntry } from '../types';
import type { ConfigOptionsType } from './ConfigEditor';
import ConfigEditor from './ConfigEditor';
import { parseESLintRC, toJson } from './utils';
export interface ConfigEslintProps {
readonly isOpen: boolean;
readonly onClose: (value?: Partial<ConfigModel>) => void;
readonly ruleOptions: RuleDetails[];
readonly config?: string;
}
function checkSeverity(value: unknown): boolean {
if (typeof value === 'string' || typeof value === 'number') {
return [0, 1, 2, 'off', 'warn', 'error'].includes(value);
}
return false;
}
function checkOptions(rule: [string, unknown]): rule is [string, RuleEntry] {
if (Array.isArray(rule[1])) {
return rule[1].length > 0 && checkSeverity(rule[1][0]);
}
return checkSeverity(rule[1]);
}
function ConfigEslint(props: ConfigEslintProps): JSX.Element {
const { isOpen, config, onClose: onCloseProps, ruleOptions } = props;
const [options, updateOptions] = useState<ConfigOptionsType[]>([]);
const [configObject, updateConfigObject] = useState<EslintRC>();
useEffect(() => {
if (isOpen) {
updateConfigObject(parseESLintRC(config));
}
}, [isOpen, config]);
useEffect(() => {
updateOptions([
{
heading: 'Rules',
fields: ruleOptions
.filter(item => item.name.startsWith('@typescript'))
.map(item => ({
key: item.name,
label: item.description,
type: 'boolean',
defaults: ['error', 2, 'warn', 1, ['error'], ['warn'], [2], [1]],
})),
},
{
heading: 'Core rules',
fields: ruleOptions
.filter(item => !item.name.startsWith('@typescript'))
.map(item => ({
key: item.name,
label: item.description,
type: 'boolean',
defaults: ['error', 2, 'warn', 1, ['error'], ['warn'], [2], [1]],
})),
},
]);
}, [ruleOptions]);
const onClose = useCallback(
(newConfig: Record<string, unknown>) => {
const cfg = Object.fromEntries(
Object.entries(newConfig)
.map<[string, unknown]>(([name, value]) =>
Array.isArray(value) && value.length === 1
? [name, value[0]]
: [name, value],
)
.filter(checkOptions),
);
if (!shallowEqual(cfg, configObject?.rules)) {
onCloseProps({
eslintrc: toJson({ ...(configObject ?? {}), rules: cfg }),
});
} else {
onCloseProps();
}
},
[onCloseProps, configObject],
);
return (
<ConfigEditor
header="Eslint Config"
options={options}
values={configObject?.rules ?? {}}
isOpen={isOpen}
onClose={onClose}
/>
);
}
export default ConfigEslint;