@shun-shobon/style-guide 1.2.0 → 1.3.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.
@@ -1,831 +0,0 @@
1
- // src/eslint/globs.ts
2
- var GLOB_SRC_EXT = "?([cm])[jt]s?(x)";
3
- var GLOB_SRC = `**/*.${GLOB_SRC_EXT}`;
4
- var GLOB_JS_EXT = "?([cm])js";
5
- var GLOB_JS = `**/*.${GLOB_JS_EXT}`;
6
- var GLOB_JSX_EXT = "?([cm])jsx";
7
- var GLOB_JSX = `**/*.${GLOB_JSX_EXT}`;
8
- var GLOB_TS_EXT = "?([cm])ts";
9
- var GLOB_TS = `**/*.${GLOB_TS_EXT}`;
10
- var GLOB_TSX_EXT = "?([cm])tsx";
11
- var GLOB_TSX = `**/*.${GLOB_TSX_EXT}`;
12
- var GLOB_DTS_EXT = "?([cm])d.ts";
13
- var GLOB_DTS = `**/*.${GLOB_DTS_EXT}`;
14
- var GLOB_STORYBOOK_EXT = `@(stories|story).${GLOB_TSX_EXT}`;
15
- var GLOB_STORYBOOK = `**/*.${GLOB_STORYBOOK_EXT}`;
16
- var GLOB_STORYBOOK_CONFIG = `**/.storybook/main.${GLOB_SRC_EXT}`;
17
- var GLOB_ASTRO_EXT = "astro";
18
- var GLOB_ASTRO = `**/*.${GLOB_ASTRO_EXT}`;
19
-
20
- // src/eslint/utils.ts
21
- async function interopDefault(module) {
22
- const resolved = await module;
23
- return resolved.default ?? resolved;
24
- }
25
- function renameRules(rules, from, to) {
26
- return Object.fromEntries(
27
- Object.entries(rules).map(([key, value]) => [
28
- key.startsWith(from) ? `${to}${key.slice(from.length)}` : key,
29
- value
30
- ])
31
- );
32
- }
33
-
34
- // src/eslint/configs/astro.ts
35
- async function astro(options = {}) {
36
- const { typescript: typescript2 = true } = options;
37
- const [pluginAstro, parserAstro] = await Promise.all([
38
- interopDefault(import("eslint-plugin-astro")),
39
- interopDefault(import("astro-eslint-parser"))
40
- ]);
41
- return [
42
- {
43
- name: "shun-shobon/astro/plugins",
44
- plugins: {
45
- astro: pluginAstro
46
- }
47
- },
48
- {
49
- name: "shun-shobon/astro/rules",
50
- files: [GLOB_ASTRO],
51
- languageOptions: {
52
- parser: parserAstro,
53
- parserOptions: {
54
- parser: typescript2 ? await interopDefault(import("@typescript-eslint/parser")) : void 0,
55
- extraFileExtensions: [".astro"]
56
- },
57
- globals: {
58
- Astro: "readonly",
59
- Fragment: "readonly"
60
- }
61
- },
62
- processor: pluginAstro.processors[typescript2 ? "client-side-ts" : "astro"],
63
- rules: {
64
- // Astroの推奨ルールを有効化
65
- ...pluginAstro.configs.recommended.at(-1).rules,
66
- // Astroのjsx-a11yの拡張ルール(strict)を有効化
67
- ...pluginAstro.configs["jsx-a11y-strict"].at(-1).rules,
68
- // 曖昧なリンクのテキストを許可しない
69
- "astro/jsx-a11y/anchor-ambiguous-text": "error",
70
- // インタラクティブな要素にラベルが付いていないことを許可しない
71
- "astro/jsx-a11y/control-has-associated-label": "error",
72
- // html要素にlang属性が付与されていないことを許可しない
73
- "astro/jsx-a11y/lang": "error",
74
- // フォーカス可能な要素に `aria-hidden` 属性を付与することを許可しない
75
- "astro/jsx-a11y/no-aria-hidden-on-focusable": "error"
76
- }
77
- }
78
- ];
79
- }
80
-
81
- // src/eslint/configs/base.ts
82
- function base() {
83
- return [
84
- {
85
- name: "shun-shobon/base/setup",
86
- linterOptions: {
87
- reportUnusedDisableDirectives: true
88
- }
89
- }
90
- ];
91
- }
92
-
93
- // src/eslint/configs/disable-type-checked.ts
94
- async function disableTypeChecked(options = {}) {
95
- const { disableTypeCheckedFiles = [] } = options;
96
- const { configs: configsTypeScript } = await interopDefault(
97
- import("typescript-eslint")
98
- );
99
- return [
100
- {
101
- name: "shun-shobon/disableTypeChecked/rules",
102
- files: disableTypeCheckedFiles,
103
- languageOptions: {
104
- parserOptions: {
105
- projectService: false
106
- }
107
- },
108
- rules: {
109
- ...renameRules(
110
- configsTypeScript.disableTypeChecked.rules,
111
- "@typescript-eslint/",
112
- "typescript/"
113
- )
114
- }
115
- }
116
- ];
117
- }
118
-
119
- // src/eslint/plugins.ts
120
- import { default as default2 } from "@eslint/js";
121
- import { default as default3 } from "eslint-plugin-import-x";
122
- import { default as default4 } from "eslint-plugin-jsx-a11y";
123
- import { default as default5 } from "eslint-plugin-n";
124
- import { default as default6 } from "eslint-plugin-regexp";
125
- import { default as default7 } from "eslint-plugin-simple-import-sort";
126
- import { default as default8 } from "eslint-plugin-unicorn";
127
-
128
- // src/eslint/configs/import-sort.ts
129
- function importSort() {
130
- return [
131
- {
132
- name: "shun-shobon/importSort/setup",
133
- plugins: {
134
- "import-sort": default7
135
- }
136
- },
137
- {
138
- name: "shun-shobon/importSort/rules",
139
- rules: {
140
- // importをソートする
141
- "import-sort/imports": "warn",
142
- // exportをソートする
143
- "import-sort/exports": "warn"
144
- }
145
- }
146
- ];
147
- }
148
-
149
- // src/eslint/configs/imports.ts
150
- function imports(options) {
151
- const { typescript: typescript2 = false } = options;
152
- return [
153
- {
154
- name: "shun-shobon/imports/setup",
155
- plugins: {
156
- import: default3
157
- },
158
- settings: {
159
- "import-x/parsers": {
160
- espree: [".js", ".cjs", ".mjs", ".jsx"],
161
- ...typescript2 ? { "@typescript-eslint/parser": [".ts", ".mts", ".cts", ".tsx"] } : {}
162
- },
163
- "import-x/extensions": [
164
- ".js",
165
- ".jsx",
166
- ...typescript2 ? [".ts", ".tsx", ".d.ts"] : []
167
- ]
168
- }
169
- },
170
- {
171
- name: "shun-shobon/imports/rules",
172
- rules: {
173
- ...renameRules(
174
- default3.configs.recommended.rules,
175
- "import-x/",
176
- "import/"
177
- ),
178
- // import先のモジュールが存在するかチェックしない
179
- // TSの型チェックで十分なため
180
- "import/namespace": "off",
181
- "import/no-unresolved": "off",
182
- "import/named": "off",
183
- // type import時に`import type { foo } from "foo"`を強制
184
- "import/consistent-type-specifier-style": ["warn", "prefer-top-level"],
185
- // import文を一番上に書くのを強制
186
- "import/first": "error",
187
- // 同じパスからのimportをまとめる
188
- "import/no-duplicates": "warn",
189
- // default import時に`{ default as foo } from "foo"`と書くのを警告
190
- "import/no-named-default": "warn",
191
- // import文のパスを簡略化する
192
- "import/no-useless-path-segments": ["warn", { noUselessIndex: true }],
193
- // 自分自身をimportするのを禁止
194
- "import/no-self-import": "error"
195
- }
196
- }
197
- ];
198
- }
199
-
200
- // src/eslint/configs/javascript.ts
201
- import globals from "globals";
202
- function javascript() {
203
- return [
204
- {
205
- name: "shun-shobon/javascript/rules",
206
- languageOptions: {
207
- ecmaVersion: "latest",
208
- sourceType: "module",
209
- globals: {
210
- ...globals.es2021,
211
- ...globals.browser,
212
- ...globals.node
213
- },
214
- parserOptions: {
215
- ecmaFeatures: {
216
- jax: true
217
- },
218
- ecmaVersion: "latest",
219
- sourceType: "module"
220
- }
221
- },
222
- rules: {
223
- ...default2.configs.recommended.rules,
224
- // Arrayの関数に`return`を忘れないようにする
225
- "array-callback-return": "error",
226
- // 常にtrue/falseになる式や短絡評価されない式を警告
227
- "no-constant-binary-expression": "warn",
228
- // コンストラクタの戻り値を許可しない
229
- "no-constructor-return": "error",
230
- // Symbol/BigIntでnewしない
231
- "no-new-native-nonconstructor": "error",
232
- // `Promise`のコンストラクタの戻り値を許可しない
233
- "no-promise-executor-return": "error",
234
- // 自分自身を比較する式を許可しない
235
- // NaNチェックは`Number.isNaN()`を使う
236
- "no-self-compare": "error",
237
- // ループの条件式の変数をループ内で変更していない場合に警告
238
- "no-unmodified-loop-condition": "warn",
239
- // 条件式が常にtrue/falseになる場合を警告
240
- // ただし、ループ内の条件式は除外
241
- "no-constant-condition": ["error", { checkLoops: false }],
242
- // 1回しかループしないループを警告
243
- "no-unreachable-loop": "warn",
244
- // 未使用のプライベートクラスメンバーを警告
245
- "no-unused-private-class-members": "warn",
246
- // `_`から始まる変数名以外の未使用変数を警告
247
- "no-unused-vars": [
248
- "warn",
249
- {
250
- varsIgnorePattern: "^_",
251
- argsIgnorePattern: "^_"
252
- }
253
- ],
254
- // 競合が発生する可能性のある値の代入を許可しない
255
- "require-atomic-updates": "error",
256
- // 循環的複雑度を15以上を警告
257
- "complexity": ["warn", 15],
258
- // switch文のデフォルトケースを最後にする
259
- "default-case-last": "error",
260
- // デフォルト引数を最後にする
261
- "default-param-last": "error",
262
- // nullチェックを除いて厳密でない等価演算子を許可しない
263
- "eqeqeq": ["error", "always", { null: "ignore" }],
264
- // getter/setterをグループ化
265
- "grouped-accessor-pairs": ["error", "setBeforeGet"],
266
- // `console.log()`/`alert`を警告
267
- "no-alert": "warn",
268
- "no-console": ["warn", { allow: ["warn", "error"] }],
269
- // `else { return }`を警告
270
- "no-else-return": "warn",
271
- // `!!`や`~`を使った短縮型変換を許可しない
272
- "no-implicit-coercion": "error",
273
- // 不要なifのネストを許可しない
274
- "no-lonely-if": "error",
275
- // 複数の代入を許可しない
276
- "no-multi-assign": "error",
277
- // 複数行文字列を警告
278
- "no-multi-str": "warn",
279
- // `Function`/`Object`/`String`/`Number`/`Boolean`のコンストラクタを許可しない
280
- "no-new-func": "error",
281
- "no-new-wrappers": "error",
282
- // 関数の引数を再代入することを許可しない
283
- "no-param-reassign": "error",
284
- // インクリメント/デクリメント演算子を許可しない
285
- "no-plusplus": "error",
286
- // `throw` に文字列を渡さない
287
- "no-throw-literal": "error",
288
- // 不要な三項演算子を警告
289
- "no-unneeded-ternary": "warn",
290
- // 未使用の式を警告
291
- "no-unused-expressions": "warn",
292
- // 意味の無いコンストラクタを警告
293
- "no-useless-constructor": "warn",
294
- // 意味の無い`return`を警告
295
- "no-useless-return": "warn",
296
- // `var`を許可しない
297
- "no-var": "error",
298
- // オブジェクトのショートハンド記法を使用していない場合は警告
299
- "object-shorthand": "warn",
300
- // 演算子のショートハンド記法を使用していない場合は警告
301
- "operator-assignment": "warn",
302
- // コールバック関数をアロー関数にする
303
- "prefer-arrow-callback": "warn",
304
- // `const`を使用する
305
- "prefer-const": "warn",
306
- // 名前付きキャプチャグループを使用する
307
- "prefer-named-capture-group": "warn",
308
- // `Number.parseInt()`を使用する
309
- "prefer-numeric-literals": "error",
310
- // `hasOwnProperty`の使用を許可しない
311
- "prefer-object-has-own": "error",
312
- // スプレッド構文を使用する
313
- "prefer-object-spread": "warn",
314
- // `Promise`の`reject`には`Error`オブジェクトを渡す
315
- "prefer-promise-reject-errors": "error",
316
- // なるべく正規表現リテラルを使用する
317
- "prefer-regex-literals": "warn",
318
- // `arguments`/`.apply()`の代わりに`...args`を使用する
319
- "prefer-rest-params": "warn",
320
- "prefer-spread": "warn",
321
- // `parseInt`には基数を渡す
322
- "radix": "error",
323
- // 正規表現のユニコードフラグを使用する
324
- "require-unicode-regexp": "warn",
325
- // シンボルに名前を付ける
326
- "symbol-description": "warn"
327
- }
328
- }
329
- ];
330
- }
331
-
332
- // src/eslint/configs/jsx-a11y.ts
333
- function jsxA11y() {
334
- return [
335
- {
336
- name: "shun-shobon/jsxA11y/setup",
337
- plugins: {
338
- // eslint-disable-next-line typescript/no-unsafe-assignment
339
- "jsx-a11y": default4
340
- },
341
- settings: {
342
- "jsx-a11y": {
343
- polymorphicPropName: "as"
344
- }
345
- }
346
- }
347
- ];
348
- }
349
-
350
- // src/eslint/configs/next.ts
351
- async function next() {
352
- const pluginNext = await interopDefault(import("@next/eslint-plugin-next"));
353
- return [
354
- {
355
- name: "shun-shobon/next/setup",
356
- plugins: {
357
- next: pluginNext
358
- }
359
- },
360
- {
361
- name: "shun-shobon/next/rules",
362
- files: [GLOB_SRC],
363
- rules: {
364
- // Next.jsの推奨ルールを有効化
365
- ...renameRules(
366
- pluginNext.configs.recommended.rules,
367
- "@next/next/",
368
- "next/"
369
- ),
370
- // Next.jsの更に厳格なルールを有効化
371
- ...renameRules(
372
- pluginNext.configs["core-web-vitals"].rules,
373
- "@next/next/",
374
- "next/"
375
- ),
376
- // `img`要素を使う場合もあるので無効化
377
- "next/no-img-element": "off"
378
- }
379
- }
380
- ];
381
- }
382
-
383
- // src/eslint/configs/node.ts
384
- function node() {
385
- return [
386
- {
387
- name: "shun-shobon/node/setup",
388
- plugins: {
389
- node: default5
390
- }
391
- },
392
- {
393
- name: "shun-shobon/node/rules",
394
- rules: {
395
- "node/no-deprecated-api": "error",
396
- "node/no-exports-assign": "error",
397
- "node/no-path-concat": "error",
398
- "node/no-process-exit": "error",
399
- "node/no-unpublished-bin": "error",
400
- "node/no-sync": "error",
401
- "node/process-exit-as-throw": "error",
402
- "node/prefer-global/console": "error",
403
- "node/prefer-global/text-decoder": "error",
404
- "node/prefer-global/text-encoder": "error",
405
- "node/prefer-global/url": "error",
406
- "node/prefer-global/url-search-params": "error",
407
- "node/prefer-promises/dns": "error",
408
- "node/prefer-promises/fs": "error"
409
- }
410
- }
411
- ];
412
- }
413
-
414
- // src/eslint/configs/qwik.ts
415
- async function qwik() {
416
- const pluginQwik = await interopDefault(import("eslint-plugin-qwik"));
417
- return [
418
- {
419
- name: "shun-shobon/qwik/setup",
420
- plugins: {
421
- // eslint-disable-next-line typescript/no-unsafe-assignment
422
- qwik: pluginQwik
423
- }
424
- },
425
- {
426
- name: "shun-shobon/qwik/rules",
427
- files: [GLOB_JSX, GLOB_TSX],
428
- rules: {
429
- // qwikの推奨ルールを有効化
430
- // eslint-disable-next-line typescript/no-unsafe-member-access
431
- ...pluginQwik.configs.recommended.rules,
432
- // qwikの厳格ルールを有効化
433
- // eslint-disable-next-line typescript/no-unsafe-member-access
434
- ...pluginQwik.configs.strict.rules
435
- }
436
- }
437
- ];
438
- }
439
-
440
- // src/eslint/configs/react.ts
441
- async function react(options = {}) {
442
- const { typescript: typescript2 = false } = options;
443
- const [pluginReact, pluginReactHooks] = await Promise.all([
444
- interopDefault(import("eslint-plugin-react")),
445
- interopDefault(import("eslint-plugin-react-hooks"))
446
- ]);
447
- return [
448
- {
449
- name: "shun-shobon/react/setup",
450
- plugins: {
451
- "react": pluginReact,
452
- "react-hooks": pluginReactHooks
453
- },
454
- settings: {
455
- react: {
456
- version: "detect"
457
- }
458
- }
459
- },
460
- {
461
- name: "shun-shobon/react/rules",
462
- files: [GLOB_JSX, GLOB_TSX],
463
- rules: {
464
- // reactの推奨ルールを有効化
465
- ...pluginReact.configs.recommended.rules,
466
- // React v17以降のJSX Runtimeを使う場合の不要なルールを無効化
467
- ...pluginReact.configs["jsx-runtime"].rules,
468
- // React Hooksの推奨ルールを有効化
469
- ...pluginReactHooks.configs.recommended.rules,
470
- // JSX A11yの厳格なルールを有効化
471
- // eslint-disable-next-line typescript/no-unsafe-member-access
472
- ...default4.configs.strict.rules,
473
- // その他必要なものを有効化
474
- // `onClick`などのイベントハンドラーの命名規則をチェック
475
- "react/jsx-handler-names": "warn",
476
- // ContextのProviderに即値を渡さないようにする
477
- // 即値で渡すと、Providerが含まれるコンポーネントの再描画時に新しい値が渡されてしまい、再描画が発生する
478
- "react/jsx-no-constructed-context-values": "warn",
479
- // `React.Fragment`を省略可能な場合は省略する
480
- // ただし、フラグメントのみの場合は許可する
481
- "react/jsx-no-useless-fragment": ["warn", { allowExpressions: true }],
482
- // rel 属性の値をチェック
483
- "react/no-invalid-html-attribute": "warn",
484
- // propsのデフォルト値としてobjectやarrayのリテラルを使用しないようにする
485
- // 使用してしまうと、再描画が発生する可能性がある
486
- "react/no-object-type-as-default-prop": "warn",
487
- // コンポーネント内でコンポーネントを定義するのを許可しない
488
- "react/no-unstable-nested-components": "error",
489
- ...typescript2 ? {
490
- // TypeScriptの型チェックで検出できるものは無効化
491
- // propTypesはTSで代替できるので無効化
492
- "react/prop-types": "off",
493
- // HTMLの属性名として認識されていない属性名を許可
494
- // TSで型チェックしているので不要
495
- "react/no-unknown-property": "off"
496
- } : {},
497
- // 曖昧なリンクのテキストを許可しない
498
- "jsx-a11y/anchor-ambiguous-text": "error",
499
- // インタラクティブな要素にラベルが付いていないことを許可しない
500
- "jsx-a11y/control-has-associated-label": "error",
501
- // html要素にlang属性が付与されていないことを許可しない
502
- "jsx-a11y/lang": "error",
503
- // フォーカス可能な要素に `aria-hidden` 属性を付与することを許可しない
504
- "jsx-a11y/no-aria-hidden-on-focusable": "error"
505
- }
506
- }
507
- ];
508
- }
509
-
510
- // src/eslint/configs/regexp.ts
511
- function regexp() {
512
- return [
513
- {
514
- name: "shun-shobon/regexp/setup",
515
- plugins: {
516
- regexp: default6
517
- }
518
- },
519
- {
520
- name: "shun-shobon/regexp/rules",
521
- rules: {
522
- // 推奨ルールを使用
523
- ...default6.configs["flat/recommended"].rules
524
- }
525
- }
526
- ];
527
- }
528
-
529
- // src/eslint/configs/storybook.ts
530
- async function storybook() {
531
- const pluginStorybook = await interopDefault(
532
- import("eslint-plugin-storybook")
533
- );
534
- return [
535
- {
536
- name: "shun-shobon/storybook/setup",
537
- plugins: {
538
- storybook: pluginStorybook
539
- }
540
- },
541
- {
542
- name: "shun-shobon/storybook/rules",
543
- files: [GLOB_STORYBOOK],
544
- rules: {
545
- // Storybookの推奨ルールから拝借
546
- "import/no-anonymous-default-export": "off",
547
- "storybook/await-interactions": "error",
548
- "storybook/context-in-play-function": "error",
549
- "storybook/default-exports": "error",
550
- "storybook/hierarchy-separator": "warn",
551
- "storybook/no-redundant-story-name": "warn",
552
- "storybook/prefer-pascal-case": "warn",
553
- "storybook/story-exports": "error",
554
- "storybook/use-storybook-expect": "error",
555
- "storybook/use-storybook-testing-library": "error"
556
- }
557
- },
558
- // Storybookの設定ファイルへのルール
559
- {
560
- name: "shun-shobon/storybook/config-rules",
561
- files: [GLOB_STORYBOOK_CONFIG],
562
- rules: {
563
- "storybook/no-uninstalled-addons": "error"
564
- }
565
- }
566
- ];
567
- }
568
-
569
- // src/eslint/configs/typescript.ts
570
- async function typescript(options = {}) {
571
- const { componentExts = [] } = options;
572
- const {
573
- plugin: pluginTypeScript,
574
- parser: parserTypeScript,
575
- configs: configsTypeScript
576
- } = await import("typescript-eslint");
577
- return [
578
- {
579
- name: "shun-shobon/typescript/setup",
580
- plugins: {
581
- typescript: pluginTypeScript
582
- }
583
- },
584
- {
585
- name: "shun-shobon/typescript/rules",
586
- files: [GLOB_SRC, ...componentExts.map((ext) => `**/*.${ext}`)],
587
- languageOptions: {
588
- parser: parserTypeScript,
589
- parserOptions: {
590
- projectService: {
591
- allowDefaultProject: ["./*.js"]
592
- }
593
- }
594
- },
595
- rules: {
596
- // 厳密なルール + 型チェックのルールを有効化
597
- ...renameRules(
598
- configsTypeScript.strictTypeChecked.at(-1).rules,
599
- "@typescript-eslint/",
600
- "typescript/"
601
- ),
602
- // コーディング規約 + 型チェックのルールを有効化
603
- ...renameRules(
604
- configsTypeScript.stylisticTypeChecked.at(-1).rules,
605
- "@typescript-eslint/",
606
- "typescript/"
607
- ),
608
- // exportされている関数は型の明示を必須にする
609
- "typescript/explicit-module-boundary-types": "warn",
610
- // 型をexportする際に`type`の付与を必須にする
611
- "typescript/consistent-type-exports": [
612
- "error",
613
- {
614
- fixMixedExportsWithInlineTypeSpecifier: true
615
- }
616
- ],
617
- // 型をimportする際に`type`の付与を必須にする
618
- "typescript/consistent-type-imports": "error",
619
- // `_`から始まる変数名以外の未使用変数を警告
620
- "typescript/no-unused-vars": [
621
- "warn",
622
- {
623
- varsIgnorePattern: "^_",
624
- argsIgnorePattern: "^_"
625
- }
626
- ],
627
- // 副作用の可能性のあるtype importを警告
628
- "typescript/no-import-type-side-effects": "warn",
629
- // なるべくreadonlyを付与する
630
- "typescript/prefer-readonly": "warn",
631
- // `Promise`を返す関数は`async`を付与する
632
- "typescript/promise-function-async": "error",
633
- // ソートでは必ず比較関数を渡す
634
- "typescript/require-array-sort-compare": "error",
635
- // `return await`を使う
636
- // 一貫性のためと、awaitが無くなったときにasyncを外すのは面倒なため
637
- // また、スタックトレースが読みやすくなる
638
- "typescript/return-await": ["warn", "always"],
639
- "typescript/no-unnecessary-condition": [
640
- "warn",
641
- { allowConstantLoopConditions: true }
642
- ],
643
- // null assertion `!` を許可
644
- "typescript/no-non-null-assertion": "off",
645
- // template stringへの変数埋め込みの制限をstrictよりも緩和
646
- "typescript/restrict-template-expressions": [
647
- "error",
648
- {
649
- allowAny: true,
650
- allowBoolean: false,
651
- allowNullish: false,
652
- allowNumber: true,
653
- allowRegExp: false,
654
- allowNever: false
655
- }
656
- ]
657
- }
658
- },
659
- {
660
- name: "shun-shobon/typescript/disables/eslint-recommended",
661
- files: [GLOB_TS, GLOB_TSX, ...componentExts.map((ext) => `**/*.${ext}`)],
662
- rules: {
663
- // ESLintの推奨ルールからTypeScriptで検証可能なものを無効化
664
- ...configsTypeScript.eslintRecommended.rules
665
- }
666
- },
667
- {
668
- name: "shun-shobon/typescript/disables/dts",
669
- files: [GLOB_DTS],
670
- rules: {
671
- // `import`の重複を許可
672
- "import/no-duplicates": "off",
673
- // `///`での参照を許可
674
- "typescript/triple-slash-reference": "off"
675
- }
676
- }
677
- ];
678
- }
679
-
680
- // src/eslint/configs/unicorn.ts
681
- function unicorn() {
682
- return [
683
- {
684
- name: "shun-shobon/unicorn/setup",
685
- plugins: {
686
- unicorn: default8
687
- }
688
- },
689
- {
690
- name: "shun-shobon/unicorn/rules",
691
- rules: {
692
- ...default8.configs.recommended.rules,
693
- // Prettierで整形できるルールは無効化
694
- "unicorn/empty-brace-spaces": "off",
695
- "unicorn/no-nested-ternary": "off",
696
- "unicorn/number-literal-case": "off",
697
- // unicornの推奨ルールから不要なものを無効化
698
- // コンポーネント内の関数など、スコープを小さくしておきたい場合があるので無効化
699
- "unicorn/consistent-function-scoping": "off",
700
- // ファイルの名前はコンポーネントなどで形式が変化するため無効化
701
- "unicorn/filename-case": "off",
702
- // 直接関数を渡したほうが簡潔に書ける場合があるので無効化
703
- "unicorn/no-array-callback-reference": "off",
704
- // `.forEach()`のほうが簡潔に書ける場合があるので無効化
705
- "unicorn/no-array-for-each": "off",
706
- // `.reduce()`/`.reduceRight()`は使ったほうが簡潔に書ける場合があるので無効化
707
- "unicorn/no-array-reduce": "off",
708
- // 否定形の方が簡潔に書ける場合があるので無効化
709
- "unicorn/no-negated-condition": "off",
710
- // nullも使う場合があるので無効化
711
- "unicorn/no-null": "off",
712
- // undefinedを使いたい場合があるので無効化
713
- "unicorn/no-useless-undefined": "off",
714
- // CommonJSを使う場合もあるため無効化
715
- "unicorn/prefer-module": "off",
716
- // `[...array].map()`は~~ダサい~~ので無効化
717
- "unicorn/prefer-spread": "off",
718
- // 略語の方が簡潔に書ける場合があるので無効化
719
- "unicorn/prevent-abbreviations": "off",
720
- // switch文のcase節を常にブロックにするのは冗長なので必要なときのみブロックにする
721
- "unicorn/switch-case-braces": ["warn", "avoid"]
722
- }
723
- }
724
- ];
725
- }
726
-
727
- // src/eslint/factory.ts
728
- import { isPackageExists } from "local-pkg";
729
- async function shun_shobon(options = {}, ...userConfigs) {
730
- const {
731
- gitignore: enableGitignore = true,
732
- ignores: userIgnores = [],
733
- typescript: enableTypescript = isPackageExists("typescript"),
734
- react: enableReact = isPackageExists("react"),
735
- next: enableNext = isPackageExists("next"),
736
- qwik: enableQwik = isPackageExists("@builder.io/qwik"),
737
- astro: enableAstro = isPackageExists("astro"),
738
- storybook: enableStorybook = isPackageExists("storybook"),
739
- componentExts = [],
740
- disableTypeCheckedFiles = []
741
- } = options;
742
- const configQueue = [];
743
- if (enableGitignore) {
744
- configQueue.push(
745
- interopDefault(import("eslint-config-flat-gitignore")).then(
746
- (gitignore) => [
747
- gitignore(
748
- typeof enableGitignore !== "boolean" ? { name: "shun-shobon/gitignore/setup", ...enableGitignore } : { name: "shun-shobon/gitignore/setup" }
749
- )
750
- ]
751
- )
752
- );
753
- }
754
- if (enableAstro) {
755
- componentExts.push(GLOB_ASTRO_EXT);
756
- disableTypeCheckedFiles.push(GLOB_ASTRO);
757
- }
758
- configQueue.push(
759
- base(),
760
- javascript(),
761
- imports({ typescript: enableTypescript }),
762
- importSort(),
763
- unicorn(),
764
- regexp(),
765
- node(),
766
- jsxA11y()
767
- );
768
- if (enableTypescript) {
769
- configQueue.push(
770
- typescript({
771
- componentExts
772
- })
773
- );
774
- disableTypeCheckedFiles.push(GLOB_JS, GLOB_JSX);
775
- }
776
- if (enableReact) {
777
- configQueue.push(
778
- react({
779
- typescript: enableTypescript
780
- })
781
- );
782
- }
783
- if (enableNext) {
784
- configQueue.push(next());
785
- }
786
- if (enableQwik) {
787
- configQueue.push(qwik());
788
- }
789
- if (enableAstro) {
790
- configQueue.push(
791
- astro({
792
- typescript: enableTypescript
793
- })
794
- );
795
- }
796
- if (enableStorybook) {
797
- configQueue.push(storybook());
798
- }
799
- if (enableTypescript) {
800
- configQueue.push(disableTypeChecked({ disableTypeCheckedFiles }));
801
- }
802
- const ignores = [...userIgnores, "**/.yarn/**"];
803
- configQueue.push([
804
- {
805
- ignores
806
- }
807
- ]);
808
- const configs = await Promise.all(configQueue).then(
809
- (configs2) => configs2.flat()
810
- );
811
- return [...configs, ...userConfigs];
812
- }
813
- export {
814
- astro,
815
- base,
816
- disableTypeChecked,
817
- importSort,
818
- imports,
819
- javascript,
820
- jsxA11y,
821
- next,
822
- node,
823
- qwik,
824
- react,
825
- regexp,
826
- shun_shobon,
827
- storybook,
828
- typescript,
829
- unicorn
830
- };
831
- //# sourceMappingURL=index.js.map