@yuu1111/quality-check 1.0.0 → 4.0.0
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/README.ja.md +102 -46
- package/README.md +105 -49
- package/dist/cli.js +21876 -419
- package/package.json +11 -14
- package/schema.json +688 -0
- package/src/config.ts +0 -490
- package/src/engines.ts +0 -403
package/src/config.ts
DELETED
|
@@ -1,490 +0,0 @@
|
|
|
1
|
-
import { existsSync } from "node:fs";
|
|
2
|
-
import { resolve } from "node:path";
|
|
3
|
-
import { pathToFileURL } from "node:url";
|
|
4
|
-
import {
|
|
5
|
-
OPT_IN_RULE_IDS as COMMENT_CHECK_OPT_IN_RULE_IDS,
|
|
6
|
-
RULE_IDS as COMMENT_CHECK_RULE_IDS,
|
|
7
|
-
type OptInRuleId as CommentCheckRuleName,
|
|
8
|
-
} from "@yuu1111/comment-check/rule-ids";
|
|
9
|
-
import {
|
|
10
|
-
OPT_IN_RULE_IDS as DOCUMENT_STYLE_CHECK_OPT_IN_RULE_IDS,
|
|
11
|
-
RULE_IDS as DOCUMENT_STYLE_CHECK_RULE_IDS,
|
|
12
|
-
type OptInRuleId as DocumentStyleCheckRuleName,
|
|
13
|
-
} from "@yuu1111/document-style-check/rule-ids";
|
|
14
|
-
import {
|
|
15
|
-
OPT_IN_RULE_IDS as TSDOC_CHECK_OPT_IN_RULE_IDS,
|
|
16
|
-
KNOWN_RULE_NAMES as TSDOC_CHECK_RULE_NAMES,
|
|
17
|
-
type TsdocRule,
|
|
18
|
-
} from "@yuu1111/tsdoc-check/rule-ids";
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* 統合CLIが起動できるengineの名前 並び順が実行順になる
|
|
22
|
-
*/
|
|
23
|
-
export const ENGINE_NAMES = [
|
|
24
|
-
"biome",
|
|
25
|
-
"typecheck",
|
|
26
|
-
"knip",
|
|
27
|
-
"code-style-check",
|
|
28
|
-
"comment-check",
|
|
29
|
-
"document-style-check",
|
|
30
|
-
"tsdoc-check",
|
|
31
|
-
] as const;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* engine名のunion型
|
|
35
|
-
*/
|
|
36
|
-
export type EngineName = (typeof ENGINE_NAMES)[number];
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* engineへ渡す起動条件
|
|
40
|
-
*/
|
|
41
|
-
export interface EngineOptions {
|
|
42
|
-
/** 検査から外すpath engineが受け取れないときはreportへ出す */
|
|
43
|
-
ignore?: string[];
|
|
44
|
-
/** 検査する対象path engineが受け取れないときはreportへ出す */
|
|
45
|
-
targets?: string[];
|
|
46
|
-
/** engineの既定引数の後ろへ足す引数 */
|
|
47
|
-
args?: string[];
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* comment-checkへ渡す起動条件
|
|
52
|
-
*/
|
|
53
|
-
export interface CommentCheckOptions extends EngineOptions {
|
|
54
|
-
/** 既定で無効のopt-in ruleを全て有効にする */
|
|
55
|
-
enable?: boolean;
|
|
56
|
-
/** rule名ごとの状態 offで無効 onで有効 省略したruleはengineの既定に従う */
|
|
57
|
-
rules?: Partial<Record<CommentCheckRuleName, "off" | "on">>;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* document-style-checkへ渡す起動条件
|
|
62
|
-
*/
|
|
63
|
-
export interface DocumentStyleCheckOptions extends EngineOptions {
|
|
64
|
-
/** 既定で無効のopt-in ruleを全て有効にする */
|
|
65
|
-
enable?: boolean;
|
|
66
|
-
/** rule名ごとの状態 offで無効 onで有効 省略したruleはengineの既定に従う */
|
|
67
|
-
rules?: Partial<Record<DocumentStyleCheckRuleName, "off" | "on">>;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* TSDoc検査へ渡す起動条件
|
|
72
|
-
*/
|
|
73
|
-
export interface TsdocCheckOptions extends EngineOptions {
|
|
74
|
-
/** 既定で無効のopt-in ruleを全て有効にする */
|
|
75
|
-
enable?: boolean;
|
|
76
|
-
/** 全てのruleを違反として扱う opt-in ruleは有効にしてから上げる */
|
|
77
|
-
error?: boolean;
|
|
78
|
-
/** rule名ごとの状態 offで無効 onで既定のseverity errorで違反として扱う */
|
|
79
|
-
rules?: Partial<Record<TsdocRule, "off" | "on" | "error">>;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* 型検査へ渡す起動条件
|
|
84
|
-
*/
|
|
85
|
-
export interface TypecheckOptions extends EngineOptions {
|
|
86
|
-
/** 型検査するtsconfigのpath 省略時はカレントのtsconfig.jsonを1回だけ読む */
|
|
87
|
-
projects?: string[];
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* engine名ごとの起動条件
|
|
92
|
-
*/
|
|
93
|
-
export interface EngineConfigMap {
|
|
94
|
-
biome: EngineOptions;
|
|
95
|
-
typecheck: TypecheckOptions;
|
|
96
|
-
knip: EngineOptions;
|
|
97
|
-
"code-style-check": EngineOptions;
|
|
98
|
-
"comment-check": CommentCheckOptions;
|
|
99
|
-
"document-style-check": DocumentStyleCheckOptions;
|
|
100
|
-
"tsdoc-check": TsdocCheckOptions;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* rule名ごとの状態
|
|
105
|
-
*/
|
|
106
|
-
export type RuleState = "off" | "on" | "error";
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* engineが公開するrule語彙 全ruleと既定で無効のopt-in ruleを持つ
|
|
110
|
-
*/
|
|
111
|
-
export const RULE_VOCABULARY: Record<
|
|
112
|
-
EngineName,
|
|
113
|
-
{ all: readonly string[]; optIn: readonly string[]; promotes: boolean }
|
|
114
|
-
> = {
|
|
115
|
-
biome: { all: [], optIn: [], promotes: false },
|
|
116
|
-
typecheck: { all: [], optIn: [], promotes: false },
|
|
117
|
-
knip: { all: [], optIn: [], promotes: false },
|
|
118
|
-
"code-style-check": { all: [], optIn: [], promotes: false },
|
|
119
|
-
"comment-check": {
|
|
120
|
-
all: COMMENT_CHECK_RULE_IDS,
|
|
121
|
-
optIn: COMMENT_CHECK_OPT_IN_RULE_IDS,
|
|
122
|
-
promotes: false,
|
|
123
|
-
},
|
|
124
|
-
"document-style-check": {
|
|
125
|
-
all: DOCUMENT_STYLE_CHECK_RULE_IDS,
|
|
126
|
-
optIn: DOCUMENT_STYLE_CHECK_OPT_IN_RULE_IDS,
|
|
127
|
-
promotes: false,
|
|
128
|
-
},
|
|
129
|
-
"tsdoc-check": {
|
|
130
|
-
all: TSDOC_CHECK_RULE_NAMES,
|
|
131
|
-
optIn: TSDOC_CHECK_OPT_IN_RULE_IDS,
|
|
132
|
-
promotes: true,
|
|
133
|
-
},
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* quality.config.tsが受け付ける統合検査の設定
|
|
138
|
-
*/
|
|
139
|
-
export interface QualityConfig {
|
|
140
|
-
/** 起動するengine 値がfalseまたは未指定のengineは起動しない */
|
|
141
|
-
engines: Partial<Record<EngineName, boolean>>;
|
|
142
|
-
/** engineごとの起動条件 省略したengineは既定値で起動する */
|
|
143
|
-
config?: Partial<EngineConfigMap>;
|
|
144
|
-
/** baseline fileのpath falseなら差分判定を行わない */
|
|
145
|
-
baseline?: string | false;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* 設定fileを型付けするための恒等関数
|
|
150
|
-
*
|
|
151
|
-
* @param config - 型付けする統合検査の設定
|
|
152
|
-
* @returns 引数をそのまま返した統合検査の設定
|
|
153
|
-
*/
|
|
154
|
-
export function defineConfig(config: QualityConfig): QualityConfig {
|
|
155
|
-
return config;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* config fileを探索する既定のfile名
|
|
160
|
-
*/
|
|
161
|
-
export const DEFAULT_CONFIG_FILES = [
|
|
162
|
-
"quality.config.ts",
|
|
163
|
-
"quality.config.mts",
|
|
164
|
-
"quality.config.js",
|
|
165
|
-
"quality.config.mjs",
|
|
166
|
-
] as const;
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* baseline fileの既定名
|
|
170
|
-
*/
|
|
171
|
-
export const DEFAULT_BASELINE_FILE = "quality-baseline.json";
|
|
172
|
-
|
|
173
|
-
type JsonObject = Record<string, unknown>;
|
|
174
|
-
|
|
175
|
-
function isJsonObject(value: unknown): value is JsonObject {
|
|
176
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
function isEngineName(value: string): value is EngineName {
|
|
180
|
-
return (ENGINE_NAMES as readonly string[]).includes(value);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const ENGINE_OPTION_KEYS: Record<EngineName, readonly string[]> = {
|
|
184
|
-
biome: ["args", "ignore", "targets"],
|
|
185
|
-
typecheck: ["args", "ignore", "projects", "targets"],
|
|
186
|
-
knip: ["args", "ignore", "targets"],
|
|
187
|
-
"code-style-check": ["args", "ignore", "targets"],
|
|
188
|
-
"comment-check": ["args", "enable", "ignore", "rules", "targets"],
|
|
189
|
-
"document-style-check": ["args", "enable", "ignore", "rules", "targets"],
|
|
190
|
-
"tsdoc-check": ["args", "enable", "error", "ignore", "rules", "targets"],
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
function readStringArray(value: unknown, field: string): string[] | undefined {
|
|
194
|
-
if (value === undefined) {
|
|
195
|
-
return undefined;
|
|
196
|
-
}
|
|
197
|
-
if (
|
|
198
|
-
!Array.isArray(value) ||
|
|
199
|
-
value.some((entry) => typeof entry !== "string" || entry === "")
|
|
200
|
-
) {
|
|
201
|
-
throw new Error(`${field} must be an array of non-empty strings`);
|
|
202
|
-
}
|
|
203
|
-
return [...value] as string[];
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
function readBoolean(value: unknown, field: string): boolean | undefined {
|
|
207
|
-
if (value === undefined) {
|
|
208
|
-
return undefined;
|
|
209
|
-
}
|
|
210
|
-
if (typeof value !== "boolean") {
|
|
211
|
-
throw new Error(`${field} must be a boolean`);
|
|
212
|
-
}
|
|
213
|
-
return value;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* rule名ごとの状態を読み取る engineが公開する語彙とengineが受け付ける状態で検証する
|
|
218
|
-
*/
|
|
219
|
-
function readRuleStates(
|
|
220
|
-
value: unknown,
|
|
221
|
-
field: string,
|
|
222
|
-
name: EngineName,
|
|
223
|
-
): Record<string, RuleState> | undefined {
|
|
224
|
-
if (value === undefined) {
|
|
225
|
-
return undefined;
|
|
226
|
-
}
|
|
227
|
-
if (!isJsonObject(value)) {
|
|
228
|
-
throw new Error(`${field} must be an object`);
|
|
229
|
-
}
|
|
230
|
-
const vocabulary = RULE_VOCABULARY[name];
|
|
231
|
-
const states: Record<string, RuleState> = {};
|
|
232
|
-
for (const [rule, state] of Object.entries(value)) {
|
|
233
|
-
if (!vocabulary.all.includes(rule)) {
|
|
234
|
-
throw new Error(`${field} has an unknown rule: ${rule}`);
|
|
235
|
-
}
|
|
236
|
-
if (state !== "off" && state !== "on" && state !== "error") {
|
|
237
|
-
throw new Error(`${field}.${rule} must be "off", "on" or "error"`);
|
|
238
|
-
}
|
|
239
|
-
if (state === "error" && !vocabulary.promotes) {
|
|
240
|
-
throw new Error(
|
|
241
|
-
`${field}.${rule}: ${name} cannot treat a rule as an error`,
|
|
242
|
-
);
|
|
243
|
-
}
|
|
244
|
-
if (state === "off" && !vocabulary.optIn.includes(rule)) {
|
|
245
|
-
throw new Error(
|
|
246
|
-
`${field}.${rule}: ${name} cannot turn off a rule that is on by default`,
|
|
247
|
-
);
|
|
248
|
-
}
|
|
249
|
-
states[rule] = state;
|
|
250
|
-
}
|
|
251
|
-
return states;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
function readBaseline(
|
|
255
|
-
value: unknown,
|
|
256
|
-
source: string,
|
|
257
|
-
): string | false | undefined {
|
|
258
|
-
if (value === undefined || value === false) {
|
|
259
|
-
return value;
|
|
260
|
-
}
|
|
261
|
-
if (typeof value === "string" && value !== "") {
|
|
262
|
-
return value;
|
|
263
|
-
}
|
|
264
|
-
throw new Error(`${source}: baseline must be a path string or false`);
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
function parseEngines(
|
|
268
|
-
value: unknown,
|
|
269
|
-
source: string,
|
|
270
|
-
): Partial<Record<EngineName, boolean>> {
|
|
271
|
-
if (!isJsonObject(value)) {
|
|
272
|
-
throw new Error(`${source} must export an engines object`);
|
|
273
|
-
}
|
|
274
|
-
const engines: Partial<Record<EngineName, boolean>> = {};
|
|
275
|
-
for (const [name, enabled] of Object.entries(value)) {
|
|
276
|
-
if (!isEngineName(name)) {
|
|
277
|
-
throw new Error(`${source}: unknown engine: ${name}`);
|
|
278
|
-
}
|
|
279
|
-
if (typeof enabled !== "boolean") {
|
|
280
|
-
throw new Error(
|
|
281
|
-
`${source}: engines.${name} must be a boolean 起動条件はconfigへ置く`,
|
|
282
|
-
);
|
|
283
|
-
}
|
|
284
|
-
engines[name] = enabled;
|
|
285
|
-
}
|
|
286
|
-
if (ENGINE_NAMES.every((name) => !engines[name])) {
|
|
287
|
-
throw new Error(`${source} must enable at least one engine`);
|
|
288
|
-
}
|
|
289
|
-
return engines;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
type ParsedEngineOptions = EngineOptions & {
|
|
293
|
-
enable?: boolean;
|
|
294
|
-
error?: boolean;
|
|
295
|
-
projects?: string[];
|
|
296
|
-
rules?: Record<string, RuleState>;
|
|
297
|
-
};
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* engine名ごとにしか受け取らない起動条件を読み取る
|
|
301
|
-
*/
|
|
302
|
-
function parseEngineExtras(
|
|
303
|
-
value: JsonObject,
|
|
304
|
-
source: string,
|
|
305
|
-
name: EngineName,
|
|
306
|
-
): ParsedEngineOptions {
|
|
307
|
-
const extras: ParsedEngineOptions = {};
|
|
308
|
-
if (
|
|
309
|
-
name === "comment-check" ||
|
|
310
|
-
name === "document-style-check" ||
|
|
311
|
-
name === "tsdoc-check"
|
|
312
|
-
) {
|
|
313
|
-
const enable = readBoolean(
|
|
314
|
-
value.enable,
|
|
315
|
-
`${source}: config.${name}.enable`,
|
|
316
|
-
);
|
|
317
|
-
if (enable !== undefined) {
|
|
318
|
-
extras.enable = enable;
|
|
319
|
-
}
|
|
320
|
-
const rules = readRuleStates(
|
|
321
|
-
value.rules,
|
|
322
|
-
`${source}: config.${name}.rules`,
|
|
323
|
-
name,
|
|
324
|
-
);
|
|
325
|
-
if (rules !== undefined) {
|
|
326
|
-
extras.rules = rules;
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
if (name === "tsdoc-check") {
|
|
330
|
-
const error = readBoolean(value.error, `${source}: config.${name}.error`);
|
|
331
|
-
if (error !== undefined) {
|
|
332
|
-
extras.error = error;
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
if (name === "typecheck") {
|
|
336
|
-
const projects = readStringArray(
|
|
337
|
-
value.projects,
|
|
338
|
-
`${source}: config.${name}.projects`,
|
|
339
|
-
);
|
|
340
|
-
if (projects !== undefined) {
|
|
341
|
-
if (projects.length === 0) {
|
|
342
|
-
throw new Error(`${source}: config.${name}.projects must not be empty`);
|
|
343
|
-
}
|
|
344
|
-
extras.projects = projects;
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
return extras;
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
function parseEngineOptions(
|
|
351
|
-
value: JsonObject,
|
|
352
|
-
source: string,
|
|
353
|
-
name: EngineName,
|
|
354
|
-
): ParsedEngineOptions {
|
|
355
|
-
const unknown = Object.keys(value).filter(
|
|
356
|
-
(key) => !ENGINE_OPTION_KEYS[name].includes(key),
|
|
357
|
-
);
|
|
358
|
-
if (unknown.length > 0) {
|
|
359
|
-
throw new Error(
|
|
360
|
-
`${source}: config.${name} has an unknown option: ${unknown[0]}`,
|
|
361
|
-
);
|
|
362
|
-
}
|
|
363
|
-
const options: ParsedEngineOptions = {};
|
|
364
|
-
const ignore = readStringArray(
|
|
365
|
-
value.ignore,
|
|
366
|
-
`${source}: config.${name}.ignore`,
|
|
367
|
-
);
|
|
368
|
-
if (ignore !== undefined) {
|
|
369
|
-
options.ignore = ignore;
|
|
370
|
-
}
|
|
371
|
-
const targets = readStringArray(
|
|
372
|
-
value.targets,
|
|
373
|
-
`${source}: config.${name}.targets`,
|
|
374
|
-
);
|
|
375
|
-
if (targets !== undefined) {
|
|
376
|
-
options.targets = targets;
|
|
377
|
-
}
|
|
378
|
-
const args = readStringArray(value.args, `${source}: config.${name}.args`);
|
|
379
|
-
if (args !== undefined) {
|
|
380
|
-
options.args = args;
|
|
381
|
-
}
|
|
382
|
-
return { ...options, ...parseEngineExtras(value, source, name) };
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
function parseEngineConfig(
|
|
386
|
-
value: unknown,
|
|
387
|
-
source: string,
|
|
388
|
-
): Partial<EngineConfigMap> | undefined {
|
|
389
|
-
if (value === undefined) {
|
|
390
|
-
return undefined;
|
|
391
|
-
}
|
|
392
|
-
if (!isJsonObject(value)) {
|
|
393
|
-
throw new Error(`${source}: config must be an object`);
|
|
394
|
-
}
|
|
395
|
-
const config: Partial<Record<EngineName, ParsedEngineOptions>> = {};
|
|
396
|
-
for (const [name, options] of Object.entries(value)) {
|
|
397
|
-
if (!isEngineName(name)) {
|
|
398
|
-
throw new Error(`${source}: unknown engine in config: ${name}`);
|
|
399
|
-
}
|
|
400
|
-
if (!isJsonObject(options)) {
|
|
401
|
-
throw new Error(`${source}: config.${name} must be an object`);
|
|
402
|
-
}
|
|
403
|
-
config[name] = parseEngineOptions(options, source, name);
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
// rule名はengineが公開するunionで縛る 実行時の入力は文字列として届くため検証済みの値をここで型へ寄せる
|
|
407
|
-
return config as Partial<EngineConfigMap>;
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
/**
|
|
411
|
-
* 読み込んだ設定を検証して不足分を補う
|
|
412
|
-
*
|
|
413
|
-
* @param value - config fileがexportした検証前の値
|
|
414
|
-
* @param source - errorメッセージへ載せるconfig fileのpath
|
|
415
|
-
* @returns 検証して既定値を補った統合検査の設定
|
|
416
|
-
*/
|
|
417
|
-
export function parseConfig(value: unknown, source: string): QualityConfig {
|
|
418
|
-
if (!isJsonObject(value)) {
|
|
419
|
-
throw new Error(`${source} must export a config object`);
|
|
420
|
-
}
|
|
421
|
-
const config: QualityConfig = {
|
|
422
|
-
engines: parseEngines(value.engines, source),
|
|
423
|
-
};
|
|
424
|
-
const engineConfig = parseEngineConfig(value.config, source);
|
|
425
|
-
if (engineConfig !== undefined) {
|
|
426
|
-
config.config = engineConfig;
|
|
427
|
-
}
|
|
428
|
-
const baseline = readBaseline(value.baseline, source);
|
|
429
|
-
if (baseline !== undefined) {
|
|
430
|
-
config.baseline = baseline;
|
|
431
|
-
}
|
|
432
|
-
return config;
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
/**
|
|
436
|
-
* 有効なengineを実行順で返す
|
|
437
|
-
*
|
|
438
|
-
* @param config - engineの有効無効を持つ統合検査の設定
|
|
439
|
-
* @returns 有効なengine名を実行順に並べた配列
|
|
440
|
-
*/
|
|
441
|
-
export function enabledEngines(config: QualityConfig): EngineName[] {
|
|
442
|
-
return ENGINE_NAMES.filter((name) => Boolean(config.engines[name]));
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
/**
|
|
446
|
-
* engineの起動条件を返す 無効なengineにはnullを返す
|
|
447
|
-
*
|
|
448
|
-
* @typeParam K - 起動条件を取り出すengine名の型
|
|
449
|
-
* @param config - engineごとの起動条件を持つ統合検査の設定
|
|
450
|
-
* @param name - 起動条件を取り出すengine名
|
|
451
|
-
* @returns 指定したengineの起動条件 無効なengineならnull
|
|
452
|
-
*/
|
|
453
|
-
export function engineConfig<K extends EngineName>(
|
|
454
|
-
config: QualityConfig,
|
|
455
|
-
name: K,
|
|
456
|
-
): EngineConfigMap[K] | null {
|
|
457
|
-
if (!config.engines[name]) {
|
|
458
|
-
return null;
|
|
459
|
-
}
|
|
460
|
-
return config.config?.[name] ?? ({} as EngineConfigMap[K]);
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
/**
|
|
464
|
-
* 作業ディレクトリからconfig fileを探す
|
|
465
|
-
*
|
|
466
|
-
* @param cwd - 探索を開始する作業ディレクトリのpath
|
|
467
|
-
* @returns 見つけたconfig fileのpath 見つからなければnull
|
|
468
|
-
*/
|
|
469
|
-
export function findConfigFile(cwd: string): string | null {
|
|
470
|
-
for (const name of DEFAULT_CONFIG_FILES) {
|
|
471
|
-
const candidate = resolve(cwd, name);
|
|
472
|
-
if (existsSync(candidate)) {
|
|
473
|
-
return candidate;
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
return null;
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
/**
|
|
480
|
-
* config fileを読み込んで検証する
|
|
481
|
-
*
|
|
482
|
-
* @param path - 読み込むconfig fileのpath
|
|
483
|
-
* @returns 読み込んで検証した統合検査の設定
|
|
484
|
-
*/
|
|
485
|
-
export async function loadConfig(path: string): Promise<QualityConfig> {
|
|
486
|
-
const module: unknown = await import(pathToFileURL(path).href);
|
|
487
|
-
const value =
|
|
488
|
-
isJsonObject(module) && "default" in module ? module.default : module;
|
|
489
|
-
return parseConfig(value, path);
|
|
490
|
-
}
|