@moso/eslint-config 1.0.4 → 2.0.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.js DELETED
@@ -1,1975 +0,0 @@
1
- // src/configurator.ts
2
- import { FlatConfigComposer } from "eslint-flat-config-utils";
3
- import { isPackageExists as isPackageExists2 } from "local-pkg";
4
-
5
- // src/utils.ts
6
- import process from "node:process";
7
- var parserPlain = {
8
- meta: {
9
- name: "parser-plain"
10
- },
11
- parseForESLint: (code) => ({
12
- ast: {
13
- body: [],
14
- comments: [],
15
- loc: { end: code.length, start: 0 },
16
- range: [0, code.length],
17
- tokens: []
18
- },
19
- scopeManager: null,
20
- services: { isPlain: true },
21
- visitorKeys: {
22
- Program: []
23
- }
24
- })
25
- };
26
- var combine = async (...configs) => {
27
- const resolved = await Promise.all(configs);
28
- return resolved.flat();
29
- };
30
- var toArray = (value) => {
31
- return Array.isArray(value) ? value : [value];
32
- };
33
- var interopDefault = async (r) => {
34
- const resolved = await r;
35
- return resolved.default || resolved;
36
- };
37
- var resolveSubOptions = (options, key) => {
38
- return typeof options[key] === "boolean" ? {} : options[key] || {};
39
- };
40
- var getOverrides = (options, key) => {
41
- const sub = resolveSubOptions(options, key);
42
- return {
43
- ...options.overrides?.[key],
44
- ..."overrides" in sub ? sub.overrides : {}
45
- };
46
- };
47
- var isInGitHooksOrLintStaged = () => {
48
- return !!(process.env.GIT_PARAMS || process.env.VSCODE_GIT_COMMAND || process.env.npm_lifecycle_script?.startsWith("lint-staged"));
49
- };
50
- var isInEditorEnv = () => {
51
- if (process.env.CI) return false;
52
- if (isInGitHooksOrLintStaged()) return false;
53
- return !!(process.env.VSCODE_PID || process.env.VSCODE_CWD || process.env.JETBRAINS_IDE || process.env.VIM || process.env.NVIM);
54
- };
55
-
56
- // src/configs/comments.ts
57
- var comments = async () => {
58
- const eslintComments = await interopDefault(import("@eslint-community/eslint-plugin-eslint-comments"));
59
- return [
60
- {
61
- name: "moso/eslint-comments/rules",
62
- plugins: {
63
- "@eslint-community/eslint-comments": eslintComments
64
- },
65
- rules: {
66
- "@eslint-community/eslint-comments/no-aggregating-enable": "error",
67
- "@eslint-community/eslint-comments/no-duplicate-disable": "error",
68
- "@eslint-community/eslint-comments/no-unlimited-disable": "error",
69
- "@eslint-community/eslint-comments/no-unused-enable": "error"
70
- }
71
- }
72
- ];
73
- };
74
-
75
- // src/globs.ts
76
- var GLOB_SRC_EXT = "?([cm])[jt]s?(x)";
77
- var GLOB_SRC = "**/*.?([cm])[jt]s?(x)";
78
- var GLOB_JS = "**/*.?([cm])js";
79
- var GLOB_JSX = "**/*.?([cm])jsx";
80
- var GLOB_TS = "**/*.?([cm])ts";
81
- var GLOB_TSX = "**/*.?([cm])tsx";
82
- var GLOB_JSON = "**/*.json";
83
- var GLOB_JSON5 = "**/*.json5";
84
- var GLOB_JSONC = "**/*.jsonc";
85
- var GLOB_HTML = "**/*.htm?(l)";
86
- var GLOB_MARKDOWN = "**/*.md";
87
- var GLOB_MARKDOWN_CODE = `${GLOB_MARKDOWN}/${GLOB_SRC}`;
88
- var GLOB_MARKDOWN_IN_MARKDOWN = "**/*.md/*.md";
89
- var GLOB_VUE = "**/*.vue";
90
- var GLOB_YAML = "**/*.y?(a)ml";
91
- var GLOB_TESTS = [
92
- `**/__tests__/**/*.${GLOB_SRC_EXT}`,
93
- `**/*.spec.${GLOB_SRC_EXT}`,
94
- `**/*.test.${GLOB_SRC_EXT}`,
95
- `**/*.bench.${GLOB_SRC_EXT}`,
96
- `**/*.benchmark.${GLOB_SRC_EXT}`
97
- ];
98
- var GLOB_ALL_SRC = [
99
- GLOB_JSON,
100
- GLOB_JSON5,
101
- GLOB_HTML,
102
- GLOB_MARKDOWN,
103
- GLOB_SRC,
104
- GLOB_VUE,
105
- GLOB_YAML
106
- ];
107
- var GLOB_EXCLUDE = [
108
- "**/node_modules",
109
- "**/dist",
110
- "**/package-lock.json",
111
- "**/yarn.lock",
112
- "**/pnpm-lock.yaml",
113
- "**/bun.lockb",
114
- "**/bun.lock",
115
- "**/output",
116
- "**/coverage",
117
- "**/temp",
118
- "**/.temp",
119
- "**/tmp",
120
- "**/.tmp",
121
- "**/.history",
122
- "**/.vitepress/cache",
123
- "**/.nuxt",
124
- "**/.next",
125
- "**/.vercel",
126
- "**/.changeset",
127
- "**/.idea",
128
- "**/.cache",
129
- "**/.output",
130
- "**/.vite-inspect",
131
- "**/.yarn",
132
- "**/vite.config.*.timestamp-*",
133
- "**/CHANGELOG*.md",
134
- "**/*.min.*",
135
- "**/LICENSE*",
136
- "**/__snapshots__",
137
- "**/auto-import?(s).d.ts",
138
- "**/components.d.ts"
139
- ];
140
-
141
- // src/configs/disables.ts
142
- var disables = () => {
143
- return [
144
- {
145
- files: [`**/scripts/${GLOB_SRC}`],
146
- name: "moso/disables/scripts",
147
- rules: {
148
- "@typescript-eslint/explicit-function-return-type": "off",
149
- "no-console": "off"
150
- }
151
- },
152
- {
153
- files: [`**/cli/${GLOB_SRC}`, `**/cli.${GLOB_SRC_EXT}`],
154
- name: "moso/disables/cli",
155
- rules: {
156
- "no-console": "off"
157
- }
158
- },
159
- {
160
- files: ["**/bin/**/*", `**/bin.${GLOB_SRC_EXT}`],
161
- name: "moso/disables/bin",
162
- rules: {
163
- "antfu/no-import-dist": "off",
164
- "antfu/no-import-node-modules-by-path": "off"
165
- }
166
- },
167
- {
168
- files: ["**/*.d.?([cm])ts"],
169
- name: "moso/disables/dts",
170
- rules: {
171
- "@eslint-community/eslint-comments/no-unlimited-disable": "off",
172
- "import-x/no-duplicates": "off",
173
- "no-restricted-syntax": "off",
174
- "unused-imports/no-unused-vars": "off"
175
- }
176
- },
177
- {
178
- files: ["**/*.js", "**/*.cjs"],
179
- name: "moso/disables/cjs",
180
- rules: {
181
- "@typescript-eslint/no-require-imports": "off"
182
- }
183
- },
184
- {
185
- files: [`**/*.config.${GLOB_SRC_EXT}`, `**/*.config.*.${GLOB_SRC_EXT}`],
186
- name: "moso/disables/config-files",
187
- rules: {
188
- "@typescript-eslint/explicit-function-return-type": "off",
189
- "no-console": "off"
190
- }
191
- }
192
- ];
193
- };
194
-
195
- // src/configs/ignores.ts
196
- var ignores = (userIgnores = []) => {
197
- return [
198
- {
199
- name: "moso/ignores",
200
- ignores: [
201
- ...GLOB_EXCLUDE,
202
- ...userIgnores
203
- ]
204
- }
205
- ];
206
- };
207
-
208
- // src/configs/imports.ts
209
- var imports = async (options = {}) => {
210
- const {
211
- stylistic: stylistic2 = true
212
- } = options;
213
- const [
214
- antfuPlugin,
215
- importXPlugin
216
- ] = await Promise.all([
217
- interopDefault(import("eslint-plugin-antfu")),
218
- interopDefault(import("eslint-plugin-import-x"))
219
- ]);
220
- return [
221
- {
222
- name: "moso/imports/rules",
223
- plugins: {
224
- "antfu": antfuPlugin,
225
- "import-x": importXPlugin
226
- },
227
- rules: {
228
- "antfu/import-dedupe": "error",
229
- "antfu/no-import-dist": "error",
230
- "antfu/no-import-node-modules-by-path": "error",
231
- "import-x/consistent-type-specifier-style": ["error", "prefer-top-level"],
232
- "import-x/first": "error",
233
- "import-x/no-duplicates": ["error", { "prefer-inline": true }],
234
- "import-x/no-mutable-exports": "error",
235
- "import-x/no-named-default": "off",
236
- "import-x/no-self-import": "error",
237
- "import-x/no-unresolved": "off",
238
- "import-x/no-webpack-loader-syntax": "error",
239
- ...stylistic2 ? {
240
- "import-x/newline-after-import": ["error", { count: 1 }]
241
- } : {}
242
- }
243
- }
244
- ];
245
- };
246
-
247
- // src/configs/javascript.ts
248
- import globals from "globals";
249
- var javascript = async (options = {}) => {
250
- const {
251
- isInEditor = false,
252
- overrides = {}
253
- } = options;
254
- const unusedImportsPlugin = await interopDefault(import("eslint-plugin-unused-imports"));
255
- return [
256
- {
257
- languageOptions: {
258
- ecmaVersion: 2022,
259
- globals: {
260
- ...globals.browser,
261
- ...globals.es2021,
262
- ...globals.node,
263
- document: "readonly",
264
- navigator: "readonly",
265
- window: "readonly"
266
- },
267
- parserOptions: {
268
- ecmaFeatures: {
269
- jsx: true
270
- },
271
- ecmaVersion: 2022,
272
- sourceType: "module"
273
- },
274
- sourceType: "module"
275
- },
276
- linterOptions: {
277
- reportUnusedDisableDirectives: true
278
- },
279
- name: "moso/javascript/setup"
280
- },
281
- {
282
- name: "moso/javascript/rules",
283
- plugins: {
284
- "unused-imports": unusedImportsPlugin
285
- },
286
- rules: {
287
- "accessor-pairs": ["error", { enforceForClassMembers: true, setWithoutGet: true }],
288
- "array-callback-return": "error",
289
- "block-scoped-var": "error",
290
- "camelcase": "off",
291
- "consistent-return": "error",
292
- "constructor-super": "error",
293
- "curly": ["error", "multi-or-nest", "consistent"],
294
- "default-case-last": "error",
295
- "dot-notation": "warn",
296
- "eqeqeq": ["error", "smart"],
297
- "for-direction": "error",
298
- "getter-return": "error",
299
- "new-cap": ["error", { capIsNew: false, newIsCap: true, properties: true }],
300
- "no-alert": "warn",
301
- "no-async-promise-executor": "error",
302
- "no-caller": "error",
303
- "no-case-declarations": "error",
304
- "no-class-assign": "error",
305
- "no-compare-neg-zero": "error",
306
- "no-cond-assign": ["error", "always"],
307
- "no-console": ["warn", { allow: ["warn", "error"] }],
308
- "no-const-assign": "error",
309
- "no-control-regex": "error",
310
- "no-debugger": "warn",
311
- "no-delete-var": "error",
312
- "no-dupe-args": "error",
313
- "no-dupe-class-members": "error",
314
- "no-dupe-else-if": "error",
315
- "no-dupe-keys": "error",
316
- "no-duplicate-case": "error",
317
- "no-duplicate-imports": "error",
318
- "no-empty": ["error", { allowEmptyCatch: true }],
319
- "no-empty-character-class": "error",
320
- "no-empty-pattern": "error",
321
- "no-eval": "error",
322
- "no-ex-assign": "error",
323
- "no-extra-bind": "error",
324
- "no-extra-boolean-cast": "error",
325
- "no-fallthrough": ["warn", { commentPattern: "break[\\s\\w]*omitted" }],
326
- "no-func-assign": "error",
327
- "no-global-assign": "error",
328
- "no-implied-eval": "error",
329
- "no-import-assign": "error",
330
- "no-inner-declarations": "error",
331
- "no-invalid-regexp": "error",
332
- "no-irregular-whitespace": "error",
333
- "no-iterator": "error",
334
- "no-lonely-if": "error",
335
- "no-loss-of-precision": "error",
336
- "no-misleading-character-class": "error",
337
- "no-multi-str": "error",
338
- "no-new-native-nonconstructor": "error",
339
- "no-nonoctal-decimal-escape": "error",
340
- "no-obj-calls": "error",
341
- "no-octal": "error",
342
- "no-param-reassign": "error",
343
- "no-prototype-builtins": "error",
344
- "no-redeclare": ["error", { builtinGlobals: true }],
345
- "no-regex-spaces": "error",
346
- "no-restricted-globals": [
347
- "error",
348
- { message: "Use `globalThis` instead", name: "global" },
349
- { message: "Use `globalThis` instead", name: "self" }
350
- ],
351
- "no-restricted-properties": [
352
- "error",
353
- { message: "Use `Object.getPrototypeOf` or `Object.setPrototypeOf` instead.", property: "__proto__" },
354
- { message: "Use `Object.defineProperty` instead.", property: "__defineGetter__" },
355
- { message: "Use `Object.defineProperty` instead.", property: "__defineSetter__" },
356
- { message: "Use `Object.getOwnPropertyDescriptor` instead.", property: "__lookupGetter__" },
357
- { message: "Use `Object.getOwnPropertyDescriptor` instead.", property: "__lookupSetter__" }
358
- ],
359
- "no-restricted-syntax": [
360
- "error",
361
- "DebuggerStatement",
362
- "ForInStatement",
363
- "LabeledStatement",
364
- "TSEnumDeclaration[const=true]",
365
- "TSExportAssignment",
366
- "WithStatement"
367
- ],
368
- "no-return-assign": "off",
369
- "no-self-assign": "error",
370
- "no-self-compare": "error",
371
- "no-sequences": "error",
372
- "no-setter-return": "error",
373
- "no-shadow-restricted-names": "error",
374
- "no-sparse-arrays": "error",
375
- "no-template-curly-in-string": "error",
376
- "no-this-before-super": "error",
377
- "no-throw-literal": "error",
378
- "no-undef": "error",
379
- "no-undef-init": "error",
380
- "no-unexpected-multiline": "error",
381
- "no-unmodified-loop-condition": "error",
382
- "no-unneeded-ternary": "error",
383
- "no-unreachable": "error",
384
- "no-unsafe-finally": "error",
385
- "no-unsafe-negation": "error",
386
- "no-unsafe-optional-chaining": "error",
387
- "no-unused-expressions": [
388
- "error",
389
- {
390
- allowShortCircuit: true,
391
- allowTaggedTemplates: true,
392
- allowTernary: true
393
- }
394
- ],
395
- "no-unused-labels": "error",
396
- "no-unused-vars": [
397
- "error",
398
- {
399
- args: "none",
400
- caughtErrors: "none",
401
- ignoreRestSiblings: true,
402
- vars: "all"
403
- }
404
- ],
405
- "no-use-before-define": "error",
406
- "no-useless-backreference": "error",
407
- "no-useless-call": "error",
408
- "no-useless-catch": "error",
409
- "no-useless-computed-key": "error",
410
- "no-useless-constructor": "error",
411
- "no-useless-escape": "error",
412
- "no-useless-rename": "error",
413
- "no-var": "error",
414
- "no-with": "error",
415
- "object-shorthand": [
416
- "error",
417
- "always",
418
- {
419
- avoidQuotes: true,
420
- ignoreConstructors: false
421
- }
422
- ],
423
- "one-var": ["error", { initialized: "never" }],
424
- "prefer-arrow-callback": [
425
- "error",
426
- {
427
- allowNamedFunctions: false,
428
- allowUnboundThis: true
429
- }
430
- ],
431
- "prefer-const": [
432
- isInEditor ? "warn" : "error",
433
- {
434
- destructuring: "any",
435
- ignoreReadBeforeAssign: true
436
- }
437
- ],
438
- "prefer-exponentiation-operator": "error",
439
- "prefer-promise-reject-errors": "error",
440
- "prefer-regex-literals": ["error", { disallowRedundantWrapping: true }],
441
- "prefer-rest-params": "error",
442
- "prefer-spread": "error",
443
- "prefer-template": "error",
444
- "symbol-description": "error",
445
- "unicode-bom": ["error", "never"],
446
- "unused-imports/no-unused-imports": isInEditor ? "warn" : "error",
447
- "unused-imports/no-unused-vars": [
448
- "error",
449
- {
450
- args: "after-used",
451
- argsIgnorePattern: "^_",
452
- ignoreRestSiblings: true,
453
- vars: "all",
454
- varsIgnorePattern: "^_"
455
- }
456
- ],
457
- "use-isnan": [
458
- "error",
459
- {
460
- enforceForIndexOf: true,
461
- enforceForSwitchCase: true
462
- }
463
- ],
464
- "valid-typeof": ["error", { requireStringLiterals: true }],
465
- "vars-on-top": "error",
466
- "yoda": ["error", "never"],
467
- ...overrides
468
- }
469
- }
470
- ];
471
- };
472
-
473
- // src/configs/jsdoc.ts
474
- var jsdoc = async (options = {}) => {
475
- const { stylistic: stylistic2 = true } = options;
476
- const jsdocPlugin = await interopDefault(import("eslint-plugin-jsdoc"));
477
- return [
478
- {
479
- name: "moso/jsdoc/rules",
480
- plugins: {
481
- jsdoc: jsdocPlugin
482
- },
483
- rules: {
484
- "jsdoc/check-access": "warn",
485
- "jsdoc/check-param-names": "warn",
486
- "jsdoc/check-property-names": "warn",
487
- "jsdoc/check-types": "warn",
488
- "jsdoc/empty-tags": "warn",
489
- "jsdoc/implements-on-classes": "warn",
490
- "jsdoc/no-defaults": "warn",
491
- "jsdoc/no-multi-asterisks": "warn",
492
- "jsdoc/require-param-name": "warn",
493
- "jsdoc/require-property": "warn",
494
- "jsdoc/require-property-description": "warn",
495
- "jsdoc/require-property-name": "warn",
496
- "jsdoc/require-returns-check": "warn",
497
- "jsdoc/require-returns-description": "warn",
498
- "jsdoc/require-yields-check": "warn",
499
- ...stylistic2 ? {
500
- "jsdoc/check-alignment": "warn",
501
- "jsdoc/multiline-blocks": "warn"
502
- } : {}
503
- }
504
- }
505
- ];
506
- };
507
-
508
- // src/configs/jsonc.ts
509
- var jsonc = async (options = {}) => {
510
- const {
511
- files = [GLOB_JSON, GLOB_JSON5, GLOB_JSONC],
512
- overrides = {},
513
- stylistic: stylistic2 = true
514
- } = options;
515
- const { indent = 4 } = typeof stylistic2 === "boolean" ? {} : stylistic2;
516
- const [
517
- jsoncPlugin,
518
- jsoncParser
519
- ] = await Promise.all([
520
- interopDefault(import("eslint-plugin-jsonc")),
521
- interopDefault(import("jsonc-eslint-parser"))
522
- ]);
523
- return [
524
- {
525
- name: "moso/jsonc/setup",
526
- plugins: {
527
- jsonc: jsoncPlugin
528
- }
529
- },
530
- {
531
- files,
532
- languageOptions: {
533
- parser: jsoncParser
534
- },
535
- name: "moso/jsonc/rules",
536
- rules: {
537
- "jsonc/no-bigint-literals": "error",
538
- "jsonc/no-binary-expression": "error",
539
- "jsonc/no-binary-numeric-literals": "error",
540
- "jsonc/no-dupe-keys": "error",
541
- "jsonc/no-escape-sequence-in-identifier": "error",
542
- "jsonc/no-floating-decimal": "error",
543
- "jsonc/no-hexadecimal-numeric-literals": "error",
544
- "jsonc/no-infinity": "error",
545
- "jsonc/no-multi-str": "error",
546
- "jsonc/no-nan": "error",
547
- "jsonc/no-number-props": "error",
548
- "jsonc/no-numeric-separators": "error",
549
- "jsonc/no-octal": "error",
550
- "jsonc/no-octal-escape": "error",
551
- "jsonc/no-octal-numeric-literals": "error",
552
- "jsonc/no-parenthesized": "error",
553
- "jsonc/no-plus-sign": "error",
554
- "jsonc/no-regexp-literals": "error",
555
- "jsonc/no-sparse-arrays": "error",
556
- "jsonc/no-template-literals": "error",
557
- "jsonc/no-undefined-value": "error",
558
- "jsonc/no-unicode-codepoint-escapes": "error",
559
- "jsonc/no-useless-escape": "error",
560
- "jsonc/space-unary-ops": "error",
561
- "jsonc/valid-json-number": "error",
562
- "jsonc/vue-custom-block/no-parsing-error": "error",
563
- ...stylistic2 ? {
564
- "jsonc/array-bracket-spacing": ["error", "never"],
565
- "jsonc/comma-dangle": ["error", "never"],
566
- "jsonc/comma-style": ["error", "last"],
567
- "jsonc/indent": ["error", indent],
568
- "jsonc/key-spacing": ["error", { afterColon: true, beforeColon: false }],
569
- "jsonc/object-curly-newline": ["error", { consistent: true, multiline: true }],
570
- "jsonc/object-curly-spacing": ["error", "always"],
571
- "jsonc/object-property-newline": ["error", { allowMultiplePropertiesPerLine: true }],
572
- "jsonc/quote-props": "error",
573
- "jsonc/quotes": "error"
574
- } : {},
575
- ...overrides
576
- }
577
- }
578
- ];
579
- };
580
-
581
- // src/configs/jsx.ts
582
- var jsx = () => {
583
- return [
584
- {
585
- name: "moso/jsx/setup",
586
- files: [GLOB_JSX, GLOB_TSX],
587
- languageOptions: {
588
- parserOptions: {
589
- ecmaFeatures: {
590
- jsx: true
591
- }
592
- }
593
- }
594
- }
595
- ];
596
- };
597
-
598
- // src/configs/node.ts
599
- var node = async () => {
600
- const nodePlugin = await interopDefault(import("eslint-plugin-n"));
601
- return [
602
- {
603
- name: "moso/node/rules",
604
- plugins: {
605
- node: nodePlugin
606
- },
607
- rules: {
608
- "node/handle-callback-err": ["error", "^(err|error)$"],
609
- "node/no-deprecated-api": "error",
610
- "node/no-exports-assign": "error",
611
- "node/no-new-require": "error",
612
- "node/no-path-concat": "error",
613
- "node/prefer-global/buffer": ["error", "never"],
614
- "node/prefer-global/process": ["error", "never"],
615
- "node/process-exit-as-throw": "error"
616
- }
617
- }
618
- ];
619
- };
620
-
621
- // src/configs/perfectionist.ts
622
- var perfectionist = async (options = {}) => {
623
- const {
624
- lessOpinionated = false,
625
- overrides = {}
626
- } = {
627
- ...options
628
- };
629
- const perfectionistPlugin = await interopDefault(import("eslint-plugin-perfectionist"));
630
- return [
631
- {
632
- name: "moso/perfectionist/setup",
633
- plugins: {
634
- perfectionist: perfectionistPlugin
635
- },
636
- rules: {
637
- ...lessOpinionated ? {} : {
638
- "perfectionist/sort-exports": ["error", { order: "asc", type: "natural" }],
639
- "perfectionist/sort-imports": ["error", {
640
- groups: [
641
- "builtin",
642
- "external",
643
- "internal",
644
- ["parent", "sibling", "index"],
645
- "side-effect",
646
- "object",
647
- "unknown",
648
- "builtin-type",
649
- "external-type",
650
- "type",
651
- ["parent-type", "sibling-type", "index-type", "internal-type"]
652
- ],
653
- newlinesBetween: "ignore",
654
- order: "asc",
655
- type: "natural"
656
- }],
657
- "perfectionist/sort-named-exports": ["error", { order: "asc", type: "natural" }],
658
- "perfectionist/sort-named-imports": ["error", { order: "asc", type: "natural" }]
659
- },
660
- ...overrides
661
- }
662
- }
663
- ];
664
- };
665
-
666
- // src/configs/react.ts
667
- import { isPackageExists } from "local-pkg";
668
- var ReactRefreshAllowConstantExportPackages = [
669
- "vite"
670
- ];
671
- var RemixPackages = [
672
- "@remix-run/node",
673
- "@remix-run/react",
674
- "@remix-run/serve",
675
- "@remix-run/dev"
676
- ];
677
- var ReactRouterPackages = [
678
- "@react-router/node",
679
- "@react-router/react",
680
- "@react-router/serve",
681
- "@react-router/dev"
682
- ];
683
- var NextJsPackages = [
684
- "next"
685
- ];
686
- var react = async (options = {}) => {
687
- const {
688
- files = [GLOB_SRC],
689
- filesTypeAware = [GLOB_TS, GLOB_TSX],
690
- ignoresTypeAware = [`${GLOB_MARKDOWN}/**`],
691
- overrides = {},
692
- tsconfigPath
693
- } = options;
694
- const isTypeAware = !!tsconfigPath;
695
- const typeAwareRules = {
696
- "@eslint-react/dom/no-unknown-property": "off",
697
- "@eslint-react/no-duplicate-jsx-props": "off",
698
- "@eslint-react/use-jsx-vars": "off",
699
- "@eslint-react/no-leaked-conditional-rendering": "warn"
700
- };
701
- const [
702
- reactPlugin,
703
- reactHooksPlugin,
704
- reactRefreshPlugin
705
- ] = await Promise.all([
706
- interopDefault(import("@eslint-react/eslint-plugin")),
707
- interopDefault(import("eslint-plugin-react-hooks")),
708
- interopDefault(import("eslint-plugin-react-refresh"))
709
- ]);
710
- const isAllowConstantExport = ReactRefreshAllowConstantExportPackages.some((x) => isPackageExists(x));
711
- const isUsingRemix = RemixPackages.some((x) => isPackageExists(x));
712
- const isUsingReactRouter = ReactRouterPackages.some((x) => isPackageExists(x));
713
- const isUsingNext = NextJsPackages.some((x) => isPackageExists(x));
714
- const plugins = reactPlugin.configs.all.plugins;
715
- return [
716
- {
717
- name: "moso/react/setup",
718
- plugins: {
719
- "@eslint-react": plugins["@eslint-react"],
720
- "@eslint-react/dom": plugins["@eslint-react/dom"],
721
- "@eslint-react/hooks-extra": plugins["@eslint-react/hooks-extra"],
722
- "@eslint-react/naming-convention": plugins["@eslint-react/naming-convention"],
723
- "@eslint-react/web-api": plugins["@eslint-react/web-api"],
724
- "react-hooks": reactHooksPlugin,
725
- "react-refresh": reactRefreshPlugin
726
- }
727
- },
728
- {
729
- files,
730
- languageOptions: {
731
- parserOptions: {
732
- ecmaFeatures: {
733
- jsx: true
734
- }
735
- },
736
- sourceType: "module"
737
- },
738
- name: "moso/react/rules",
739
- rules: {
740
- // Recommended rules from @eslint-react/react-x
741
- // @see https://eslint-react.xyz/docs/rules/overview#core-rules
742
- "@eslint-react/jsx-no-duplicate-props": "error",
743
- "@eslint-react/jsx-no-undef": "error",
744
- "@eslint-react/no-access-state-in-setstate": "error",
745
- "@eslint-react/no-array-index-key": "warn",
746
- "@eslint-react/no-children-count": "warn",
747
- "@eslint-react/no-children-for-each": "warn",
748
- "@eslint-react/no-children-map": "warn",
749
- "@eslint-react/no-children-only": "warn",
750
- "@eslint-react/no-children-to-array": "warn",
751
- "@eslint-react/no-clone-element": "warn",
752
- "@eslint-react/no-comment-textnodes": "warn",
753
- "@eslint-react/no-component-will-mount": "error",
754
- "@eslint-react/no-component-will-receive-props": "error",
755
- "@eslint-react/no-component-will-update": "error",
756
- "@eslint-react/no-context-provider": "warn",
757
- "@eslint-react/no-create-ref": "error",
758
- "@eslint-react/no-default-props": "error",
759
- "@eslint-react/no-direct-mutation-state": "error",
760
- "@eslint-react/no-duplicate-jsx-props": "warn",
761
- "@eslint-react/no-duplicate-key": "warn",
762
- "@eslint-react/no-forward-ref": "warn",
763
- "@eslint-react/no-implicit-key": "warn",
764
- "@eslint-react/no-missing-key": "error",
765
- "@eslint-react/no-nested-component-definitions": "error",
766
- "@eslint-react/no-prop-types": "error",
767
- "@eslint-react/no-redundant-should-component-update": "error",
768
- "@eslint-react/no-set-state-in-component-did-mount": "warn",
769
- "@eslint-react/no-set-state-in-component-did-update": "warn",
770
- "@eslint-react/no-set-state-in-component-will-update": "warn",
771
- "@eslint-react/no-string-refs": "error",
772
- "@eslint-react/no-unsafe-component-will-mount": "warn",
773
- "@eslint-react/no-unsafe-component-will-receive-props": "warn",
774
- "@eslint-react/no-unsafe-component-will-update": "warn",
775
- "@eslint-react/no-unstable-context-value": "warn",
776
- "@eslint-react/no-unstable-default-props": "warn",
777
- "@eslint-react/no-unused-class-component-members": "warn",
778
- "@eslint-react/no-unused-state": "warn",
779
- "@eslint-react/no-use-context": "warn",
780
- "@eslint-react/no-useless-forward-ref": "warn",
781
- "@eslint-react/use-jsx-vars": "warn",
782
- // Recommended rules from @eslint-react/dom
783
- // @see https://eslint-react.xyz/docs/rules/overview#dom-rules
784
- "@eslint-react/dom/no-dangerously-set-innerhtml": "warn",
785
- "@eslint-react/dom/no-dangerously-set-innerhtml-with-children": "error",
786
- "@eslint-react/dom/no-find-dom-node": "error",
787
- "@eslint-react/dom/no-flush-sync": "error",
788
- "@eslint-react/dom/no-hydrate": "error",
789
- "@eslint-react/dom/no-missing-button-type": "warn",
790
- "@eslint-react/dom/no-missing-iframe-sandbox": "warn",
791
- "@eslint-react/dom/no-namespace": "error",
792
- "@eslint-react/dom/no-render": "error",
793
- "@eslint-react/dom/no-render-return-value": "error",
794
- "@eslint-react/dom/no-script-url": "warn",
795
- "@eslint-react/dom/no-unsafe-iframe-sandbox": "warn",
796
- "@eslint-react/dom/no-unsafe-target-blank": "warn",
797
- "@eslint-react/dom/no-use-form-state": "error",
798
- "@eslint-react/dom/no-void-elements-with-children": "error",
799
- // Recommended rules for eslint-plugin-react-hooks
800
- // @see https://github.com/facebook/react/tree/main/packages/eslint-plugin-react-hooks/src/rules
801
- "react-hooks/exhaustive-deps": "warn",
802
- "react-hooks/rules-of-hooks": "error",
803
- // Recommended rules for eslint-plugin-react-hooks-extra
804
- // @see https://eslint-react.xyz/docs/rules/overview#hooks-extra-rules
805
- "@eslint-react/hooks-extra/no-direct-set-state-in-use-effect": "warn",
806
- "@eslint-react/hooks-extra/no-useless-custom-hooks": "warn",
807
- "@eslint-react/hooks-extra/prefer-use-state-lazy-initialization": "warn",
808
- // Recommended rules from @eslint-react/web-api
809
- // @see https://eslint-react.xyz/docs/rules/overview#web-api-rules
810
- "@eslint-react/web-api/no-leaked-event-listener": "warn",
811
- "@eslint-react/web-api/no-leaked-interval": "warn",
812
- "@eslint-react/web-api/no-leaked-resize-observer": "warn",
813
- "@eslint-react/web-api/no-leaked-timeout": "warn",
814
- // Preconfigured rules from eslint-plugin-react-refresh
815
- // @see https://github.com/ArnaudBarre/eslint-plugin-react-refresh/tree/main/src
816
- "react-refresh/only-export-components": [
817
- "warn",
818
- {
819
- allowConstantExport: isAllowConstantExport,
820
- allowExportNames: [
821
- ...isUsingNext ? [
822
- "dynamic",
823
- "dynamicParams",
824
- "revalidate",
825
- "fetchCache",
826
- "runtime",
827
- "preferredRegion",
828
- "maxDuration",
829
- "config",
830
- "generateStaticParams",
831
- "metadata",
832
- "generateMetadata",
833
- "viewport",
834
- "generateViewport"
835
- ] : [],
836
- ...isUsingRemix || isUsingReactRouter ? [
837
- "meta",
838
- "links",
839
- "headers",
840
- "loader",
841
- "action"
842
- ] : []
843
- ]
844
- }
845
- ],
846
- // @moso's rules
847
- "@eslint-react/naming-convention/context-name": "warn",
848
- "@eslint-react/naming-convention/use-state": "warn",
849
- "@eslint-react/ensure-forward-ref-using-ref": "warn",
850
- "@eslint-react/no-nested-components": "error",
851
- "@eslint-react/prefer-destructuring-assignment": "warn",
852
- "@eslint-react/prefer-shorthand-boolean": "warn",
853
- "@eslint-react/prefer-shorthand-fragment": "warn",
854
- ...overrides
855
- }
856
- },
857
- ...isTypeAware ? [
858
- {
859
- files: filesTypeAware,
860
- ignores: ignoresTypeAware,
861
- name: "moso/react/type-aware-rules",
862
- rules: {
863
- ...typeAwareRules
864
- }
865
- }
866
- ] : []
867
- ];
868
- };
869
-
870
- // src/configs/sort.ts
871
- var sortPackageJson = () => {
872
- return [
873
- {
874
- files: ["**/package.json"],
875
- name: "moso/sort/package-json",
876
- rules: {
877
- "jsonc/sort-array-values": [
878
- "error",
879
- {
880
- order: { type: "asc" },
881
- pathPattern: "^files$"
882
- }
883
- ],
884
- "jsonc/sort-keys": [
885
- "error",
886
- {
887
- order: [
888
- "publisher",
889
- "name",
890
- "displayName",
891
- "type",
892
- "version",
893
- "private",
894
- "packageManager",
895
- "description",
896
- "author",
897
- "contributors",
898
- "license",
899
- "funding",
900
- "homepage",
901
- "repository",
902
- "bugs",
903
- "keywords",
904
- "categories",
905
- "sideEffects",
906
- "exports",
907
- "main",
908
- "module",
909
- "unpkg",
910
- "jsdelivr",
911
- "types",
912
- "typesVersions",
913
- "bin",
914
- "icon",
915
- "files",
916
- "engines",
917
- "activationEvents",
918
- "contributes",
919
- "scripts",
920
- "peerDependencies",
921
- "peerDependenciesMeta",
922
- "dependencies",
923
- "optionalDependencies",
924
- "devDependencies",
925
- "pnpm",
926
- "overrides",
927
- "resolutions",
928
- "husky",
929
- "simple-git-hooks",
930
- "lint-staged",
931
- "eslintConfig"
932
- ],
933
- pathPattern: "^$"
934
- },
935
- {
936
- order: { type: "asc" },
937
- pathPattern: "^(?:dev|peer|optional|bundled)?[Dd]ependencies(Meta)?$"
938
- },
939
- {
940
- order: { type: "asc" },
941
- pathPattern: "^(?:resolutions|overrides|pnpm.overrides)$"
942
- },
943
- {
944
- order: [
945
- "types",
946
- "import",
947
- "require",
948
- "default"
949
- ],
950
- pathPattern: "^exports.*$"
951
- },
952
- {
953
- order: [
954
- "pre-commit",
955
- "prepare-commit-msg",
956
- "commit-msg",
957
- "post-commit",
958
- "pre-rebase",
959
- "post-rewrite",
960
- "post-checkout",
961
- "post-merge",
962
- "pre-push",
963
- "pre-auto-gc"
964
- ],
965
- pathPattern: "^(?:gitHooks|husky|simple-git-hooks)$"
966
- }
967
- ]
968
- }
969
- }
970
- ];
971
- };
972
- var sortTsconfig = () => {
973
- return [
974
- {
975
- files: ["**/tsconfig.json", "**/tsconfig.*.json"],
976
- name: "moso/sort/tsconfig-json",
977
- rules: {
978
- "jsonc/sort-keys": [
979
- "error",
980
- {
981
- order: [
982
- "extends",
983
- "compilerOptions",
984
- "references",
985
- "files",
986
- "include",
987
- "exclude"
988
- ],
989
- pathPattern: "^$"
990
- },
991
- {
992
- order: [
993
- "incremental",
994
- "composite",
995
- "tsBuildInfoFile",
996
- "disableSourceOfProjectReferenceRedirect",
997
- "disableSolutionSearching",
998
- "disableReferencedProjectLoad",
999
- "target",
1000
- "jsx",
1001
- "jsxFactory",
1002
- "jsxFragmentFactory",
1003
- "jsxImportSource",
1004
- "lib",
1005
- "moduleDetection",
1006
- "noLib",
1007
- "reactNamespace",
1008
- "useDefineForClassFields",
1009
- "emitDecoratorMetadata",
1010
- "experimentalDecorators",
1011
- "libReplacement",
1012
- "baseUrl",
1013
- "rootDir",
1014
- "rootDirs",
1015
- "customConditions",
1016
- "module",
1017
- "moduleResolution",
1018
- "moduleSuffixes",
1019
- "noResolve",
1020
- "paths",
1021
- "resolveJsonModule",
1022
- "resolvePackageJsonExports",
1023
- "resolvePackageJsonImports",
1024
- "typeRoots",
1025
- "types",
1026
- "allowArbitraryExtensions",
1027
- "allowImportingTsExtensions",
1028
- "allowUmdGlobalAccess",
1029
- "allowJs",
1030
- "checkJs",
1031
- "maxNodeModuleJsDepth",
1032
- "strict",
1033
- "strictBindCallApply",
1034
- "strictFunctionTypes",
1035
- "strictNullChecks",
1036
- "strictPropertyInitialization",
1037
- "allowUnreachableCode",
1038
- "allowUnusedLabels",
1039
- "alwaysStrict",
1040
- "exactOptionalPropertyTypes",
1041
- "noFallthroughCasesInSwitch",
1042
- "noImplicitAny",
1043
- "noImplicitOverride",
1044
- "noImplicitReturns",
1045
- "noImplicitThis",
1046
- "noPropertyAccessFromIndexSignature",
1047
- "noUncheckedIndexedAccess",
1048
- "noUnusedLocals",
1049
- "noUnusedParameters",
1050
- "useUnknownInCatchVariables",
1051
- "declaration",
1052
- "declarationDir",
1053
- "declarationMap",
1054
- "downlevelIteration",
1055
- "emitBOM",
1056
- "emitDeclarationOnly",
1057
- "importHelpers",
1058
- "importsNotUsedAsValues",
1059
- "inlineSourceMap",
1060
- "inlineSources",
1061
- "mapRoot",
1062
- "newLine",
1063
- "noEmit",
1064
- "noEmitHelpers",
1065
- "noEmitOnError",
1066
- "outDir",
1067
- "outFile",
1068
- "preserveConstEnums",
1069
- "preserveValueImports",
1070
- "removeComments",
1071
- "sourceMap",
1072
- "sourceRoot",
1073
- "stripInternal",
1074
- "allowSyntheticDefaultImports",
1075
- "esModuleInterop",
1076
- "forceConsistentCasingInFileNames",
1077
- "isolatedModules",
1078
- "preserveSymlinks",
1079
- "verbatimModuleSyntax",
1080
- "erasableSyntaxOnly",
1081
- "skipDefaultLibCheck",
1082
- "skipLibCheck"
1083
- ],
1084
- pathPattern: "^compilerOptions$"
1085
- }
1086
- ]
1087
- }
1088
- }
1089
- ];
1090
- };
1091
-
1092
- // src/configs/stylistic.ts
1093
- var StylisticConfigDefaults = {
1094
- indent: 4,
1095
- jsx: true,
1096
- quotes: "single",
1097
- semi: true
1098
- };
1099
- var stylistic = async (options = {}) => {
1100
- const {
1101
- indent,
1102
- jsx: jsx2,
1103
- lessOpinionated = false,
1104
- overrides = {},
1105
- quotes,
1106
- semi
1107
- } = {
1108
- ...StylisticConfigDefaults,
1109
- ...options
1110
- };
1111
- const [
1112
- antfuPlugin,
1113
- stylisticPlugin
1114
- ] = await Promise.all([
1115
- interopDefault(import("eslint-plugin-antfu")),
1116
- interopDefault(import("@stylistic/eslint-plugin"))
1117
- ]);
1118
- const config = stylisticPlugin.configs.customize({
1119
- indent,
1120
- jsx: jsx2,
1121
- quotes,
1122
- semi
1123
- });
1124
- return [
1125
- {
1126
- name: "moso/stylistic/rules",
1127
- plugins: {
1128
- "@stylistic": stylisticPlugin,
1129
- "antfu": antfuPlugin
1130
- },
1131
- rules: {
1132
- ...config.rules,
1133
- "antfu/consistent-list-newline": "error",
1134
- "@stylistic/object-curly-newline": "off",
1135
- ...lessOpinionated ? {
1136
- curly: ["error", "all"]
1137
- } : {
1138
- "@stylistic/array-bracket-spacing": ["error", "never"],
1139
- "@stylistic/arrow-parens": ["error", "always"],
1140
- "@stylistic/block-spacing": ["error", "always"],
1141
- "@stylistic/brace-style": ["error", "1tbs", { allowSingleLine: true }],
1142
- "@stylistic/comma-dangle": ["error", "always-multiline"],
1143
- "@stylistic/comma-spacing": ["error", { before: false, after: true }],
1144
- "@stylistic/comma-style": ["error", "last"],
1145
- "@stylistic/func-call-spacing": ["error", "never"],
1146
- "@stylistic/generator-star-spacing": "off",
1147
- "@stylistic/indent": [
1148
- "error",
1149
- 4,
1150
- {
1151
- SwitchCase: 1,
1152
- VariableDeclarator: 1,
1153
- outerIIFEBody: 1,
1154
- MemberExpression: "off"
1155
- }
1156
- ],
1157
- "@stylistic/key-spacing": [
1158
- "error",
1159
- {
1160
- beforeColon: false,
1161
- afterColon: true
1162
- }
1163
- ],
1164
- "@stylistic/member-delimiter-style": [
1165
- "error",
1166
- {
1167
- multiline: {
1168
- delimiter: "semi",
1169
- requireLast: true
1170
- }
1171
- }
1172
- ],
1173
- "@stylistic/no-confusing-arrow": ["error", { onlyOneSimpleParam: true }],
1174
- "@stylistic/no-mixed-operators": [
1175
- "error",
1176
- {
1177
- groups: [
1178
- ["&", "|", "^", "~", "<<", ">>", ">>>"],
1179
- ["&&", "||"]
1180
- ]
1181
- }
1182
- ],
1183
- "@stylistic/no-mixed-spaces-and-tabs": "error",
1184
- "@stylistic/no-multi-spaces": "error",
1185
- "@stylistic/no-tabs": "error",
1186
- "@stylistic/no-trailing-spaces": [
1187
- "error",
1188
- {
1189
- skipBlankLines: true,
1190
- ignoreComments: true
1191
- }
1192
- ],
1193
- "@stylistic/operator-linebreak": ["error", "before"],
1194
- "@stylistic/quote-props": ["error", "consistent"],
1195
- "@stylistic/quotes": ["error", "single", { allowTemplateLiterals: true }],
1196
- "@stylistic/rest-spread-spacing": ["error", "never"],
1197
- "@stylistic/semi": ["error", "always"],
1198
- "@stylistic/semi-spacing": "error",
1199
- "@stylistic/semi-style": ["error", "last"],
1200
- "@stylistic/space-before-blocks": "error",
1201
- "@stylistic/space-before-function-paren": [
1202
- "error",
1203
- {
1204
- anonymous: "never",
1205
- named: "never",
1206
- asyncArrow: "always"
1207
- }
1208
- ],
1209
- "@stylistic/space-infix-ops": "error",
1210
- "@stylistic/space-unary-ops": "error",
1211
- "@stylistic/spaced-comment": ["error", "always"],
1212
- "@stylistic/switch-colon-spacing": "error",
1213
- "@stylistic/template-curly-spacing": "error",
1214
- "@stylistic/template-tag-spacing": ["error", "always"],
1215
- "@stylistic/wrap-iife": ["error", "any", { functionPrototypeMethods: true }],
1216
- "@stylistic/wrap-regex": "error",
1217
- "@stylistic/yield-star-spacing": ["error", "before"]
1218
- },
1219
- ...overrides
1220
- }
1221
- }
1222
- ];
1223
- };
1224
-
1225
- // src/configs/test.ts
1226
- var test = async (options = {}) => {
1227
- const {
1228
- files = GLOB_TESTS,
1229
- isInEditor = false,
1230
- overrides = {}
1231
- } = options;
1232
- const [
1233
- vitestPlugin,
1234
- noOnlyTestsPlugin
1235
- ] = await Promise.all([
1236
- interopDefault(import("@vitest/eslint-plugin")),
1237
- interopDefault(import("eslint-plugin-no-only-tests"))
1238
- ]);
1239
- return [
1240
- {
1241
- name: "moso/test/setup",
1242
- plugins: {
1243
- "vitest": vitestPlugin,
1244
- "no-only-tests": noOnlyTestsPlugin
1245
- }
1246
- },
1247
- {
1248
- files,
1249
- name: "moso/test/rules",
1250
- rules: {
1251
- "vitest/consistent-test-it": ["error", { fn: "it", withinDescribe: "it" }],
1252
- "vitest/no-identical-title": "error",
1253
- "vitest/no-import-node-test": "error",
1254
- "vitest/prefer-hooks-in-order": "error",
1255
- "vitest/prefer-lowercase-title": "error",
1256
- "no-only-tests/no-only-tests": isInEditor ? "warn" : "error",
1257
- // Disables for tests
1258
- ...{
1259
- "no-unused-expressions": "off",
1260
- "node/prefer-global/process": "off",
1261
- "@typescript-eslint/explicit-function-return-type": "off"
1262
- },
1263
- ...overrides
1264
- }
1265
- }
1266
- ];
1267
- };
1268
-
1269
- // src/configs/typescript.ts
1270
- import process2 from "node:process";
1271
- var typescript = async (options = {}) => {
1272
- const {
1273
- componentExts = [],
1274
- lessOpinionated = false,
1275
- overrides = {},
1276
- overridesTypeAware = {},
1277
- parserOptions = {}
1278
- } = options;
1279
- const files = options.files ?? [
1280
- GLOB_TS,
1281
- GLOB_TSX,
1282
- ...componentExts.map((ext) => `**/*.${ext}`)
1283
- ];
1284
- const filesTypeAware = options.filesTypeAware ?? [GLOB_TS, GLOB_TSX];
1285
- const ignoresTypeAware = options.ignoresTypeAware ?? [`${GLOB_MARKDOWN}/**`];
1286
- const tsconfigPath = options?.tsconfigPath ? options.tsconfigPath : void 0;
1287
- const isTypeAware = !!tsconfigPath;
1288
- const typeAwareRules = {
1289
- // JS off
1290
- "dot-notation": "off",
1291
- "no-implied-eval": "off",
1292
- "no-throw-literal": "off",
1293
- // TypeScript
1294
- "@typescript-eslint/await-thenable": "error",
1295
- "@typescript-eslint/dot-notation": ["error", { allowKeywords: true }],
1296
- "@typescript-eslint/explicit-function-return-type": "off",
1297
- "@typescript-eslint/explicit-member-accessibility": "off",
1298
- "@typescript-eslint/no-empty-function": "off",
1299
- "@typescript-eslint/no-empty-interface": "off",
1300
- "@typescript-eslint/no-explicit-any": "off",
1301
- "@typescript-eslint/no-floating-promises": "error",
1302
- "@typescript-eslint/no-for-in-array": "error",
1303
- "@typescript-eslint/no-implied-eval": "error",
1304
- "@typescript-eslint/no-misused-promises": "error",
1305
- "@typescript-eslint/no-non-null-assertion": "off",
1306
- "@typescript-eslint/no-var-requires": "off",
1307
- "@typescript-eslint/no-unnecessary-type-assertion": "error",
1308
- "@typescript-eslint/no-unsafe-argument": "error",
1309
- "@typescript-eslint/no-unsafe-assignment": "error",
1310
- "@typescript-eslint/no-unsafe-call": "error",
1311
- "@typescript-eslint/no-unsafe-member-access": "error",
1312
- "@typescript-eslint/only-throw-error": "error",
1313
- "@typescript-eslint/parameter-properties": "off",
1314
- "@typescript-eslint/restrict-plus-operands": "error",
1315
- "@typescript-eslint/restrict-template-expressions": "error",
1316
- "@typescript-eslint/unbound-method": "error",
1317
- ...lessOpinionated ? {} : {
1318
- // Opinionated TypeScript
1319
- "@typescript-eslint/no-unsafe-return": "error",
1320
- "@typescript-eslint/switch-exhaustiveness-check": [
1321
- "error",
1322
- {
1323
- considerDefaultExhaustiveForUnions: true
1324
- }
1325
- ],
1326
- // Opinionated Functional
1327
- // @see https://github.com/eslint-functional/eslint-plugin-functional
1328
- "functional/no-mixed-types": "error",
1329
- "functional/prefer-property-signatures": "error",
1330
- "functional/readonly-type": "error",
1331
- "functional/type-declaration-immutability": [
1332
- "error",
1333
- {
1334
- rules: [
1335
- {
1336
- identifiers: "I?Immutable.+",
1337
- immutability: "Immutable",
1338
- comparator: "AtLeast"
1339
- },
1340
- {
1341
- identifiers: "I?ReadonlyDeep.+",
1342
- immutability: "ReadonlyDeep",
1343
- comparator: "AtLeast"
1344
- },
1345
- {
1346
- identifiers: "I?Readonly.+",
1347
- immutability: "ReadonlyShallow",
1348
- comparator: "AtLeast",
1349
- fixer: [
1350
- {
1351
- pattern: "^(Array|Map|Set)<(.+)>$",
1352
- replace: "Readonly$1<$2>"
1353
- },
1354
- {
1355
- pattern: "^(.+)$",
1356
- replace: "Readonly<$1>"
1357
- }
1358
- ]
1359
- },
1360
- {
1361
- identifiers: "I?Mutable.+",
1362
- immutability: "Mutable",
1363
- comparator: "AtMost",
1364
- fixer: [
1365
- {
1366
- pattern: "^Readonly(Array|Map|Set)<(.+)>$",
1367
- replace: "$1<$2>"
1368
- },
1369
- {
1370
- pattern: "^Readonly<(.+)>$",
1371
- replace: "$1"
1372
- }
1373
- ]
1374
- }
1375
- ]
1376
- }
1377
- ]
1378
- }
1379
- };
1380
- const [
1381
- antfuPlugin,
1382
- functionalPlugin,
1383
- typeScriptParser,
1384
- typeScriptPlugin
1385
- ] = await Promise.all([
1386
- interopDefault(import("eslint-plugin-antfu")),
1387
- interopDefault(import("eslint-plugin-functional")),
1388
- interopDefault(import("@typescript-eslint/parser")),
1389
- interopDefault(import("@typescript-eslint/eslint-plugin"))
1390
- ]);
1391
- const makeParser = (typeAware, files2, ignores2) => {
1392
- return {
1393
- files: files2,
1394
- ...ignores2 ? { ignores: ignores2 } : {},
1395
- languageOptions: {
1396
- parser: typeScriptParser,
1397
- parserOptions: {
1398
- extraFileExtensions: componentExts.map((ext) => `.${ext}`),
1399
- sourceType: "module",
1400
- ...typeAware ? {
1401
- projectService: {
1402
- allowDefaultProject: ["./*.js"],
1403
- defaultProject: tsconfigPath
1404
- },
1405
- tsconfigRootDir: process2.cwd()
1406
- } : {},
1407
- ...parserOptions
1408
- }
1409
- },
1410
- name: `moso/typescript/${typeAware ? "type-aware-parser" : "parser"}`
1411
- };
1412
- };
1413
- return [
1414
- {
1415
- name: "moso/typescript/setup",
1416
- plugins: {
1417
- "antfu": antfuPlugin,
1418
- "functional": functionalPlugin,
1419
- "@typescript-eslint": typeScriptPlugin
1420
- }
1421
- },
1422
- ...isTypeAware ? [
1423
- makeParser(false, files),
1424
- makeParser(true, filesTypeAware, ignoresTypeAware)
1425
- ] : [
1426
- makeParser(false, files)
1427
- ],
1428
- {
1429
- files,
1430
- name: "moso/typescript/rules",
1431
- rules: {
1432
- ...typeScriptPlugin.configs["eslint-recommended"].overrides[0].rules,
1433
- ...typeScriptPlugin.configs.strict.rules,
1434
- // JS off
1435
- "no-dupe-class-members": "off",
1436
- "no-redeclare": "off",
1437
- "no-loss-of-precision": "off",
1438
- "no-unused-vars": "off",
1439
- "no-use-before-define": "off",
1440
- "no-useless-constructor": "off",
1441
- // Stylistic
1442
- "@stylistic/type-annotation-spacing": "error",
1443
- // Typescript
1444
- "@typescript-eslint/ban-ts-comment": [
1445
- "error",
1446
- {
1447
- "ts-ignore": "allow-with-description"
1448
- }
1449
- ],
1450
- "@typescript-eslint/consistent-type-imports": [
1451
- "error",
1452
- {
1453
- disallowTypeAnnotations: false,
1454
- prefer: "type-imports"
1455
- }
1456
- ],
1457
- "@typescript-eslint/method-signature-style": ["error", "property"],
1458
- "@typescript-eslint/no-dynamic-delete": "off",
1459
- "@typescript-eslint/no-empty-object-type": ["error", { allowInterfaces: "always" }],
1460
- "@typescript-eslint/no-explicit-any": "off",
1461
- "@typescript-eslint/no-extraneous-class": "off",
1462
- "@typescript-eslint/no-import-type-side-effects": "error",
1463
- "@typescript-eslint/no-invalid-void-type": "off",
1464
- "@typescript-eslint/no-non-null-assertion": "off",
1465
- "@typescript-eslint/no-require-imports": "error",
1466
- "@typescript-eslint/no-unused-expressions": [
1467
- "error",
1468
- {
1469
- allowShortCircuit: true,
1470
- allowTaggedTemplates: true,
1471
- allowTernary: true
1472
- }
1473
- ],
1474
- "@typescript-eslint/no-unused-vars": [
1475
- "error",
1476
- {
1477
- argsIgnorePattern: "^_",
1478
- args: "none",
1479
- ignoreRestSiblings: true
1480
- }
1481
- ],
1482
- "@typescript-eslint/no-use-before-define": [
1483
- "error",
1484
- {
1485
- classes: false,
1486
- functions: false,
1487
- variables: true
1488
- }
1489
- ],
1490
- "@typescript-eslint/no-useless-constructor": "off",
1491
- "@typescript-eslint/triple-slash-reference": "off",
1492
- "@typescript-eslint/unified-signatures": "off",
1493
- ...overrides
1494
- }
1495
- },
1496
- ...isTypeAware ? [{
1497
- files: filesTypeAware,
1498
- ignores: ignoresTypeAware,
1499
- name: "moso/typescript/rules-type-aware",
1500
- rules: {
1501
- ...typeAwareRules,
1502
- ...overridesTypeAware
1503
- }
1504
- }] : [],
1505
- {
1506
- files: ["**/*.d.ts"],
1507
- name: "moso/typescript/disables/dts",
1508
- rules: {
1509
- "@eslint-community/eslint-comments/no-unlimited-disable": "off",
1510
- "import-x/no-duplicates": "off",
1511
- "no-restricted-syntax": "off",
1512
- "unused-imports/no-unused-vars": "off"
1513
- }
1514
- },
1515
- {
1516
- files: ["**/*.{test,spec}.ts?(x)"],
1517
- name: "moso/typescript/disables/test",
1518
- rules: {
1519
- "no-unused-expressions": "off"
1520
- }
1521
- },
1522
- {
1523
- files: ["**/*.js", "**/*.cjs"],
1524
- name: "moso/typescript/disables/cjs",
1525
- rules: {
1526
- "@typescript-eslint/no-require-imports": "off"
1527
- }
1528
- }
1529
- ];
1530
- };
1531
-
1532
- // src/configs/unicorn.ts
1533
- var unicorn = async (options = {}) => {
1534
- const unicornPlugin = await interopDefault(import("eslint-plugin-unicorn"));
1535
- return [
1536
- {
1537
- name: "moso/unicorn/rules",
1538
- plugins: {
1539
- unicorn: unicornPlugin
1540
- },
1541
- rules: {
1542
- ...options.allRecommended ? unicornPlugin.configs.recommended.rules : {
1543
- "unicorn/consistent-empty-array-spread": "error",
1544
- "unicorn/error-message": "error",
1545
- "unicorn/escape-case": "error",
1546
- "unicorn/no-instanceof-builtins": "error",
1547
- "unicorn/no-new-array": "error",
1548
- "unicorn/no-new-buffer": "error",
1549
- "unicorn/number-literal-case": "error",
1550
- "unicorn/prefer-dom-node-text-content": "error",
1551
- "unicorn/prefer-includes": "error",
1552
- "unicorn/prefer-node-protocol": "error",
1553
- "unicorn/prefer-number-properties": "error",
1554
- "unicorn/prefer-string-starts-ends-with": "error",
1555
- "unicorn/prefer-type-error": "error",
1556
- "unicorn/throw-new-error": "error"
1557
- }
1558
- }
1559
- }
1560
- ];
1561
- };
1562
-
1563
- // src/configs/vue.ts
1564
- import { mergeProcessors } from "eslint-merge-processors";
1565
- var vue = async (options = {}) => {
1566
- const {
1567
- files = [GLOB_VUE],
1568
- overrides = {},
1569
- stylistic: stylistic2 = true
1570
- } = options;
1571
- const sfcBlocks = options.sfcBlocks === true ? {} : options.sfcBlocks ?? {};
1572
- const { indent = 4 } = typeof stylistic2 === "boolean" ? {} : stylistic2;
1573
- const [
1574
- vuePlugin,
1575
- vueParser,
1576
- processorVueBlocks
1577
- ] = await Promise.all([
1578
- interopDefault(import("eslint-plugin-vue")),
1579
- interopDefault(import("vue-eslint-parser")),
1580
- interopDefault(import("eslint-processor-vue-blocks"))
1581
- ]);
1582
- return [
1583
- {
1584
- languageOptions: {
1585
- globals: {
1586
- computed: "readonly",
1587
- defineEmits: "readonly",
1588
- defineExpose: "readonly",
1589
- defineProps: "readonly",
1590
- onMounted: "readonly",
1591
- onUnmounted: "readonly",
1592
- reactive: "readonly",
1593
- ref: "readonly",
1594
- shallowReactive: "readonly",
1595
- shallowRef: "readonly",
1596
- toRef: "readonly",
1597
- toRefs: "readonly",
1598
- watch: "readonly",
1599
- watchEffect: "readonly"
1600
- }
1601
- },
1602
- name: "moso/vue/setup",
1603
- plugins: {
1604
- vue: vuePlugin
1605
- }
1606
- },
1607
- {
1608
- files,
1609
- languageOptions: {
1610
- parser: vueParser,
1611
- parserOptions: {
1612
- ecmaFeatures: {
1613
- jsx: true
1614
- },
1615
- extraFileExtensions: [".vue"],
1616
- parser: options.typescript ? await interopDefault(import("@typescript-eslint/parser")) : null,
1617
- sourceType: "module"
1618
- }
1619
- },
1620
- name: "moso/vue/rules",
1621
- processor: sfcBlocks === false ? vuePlugin.processors[".vue"] : mergeProcessors([
1622
- vuePlugin.processors[".vue"],
1623
- processorVueBlocks({
1624
- ...sfcBlocks,
1625
- blocks: {
1626
- styles: true,
1627
- ...sfcBlocks.blocks
1628
- }
1629
- })
1630
- ]),
1631
- rules: {
1632
- ...vuePlugin.configs.base.rules,
1633
- ...vuePlugin.configs["flat/essential"].map((x) => x.rules).reduce((acc, x) => ({ ...acc, ...x }), {}),
1634
- ...vuePlugin.configs["flat/strongly-recommended"].map((x) => x.rules).reduce((acc, x) => ({ ...acc, ...x }), {}),
1635
- ...vuePlugin.configs["flat/recommended"].map((x) => x.rules).reduce((acc, x) => ({ ...acc, ...x }), {}),
1636
- "node/prefer-global/process": "off",
1637
- "@typescript-eslint/explicit-function-return-type": "off",
1638
- "vue/block-order": ["error", {
1639
- order: ["script", "template", "style"]
1640
- }],
1641
- "vue/component-name-in-template-casing": ["error", "PascalCase"],
1642
- "vue/component-options-name-casing": ["error", "PascalCase"],
1643
- "vue/custom-event-name-casing": ["error", "camelCase"],
1644
- "vue/define-macros-order": ["error", {
1645
- order: ["defineOptions", "defineProps", "defineEmits", "defineSlots"]
1646
- }],
1647
- "vue/dot-location": ["error", "property"],
1648
- "vue/dot-notation": ["error", { allowKeywords: true }],
1649
- "vue/eqeqeq": ["error", "smart"],
1650
- "vue/html-indent": ["error", indent],
1651
- "vue/html-quotes": [
1652
- "error",
1653
- "double",
1654
- {
1655
- avoidEscape: true
1656
- }
1657
- ],
1658
- "vue/html-self-closing": "off",
1659
- "vue/max-attributes-per-line": ["warn", { singleline: 5 }],
1660
- "vue/multi-word-component-names": "off",
1661
- "vue/no-dupe-keys": "off",
1662
- "vue/no-empty-pattern": "error",
1663
- "vue/no-irregular-whitespace": "error",
1664
- "vue/no-loss-of-precision": "error",
1665
- "vue/no-restricted-syntax": [
1666
- "error",
1667
- "DebuggerStatement",
1668
- "LabeledStatement",
1669
- "WithStatement"
1670
- ],
1671
- "vue/no-restricted-v-bind": ["error", "/^v-/"],
1672
- "vue/no-setup-props-reactivity-loss": "off",
1673
- "vue/no-sparse-arrays": "error",
1674
- "vue/no-unused-refs": "error",
1675
- "vue/no-useless-v-bind": "error",
1676
- "vue/no-v-html": "off",
1677
- "vue/no-v-text-v-html-on-component": "off",
1678
- "vue/object-shorthand": [
1679
- "error",
1680
- "always",
1681
- {
1682
- avoidQuotes: true,
1683
- ignoreConstructors: false
1684
- }
1685
- ],
1686
- "vue/prefer-import-from-vue": "off",
1687
- "vue/prefer-separate-static-class": "error",
1688
- "vue/prefer-template": "error",
1689
- "vue/prop-name-casing": ["error", "camelCase"],
1690
- "vue/require-default-prop": "off",
1691
- "vue/require-prop-types": "off",
1692
- "vue/space-infix-ops": "error",
1693
- "vue/space-unary-ops": ["error", { nonwords: false, words: true }],
1694
- ...stylistic2 ? {
1695
- "vue/array-bracket-spacing": ["error", "never"],
1696
- "vue/arrow-spacing": ["error", { after: true, before: true }],
1697
- "vue/block-spacing": ["error", "always"],
1698
- "vue/brace-style": ["error", "stroustrup", { allowSingleLine: true }],
1699
- "vue/comma-dangle": ["error", "always-multiline"],
1700
- "vue/comma-spacing": ["error", { after: true, before: false }],
1701
- "vue/comma-style": ["error", "last"],
1702
- "vue/html-comment-content-spacing": ["error", "always", {
1703
- exceptions: ["-"]
1704
- }],
1705
- "vue/key-spacing": ["error", { afterColon: true, beforeColon: false }],
1706
- "vue/keyword-spacing": ["error", { after: true, before: true }],
1707
- "vue/object-curly-newline": "off",
1708
- "vue/object-curly-spacing": ["error", "always"],
1709
- "vue/object-property-newline": ["error", { allowMultiplePropertiesPerLine: true }],
1710
- "vue/operator-linebreak": ["error", "before"],
1711
- "vue/padding-line-between-blocks": ["error", "always"],
1712
- "vue/quote-props": ["error", "consistent-as-needed"],
1713
- "vue/singleline-html-element-content-newline": "off",
1714
- "vue/space-in-parens": ["error", "never"],
1715
- "vue/template-curly-spacing": "error"
1716
- } : {},
1717
- ...overrides
1718
- }
1719
- }
1720
- ];
1721
- };
1722
-
1723
- // src/configs/yaml.ts
1724
- var yaml = async (options = {}) => {
1725
- const {
1726
- files = [GLOB_YAML],
1727
- overrides = {},
1728
- stylistic: stylistic2 = true
1729
- } = options;
1730
- const {
1731
- indent = 2,
1732
- quotes = "single"
1733
- } = typeof stylistic2 === "boolean" ? {} : stylistic2;
1734
- const [
1735
- yamlPlugin,
1736
- yamlParser
1737
- ] = await Promise.all([
1738
- interopDefault(import("eslint-plugin-yml")),
1739
- interopDefault(import("yaml-eslint-parser"))
1740
- ]);
1741
- return [
1742
- {
1743
- name: "moso/yaml/setup",
1744
- plugins: {
1745
- yml: yamlPlugin
1746
- }
1747
- },
1748
- {
1749
- files,
1750
- languageOptions: {
1751
- parser: yamlParser
1752
- },
1753
- name: "moso/yaml/rules",
1754
- rules: {
1755
- "@stylistic/spaced-comment": "off",
1756
- "yml/block-mapping": "error",
1757
- "yml/block-sequence": "error",
1758
- "yml/no-empty-key": "error",
1759
- "yml/no-empty-sequence-entry": "error",
1760
- "yml/no-irregular-whitespace": "error",
1761
- "yml/plain-scalar": "error",
1762
- "yml/vue-custom-block/no-parsing-error": "error",
1763
- ...stylistic2 ? {
1764
- "yml/block-mapping-question-indicator-newline": "error",
1765
- "yml/block-sequence-hyphen-indicator-newline": "error",
1766
- "yml/flow-mapping-curly-newline": "error",
1767
- "yml/flow-mapping-curly-spacing": "error",
1768
- "yml/flow-sequence-bracket-newline": "error",
1769
- "yml/flow-sequence-bracket-spacing": "error",
1770
- "yml/indent": ["error", indent === "tab" ? 2 : indent],
1771
- "yml/key-spacing": "error",
1772
- "yml/no-tab-indent": "error",
1773
- "yml/quotes": ["error", { avoidEscape: true, prefer: quotes === "backtick" ? "single" : quotes }],
1774
- "yml/spaced-comment": "error"
1775
- } : {},
1776
- ...overrides
1777
- }
1778
- }
1779
- ];
1780
- };
1781
-
1782
- // src/configurator.ts
1783
- var flatConfigProps = [
1784
- "languageOptions",
1785
- "linterOptions",
1786
- "name",
1787
- "processor",
1788
- "plugins",
1789
- "rules",
1790
- "settings"
1791
- ];
1792
- var VuePackages = [
1793
- "nuxt",
1794
- "vitepress",
1795
- "vue"
1796
- ];
1797
- var ReactPackages = [
1798
- "gatsby",
1799
- "next",
1800
- "nextra",
1801
- "react",
1802
- "remix"
1803
- ];
1804
- var moso = (options = {}, ...userConfigs) => {
1805
- const {
1806
- componentExts = [],
1807
- gitignore: enableGitignore = true,
1808
- jsx: enableJsx = true,
1809
- react: enableReact = ReactPackages.some((x) => isPackageExists2(x)),
1810
- typescript: enableTypeScript = isPackageExists2("typescript"),
1811
- unicorn: enableUnicorn = true,
1812
- vue: enableVue = VuePackages.some((x) => isPackageExists2(x))
1813
- } = options;
1814
- let isInEditor = options.isInEditor;
1815
- if (isInEditor == null) {
1816
- isInEditor = isInEditorEnv();
1817
- if (isInEditor) {
1818
- console.log("[@moso/eslint-config] Detected running in editor, some rules are disabled.");
1819
- }
1820
- }
1821
- const stylisticOptions = options.stylistic === false ? false : typeof options.stylistic === "object" ? options.stylistic : {};
1822
- if (stylisticOptions && !("jsx" in stylisticOptions)) stylisticOptions.jsx = enableJsx;
1823
- const configs = [];
1824
- if (enableGitignore) {
1825
- if (typeof enableGitignore !== "boolean") {
1826
- configs.push(interopDefault(import("eslint-config-flat-gitignore")).then((x) => [x({
1827
- name: "moso/gitignore",
1828
- ...enableGitignore
1829
- })]));
1830
- } else {
1831
- configs.push(interopDefault(import("eslint-config-flat-gitignore")).then((x) => [x({
1832
- name: "moso/gitignore",
1833
- strict: false
1834
- })]));
1835
- }
1836
- }
1837
- const typescriptOptions = resolveSubOptions(options, "typescript");
1838
- const tsconfigPath = "tsconfigPath" in typescriptOptions ? typescriptOptions.tsconfigPath : void 0;
1839
- configs.push(
1840
- ignores(options.ignores),
1841
- javascript({ overrides: getOverrides(options, "javascript") }),
1842
- comments(),
1843
- node(),
1844
- jsdoc({ stylistic: stylisticOptions }),
1845
- imports({ stylistic: stylisticOptions }),
1846
- perfectionist()
1847
- );
1848
- if (enableUnicorn) configs.push(unicorn(enableUnicorn === true ? {} : enableUnicorn));
1849
- if (enableVue) componentExts.push("vue");
1850
- if (enableJsx) configs.push(jsx());
1851
- if (enableTypeScript) {
1852
- configs.push(typescript({
1853
- ...typescriptOptions,
1854
- componentExts,
1855
- overrides: getOverrides(options, "typescript")
1856
- }));
1857
- }
1858
- if (stylisticOptions) {
1859
- configs.push(stylistic({
1860
- ...stylisticOptions,
1861
- lessOpinionated: options.lessOpinionated,
1862
- overrides: getOverrides(options, "stylistic")
1863
- }));
1864
- }
1865
- if (options.test ?? true) configs.push(test({ overrides: getOverrides(options, "test") }));
1866
- if (enableVue) {
1867
- configs.push(vue({
1868
- ...resolveSubOptions(options, "vue"),
1869
- overrides: getOverrides(options, "vue"),
1870
- stylistic: stylisticOptions,
1871
- typescript: !!enableTypeScript
1872
- }));
1873
- }
1874
- if (enableReact) {
1875
- configs.push(react({
1876
- ...typescriptOptions,
1877
- overrides: getOverrides(options, "react"),
1878
- tsconfigPath
1879
- }));
1880
- }
1881
- if (options.jsonc ?? true) {
1882
- configs.push(
1883
- jsonc({
1884
- overrides: getOverrides(options, "jsonc"),
1885
- stylistic: stylisticOptions
1886
- }),
1887
- sortPackageJson(),
1888
- sortTsconfig()
1889
- );
1890
- }
1891
- if (options.yaml ?? true) {
1892
- configs.push(yaml({
1893
- overrides: getOverrides(options, "yaml"),
1894
- stylistic: stylisticOptions
1895
- }));
1896
- }
1897
- configs.push(
1898
- disables()
1899
- );
1900
- if ("files" in options)
1901
- throw new Error('[@moso/eslint-config] The first argument should not contain the "files" property as the options are supposed to be global. Place it in the second or later config instead.');
1902
- const fusedConfig = flatConfigProps.reduce((acc, key) => {
1903
- if (key in options) acc[key] = options[key];
1904
- return acc;
1905
- }, {});
1906
- if (Object.keys(fusedConfig).length) configs.push([fusedConfig]);
1907
- let composer = new FlatConfigComposer();
1908
- composer = composer.append(
1909
- ...configs,
1910
- ...userConfigs
1911
- );
1912
- if (isInEditor) {
1913
- composer = composer.disableRulesFix([
1914
- "unused-imports/no-unused-imports",
1915
- "no-only-tests/no-only-tests",
1916
- "prefer-const"
1917
- ], {
1918
- builtinRules: () => import(["eslint", "use-at-your-own-risk"].join("/")).then((x) => x.builtinRules)
1919
- });
1920
- }
1921
- return composer;
1922
- };
1923
-
1924
- // src/index.ts
1925
- var index_default = moso;
1926
- export {
1927
- GLOB_ALL_SRC,
1928
- GLOB_EXCLUDE,
1929
- GLOB_HTML,
1930
- GLOB_JS,
1931
- GLOB_JSON,
1932
- GLOB_JSON5,
1933
- GLOB_JSONC,
1934
- GLOB_JSX,
1935
- GLOB_MARKDOWN,
1936
- GLOB_MARKDOWN_CODE,
1937
- GLOB_MARKDOWN_IN_MARKDOWN,
1938
- GLOB_SRC,
1939
- GLOB_SRC_EXT,
1940
- GLOB_TESTS,
1941
- GLOB_TS,
1942
- GLOB_TSX,
1943
- GLOB_VUE,
1944
- GLOB_YAML,
1945
- StylisticConfigDefaults,
1946
- combine,
1947
- comments,
1948
- index_default as default,
1949
- disables,
1950
- getOverrides,
1951
- ignores,
1952
- imports,
1953
- interopDefault,
1954
- isInEditorEnv,
1955
- isInGitHooksOrLintStaged,
1956
- javascript,
1957
- jsdoc,
1958
- jsonc,
1959
- jsx,
1960
- moso,
1961
- node,
1962
- parserPlain,
1963
- perfectionist,
1964
- react,
1965
- resolveSubOptions,
1966
- sortPackageJson,
1967
- sortTsconfig,
1968
- stylistic,
1969
- test,
1970
- toArray,
1971
- typescript,
1972
- unicorn,
1973
- vue,
1974
- yaml
1975
- };