@nojaja/greputil 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +7 -0
- package/.dependency-cruiser.js +89 -0
- package/.eslintignore +6 -0
- package/.eslintrc.cjs +48 -0
- package/.github/skills/completion-mandatory-quality-gates.md +26 -0
- package/.github/skills/nodejs-project-quality-guardrails.md +417 -0
- package/.github/workflows/release.yml +44 -0
- package/.github/workflows/webpack.yml +28 -0
- package/LICENSE +21 -0
- package/MIGRATION_REPORT.md +77 -0
- package/README.md +336 -0
- package/jest.config.js +16 -0
- package/jest.unit.config.js +31 -0
- package/package.json +43 -0
- package/src/BufferPatternMatcher.ts +61 -0
- package/src/RegExpArray.ts +209 -0
- package/src/index.ts +15 -0
- package/tests/unit/RegExpArray.spec.ts +205 -0
- package/tsconfig.json +22 -0
- package/typedoc.js +16 -0
- package/webpack.config.js +32 -0
package/.babelrc
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
forbidden: [
|
|
3
|
+
{
|
|
4
|
+
name: 'no-circular',
|
|
5
|
+
severity: 'error',
|
|
6
|
+
comment: '循環依存を禁止',
|
|
7
|
+
from: {},
|
|
8
|
+
to: {
|
|
9
|
+
circular: true
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
name: 'no-orphans',
|
|
14
|
+
severity: 'warn',
|
|
15
|
+
comment: '未使用ファイルを警告',
|
|
16
|
+
from: {
|
|
17
|
+
orphan: true,
|
|
18
|
+
pathNot: [
|
|
19
|
+
'(^|/)\\.[^/]+\\.(js|cjs|mjs|ts|json)$',
|
|
20
|
+
'\\.d\\.ts$',
|
|
21
|
+
'(^|/)tsconfig\\.json$',
|
|
22
|
+
'(^|/)(babel|webpack)\\.config\\.(js|cjs|mjs|ts|json)$'
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
to: {}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: 'no-deprecated-core',
|
|
29
|
+
comment: '非推奨のNode.js coreモジュールを禁止',
|
|
30
|
+
severity: 'warn',
|
|
31
|
+
from: {},
|
|
32
|
+
to: {
|
|
33
|
+
dependencyTypes: [
|
|
34
|
+
'core'
|
|
35
|
+
],
|
|
36
|
+
path: [
|
|
37
|
+
'^(punycode|domain|constants|sys|_linklist)$'
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'not-to-deprecated',
|
|
43
|
+
comment: '非推奨のnpmモジュールを禁止',
|
|
44
|
+
severity: 'warn',
|
|
45
|
+
from: {},
|
|
46
|
+
to: {
|
|
47
|
+
dependencyTypes: [
|
|
48
|
+
'deprecated'
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: 'no-non-package-json',
|
|
54
|
+
severity: 'error',
|
|
55
|
+
comment: 'package.jsonに記載されていない依存を禁止',
|
|
56
|
+
from: {},
|
|
57
|
+
to: {
|
|
58
|
+
dependencyTypes: [
|
|
59
|
+
'npm-no-pkg',
|
|
60
|
+
'npm-unknown'
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
options: {
|
|
66
|
+
doNotFollow: {
|
|
67
|
+
path: 'node_modules'
|
|
68
|
+
},
|
|
69
|
+
tsPreCompilationDeps: true,
|
|
70
|
+
tsConfig: {
|
|
71
|
+
fileName: './tsconfig.json'
|
|
72
|
+
},
|
|
73
|
+
enhancedResolveOptions: {
|
|
74
|
+
exportsFields: ['exports'],
|
|
75
|
+
conditionNames: ['import', 'require', 'node', 'default']
|
|
76
|
+
},
|
|
77
|
+
reporterOptions: {
|
|
78
|
+
dot: {
|
|
79
|
+
collapsePattern: 'node_modules/[^/]+'
|
|
80
|
+
},
|
|
81
|
+
archi: {
|
|
82
|
+
collapsePattern: '^(node_modules|packages|src|lib|app|bin|test|spec)/[^/]+'
|
|
83
|
+
},
|
|
84
|
+
text: {
|
|
85
|
+
highlightFocused: true
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
};
|
package/.eslintignore
ADDED
package/.eslintrc.cjs
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
root: true,
|
|
3
|
+
parser: '@typescript-eslint/parser',
|
|
4
|
+
parserOptions: {
|
|
5
|
+
ecmaVersion: 2022,
|
|
6
|
+
sourceType: 'module',
|
|
7
|
+
project: './tsconfig.json'
|
|
8
|
+
},
|
|
9
|
+
plugins: ['@typescript-eslint', 'sonarjs', 'jsdoc'],
|
|
10
|
+
extends: [
|
|
11
|
+
'eslint:recommended',
|
|
12
|
+
'plugin:@typescript-eslint/recommended',
|
|
13
|
+
'plugin:sonarjs/recommended',
|
|
14
|
+
'plugin:jsdoc/recommended'
|
|
15
|
+
],
|
|
16
|
+
rules: {
|
|
17
|
+
'sonarjs/cognitive-complexity': ['error', 10],
|
|
18
|
+
'@typescript-eslint/no-unused-vars': ['warn'],
|
|
19
|
+
'@typescript-eslint/no-explicit-any': ['error'],
|
|
20
|
+
'jsdoc/require-jsdoc': [
|
|
21
|
+
'error',
|
|
22
|
+
{
|
|
23
|
+
require: {
|
|
24
|
+
FunctionDeclaration: true,
|
|
25
|
+
MethodDefinition: true,
|
|
26
|
+
ClassDeclaration: true,
|
|
27
|
+
ArrowFunctionExpression: false,
|
|
28
|
+
FunctionExpression: true
|
|
29
|
+
},
|
|
30
|
+
contexts: [
|
|
31
|
+
'TSInterfaceDeclaration',
|
|
32
|
+
'TSTypeAliasDeclaration'
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
'jsdoc/require-param': 'error',
|
|
37
|
+
'jsdoc/require-returns': 'error',
|
|
38
|
+
'jsdoc/require-param-type': 'off',
|
|
39
|
+
'jsdoc/require-returns-type': 'off',
|
|
40
|
+
'jsdoc/check-tag-names': ['error', {
|
|
41
|
+
definedTags: ['処理名', '処理概要', '実装理由']
|
|
42
|
+
}]
|
|
43
|
+
},
|
|
44
|
+
env: {
|
|
45
|
+
node: true,
|
|
46
|
+
es2022: true
|
|
47
|
+
}
|
|
48
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: completion-mandatory-quality-gates
|
|
3
|
+
description: 作業完了時に必ず品質ゲートを全通過させるためのSkill。ビルド・依存関係チェック・テスト・Lintを例外なく実行し、設定変更や除外を禁止する。
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Agent Skills format (agentskills.io) および GitHub Copilot / Claude / Codex に対応
|
|
6
|
+
metadata:
|
|
7
|
+
author: nojaja
|
|
8
|
+
version: "1.0.0"
|
|
9
|
+
allowed-tools: Read Write Bash
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# 作業完了時の強制品質ゲート Skill
|
|
13
|
+
|
|
14
|
+
本Skillは、作業完了タイミングで必ず以下の品質ゲートを**設定変更・除外なし**で実行し、全て成功させることをエージェントに強制します。いずれかをスキップ・省略・設定変更することを禁止します。
|
|
15
|
+
|
|
16
|
+
## 必須実行コマンド(順不同可、全て成功が条件)
|
|
17
|
+
- `npm run build`
|
|
18
|
+
- `npm run depcruise`
|
|
19
|
+
- `npm run test`
|
|
20
|
+
- `npm run lint`
|
|
21
|
+
|
|
22
|
+
## 運用ルール
|
|
23
|
+
- 各ゲートの設定を変更してはならない(閾値・対象・オプションの調整禁止)。
|
|
24
|
+
- いかなる理由でも実行対象からの除外・スキップを禁止する。
|
|
25
|
+
- 実行結果は成功が確認できるまで対応を継続し、失敗時は設定を変えずに修正して再実行する。
|
|
26
|
+
- 作業完了の宣言は、上記4コマンドが全て成功した後のみ行うこと。
|
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nodejs-project-quality-guardrails
|
|
3
|
+
description: Defines reusable quality assurance guardrails for Node.js/TypeScript projects, including testing coverage, linting, documentation, design principles, and CI gating. Use when generating or modifying project code to ensure consistent high quality.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Designed for AI agents that support Agent Skills format (agentskills.io specification) and GitHub Copilot / Claude / Codex agents
|
|
6
|
+
metadata:
|
|
7
|
+
author: nojaja
|
|
8
|
+
version: "1.0.0"
|
|
9
|
+
allowed-tools: Read Write Bash
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Node.js/TypeScript プロジェクト 品質担保ガードレール Skill
|
|
13
|
+
|
|
14
|
+
このスキルは、Node.js(TypeScript)プロジェクトの品質担保のために
|
|
15
|
+
**一貫したテスト、静的解析、ドキュメント、設計ルール、CI 条件** を
|
|
16
|
+
AI エージェント(GitHub Copilot / Claude / OpenAI Codex)に理解させ、
|
|
17
|
+
**生成・修正・レビュー作業** に常に適用させることを目的とします。
|
|
18
|
+
|
|
19
|
+
## このスキルを使うべきタイミング
|
|
20
|
+
|
|
21
|
+
- 新規機能のコードを生成する際
|
|
22
|
+
- 既存コードをリファクタリングする際
|
|
23
|
+
- Unit テスト追加や修正書き換えを行う際
|
|
24
|
+
- CI 周りの構成や静的解析指摘を修正する際
|
|
25
|
+
- プロジェクト全体の品質ルールをエージェントに認識させたい場合
|
|
26
|
+
- 1 つのワークスペースに複数プロジェクトがある場合は、各プロジェクトごとに本スキルで示す構成(docs/typedoc-md、src、test/unit・e2e、.dependency-cruiser.js、eslint.config.cjs、jest.unit.config.js、jest.e2e.config.js、typedoc.js など)を持たせ、プロジェクト単位で適用・監査すること
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 品質担保ルール概観
|
|
31
|
+
|
|
32
|
+
### 1. 単体テスト
|
|
33
|
+
- Jest + ts-jest を利用する
|
|
34
|
+
- カバレッジを 80%以上 にする
|
|
35
|
+
- テスト対象は unit テストが主、E2E は補助的に扱う
|
|
36
|
+
- CI では `npm run test:ci` を定義し `jest --coverage` を実行する
|
|
37
|
+
- coverageThreshold で 80% 未満ならエラー扱いとし必ず失敗させる
|
|
38
|
+
|
|
39
|
+
### 2. ドキュメント生成
|
|
40
|
+
- typedoc + typedoc-plugin-markdown を使う
|
|
41
|
+
- Markdown 出力先: `docs/typedoc-md/`
|
|
42
|
+
- public API のみ対象
|
|
43
|
+
|
|
44
|
+
### 3. 静的解析
|
|
45
|
+
- ESLint(flat-config)
|
|
46
|
+
- TypeScript, sonarjs, jsdoc 最小構成
|
|
47
|
+
- dependency-cruiser を使い依存関係ルールを強制
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 実装設計原則
|
|
52
|
+
|
|
53
|
+
### DI(Dependency Injection)
|
|
54
|
+
- DIコンテナは使わない
|
|
55
|
+
- 外部依存の差し替えは Jest のモック で対応
|
|
56
|
+
|
|
57
|
+
> ⚠ DI は避けるが、外部アクセス用ラッパーの差し替えは許容(DI コンテナを使わないという意味での「DI 回避」)
|
|
58
|
+
|
|
59
|
+
### 外部アクセス設計
|
|
60
|
+
- ファイルI/O や外部API は必ず ラッパー経由
|
|
61
|
+
- ラッパーはシングルトン & モック可能
|
|
62
|
+
|
|
63
|
+
### クラス設計とインスタンス管理
|
|
64
|
+
- SRP(単一責務)を最優先
|
|
65
|
+
- 共通基底クラスは乱用しない
|
|
66
|
+
- 明確な共有状態が必要な場合のみ Singleton を使用可
|
|
67
|
+
- Singleton は状態を限定し、テストで差し替え可能にする
|
|
68
|
+
|
|
69
|
+
### SOLID & フォルダ構成
|
|
70
|
+
- SRP, DIP を満たす設計
|
|
71
|
+
- フォルダ構成は責務が分かる形に
|
|
72
|
+
|
|
73
|
+
### コードライフサイクル
|
|
74
|
+
- フェールバックや後方互換・マイグレーションは考慮しない
|
|
75
|
+
- 不要になったコードは コメントアウトせず完全削除
|
|
76
|
+
|
|
77
|
+
### 使用言語
|
|
78
|
+
- TypeScript のみ
|
|
79
|
+
- 設定ファイル用途のみ `.js / .cjs` を許可
|
|
80
|
+
- 作業完了条件: `npm run test` と `npm run build` が成功していること
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## 成果物として必須なもの
|
|
85
|
+
|
|
86
|
+
- 単体テスト(Jest + ts-jest): カバレッジ 80%以上
|
|
87
|
+
- 静的解析: ESLint / dependency-cruiser
|
|
88
|
+
- API ドキュメント: typedoc → Markdown 出力
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## プロジェクト構成(期待形)
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
プロジェクトフォルダ/
|
|
96
|
+
├─ docs/
|
|
97
|
+
│ └─ typedoc-md/ # typedoc Markdown 出力
|
|
98
|
+
├─ src/ # 本体ソース
|
|
99
|
+
├─ test/
|
|
100
|
+
│ ├─ unit/ # 単体テスト(Jest)
|
|
101
|
+
│ └─ e2e/ # E2E テスト
|
|
102
|
+
├─ .dependency-cruiser.js # dependency-cruiser 設定
|
|
103
|
+
├─ eslint.config.cjs # ESLint flat-config
|
|
104
|
+
├─ jest.unit.config.js # Jest unit 設定
|
|
105
|
+
├─ jest.e2e.config.js # Jest E2E 設定
|
|
106
|
+
└─ typedoc.js # typedoc 設定
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## テストカバレッジ & CI ゲート
|
|
112
|
+
|
|
113
|
+
- `npm run test:ci` で `jest --coverage` を実行し、coverage 80% 未満は失敗
|
|
114
|
+
- `npm run lint` で ESLint を実行し、エラーがあれば CI を失敗させる
|
|
115
|
+
- `npm run depcruise` の違反があれば CI を失敗させる
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## CI/品質ゲート要件
|
|
120
|
+
|
|
121
|
+
1. `npm run test` が成功すること
|
|
122
|
+
2. `npm run lint` がエラーを出さないこと
|
|
123
|
+
3. `npm run depcruise` が違反なし
|
|
124
|
+
4. `npm run build` が成功しバンドル生成されること
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## ESLint ルール / 必須条件
|
|
129
|
+
|
|
130
|
+
- Cognitive Complexity ≤ 10
|
|
131
|
+
|
|
132
|
+
```js
|
|
133
|
+
// eslint.config.cjs
|
|
134
|
+
module.exports = {
|
|
135
|
+
extends: [
|
|
136
|
+
'eslint:recommended',
|
|
137
|
+
'plugin:sonarjs/recommended',
|
|
138
|
+
'plugin:jsdoc/recommended'
|
|
139
|
+
],
|
|
140
|
+
plugins: ['sonarjs', 'jsdoc'],
|
|
141
|
+
rules: {
|
|
142
|
+
'sonarjs/cognitive-complexity': ['error', 10],
|
|
143
|
+
'no-unused-vars': ['warn'],
|
|
144
|
+
'jsdoc/require-jsdoc': [
|
|
145
|
+
'error',
|
|
146
|
+
{
|
|
147
|
+
require: {
|
|
148
|
+
FunctionDeclaration: true,
|
|
149
|
+
MethodDefinition: true,
|
|
150
|
+
ClassDeclaration: true,
|
|
151
|
+
ArrowFunctionExpression: true,
|
|
152
|
+
FunctionExpression: true
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
],
|
|
156
|
+
'jsdoc/require-param': 'error',
|
|
157
|
+
'jsdoc/require-returns': 'error'
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
```
|
|
161
|
+
- JSDoc コメント必須
|
|
162
|
+
- JSDoc 内で param / returns を記載
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## typedoc / JSDoc ガイドライン
|
|
167
|
+
|
|
168
|
+
### JSDoc 必須記載項目
|
|
169
|
+
1. 処理名(短いタイトル)
|
|
170
|
+
2. 処理概要(何をするか)
|
|
171
|
+
3. 実装理由(設計判断)
|
|
172
|
+
|
|
173
|
+
### 記述方針
|
|
174
|
+
- すべて日本語で記載
|
|
175
|
+
- public / internal を問わず 全 function / method / class / interface に必須
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
/**
|
|
179
|
+
* 処理名: タスク保存
|
|
180
|
+
*
|
|
181
|
+
* 処理概要: WebView から受け取ったタスク差分を永続化する
|
|
182
|
+
*
|
|
183
|
+
* 実装理由: ユーザーの編集内容を保存し再起動時に復元するため
|
|
184
|
+
*/
|
|
185
|
+
function saveTasks(...) {}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## dependency-cruiser ルール
|
|
191
|
+
|
|
192
|
+
- レイヤー間の不適切な依存を防止するため `.dependency-cruiser.js` を用意する
|
|
193
|
+
- 依存は interface / contract 経由のみ許可するなど、ルール違反時は CI で失敗させる
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## テスト & 受け入れ基準
|
|
198
|
+
|
|
199
|
+
### テスト要件
|
|
200
|
+
- Unit Test: Jest。外部通信・I/O はすべてモック
|
|
201
|
+
- E2E Test: docker-compose で起動し Playwright を使用
|
|
202
|
+
|
|
203
|
+
### 機能受け入れ条件(例)
|
|
204
|
+
- 入力受入: 100 行の断片データをインポートし UI で編集可能
|
|
205
|
+
- 重複検出: サンプルデータで 80%以上の論理的重複を検出
|
|
206
|
+
- 分解提案: 10 件中 7 件以上で適切な分割候補を提示
|
|
207
|
+
- 状態抽出: 「ユーザー登録」マトリクスから主要状態遷移を自動生成
|
|
208
|
+
- コラボレーション: 複数ユーザーの同時編集を競合なくマージ可能
|
|
209
|
+
|
|
210
|
+
### 最終ゲート
|
|
211
|
+
- `npm run test` 成功
|
|
212
|
+
- `npm run lint` エラーなし
|
|
213
|
+
- `npm run build` 成功
|
|
214
|
+
- `dist/index.bundle.js` が生成されていること
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## ルール概要 — Checklist
|
|
219
|
+
|
|
220
|
+
* Unit テストカバレッジ ≥ 80%
|
|
221
|
+
* ESLint エラーなし(complexity ルール含む)
|
|
222
|
+
* typedoc で Markdown ドキュメント生成
|
|
223
|
+
* CI で全ての品質ゲートを通過
|
|
224
|
+
* 依存関係ルール違反なし
|
|
225
|
+
* TypeScript のみ利用
|
|
226
|
+
* 外部I/O はラッパー経由
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## 活用例
|
|
231
|
+
|
|
232
|
+
### 新機能生成時
|
|
233
|
+
* このスキルを読み込ませ、コード生成に従わせる
|
|
234
|
+
* テスト・lint・coverage を常に同一基準で生成
|
|
235
|
+
|
|
236
|
+
### 既存コード修正時
|
|
237
|
+
* ESLint / type errors を修正
|
|
238
|
+
* テストが不足している場合は追加する
|
|
239
|
+
|
|
240
|
+
### PR 修正提案時
|
|
241
|
+
* ガイドライン違反を検知し改善案を提示する
|
|
242
|
+
|
|
243
|
+
## 1. 品質担保のための必須ツール
|
|
244
|
+
|
|
245
|
+
### 1.1 単体テスト
|
|
246
|
+
- Jest + ts-jest を採用する。
|
|
247
|
+
- テスト対象は unit テストが主、E2E は補助。
|
|
248
|
+
- カバレッジ 80%以上を必須。`npm run test:ci` で `jest --coverage` と coverageThreshold を用いて 80% 未満は失敗させる。
|
|
249
|
+
|
|
250
|
+
### 1.2 ドキュメント生成
|
|
251
|
+
- typedoc + typedoc-plugin-markdown を使用。
|
|
252
|
+
- 出力形式: Markdown、出力先: `docs/typedoc-md/`。
|
|
253
|
+
- 対象: `src/` 配下の public API のみ。
|
|
254
|
+
|
|
255
|
+
### 1.3 静的解析
|
|
256
|
+
- ESLint(flat-config、TypeScript/jsdoc/sonarjs の最小構成)。
|
|
257
|
+
- dependency-cruiser(レイヤー間の不正依存を検知し CI で失敗)。
|
|
258
|
+
|
|
259
|
+
## 2. 実装ルール(品質担保ポリシー)
|
|
260
|
+
|
|
261
|
+
### 2.1 DI(Dependency Injection)
|
|
262
|
+
- DI コンテナやフレームワークは使用しない。
|
|
263
|
+
- 依存の差し替えは Jest のモック機能で行う。
|
|
264
|
+
- 例外: ファイル I/O、外部サービスは明示的なラッパー層を作成する。
|
|
265
|
+
|
|
266
|
+
### 2.2 外部依存の扱い
|
|
267
|
+
- 外部アクセスは必ずラッパー経由。
|
|
268
|
+
- ラッパー要件: 単一責務、シングルトン、テスト時にモック可能。
|
|
269
|
+
- DI は避けるが、ラッパーの差し替えは許容(DI コンテナ不使用の意味での DI 回避)。
|
|
270
|
+
|
|
271
|
+
### 2.3 クラス設計とインスタンス管理
|
|
272
|
+
- SRP(単一責務)を最優先。
|
|
273
|
+
- 共通基底クラスの乱用禁止。
|
|
274
|
+
- 明確な共有状態が必要な場合のみ Singleton を使用可。Singleton は状態が限定的でテストで差し替え可能であること。
|
|
275
|
+
|
|
276
|
+
### 2.4 設計原則
|
|
277
|
+
- SRP と DIP を常に満たす構成にする。
|
|
278
|
+
- フォルダ構成で責務境界を明確にする。
|
|
279
|
+
|
|
280
|
+
### 2.5 コードライフサイクル方針
|
|
281
|
+
- フェールバック・後方互換・マイグレーションは考慮しない。
|
|
282
|
+
- 不要コードはコメントアウトせず完全削除。
|
|
283
|
+
|
|
284
|
+
### 2.6 言語・ビルド制約
|
|
285
|
+
- TypeScript のみ使用。
|
|
286
|
+
- `.js` / `.cjs` は設定ファイル用途のみ許可。
|
|
287
|
+
- `npm run test` と `npm run build` を必ず成功させる。
|
|
288
|
+
|
|
289
|
+
## 3. 成果物として必須なもの
|
|
290
|
+
- 単体テスト(Jest + ts-jest、カバレッジ ≥ 80%)。
|
|
291
|
+
- 静的解析(ESLint、dependency-cruiser)。
|
|
292
|
+
- API ドキュメント(typedoc → Markdown 出力)。
|
|
293
|
+
|
|
294
|
+
## 4. プロジェクト構成(期待形)
|
|
295
|
+
|
|
296
|
+
```
|
|
297
|
+
プロジェクト/
|
|
298
|
+
├─ docs/
|
|
299
|
+
│ └─ typedoc-md/
|
|
300
|
+
├─ src/
|
|
301
|
+
├─ test/
|
|
302
|
+
│ ├─ unit/
|
|
303
|
+
│ └─ e2e/
|
|
304
|
+
├─ .dependency-cruiser.js
|
|
305
|
+
├─ eslint.config.cjs
|
|
306
|
+
├─ jest.unit.config.js
|
|
307
|
+
├─ jest.e2e.config.js
|
|
308
|
+
└─ typedoc.js
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
## 5. テストカバレッジ & CI ゲート
|
|
312
|
+
- `npm run test:ci`(jest --coverage、80% 未満で失敗)。
|
|
313
|
+
- `npm run lint`(ESLint エラーで失敗)。
|
|
314
|
+
- `npm run depcruise`(dependency-cruiser 依存違反で失敗)。
|
|
315
|
+
|
|
316
|
+
## 6. ESLint ルール(必須要件)
|
|
317
|
+
|
|
318
|
+
### 方針
|
|
319
|
+
- 可読性・保守性を重視。
|
|
320
|
+
- 複雑度を機械的に制限。
|
|
321
|
+
- ドキュメント未記載をエラー扱い。
|
|
322
|
+
|
|
323
|
+
### 必須ルール
|
|
324
|
+
- Cognitive Complexity ≤ 10。
|
|
325
|
+
- JSDoc 必須(param / returns 必須)。
|
|
326
|
+
|
|
327
|
+
```js
|
|
328
|
+
// eslint.config.cjs
|
|
329
|
+
module.exports = {
|
|
330
|
+
extends: [
|
|
331
|
+
'eslint:recommended',
|
|
332
|
+
'plugin:sonarjs/recommended',
|
|
333
|
+
'plugin:jsdoc/recommended'
|
|
334
|
+
],
|
|
335
|
+
plugins: ['sonarjs', 'jsdoc'],
|
|
336
|
+
rules: {
|
|
337
|
+
'sonarjs/cognitive-complexity': ['error', 10],
|
|
338
|
+
'no-unused-vars': ['warn'],
|
|
339
|
+
|
|
340
|
+
'jsdoc/require-jsdoc': [
|
|
341
|
+
'error',
|
|
342
|
+
{
|
|
343
|
+
require: {
|
|
344
|
+
FunctionDeclaration: true,
|
|
345
|
+
MethodDefinition: true,
|
|
346
|
+
ClassDeclaration: true,
|
|
347
|
+
ArrowFunctionExpression: true,
|
|
348
|
+
FunctionExpression: true
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
],
|
|
352
|
+
'jsdoc/require-param': 'error',
|
|
353
|
+
'jsdoc/require-returns': 'error'
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
## 7. typedoc / JSDoc ルール
|
|
359
|
+
|
|
360
|
+
### 基本方針
|
|
361
|
+
- すべて日本語で記載。
|
|
362
|
+
- public / internal を問わず全 function / method / class / interface に必須。
|
|
363
|
+
|
|
364
|
+
### 必須記載項目
|
|
365
|
+
1. 処理名(短いタイトル)
|
|
366
|
+
2. 処理概要(何をするか)
|
|
367
|
+
3. 実装理由(なぜ必要か・設計判断)
|
|
368
|
+
|
|
369
|
+
```ts
|
|
370
|
+
/**
|
|
371
|
+
* 処理名: タスク保存
|
|
372
|
+
*
|
|
373
|
+
* 処理概要:
|
|
374
|
+
* WebView から受け取ったタスク差分を永続化する
|
|
375
|
+
*
|
|
376
|
+
* 実装理由:
|
|
377
|
+
* ユーザーの編集内容をワークスペースに保存し、
|
|
378
|
+
* 再起動後に状態を復元する必要があるため
|
|
379
|
+
*/
|
|
380
|
+
function saveTasks(...) {}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
## 8. dependency-cruiser ルール
|
|
384
|
+
|
|
385
|
+
### 目的
|
|
386
|
+
- レイヤー間の不適切依存を防止する。
|
|
387
|
+
|
|
388
|
+
### 例
|
|
389
|
+
- 依存は interface / contract 経由のみ許可。
|
|
390
|
+
- 設定ファイル: `.dependency-cruiser.js`。
|
|
391
|
+
- 違反時は CI 失敗。
|
|
392
|
+
|
|
393
|
+
## 9. テスト & 受け入れ基準
|
|
394
|
+
|
|
395
|
+
### テスト要件
|
|
396
|
+
|
|
397
|
+
* Unit Test
|
|
398
|
+
* Jest
|
|
399
|
+
* 外部通信・I/O はすべてモック
|
|
400
|
+
* E2E Test
|
|
401
|
+
* docker-compose で起動
|
|
402
|
+
* Playwright を使用
|
|
403
|
+
|
|
404
|
+
### 機能受け入れ条件(例)
|
|
405
|
+
|
|
406
|
+
* 入力受入: 100 行の断片データをインポートし、UI で編集可能。
|
|
407
|
+
* 重複検出: サンプルデータで 80%以上の論理的重複を検出。
|
|
408
|
+
* 分解提案: 10 件中 7 件以上で適切な分割候補を提示。
|
|
409
|
+
* 状態抽出: 「ユーザー登録」マトリクスから主要状態遷移を自動生成。
|
|
410
|
+
* コラボレーション: 複数ユーザーの同時編集を競合なくマージ可能。
|
|
411
|
+
|
|
412
|
+
### 最終ゲート
|
|
413
|
+
|
|
414
|
+
* `npm run test` 成功
|
|
415
|
+
* `npm run lint` エラーなし
|
|
416
|
+
* `npm run build` 成功
|
|
417
|
+
* `dist/index.bundle.js` が生成されていること
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: Publish package to GitHub Packages
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [created]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
test:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
node-version: [14.x, 16.x]
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- name: Use Node.js ${{ matrix.node-version }}
|
|
19
|
+
uses: actions/setup-node@v4
|
|
20
|
+
with:
|
|
21
|
+
node-version: ${{ matrix.node-version }}
|
|
22
|
+
|
|
23
|
+
- name: Test
|
|
24
|
+
run: |
|
|
25
|
+
npm ci
|
|
26
|
+
npm run test
|
|
27
|
+
|
|
28
|
+
publish-npm:
|
|
29
|
+
needs: test
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
permissions:
|
|
32
|
+
id-token: write
|
|
33
|
+
contents: read
|
|
34
|
+
steps:
|
|
35
|
+
- uses: actions/checkout@v4
|
|
36
|
+
- uses: actions/setup-node@v4
|
|
37
|
+
with:
|
|
38
|
+
node-version: '20.x'
|
|
39
|
+
registry-url: https://registry.npmjs.org/
|
|
40
|
+
- run: npm install -g npm@latest
|
|
41
|
+
- run: npm ci
|
|
42
|
+
- run: npm run build
|
|
43
|
+
- name: Publish to NPM with Trusted Publishing
|
|
44
|
+
run: npm publish --access public
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: NodeJS with Webpack
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
strategy:
|
|
14
|
+
matrix:
|
|
15
|
+
node-version: [14.x, 16.x]
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Use Node.js ${{ matrix.node-version }}
|
|
21
|
+
uses: actions/setup-node@v4
|
|
22
|
+
with:
|
|
23
|
+
node-version: ${{ matrix.node-version }}
|
|
24
|
+
|
|
25
|
+
- name: Test
|
|
26
|
+
run: |
|
|
27
|
+
npm ci
|
|
28
|
+
npm run test
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 nojaja
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|