@w5s/dev 3.3.0 → 3.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +254 -162
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +153 -104
- package/dist/index.d.ts +153 -104
- package/dist/index.js +252 -150
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/ESLintConfig.ts +122 -71
- package/src/Project.ts +141 -133
- package/src/ProjectScript.ts +1 -0
- package/dist/index.d.cts.map +0 -1
package/src/ESLintConfig.ts
CHANGED
|
@@ -1,79 +1,130 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Linter } from 'eslint';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Return a new merged flat configuration
|
|
5
|
+
*
|
|
6
|
+
* @param configs
|
|
7
|
+
*/
|
|
8
|
+
function merge<T extends Linter.Config = Linter.Config>(...configs: Array<T>): T {
|
|
9
|
+
const keys = new Set(configs.flatMap((i) => Object.keys(i)));
|
|
10
|
+
const merged = configs.reduce((acc, cur) => {
|
|
11
|
+
return {
|
|
12
|
+
...acc,
|
|
13
|
+
...cur,
|
|
14
|
+
files: [
|
|
15
|
+
...(acc.files ?? []),
|
|
16
|
+
...(cur.files ?? []),
|
|
17
|
+
],
|
|
18
|
+
ignores: [
|
|
19
|
+
...(acc.ignores ?? []),
|
|
20
|
+
...(cur.ignores ?? []),
|
|
21
|
+
],
|
|
22
|
+
plugins: {
|
|
23
|
+
...acc.plugins,
|
|
24
|
+
...cur.plugins,
|
|
25
|
+
},
|
|
26
|
+
rules: {
|
|
27
|
+
...acc.rules,
|
|
28
|
+
...cur.rules,
|
|
29
|
+
},
|
|
30
|
+
languageOptions: {
|
|
31
|
+
...acc.languageOptions,
|
|
32
|
+
...cur.languageOptions,
|
|
33
|
+
},
|
|
34
|
+
linterOptions: {
|
|
35
|
+
...acc.linterOptions,
|
|
36
|
+
...cur.linterOptions,
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
// eslint-disable-next-line ts/consistent-type-assertions
|
|
40
|
+
}, {} as T);
|
|
41
|
+
|
|
42
|
+
// Remove unused keys
|
|
43
|
+
for (const key of Object.keys(merged)) {
|
|
44
|
+
if (!keys.has(key))
|
|
45
|
+
// eslint-disable-next-line ts/no-dynamic-delete
|
|
46
|
+
delete (merged as any)[key];
|
|
9
47
|
}
|
|
10
|
-
return [value];
|
|
11
|
-
}
|
|
12
48
|
|
|
13
|
-
|
|
14
|
-
return [...toArray(left), ...toArray(right)];
|
|
49
|
+
return merged as T;
|
|
15
50
|
}
|
|
16
51
|
|
|
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
|
-
|
|
52
|
+
/**
|
|
53
|
+
* Concat multiple flat configs into a single flat config array.
|
|
54
|
+
*
|
|
55
|
+
* It also resolves promises and flattens the result.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
*
|
|
59
|
+
* ```ts
|
|
60
|
+
* import eslint from '@eslint/js'
|
|
61
|
+
*
|
|
62
|
+
* export default ESLintConfig.concat(
|
|
63
|
+
* {
|
|
64
|
+
* plugins: {},
|
|
65
|
+
* rules: {},
|
|
66
|
+
* },
|
|
67
|
+
* // It can also takes a array of configs:
|
|
68
|
+
* [
|
|
69
|
+
* {
|
|
70
|
+
* plugins: {},
|
|
71
|
+
* rules: {},
|
|
72
|
+
* }
|
|
73
|
+
* // ...
|
|
74
|
+
* ],
|
|
75
|
+
* // Or promises:
|
|
76
|
+
* Promise.resolve({
|
|
77
|
+
* files: ['*.ts'],
|
|
78
|
+
* rules: {},
|
|
79
|
+
* })
|
|
80
|
+
* );
|
|
81
|
+
* ```
|
|
82
|
+
* @param configs
|
|
83
|
+
*/
|
|
84
|
+
async function concat<T extends Linter.Config = Linter.Config>(
|
|
85
|
+
...configs: Array<T | ReadonlyArray<T> | Promise<T> | Promise<ReadonlyArray<T>>>
|
|
86
|
+
): Promise<Array<T>> {
|
|
87
|
+
const resolved = await Promise.all(configs);
|
|
88
|
+
return resolved.flat() as Array<T>;
|
|
89
|
+
}
|
|
48
90
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
91
|
+
/**
|
|
92
|
+
* Always return 'off'. `_status` is the previous rule value.
|
|
93
|
+
*
|
|
94
|
+
* @param _status
|
|
95
|
+
*/
|
|
96
|
+
function fixme(_status: string | number | [string | number, ...any[]] | undefined) {
|
|
97
|
+
return 'off' as const;
|
|
98
|
+
}
|
|
57
99
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
100
|
+
/**
|
|
101
|
+
* Renames rules in the given object according to the given map.
|
|
102
|
+
*
|
|
103
|
+
* Given a map `{ 'old-prefix': 'new-prefix' }`, and a rule object
|
|
104
|
+
* `{ 'old-prefix/rule-name': 'error' }`, this function will return
|
|
105
|
+
* `{ 'new-prefix/rule-name': 'error' }`.
|
|
106
|
+
*
|
|
107
|
+
* @param rules The object containing the rules to rename.
|
|
108
|
+
* @param map The object containing the rename map.
|
|
109
|
+
*/
|
|
110
|
+
function renameRules(rules: Record<string, any>, map: Record<string, string>): Record<string, any> {
|
|
111
|
+
return Object.fromEntries(
|
|
112
|
+
Object.entries(rules).map(([key, value]) => {
|
|
113
|
+
for (const [from, to] of Object.entries(map)) {
|
|
114
|
+
if (key.startsWith(`${from}/`)) return [to + key.slice(from.length), value];
|
|
115
|
+
else if (from === '' && !key.includes('/') && to !== '') return [to + key, value];
|
|
116
|
+
}
|
|
117
|
+
return [key, value];
|
|
118
|
+
}),
|
|
119
|
+
);
|
|
79
120
|
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @namespace
|
|
124
|
+
*/
|
|
125
|
+
export const ESLintConfig = Object.freeze({
|
|
126
|
+
merge,
|
|
127
|
+
concat,
|
|
128
|
+
fixme,
|
|
129
|
+
renameRules,
|
|
130
|
+
});
|
package/src/Project.ts
CHANGED
|
@@ -1,150 +1,158 @@
|
|
|
1
1
|
import type { LanguageId } from './LanguageId.js';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* A type of a file extension
|
|
5
|
+
*/
|
|
6
|
+
export type Extension = `.${string}`;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Object hash of all well-known file extension category to file extensions mapping
|
|
10
|
+
*/
|
|
11
|
+
export type ExtensionRegistry = { [K in LanguageId]: readonly Extension[] };
|
|
12
|
+
|
|
3
13
|
function escapeRegExp(value: string) {
|
|
4
14
|
// eslint-disable-next-line unicorn/prefer-string-raw
|
|
5
15
|
return value.replaceAll(/[$()*+.?[\\\]^{|}]/g, '\\$&'); // $& means the whole matched string
|
|
6
16
|
}
|
|
7
17
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Supported ECMA version
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* ```ts
|
|
24
|
-
* Project.ecmaVersion() // 2022
|
|
25
|
-
* ```
|
|
26
|
-
*/
|
|
27
|
-
export function ecmaVersion() {
|
|
28
|
-
return 2022 as const;
|
|
29
|
-
}
|
|
18
|
+
/**
|
|
19
|
+
* Supported ECMA version
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* Project.ecmaVersion() // 2022
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
function ecmaVersion() {
|
|
27
|
+
return 2022 as const;
|
|
28
|
+
}
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
30
|
+
const registry: ExtensionRegistry = {
|
|
31
|
+
css: ['.css'],
|
|
32
|
+
graphql: ['.gql', '.graphql'],
|
|
33
|
+
javascript: ['.js', '.cjs', '.mjs'],
|
|
34
|
+
javascriptreact: ['.jsx'],
|
|
35
|
+
jpeg: ['.jpg', '.jpeg'],
|
|
36
|
+
json: ['.json'],
|
|
37
|
+
jsonc: ['.jsonc'],
|
|
38
|
+
less: ['.less'],
|
|
39
|
+
markdown: ['.markdown', '.mdown', '.mkd', '.md'],
|
|
40
|
+
sass: ['.sass'],
|
|
41
|
+
scss: ['.scss'],
|
|
42
|
+
typescript: ['.ts', '.cts', '.mts'],
|
|
43
|
+
typescriptreact: ['.tsx'],
|
|
44
|
+
vue: ['.vue'],
|
|
45
|
+
yaml: ['.yaml', '.yml'],
|
|
46
|
+
};
|
|
48
47
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Return a list of extensions
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* Project.queryExtensions(['javascript']); // ['.js', '.cjs', ...]
|
|
54
|
+
* Project.queryExtensions(['typescript', 'typescriptreact']); // ['.ts', '.mts', ..., '.tsx']
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* @param languages
|
|
58
|
+
*/
|
|
59
|
+
function queryExtensions(languages: LanguageId[]): readonly Extension[] {
|
|
60
|
+
return languages
|
|
61
|
+
.reduce<Extension[]>((previousValue, currentValue) =>
|
|
62
|
+
// eslint-disable-next-line unicorn/prefer-spread
|
|
63
|
+
previousValue.concat(registry[currentValue] ?? ([] as Extension[])), [])
|
|
64
|
+
// eslint-disable-next-line unicorn/no-array-sort
|
|
65
|
+
.sort();
|
|
66
|
+
}
|
|
68
67
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
68
|
+
/**
|
|
69
|
+
* Supported file extensions
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* Project.sourceExtensions() // ['.ts', '.js', ...]
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
function sourceExtensions() {
|
|
77
|
+
return queryExtensions(['javascript', 'javascriptreact', 'typescript', 'typescriptreact']);
|
|
78
|
+
}
|
|
80
79
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
80
|
+
const RESOURCE_EXTENSIONS: readonly Extension[] = Object.freeze([
|
|
81
|
+
'.gif',
|
|
82
|
+
'.png',
|
|
83
|
+
'.svg',
|
|
84
|
+
...queryExtensions(['css', 'graphql', 'jpeg', 'less', 'sass', 'sass', 'yaml']),
|
|
85
|
+
]);
|
|
87
86
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
87
|
+
/**
|
|
88
|
+
* Resource file extensions
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```ts
|
|
92
|
+
* Project.resourceExtensions() // ['.css', '.sass', ...]
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
function resourceExtensions() {
|
|
96
|
+
return RESOURCE_EXTENSIONS;
|
|
97
|
+
}
|
|
99
98
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
99
|
+
const IGNORED = Object.freeze([
|
|
100
|
+
'node_modules/',
|
|
101
|
+
'build/',
|
|
102
|
+
'cjs/',
|
|
103
|
+
'coverage/',
|
|
104
|
+
'dist/',
|
|
105
|
+
'dts/',
|
|
106
|
+
'esm/',
|
|
107
|
+
'lib/',
|
|
108
|
+
'mjs/',
|
|
109
|
+
'umd/',
|
|
110
|
+
]);
|
|
112
111
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
112
|
+
/**
|
|
113
|
+
* Files and folders to always ignore
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```ts
|
|
117
|
+
* IGNORED // ['node_modules/', 'build/', ...]
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
function ignored() {
|
|
121
|
+
return IGNORED;
|
|
122
|
+
}
|
|
124
123
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
124
|
+
/**
|
|
125
|
+
* Return a RegExp that will match any list of extensions
|
|
126
|
+
*
|
|
127
|
+
* @param extensions
|
|
128
|
+
* @example
|
|
129
|
+
* ```ts
|
|
130
|
+
* Project.extensionsToMatcher(['.js', '.ts']) // RegExp = /(\.js|\.ts)$/
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
function extensionsToMatcher(extensions: readonly Extension[]): RegExp {
|
|
134
|
+
return new RegExp(`(${extensions.map(escapeRegExp).join('|')})$`);
|
|
135
|
+
}
|
|
137
136
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
137
|
+
/**
|
|
138
|
+
* Return a glob matcher that will match any list of extensions
|
|
139
|
+
*
|
|
140
|
+
* @param extensions
|
|
141
|
+
* @example
|
|
142
|
+
* ```ts
|
|
143
|
+
* Project.extensionsToGlob(['.js', '.ts']) // '*.+(js|ts)'
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
function extensionsToGlob(extensions: readonly Extension[]): string {
|
|
147
|
+
return `*.+(${extensions.map((_) => _.replace(/^\./, '')).join('|')})`;
|
|
150
148
|
}
|
|
149
|
+
|
|
150
|
+
export const Project = Object.freeze({
|
|
151
|
+
ecmaVersion,
|
|
152
|
+
extensionsToGlob,
|
|
153
|
+
extensionsToMatcher,
|
|
154
|
+
ignored,
|
|
155
|
+
queryExtensions,
|
|
156
|
+
resourceExtensions,
|
|
157
|
+
sourceExtensions,
|
|
158
|
+
});
|
package/src/ProjectScript.ts
CHANGED
package/dist/index.d.cts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/ESLintConfig.ts","../src/interopDefault.ts","../src/LanguageId.ts","../src/meta.ts","../src/Project.ts","../src/ProjectScript.ts"],"mappings":";;;kBAgBiB,YAAA;;AAAjB;;;WAKkB,MAAA,CAAA,GAAU,OAAA,EAAS,MAAA,CAAO,UAAA,KAAe,MAAA,CAAO,UAAA;EAAP;;;;;EAAA,SAgCzC,KAAA,CAAM,OAAA;EAhCN;;;;;;;;;;EAAA,SA8CA,WAAA,CAAY,KAAA,EAAO,MAAA,eAAqB,GAAA,EAAK,MAAA,mBAAyB,MAAA;AAAA;;;;;;AAnDxF;;;;;;;;;;;;;;;;;iBCMgB,cAAA,GAAA,CAAkB,CAAA,EAAG,WAAA,CAAY,CAAA,IAAK,OAAA,CAAQ,CAAA;EAAY,OAAA;AAAA,IAAqB,CAAA,GAAI,CAAA;AAAA,iBACnF,cAAA,GAAA,CAAkB,CAAA,EAAG,CAAA,GAAI,CAAA;EAAY,OAAA;AAAA,IAAqB,CAAA,GAAI,CAAA;;;UCvB7D,aAAA;EACf,GAAA;EACA,OAAA;EACA,UAAA;EACA,eAAA;EACA,IAAA;EACA,IAAA;EACA,KAAA;EACA,IAAA;EACA,QAAA;EACA,IAAA;EACA,IAAA;EACA,UAAA;EACA,eAAA;EACA,GAAA;EACA,IAAA;AAAA;;;;KAMU,UAAA,SAAmB,aAAA;;;cCrBlB,IAAA,EAAI,QAAA;;;;;;;kBCOA,OAAA;;AJSjB;;OILc,SAAA;EJUuB;;;EAAA,KILvB,iBAAA,WAA4B,UAAA,YAAsB,SAAA;EJmD8B;;;;;;;;EAAA,SIzC5E,WAAA,CAAA;EJyCA;;;;;;;;;;;EAAA,SIRA,eAAA,CAAgB,SAAA,EAAW,UAAA,cAAwB,SAAA;EHrCvC;;;;;;;;EAAA,SGsDZ,gBAAA,CAAA;EHtDa;;;;;;;;EAAA,SGyEb,kBAAA,CAAA;EHzEiF;;;AACnG;;;;;EADmG,SGkGjF,OAAA,CAAA;EHjG6D;;;;;;;;;EAAA,SG8G7D,mBAAA,CAAoB,UAAA,WAAqB,SAAA,KAAc,MAAA;EH9GM;;;;;ACvB/E;;;;EDuB+E,SG2H7D,gBAAA,CAAiB,UAAA,WAAqB,SAAA;AAAA;;;;;;cC/I3C,aAAA;EAAA;;;;;;;;;;;;;;;;KAiBD,aAAA,WAAwB,aAAA,eAA4B,aAAA"}
|