-
Notifications
You must be signed in to change notification settings - Fork 38
/
Copy pathconfigs.ts
106 lines (94 loc) · 2.99 KB
/
configs.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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import tseslint from 'typescript-eslint'
import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint'
const CONFIG_NAMES = [
'all',
'base',
'disableTypeChecked',
'eslintRecommended',
'recommended',
'recommendedTypeChecked',
'recommendedTypeCheckedOnly',
'strict',
'strictTypeChecked',
'strictTypeCheckedOnly',
'stylistic',
'stylisticTypeChecked',
'stylisticTypeCheckedOnly',
] as const
export type ExtendableConfigName = (typeof CONFIG_NAMES)[number]
function toArray<T>(value: T | T[]): T[] {
return Array.isArray(value) ? value : [value]
}
/**
* The options that a config in the `extends` should inherit.
*/
type ExtendsOptions = {
name?: string
files?: (string | string[])[]
ignores?: string[]
}
export class TsEslintConfigForVue {
/**
* The name of the config object as defined in `typescript-eslint`.
*/
configName: ExtendableConfigName
/**
* the name property is here to provide better error messages when ESLint throws an error
*/
name: string
constructor(configName: ExtendableConfigName) {
this.configName = configName
this.name = `vueTsConfigs.${configName}`
}
extendsOptions?: ExtendsOptions
/**
* Create a new instance of `TsEslintConfigForVue` with the `restOfConfig` merged into it.
* Should be used when the config is used in the `extends` field of another config.
*/
asExtendedWith(restOfConfig: ExtendsOptions): TsEslintConfigForVue {
const extendedConfig = new TsEslintConfigForVue(this.configName)
extendedConfig.extendsOptions = {
name: [restOfConfig.name, this.name].filter(Boolean).join('__'),
...(restOfConfig.files && { files: restOfConfig.files }),
...(restOfConfig.ignores && { ignores: restOfConfig.ignores }),
}
return extendedConfig
}
needsTypeChecking(): boolean {
if (this.configName === 'disableTypeChecked') {
return false
}
if (this.configName === 'all') {
return true
}
return this.configName.includes('TypeChecked')
}
toConfigArray(): FlatConfig.ConfigArray {
return toArray(tseslint.configs[this.configName])
.flat()
.map(config => ({
...config,
...(config.files && config.files.includes('**/*.ts')
? { files: [...config.files, '**/*.vue'] }
: {}),
...this.extendsOptions,
}))
}
}
export const vueTsConfigs = Object.fromEntries(
CONFIG_NAMES.map(name => [
name,
new Proxy(new TsEslintConfigForVue(name), {
// `ownKeys` is called by ESLint when validating the config object.
// The only possible scenario where this is called is when the placeholder object
// isn't replaced, which means it's passed to ESLint without being wrapped by
// `defineConfigWithVueTs()`
// We throw an error here to provide a better error message to the user.
ownKeys() {
throw new Error(
'Please wrap the config object with `defineConfigWithVueTs()`',
)
},
}),
]),
) as Record<ExtendableConfigName, TsEslintConfigForVue>