@shun-shobon/style-guide 0.4.2 → 1.0.1

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