@geoql/doctor-core 0.1.0-alpha.0 → 0.1.1
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.md +70 -10
- package/dist/index.d.ts +381 -11
- package/dist/index.js +2895 -198
- package/dist/index.js.map +1 -1
- package/dist/load-BGjurxpY.js +629 -0
- package/dist/load-BGjurxpY.js.map +1 -0
- package/package.json +14 -5
|
@@ -0,0 +1,629 @@
|
|
|
1
|
+
import { extname, resolve } from "node:path";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { loadConfig } from "c12";
|
|
4
|
+
//#region \0rolldown/runtime.js
|
|
5
|
+
var __defProp = Object.defineProperty;
|
|
6
|
+
var __exportAll = (all, no_symbols) => {
|
|
7
|
+
let target = {};
|
|
8
|
+
for (var name in all) __defProp(target, name, {
|
|
9
|
+
get: all[name],
|
|
10
|
+
enumerable: true
|
|
11
|
+
});
|
|
12
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
13
|
+
return target;
|
|
14
|
+
};
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/config/built-in.ts
|
|
17
|
+
const BUILT_IN_RECOMMENDED = {
|
|
18
|
+
include: [
|
|
19
|
+
"**/*.vue",
|
|
20
|
+
"**/*.ts",
|
|
21
|
+
"**/*.tsx",
|
|
22
|
+
"**/*.js",
|
|
23
|
+
"**/*.jsx"
|
|
24
|
+
],
|
|
25
|
+
exclude: [
|
|
26
|
+
"node_modules",
|
|
27
|
+
"dist",
|
|
28
|
+
".nuxt",
|
|
29
|
+
".output",
|
|
30
|
+
"coverage"
|
|
31
|
+
],
|
|
32
|
+
failOn: "error",
|
|
33
|
+
threshold: 0,
|
|
34
|
+
rules: {}
|
|
35
|
+
};
|
|
36
|
+
//#endregion
|
|
37
|
+
//#region src/config/errors.ts
|
|
38
|
+
var ConfigFileNotFoundError = class extends Error {
|
|
39
|
+
name = "ConfigFileNotFoundError";
|
|
40
|
+
constructor(path) {
|
|
41
|
+
super(`Config file not found: ${path}`);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
var ConfigCycleError = class extends Error {
|
|
45
|
+
name = "ConfigCycleError";
|
|
46
|
+
constructor(chain) {
|
|
47
|
+
super(`Config extends cycle detected: ${chain.join(" -> ")}`);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
var InvalidConfigError = class extends Error {
|
|
51
|
+
name = "InvalidConfigError";
|
|
52
|
+
};
|
|
53
|
+
//#endregion
|
|
54
|
+
//#region src/rule-registry.ts
|
|
55
|
+
const RULE_REGISTRY = [
|
|
56
|
+
{
|
|
57
|
+
id: "vue/no-export-in-script-setup",
|
|
58
|
+
severity: "error",
|
|
59
|
+
category: "vue-builtin",
|
|
60
|
+
source: "oxlint-builtin",
|
|
61
|
+
recommended: true
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: "vue/require-typed-ref",
|
|
65
|
+
severity: "warn",
|
|
66
|
+
category: "vue-builtin",
|
|
67
|
+
source: "oxlint-builtin",
|
|
68
|
+
recommended: true
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: "vue-doctor/no-em-dash-in-string",
|
|
72
|
+
severity: "warn",
|
|
73
|
+
category: "ai-slop",
|
|
74
|
+
source: "doctor",
|
|
75
|
+
recommended: true
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
id: "vue-doctor/no-destructure-props-without-to-refs",
|
|
79
|
+
severity: "error",
|
|
80
|
+
category: "ai-slop",
|
|
81
|
+
source: "doctor",
|
|
82
|
+
recommended: true
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
id: "vue-doctor/no-destructure-reactive-without-to-refs",
|
|
86
|
+
severity: "error",
|
|
87
|
+
category: "ai-slop",
|
|
88
|
+
source: "doctor",
|
|
89
|
+
recommended: true
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
id: "vue-doctor/no-non-null-assertion-on-ref-value",
|
|
93
|
+
severity: "warn",
|
|
94
|
+
category: "ai-slop",
|
|
95
|
+
source: "doctor",
|
|
96
|
+
recommended: true
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: "vue-doctor/no-imports-from-vue-when-auto-imported",
|
|
100
|
+
severity: "warn",
|
|
101
|
+
category: "ai-slop",
|
|
102
|
+
source: "doctor",
|
|
103
|
+
recommended: true
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
id: "vue-doctor/reactivity/watch-without-cleanup",
|
|
107
|
+
severity: "warn",
|
|
108
|
+
category: "reactivity",
|
|
109
|
+
source: "doctor",
|
|
110
|
+
recommended: true
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: "vue-doctor/reactivity/prefer-shallowRef-for-large-data",
|
|
114
|
+
severity: "info",
|
|
115
|
+
category: "reactivity",
|
|
116
|
+
source: "doctor",
|
|
117
|
+
recommended: false
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
id: "vue-doctor/reactivity/prefer-readonly-for-injected",
|
|
121
|
+
severity: "info",
|
|
122
|
+
category: "reactivity",
|
|
123
|
+
source: "doctor",
|
|
124
|
+
recommended: false
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
id: "vue-doctor/composition/prefer-script-setup-for-new-files",
|
|
128
|
+
severity: "warn",
|
|
129
|
+
category: "composition",
|
|
130
|
+
source: "doctor",
|
|
131
|
+
recommended: true
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
id: "vue-doctor/composition/defineProps-typed",
|
|
135
|
+
severity: "warn",
|
|
136
|
+
category: "composition",
|
|
137
|
+
source: "doctor",
|
|
138
|
+
recommended: true
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
id: "vue-doctor/performance/prefer-defineAsyncComponent-on-route",
|
|
142
|
+
severity: "info",
|
|
143
|
+
category: "performance",
|
|
144
|
+
source: "doctor",
|
|
145
|
+
recommended: false
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
id: "vue-doctor/template/v-for-has-key",
|
|
149
|
+
severity: "error",
|
|
150
|
+
category: "template",
|
|
151
|
+
source: "doctor",
|
|
152
|
+
recommended: true
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
id: "vue-doctor/template/v-if-v-for-precedence",
|
|
156
|
+
severity: "error",
|
|
157
|
+
category: "template",
|
|
158
|
+
source: "doctor",
|
|
159
|
+
recommended: true
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
id: "vue-doctor/template/v-memo-on-large-list",
|
|
163
|
+
severity: "warn",
|
|
164
|
+
category: "performance",
|
|
165
|
+
source: "doctor",
|
|
166
|
+
recommended: true
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
id: "vue-doctor/template/no-inline-object-prop-in-list",
|
|
170
|
+
severity: "warn",
|
|
171
|
+
category: "performance",
|
|
172
|
+
source: "doctor",
|
|
173
|
+
recommended: true
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
id: "vue-doctor/template/no-computed-getter-in-template-loop",
|
|
177
|
+
severity: "warn",
|
|
178
|
+
category: "template-perf",
|
|
179
|
+
source: "doctor",
|
|
180
|
+
recommended: true
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
id: "vue-doctor/template/avoid-deep-v-bind-spread-in-list",
|
|
184
|
+
severity: "info",
|
|
185
|
+
category: "template-perf",
|
|
186
|
+
source: "doctor",
|
|
187
|
+
recommended: true
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
id: "vue-doctor/sfc/no-mixed-options-and-composition-api",
|
|
191
|
+
severity: "warn",
|
|
192
|
+
category: "sfc",
|
|
193
|
+
source: "doctor",
|
|
194
|
+
recommended: true
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
id: "vue-doctor/build-quality/tsconfig-strict-required",
|
|
198
|
+
severity: "warn",
|
|
199
|
+
category: "build-quality",
|
|
200
|
+
source: "doctor",
|
|
201
|
+
recommended: true
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
id: "vue-doctor/build-quality/vue-tsc-in-devDeps",
|
|
205
|
+
severity: "warn",
|
|
206
|
+
category: "build-quality",
|
|
207
|
+
source: "doctor",
|
|
208
|
+
recommended: true
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
id: "vue-doctor/build-quality/no-vue-cli",
|
|
212
|
+
severity: "warn",
|
|
213
|
+
category: "build-quality",
|
|
214
|
+
source: "doctor",
|
|
215
|
+
recommended: true
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
id: "vue-doctor/build-quality/eslint-plugin-vue-installed",
|
|
219
|
+
severity: "info",
|
|
220
|
+
category: "build-quality",
|
|
221
|
+
source: "doctor",
|
|
222
|
+
recommended: true
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
id: "vue-doctor/deps/duplicate-vue-versions",
|
|
226
|
+
severity: "error",
|
|
227
|
+
category: "deps",
|
|
228
|
+
source: "doctor",
|
|
229
|
+
recommended: true
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
id: "vue-doctor/deps/vue-major-current",
|
|
233
|
+
severity: "info",
|
|
234
|
+
category: "deps",
|
|
235
|
+
source: "doctor",
|
|
236
|
+
recommended: false
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
id: "dead-code/unused-file",
|
|
240
|
+
severity: "warn",
|
|
241
|
+
category: "dead-code",
|
|
242
|
+
source: "doctor",
|
|
243
|
+
recommended: true
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
id: "dead-code/unused-export",
|
|
247
|
+
severity: "warn",
|
|
248
|
+
category: "dead-code",
|
|
249
|
+
source: "doctor",
|
|
250
|
+
recommended: true
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
id: "dead-code/unused-type-export",
|
|
254
|
+
severity: "info",
|
|
255
|
+
category: "dead-code",
|
|
256
|
+
source: "doctor",
|
|
257
|
+
recommended: true
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
id: "dead-code/unused-member",
|
|
261
|
+
severity: "info",
|
|
262
|
+
category: "dead-code",
|
|
263
|
+
source: "doctor",
|
|
264
|
+
recommended: true
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
id: "dead-code/unused-dependency",
|
|
268
|
+
severity: "warn",
|
|
269
|
+
category: "dead-code",
|
|
270
|
+
source: "doctor",
|
|
271
|
+
recommended: true
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
id: "dead-code/unlisted-dependency",
|
|
275
|
+
severity: "error",
|
|
276
|
+
category: "dead-code",
|
|
277
|
+
source: "doctor",
|
|
278
|
+
recommended: true
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
id: "dead-code/duplicate-export",
|
|
282
|
+
severity: "warn",
|
|
283
|
+
category: "dead-code",
|
|
284
|
+
source: "doctor",
|
|
285
|
+
recommended: true
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
id: "nuxt-doctor/structure/uses-app-directory",
|
|
289
|
+
severity: "warn",
|
|
290
|
+
category: "structure",
|
|
291
|
+
source: "doctor",
|
|
292
|
+
recommended: true
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
id: "nuxt-doctor/structure/nuxt-major-current",
|
|
296
|
+
severity: "info",
|
|
297
|
+
category: "structure",
|
|
298
|
+
source: "doctor",
|
|
299
|
+
recommended: false
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
id: "nuxt-doctor/modules-deps/no-modules-incompatible-with-nuxt-4",
|
|
303
|
+
severity: "warn",
|
|
304
|
+
category: "modules-deps",
|
|
305
|
+
source: "doctor",
|
|
306
|
+
recommended: true
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
id: "nuxt-doctor/modules-deps/recommended-modules-installed",
|
|
310
|
+
severity: "info",
|
|
311
|
+
category: "modules-deps",
|
|
312
|
+
source: "doctor",
|
|
313
|
+
recommended: false
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
id: "nuxt-doctor/nitro/compatibilityDate-set",
|
|
317
|
+
severity: "error",
|
|
318
|
+
category: "nitro",
|
|
319
|
+
source: "doctor",
|
|
320
|
+
recommended: true
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
id: "nuxt-doctor/nitro/preset-defined-for-deploy-target",
|
|
324
|
+
severity: "warn",
|
|
325
|
+
category: "nitro",
|
|
326
|
+
source: "doctor",
|
|
327
|
+
recommended: true
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
id: "nuxt-doctor/nitro/runtime-config-typed",
|
|
331
|
+
severity: "info",
|
|
332
|
+
category: "nitro",
|
|
333
|
+
source: "doctor",
|
|
334
|
+
recommended: false
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
id: "nuxt-doctor/seo/lang-on-html",
|
|
338
|
+
severity: "warn",
|
|
339
|
+
category: "seo",
|
|
340
|
+
source: "doctor",
|
|
341
|
+
recommended: true
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
id: "nuxt-doctor/seo/useSeoMeta-on-public-page",
|
|
345
|
+
severity: "warn",
|
|
346
|
+
category: "seo",
|
|
347
|
+
source: "doctor",
|
|
348
|
+
recommended: true
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
id: "nuxt-doctor/seo/og-image-defined",
|
|
352
|
+
severity: "warn",
|
|
353
|
+
category: "seo",
|
|
354
|
+
source: "doctor",
|
|
355
|
+
recommended: true
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
id: "nuxt-doctor/cloudflare/nitro-cloudflare-preset",
|
|
359
|
+
severity: "warn",
|
|
360
|
+
category: "cloudflare",
|
|
361
|
+
source: "doctor",
|
|
362
|
+
recommended: true
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
id: "nuxt-doctor/cloudflare/og-image-via-satori",
|
|
366
|
+
severity: "info",
|
|
367
|
+
category: "cloudflare",
|
|
368
|
+
source: "doctor",
|
|
369
|
+
recommended: false
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
id: "nuxt-doctor/cloudflare/no-node-only-modules",
|
|
373
|
+
severity: "warn",
|
|
374
|
+
category: "cloudflare",
|
|
375
|
+
source: "doctor",
|
|
376
|
+
recommended: true
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
id: "nuxt-doctor/data-fetching/no-shared-key-across-pages",
|
|
380
|
+
severity: "warn",
|
|
381
|
+
category: "data-fetching",
|
|
382
|
+
source: "doctor",
|
|
383
|
+
recommended: true
|
|
384
|
+
},
|
|
385
|
+
{
|
|
386
|
+
id: "nuxt-doctor/data-fetching/ssr-safe-onMounted-only-for-client",
|
|
387
|
+
severity: "warn",
|
|
388
|
+
category: "data-fetching",
|
|
389
|
+
source: "doctor",
|
|
390
|
+
recommended: true
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
id: "nuxt-doctor/ai-slop/no-mixed-app-and-root-layout",
|
|
394
|
+
severity: "warn",
|
|
395
|
+
category: "ai-slop",
|
|
396
|
+
source: "doctor",
|
|
397
|
+
recommended: true
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
id: "nuxt-doctor/ai-slop/no-process-client-server",
|
|
401
|
+
severity: "error",
|
|
402
|
+
category: "ai-slop",
|
|
403
|
+
source: "doctor",
|
|
404
|
+
recommended: true
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
id: "nuxt-doctor/ai-slop/no-explicit-imports-of-auto-imported",
|
|
408
|
+
severity: "warn",
|
|
409
|
+
category: "ai-slop",
|
|
410
|
+
source: "doctor",
|
|
411
|
+
recommended: true
|
|
412
|
+
},
|
|
413
|
+
{
|
|
414
|
+
id: "nuxt-doctor/ai-slop/no-useState-for-server-data",
|
|
415
|
+
severity: "warn",
|
|
416
|
+
category: "ai-slop",
|
|
417
|
+
source: "doctor",
|
|
418
|
+
recommended: true
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
id: "nuxt-doctor/ai-slop/no-fetch-in-setup",
|
|
422
|
+
severity: "warn",
|
|
423
|
+
category: "ai-slop",
|
|
424
|
+
source: "doctor",
|
|
425
|
+
recommended: true
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
id: "nuxt-doctor/data-fetching/useAsyncData-key-required-in-loop",
|
|
429
|
+
severity: "error",
|
|
430
|
+
category: "data-fetching",
|
|
431
|
+
source: "doctor",
|
|
432
|
+
recommended: true
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
id: "nuxt-doctor/server-routes/defineEventHandler-typed",
|
|
436
|
+
severity: "warn",
|
|
437
|
+
category: "server-routes",
|
|
438
|
+
source: "doctor",
|
|
439
|
+
recommended: true
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
id: "nuxt-doctor/server-routes/validate-body-with-h3-v2",
|
|
443
|
+
severity: "warn",
|
|
444
|
+
category: "server-routes",
|
|
445
|
+
source: "doctor",
|
|
446
|
+
recommended: true
|
|
447
|
+
},
|
|
448
|
+
{
|
|
449
|
+
id: "nuxt-doctor/server-routes/createError-on-failure",
|
|
450
|
+
severity: "warn",
|
|
451
|
+
category: "server-routes",
|
|
452
|
+
source: "doctor",
|
|
453
|
+
recommended: true
|
|
454
|
+
},
|
|
455
|
+
{
|
|
456
|
+
id: "nuxt-doctor/hydration/no-document-in-setup",
|
|
457
|
+
severity: "error",
|
|
458
|
+
category: "hydration",
|
|
459
|
+
source: "doctor",
|
|
460
|
+
recommended: true
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
id: "nuxt-doctor/hydration/clientOnly-for-browser-apis",
|
|
464
|
+
severity: "error",
|
|
465
|
+
category: "hydration",
|
|
466
|
+
source: "doctor",
|
|
467
|
+
recommended: true
|
|
468
|
+
}
|
|
469
|
+
];
|
|
470
|
+
function listRules(filter = {}) {
|
|
471
|
+
let rules = [...RULE_REGISTRY];
|
|
472
|
+
if (filter.preset === "recommended") rules = rules.filter((r) => r.recommended);
|
|
473
|
+
if (filter.category) rules = rules.filter((r) => r.category === filter.category);
|
|
474
|
+
if (filter.source) rules = rules.filter((r) => r.source === filter.source);
|
|
475
|
+
if (filter.severity) rules = rules.filter((r) => r.severity === filter.severity);
|
|
476
|
+
return rules.sort((a, b) => a.id.localeCompare(b.id));
|
|
477
|
+
}
|
|
478
|
+
//#endregion
|
|
479
|
+
//#region src/config/presets.ts
|
|
480
|
+
const PRESET_NAMES = [
|
|
481
|
+
"minimal",
|
|
482
|
+
"recommended",
|
|
483
|
+
"strict",
|
|
484
|
+
"all"
|
|
485
|
+
];
|
|
486
|
+
function isPresetName(value) {
|
|
487
|
+
return PRESET_NAMES.includes(value);
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Resolve a preset name to its base ruleId -> Severity map.
|
|
491
|
+
*
|
|
492
|
+
* - `minimal` : errors only (warn/info turned off)
|
|
493
|
+
* - `recommended` : errors + warns (info off) — same as today's default
|
|
494
|
+
* - `strict` : errors + warns + infos all on at registered severity
|
|
495
|
+
* - `all` : alias of `strict` for now; reserved to surface every
|
|
496
|
+
* known ruleId regardless of preset opt-in policy
|
|
497
|
+
*
|
|
498
|
+
* The returned map is the BASE; downstream code merges user config
|
|
499
|
+
* `rules:` on top, then CLI `--rule` overrides on top of that.
|
|
500
|
+
*/
|
|
501
|
+
function resolvePreset(name) {
|
|
502
|
+
const rules = {};
|
|
503
|
+
for (const rule of RULE_REGISTRY) if (name === "minimal") {
|
|
504
|
+
if (rule.severity === "error") rules[rule.id] = "error";
|
|
505
|
+
} else if (name === "recommended") {
|
|
506
|
+
if (rule.severity === "error" || rule.severity === "warn") rules[rule.id] = rule.severity;
|
|
507
|
+
} else rules[rule.id] = rule.severity;
|
|
508
|
+
return rules;
|
|
509
|
+
}
|
|
510
|
+
//#endregion
|
|
511
|
+
//#region src/config/validate.ts
|
|
512
|
+
const VALID_SEVERITIES = new Set([
|
|
513
|
+
"error",
|
|
514
|
+
"warn",
|
|
515
|
+
"info",
|
|
516
|
+
"off"
|
|
517
|
+
]);
|
|
518
|
+
const VALID_FAIL_ON = new Set([
|
|
519
|
+
"error",
|
|
520
|
+
"warn",
|
|
521
|
+
"none"
|
|
522
|
+
]);
|
|
523
|
+
function validateConfig(raw) {
|
|
524
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) throw new InvalidConfigError("config: must be an object");
|
|
525
|
+
const config = raw;
|
|
526
|
+
if ("threshold" in config) {
|
|
527
|
+
const threshold = config.threshold;
|
|
528
|
+
if (typeof threshold !== "number" || !Number.isInteger(threshold)) throw new InvalidConfigError(`threshold: must be an integer 0..100, got ${JSON.stringify(threshold)}`);
|
|
529
|
+
if (threshold < 0 || threshold > 100) throw new InvalidConfigError(`threshold: must be 0..100, got ${threshold}`);
|
|
530
|
+
}
|
|
531
|
+
if ("preset" in config) {
|
|
532
|
+
const preset = config.preset;
|
|
533
|
+
if (typeof preset !== "string" || !isPresetName(preset)) throw new InvalidConfigError(`preset: must be one of 'minimal', 'recommended', 'strict', 'all', got ${JSON.stringify(preset)}`);
|
|
534
|
+
}
|
|
535
|
+
if ("failOn" in config) {
|
|
536
|
+
const failOn = config.failOn;
|
|
537
|
+
if (typeof failOn !== "string" || !VALID_FAIL_ON.has(failOn)) throw new InvalidConfigError(`failOn: must be 'error', 'warn', or 'none', got ${JSON.stringify(failOn)}`);
|
|
538
|
+
}
|
|
539
|
+
if ("include" in config) {
|
|
540
|
+
const include = config.include;
|
|
541
|
+
if (!Array.isArray(include)) throw new InvalidConfigError("include: must be an array of strings");
|
|
542
|
+
if (!include.every((v) => typeof v === "string")) throw new InvalidConfigError("include: must be an array of strings");
|
|
543
|
+
}
|
|
544
|
+
if ("exclude" in config) {
|
|
545
|
+
const exclude = config.exclude;
|
|
546
|
+
if (!Array.isArray(exclude)) throw new InvalidConfigError("exclude: must be an array of strings");
|
|
547
|
+
if (!exclude.every((v) => typeof v === "string")) throw new InvalidConfigError("exclude: must be an array of strings");
|
|
548
|
+
}
|
|
549
|
+
if ("rules" in config) {
|
|
550
|
+
const rules = config.rules;
|
|
551
|
+
if (rules === null || typeof rules !== "object" || Array.isArray(rules)) throw new InvalidConfigError("rules: must be an object");
|
|
552
|
+
for (const [key, value] of Object.entries(rules)) if (typeof value !== "string" || !VALID_SEVERITIES.has(value)) throw new InvalidConfigError(`rules.${key}: must be a severity ('error', 'warn', 'info', or 'off'), got ${JSON.stringify(value)}`);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
//#endregion
|
|
556
|
+
//#region src/config/load.ts
|
|
557
|
+
var load_exports = /* @__PURE__ */ __exportAll({ loadDoctorConfig: () => loadDoctorConfig });
|
|
558
|
+
const SOURCE_MAP = {
|
|
559
|
+
ts: "ts",
|
|
560
|
+
mjs: "mjs",
|
|
561
|
+
js: "js",
|
|
562
|
+
json: "json"
|
|
563
|
+
};
|
|
564
|
+
async function loadDoctorConfig(rootDir, explicitPathOrOptions) {
|
|
565
|
+
const opts = typeof explicitPathOrOptions === "string" ? { explicitPath: explicitPathOrOptions } : explicitPathOrOptions ?? {};
|
|
566
|
+
const explicitPath = opts.explicitPath;
|
|
567
|
+
if (opts.presetOverride !== void 0 && !isPresetName(opts.presetOverride)) throw new InvalidConfigError(`preset: must be one of 'minimal', 'recommended', 'strict', 'all', got ${JSON.stringify(opts.presetOverride)}`);
|
|
568
|
+
if (explicitPath) {
|
|
569
|
+
if (!existsSync(resolve(rootDir, explicitPath))) throw new ConfigFileNotFoundError(explicitPath);
|
|
570
|
+
}
|
|
571
|
+
const chain = [];
|
|
572
|
+
const result = await loadConfig({
|
|
573
|
+
cwd: rootDir,
|
|
574
|
+
name: "doctor",
|
|
575
|
+
packageJson: "doctor",
|
|
576
|
+
rcFile: false,
|
|
577
|
+
globalRc: false,
|
|
578
|
+
...explicitPath ? { configFile: resolve(rootDir, explicitPath) } : {},
|
|
579
|
+
resolve(source, options) {
|
|
580
|
+
const base = options.cwd;
|
|
581
|
+
const key = resolve(base, source);
|
|
582
|
+
if (chain.includes(key)) throw new ConfigCycleError([...chain, key]);
|
|
583
|
+
chain.push(key);
|
|
584
|
+
}
|
|
585
|
+
});
|
|
586
|
+
const raw = result.config;
|
|
587
|
+
validateConfig(raw);
|
|
588
|
+
let source;
|
|
589
|
+
let configFile;
|
|
590
|
+
if (explicitPath) {
|
|
591
|
+
source = "flag";
|
|
592
|
+
configFile = resolve(rootDir, explicitPath);
|
|
593
|
+
} else if (result._configFile) {
|
|
594
|
+
source = SOURCE_MAP[extname(result._configFile).slice(1)];
|
|
595
|
+
configFile = result._configFile;
|
|
596
|
+
} else if (Object.keys(raw).length > 0) {
|
|
597
|
+
source = "package.json";
|
|
598
|
+
configFile = resolve(rootDir, "package.json");
|
|
599
|
+
} else {
|
|
600
|
+
source = "built-in";
|
|
601
|
+
configFile = void 0;
|
|
602
|
+
}
|
|
603
|
+
const presetName = opts.presetOverride ?? raw.preset ?? "recommended";
|
|
604
|
+
const presetRules = resolvePreset(presetName);
|
|
605
|
+
const userRules = {};
|
|
606
|
+
const userOff = /* @__PURE__ */ new Set();
|
|
607
|
+
if (raw.rules && typeof raw.rules === "object") for (const [key, value] of Object.entries(raw.rules)) if (value === "off") userOff.add(key);
|
|
608
|
+
else userRules[key] = value;
|
|
609
|
+
const mergedRules = {
|
|
610
|
+
...presetRules,
|
|
611
|
+
...userRules
|
|
612
|
+
};
|
|
613
|
+
for (const key of userOff) delete mergedRules[key];
|
|
614
|
+
return {
|
|
615
|
+
rootDir,
|
|
616
|
+
include: raw.include ?? BUILT_IN_RECOMMENDED.include,
|
|
617
|
+
exclude: raw.exclude ?? BUILT_IN_RECOMMENDED.exclude,
|
|
618
|
+
failOn: raw.failOn ?? BUILT_IN_RECOMMENDED.failOn,
|
|
619
|
+
threshold: raw.threshold ?? BUILT_IN_RECOMMENDED.threshold,
|
|
620
|
+
rules: mergedRules,
|
|
621
|
+
preset: presetName,
|
|
622
|
+
source,
|
|
623
|
+
configFile
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
//#endregion
|
|
627
|
+
export { listRules as a, InvalidConfigError as c, RULE_REGISTRY as i, BUILT_IN_RECOMMENDED as l, load_exports as n, ConfigCycleError as o, validateConfig as r, ConfigFileNotFoundError as s, loadDoctorConfig as t };
|
|
628
|
+
|
|
629
|
+
//# sourceMappingURL=load-BGjurxpY.js.map
|