@kazupon/eslint-config 0.19.0 → 0.20.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/dist/index.cjs DELETED
@@ -1,659 +0,0 @@
1
- "use strict";
2
- //#region rolldown:runtime
3
- var __create = Object.create;
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getProtoOf = Object.getPrototypeOf;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
- key = keys[i];
12
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
- get: ((k) => from[k]).bind(null, key),
14
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
- });
16
- }
17
- return to;
18
- };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
- value: mod,
21
- enumerable: true
22
- }) : target, mod));
23
-
24
- //#endregion
25
- const eslint_flat_config_utils = __toESM(require("eslint-flat-config-utils"));
26
- const __kazupon_jts_utils_module = __toESM(require("@kazupon/jts-utils/module"));
27
- const globals = __toESM(require("globals"));
28
-
29
- //#region src/config.ts
30
- function defineConfig(...configs) {
31
- const baseConfigs = [];
32
- return new eslint_flat_config_utils.FlatConfigComposer().append(...baseConfigs, ...configs);
33
- }
34
-
35
- //#endregion
36
- //#region src/globs.ts
37
- const GLOB_JS = "**/*.?([cm])js";
38
- const GLOB_JSX = "**/*.?([cm])jsx";
39
- const GLOB_TS = "**/*.?([cm])ts";
40
- const GLOB_TSX = "**/*.?([cm])tsx";
41
- const GLOB_JSON = "**/*.json";
42
- const GLOB_JSON5 = "**/*.json5";
43
- const GLOB_JSONC = "**/*.jsonc";
44
- const GLOB_YAML = "**/*.y?(a)ml";
45
- const GLOB_TOML = "**/*.toml";
46
- const GLOB_VUE = "**/*.vue";
47
- const GLOB_SVELTE = "**/*.svelte";
48
- const GLOB_MARKDOWN = "**/*.md";
49
- const GLOB_SRC_EXT = "?([cm])[jt]s?(x)";
50
- const GLOB_TESTS = [
51
- `**/test/**/*.${GLOB_SRC_EXT}`,
52
- `**/tests/**/*.${GLOB_SRC_EXT}`,
53
- `**/spec/**/*.${GLOB_SRC_EXT}`,
54
- `**/specs/**/*.${GLOB_SRC_EXT}`,
55
- `**/e2e/**/*.${GLOB_SRC_EXT}`,
56
- `**/__tests__/**/*.${GLOB_SRC_EXT}`,
57
- `**/__test__/**/*.${GLOB_SRC_EXT}`,
58
- `**/*.spec.${GLOB_SRC_EXT}`,
59
- `**/*.test.${GLOB_SRC_EXT}`
60
- ];
61
- const GLOB_TESTS_TYPE = [`**/*.test-d.${GLOB_SRC_EXT}`, `**/*.spec-d.${GLOB_SRC_EXT}`];
62
-
63
- //#endregion
64
- //#region src/utils.ts
65
- async function loadPlugin(name) {
66
- const mod = await import(name).catch((error) => {
67
- console.error(error);
68
- throw new Error(`Failed to load eslint plugin '${name}'. Please install it!`);
69
- });
70
- return (0, __kazupon_jts_utils_module.interopDefault)(mod);
71
- }
72
- async function getTypeScriptParser() {
73
- const ts = await loadPlugin("typescript-eslint");
74
- return ts.parser;
75
- }
76
- function getGlobSourceFiles(useTypeScript = false) {
77
- return [
78
- GLOB_JS,
79
- GLOB_JSX,
80
- ...useTypeScript ? [GLOB_TS, GLOB_TSX] : []
81
- ];
82
- }
83
-
84
- //#endregion
85
- //#region src/configs/comments.ts
86
- async function comments(options = {}) {
87
- const { rules: overrideRules = {} } = options;
88
- const comments$1 = await loadPlugin("@eslint-community/eslint-plugin-eslint-comments");
89
- return [{
90
- name: "@eslint-community/eslint-comments/recommended",
91
- plugins: { "@eslint-community/eslint-comments": comments$1 },
92
- rules: { ...comments$1.configs.recommended.rules }
93
- }, {
94
- name: "@kazupon/eslint-comments",
95
- rules: { ...overrideRules }
96
- }];
97
- }
98
-
99
- //#endregion
100
- //#region src/configs/imports.ts
101
- const IMPORTS_FILES = [
102
- GLOB_JS,
103
- GLOB_JSX,
104
- GLOB_TS,
105
- GLOB_TSX
106
- ];
107
- async function imports(options = {}) {
108
- const { rules: overrideRules = {} } = options;
109
- const unused = await loadPlugin(
110
- // eslint-disable-line @typescript-eslint/no-unsafe-assignment
111
- "eslint-plugin-unused-imports"
112
- );
113
- const imports$1 = await loadPlugin("eslint-plugin-import");
114
- const configs = [imports$1.flatConfigs.recommended];
115
- if (options.typescript) try {
116
- await loadPlugin("eslint-import-resolver-typescript");
117
- imports$1.flatConfigs.typescript.settings["import/resolver"]["typescript"] = true;
118
- configs.push(imports$1.flatConfigs.typescript);
119
- } catch (error) {
120
- throw new Error(`Not found eslint-import-resolver-typescript: ${error.message}`);
121
- }
122
- configs.push({
123
- name: "unused-imports",
124
- plugins: { "unused-imports": unused },
125
- files: IMPORTS_FILES,
126
- rules: {
127
- "no-unused-vars": "off",
128
- "@typescript-eslint/no-unused-vars": "off",
129
- "unused-imports/no-unused-imports": "error",
130
- "unused-imports/no-unused-vars": ["error", {
131
- args: "all",
132
- argsIgnorePattern: "^_",
133
- caughtErrors: "all",
134
- caughtErrorsIgnorePattern: "^_",
135
- destructuredArrayIgnorePattern: "^_",
136
- vars: "all",
137
- varsIgnorePattern: "^_",
138
- ignoreRestSiblings: true
139
- }]
140
- }
141
- });
142
- const overriddenConfig = {
143
- name: "@kazupon/imports",
144
- files: IMPORTS_FILES,
145
- rules: { ...overrideRules }
146
- };
147
- configs.push(overriddenConfig);
148
- return configs;
149
- }
150
-
151
- //#endregion
152
- //#region src/configs/javascript.ts
153
- async function javascript(options = {}) {
154
- const { rules: overrideRules = {} } = options;
155
- const js = await loadPlugin("@eslint/js");
156
- return [{
157
- name: "eslint/defaults/rules",
158
- ...js.configs.recommended
159
- }, {
160
- name: "@kazupon/javascript/@eslint/js",
161
- languageOptions: {
162
- ecmaVersion: 2022,
163
- globals: {
164
- ...globals.default.browser,
165
- ...globals.default.node,
166
- ...globals.default.es2022,
167
- document: "readonly",
168
- navigator: "readonly",
169
- window: "readonly"
170
- },
171
- parserOptions: {
172
- ecmaFeatures: { jsx: true },
173
- ecmaVersion: 2022,
174
- sourceType: "module"
175
- },
176
- sourceType: "module"
177
- },
178
- linterOptions: { reportUnusedDisableDirectives: true },
179
- rules: { ...overrideRules }
180
- }];
181
- }
182
-
183
- //#endregion
184
- //#region src/configs/jsdoc.ts
185
- async function jsdoc(options = {}) {
186
- const { rules: overrideRules = {}, typescript: typescript$1, error = false } = options;
187
- const jsdoc$1 = await loadPlugin("eslint-plugin-jsdoc");
188
- function resolvePreset() {
189
- let preset = "recommended";
190
- if (typescript$1 === "syntax") preset = `${preset}-typescript`;
191
- else if (typescript$1 === "flavor") preset = `${preset}-typescript-flavor`;
192
- if (error) preset = `${preset}-error`;
193
- return preset;
194
- }
195
- return [jsdoc$1.configs[`flat/${resolvePreset()}`], {
196
- name: "@kazupon/jsdoc",
197
- rules: { ...overrideRules }
198
- }];
199
- }
200
-
201
- //#endregion
202
- //#region src/configs/jsonc.ts
203
- async function jsonc(options = {}) {
204
- const { rules: overrideRules = {} } = options;
205
- const kinds = [
206
- options.json ? "json" : "",
207
- options.jsonc ? "jsonc" : "",
208
- options.json5 ? "json5" : ""
209
- ];
210
- const usePrettier = !!options.prettier;
211
- const jsonc$1 = await loadPlugin("eslint-plugin-jsonc");
212
- const configs = [];
213
- for (const kind of kinds) if (kind) configs.push(...jsonc$1.configs[`flat/recommended-with-${kind}`].map((config, index) => {
214
- return config.name ? config : {
215
- name: `jsonc/flat/recommended-with-${kind}/${index}`,
216
- ...config
217
- };
218
- }));
219
- if (usePrettier) configs.push(...jsonc$1.configs["flat/prettier"].map((config, index) => {
220
- return config.name ? config : {
221
- name: `jsonc/flat/prettier/${index}`,
222
- ...config
223
- };
224
- }));
225
- const overriddenConfig = {
226
- name: "@kazupon/jsonc",
227
- files: [
228
- GLOB_JSON,
229
- GLOB_JSON5,
230
- GLOB_JSONC
231
- ],
232
- rules: { ...overrideRules }
233
- };
234
- configs.push(...jsoncSort(), overriddenConfig);
235
- return configs;
236
- }
237
- /**
238
- * jsonc sort configurations
239
- * @returns {Linter.Config[]} jsonc sort configurations
240
- */
241
- function jsoncSort() {
242
- return [{
243
- name: "@kazupon/jsonc/sort/package.json",
244
- files: ["**/package.json"],
245
- rules: {
246
- "jsonc/sort-array-values": ["error", {
247
- order: { type: "asc" },
248
- pathPattern: "^files$"
249
- }],
250
- "jsonc/sort-keys": [
251
- "error",
252
- {
253
- order: [
254
- "name",
255
- "description",
256
- "private",
257
- "version",
258
- "author",
259
- "contributors",
260
- "license",
261
- "funding",
262
- "bugs",
263
- "repository",
264
- "keywords",
265
- "homepage",
266
- "publishConfig",
267
- "packageManager",
268
- "engines",
269
- "os",
270
- "cpu",
271
- "type",
272
- "sideEffects",
273
- "bin",
274
- "files",
275
- "main",
276
- "module",
277
- "browser",
278
- "unpkg",
279
- "jsdelivr",
280
- "directories",
281
- "exports",
282
- "types",
283
- "typesVersions",
284
- "scripts",
285
- "dependencies",
286
- "peerDependencies",
287
- "peerDependenciesMeta",
288
- "optionalDependencies",
289
- "devDependencies",
290
- "pnpm",
291
- "overrides",
292
- "resolutions",
293
- "workspaces",
294
- "prettier",
295
- "buildOptions",
296
- "lint-staged"
297
- ],
298
- pathPattern: "^$"
299
- },
300
- {
301
- order: { type: "asc" },
302
- pathPattern: "^scripts$"
303
- },
304
- {
305
- order: { type: "asc" },
306
- pathPattern: "^(?:dev|peer|optional|bundled)?[Dd]ependencies(Meta)?$"
307
- },
308
- {
309
- order: { type: "asc" },
310
- pathPattern: "^(?:resolutions|overrides|pnpm.overrides)$"
311
- }
312
- ]
313
- }
314
- }];
315
- }
316
-
317
- //#endregion
318
- //#region src/configs/markdown.ts
319
- async function markdown(options = {}) {
320
- const { rules: overrideRules = {} } = options;
321
- const language = options.language || "gfm";
322
- const fencedCodeBlocks = typeof options.fencedCodeBlocks === "boolean" ? options.fencedCodeBlocks : true;
323
- const markdown$1 = await loadPlugin("@eslint/markdown");
324
- const recommended = markdown$1.configs["recommended"][0];
325
- recommended.language = `markdown/${language}`;
326
- return [
327
- recommended,
328
- ...fencedCodeBlocks ? markdown$1.configs["processor"] : [],
329
- {
330
- name: "@kazupon/markdown",
331
- files: [GLOB_MARKDOWN],
332
- rules: { ...overrideRules }
333
- }
334
- ];
335
- }
336
- const md = markdown;
337
-
338
- //#endregion
339
- //#region src/configs/prettier.ts
340
- async function prettier(options = {}) {
341
- const { rules: overrideRules = {} } = options;
342
- const prettier$1 = await loadPlugin("eslint-config-prettier");
343
- return [prettier$1, {
344
- name: "@kazupon/prettier",
345
- rules: { ...overrideRules }
346
- }];
347
- }
348
-
349
- //#endregion
350
- //#region src/configs/promise.ts
351
- async function promise(options = {}) {
352
- const { rules: overrideRules = {} } = options;
353
- const promise$1 = await loadPlugin("eslint-plugin-promise");
354
- return [{
355
- name: "promise/flat/recommended",
356
- ...promise$1.configs["flat/recommended"]
357
- }, {
358
- name: "@kazupon/promise",
359
- rules: { ...overrideRules }
360
- }];
361
- }
362
-
363
- //#endregion
364
- //#region src/configs/react.ts
365
- async function react(options = {}) {
366
- const { rules: overrideRules = {}, settings = {} } = options;
367
- const useTypeScript = !options.typescript;
368
- const enableRefresh = !!options.refresh;
369
- const [react$1, reactHooks, reactRefresh] = await Promise.all([
370
- loadPlugin("eslint-plugin-react"),
371
- loadPlugin("eslint-plugin-react-hooks"),
372
- enableRefresh ? loadPlugin("eslint-plugin-react-refresh") : null
373
- ]);
374
- const customConfig = {
375
- name: "@kazupon/react",
376
- files: getGlobSourceFiles(useTypeScript),
377
- rules: { ...overrideRules }
378
- };
379
- const configs = [{
380
- name: "react/flat/recommended",
381
- files: getGlobSourceFiles(useTypeScript),
382
- settings,
383
- ...react$1.configs.flat.recommended
384
- }, {
385
- name: "react-hooks/flat",
386
- files: getGlobSourceFiles(useTypeScript),
387
- plugins: { "react-hooks": reactHooks }
388
- }];
389
- if (enableRefresh) configs.push({
390
- name: "react-refresh/flat",
391
- files: getGlobSourceFiles(useTypeScript),
392
- plugins: { "react-refresh": reactRefresh }
393
- });
394
- return [...configs, customConfig];
395
- }
396
-
397
- //#endregion
398
- //#region src/configs/regexp.ts
399
- async function regexp(options = {}) {
400
- const { rules: overrideRules = {} } = options;
401
- const regexp$1 = await loadPlugin("eslint-plugin-regexp");
402
- return [{
403
- name: "regexp/flat/recommended",
404
- ...regexp$1.configs["flat/recommended"]
405
- }, {
406
- name: "@kazupon/eslint-regexp",
407
- rules: { ...overrideRules }
408
- }];
409
- }
410
-
411
- //#endregion
412
- //#region src/configs/svelte.ts
413
- async function svelte(options = {}) {
414
- const { rules: overrideRules = {}, parserOptions = { project: true } } = options;
415
- const useTypeScript = !!options.typescript;
416
- const svelte$1 = await loadPlugin("eslint-plugin-svelte");
417
- const svelteParser = svelte$1.configs["flat/base"][1]["languageOptions"]?.parser;
418
- const customConfig = {
419
- name: "@kazupon/svelte",
420
- files: [GLOB_SVELTE],
421
- rules: { ...overrideRules }
422
- };
423
- if (useTypeScript) customConfig.languageOptions = {
424
- parser: svelteParser,
425
- parserOptions: {
426
- sourceType: "module",
427
- parser: await getTypeScriptParser(),
428
- ecmaFeatures: { jsx: true },
429
- extraFileExtensions: [".svelte"],
430
- ...parserOptions
431
- }
432
- };
433
- return [...svelte$1.configs["flat/recommended"], customConfig];
434
- }
435
-
436
- //#endregion
437
- //#region src/configs/toml.ts
438
- async function toml(options = {}) {
439
- const { rules: overrideRules = {} } = options;
440
- const toml$1 = await loadPlugin("eslint-plugin-toml");
441
- const configs = [];
442
- configs.push(...toml$1.configs["flat/standard"].map((config, index) => {
443
- return config.name ? config : {
444
- name: `toml/flat/standard/${index}`,
445
- ...config
446
- };
447
- }));
448
- const overriddenConfig = {
449
- name: "@kazupon/toml",
450
- files: [GLOB_TOML],
451
- rules: { ...overrideRules }
452
- };
453
- configs.push(overriddenConfig);
454
- return configs;
455
- }
456
-
457
- //#endregion
458
- //#region src/configs/typescript.ts
459
- async function typescript(options = {}) {
460
- const { rules: overrideRules = {}, extraFileExtensions = [], parserOptions = { project: true } } = options;
461
- const ts = await loadPlugin("typescript-eslint");
462
- const files = options.files ?? [
463
- GLOB_TS,
464
- GLOB_TSX,
465
- ...extraFileExtensions.map((ext) => `**/*${ext}`)
466
- ];
467
- return [
468
- ...ts.configs.recommendedTypeChecked,
469
- {
470
- files: [
471
- GLOB_JS,
472
- GLOB_JSX,
473
- GLOB_JSON,
474
- GLOB_JSON5,
475
- GLOB_JSONC,
476
- GLOB_YAML,
477
- GLOB_TOML
478
- ],
479
- ...ts.configs.disableTypeChecked
480
- },
481
- {
482
- name: "@kazupon/typescipt/typescript-eslint",
483
- files,
484
- languageOptions: {
485
- parser: ts.parser,
486
- parserOptions: {
487
- extraFileExtensions: extraFileExtensions.map((ext) => `${ext}`),
488
- sourceType: "module",
489
- ...parserOptions
490
- }
491
- },
492
- rules: {
493
- "@typescript-eslint/no-unused-vars": ["error", {
494
- args: "all",
495
- argsIgnorePattern: "^_",
496
- caughtErrors: "all",
497
- caughtErrorsIgnorePattern: "^_",
498
- destructuredArrayIgnorePattern: "^_",
499
- varsIgnorePattern: "^_",
500
- ignoreRestSiblings: true
501
- }],
502
- ...overrideRules
503
- }
504
- }
505
- ];
506
- }
507
-
508
- //#endregion
509
- //#region src/configs/unicorn.ts
510
- async function unicorn(options = {}) {
511
- const { rules: overrideRules = {} } = options;
512
- const useTypeScript = !options.typescript;
513
- const unicorn$1 = await loadPlugin("eslint-plugin-unicorn");
514
- return [{
515
- files: getGlobSourceFiles(useTypeScript),
516
- ...unicorn$1.configs["flat/recommended"]
517
- }, {
518
- name: "@kazupon/unicorn",
519
- files: getGlobSourceFiles(useTypeScript),
520
- rules: { ...overrideRules }
521
- }];
522
- }
523
-
524
- //#endregion
525
- //#region src/configs/vitest.ts
526
- async function vitest(options = {}) {
527
- const { rules: overrideRules = {}, files: overrideFiles = [] } = options;
528
- const typeTesting = !!options.typeTesting;
529
- const vitest$1 = await loadPlugin("@vitest/eslint-plugin");
530
- const configs = [];
531
- const base = {
532
- files: GLOB_TESTS,
533
- ...vitest$1.configs["recommended"]
534
- };
535
- if (base.name == undefined) base.name = "@vitest/eslint-plugin";
536
- if (typeTesting) {
537
- base.files = [...base.files, ...GLOB_TESTS_TYPE];
538
- base.settings = { vitest: { typecheck: true } };
539
- base.languageOptions = { globals: { ...vitest$1.environments.env.globals } };
540
- }
541
- configs.push(base);
542
- const custom = {
543
- name: "@kazupon/vitest",
544
- rules: { ...overrideRules }
545
- };
546
- if (overrideFiles.length > 0) custom.files = overrideFiles;
547
- configs.push(custom);
548
- return configs;
549
- }
550
-
551
- //#endregion
552
- //#region src/configs/vue.ts
553
- async function vue(options = {}) {
554
- const { rules: overrideRules = {}, parserOptions = { project: true } } = options;
555
- const vue$1 = await loadPlugin("eslint-plugin-vue");
556
- const vueParser = vue$1.configs["flat/base"][1]["languageOptions"]?.parser;
557
- const configs = [];
558
- configs.push(...vue$1.configs["flat/recommended"]);
559
- if (options.composable) {
560
- const composable = await loadPlugin("eslint-plugin-vue-composable");
561
- const composableBase = { ...composable.configs["flat/recommended"][0] };
562
- delete composableBase.languageOptions;
563
- configs.push(composableBase, composable.configs["flat/recommended"][1]);
564
- }
565
- if (options.scopedCss) {
566
- const scopedCss = await loadPlugin("eslint-plugin-vue-scoped-css");
567
- const scopedCssMapped = scopedCss.configs["flat/recommended"].map(
568
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
569
- (config, index) => {
570
- return config.name ? config : {
571
- name: `vue/scoped-css/recommended/${index}`,
572
- ...config
573
- };
574
- }
575
- );
576
- configs.push(scopedCssMapped[0], scopedCssMapped[2]);
577
- }
578
- if (options.a11y) {
579
- const a11y = await loadPlugin("eslint-plugin-vuejs-accessibility");
580
- const a11yBase = { ...a11y.configs["flat/recommended"][0] };
581
- delete a11yBase.languageOptions;
582
- configs.push(a11yBase);
583
- const a11yRules = {
584
- ...a11y.configs["flat/recommended"][1],
585
- name: "vuejs-accessibility:rules"
586
- };
587
- delete a11yRules.languageOptions;
588
- delete a11yRules.plugins;
589
- configs.push(a11yRules);
590
- }
591
- const customConfig = {
592
- name: "@kazupon/vue",
593
- files: [GLOB_VUE],
594
- rules: { ...overrideRules }
595
- };
596
- if (options.typescript) customConfig.languageOptions = {
597
- parser: vueParser,
598
- parserOptions: {
599
- sourceType: "module",
600
- parser: await getTypeScriptParser(),
601
- ecmaFeatures: { jsx: true },
602
- extraFileExtensions: [".vue"],
603
- ...parserOptions
604
- }
605
- };
606
- configs.push(customConfig);
607
- return configs;
608
- }
609
-
610
- //#endregion
611
- //#region src/configs/yml.ts
612
- async function yml(options = {}) {
613
- const { rules: overrideRules = {} } = options;
614
- const usePrettier = !!options.prettier;
615
- const yml$1 = await loadPlugin("eslint-plugin-yml");
616
- const configs = [];
617
- configs.push(...yml$1.configs["flat/standard"].map((config, index) => {
618
- return config.name ? config : {
619
- name: `yml/flat/standard/${index}`,
620
- ...config
621
- };
622
- }));
623
- if (usePrettier) configs.push(...yml$1.configs["flat/prettier"].map((config, index) => {
624
- return config.name ? config : {
625
- name: `yml/flat/prettier/${index}`,
626
- ...config
627
- };
628
- }));
629
- const overriddenConfig = {
630
- name: "@kazupon/yml",
631
- files: [GLOB_YAML],
632
- rules: { ...overrideRules }
633
- };
634
- configs.push(overriddenConfig);
635
- return configs;
636
- }
637
- const yaml = yml;
638
-
639
- //#endregion
640
- exports.comments = comments
641
- exports.defineConfig = defineConfig
642
- exports.imports = imports
643
- exports.javascript = javascript
644
- exports.jsdoc = jsdoc
645
- exports.jsonc = jsonc
646
- exports.markdown = markdown
647
- exports.md = md
648
- exports.prettier = prettier
649
- exports.promise = promise
650
- exports.react = react
651
- exports.regexp = regexp
652
- exports.svelte = svelte
653
- exports.toml = toml
654
- exports.typescript = typescript
655
- exports.unicorn = unicorn
656
- exports.vitest = vitest
657
- exports.vue = vue
658
- exports.yaml = yaml
659
- exports.yml = yml