# 機能設計書 33-jest-regex-util

## 概要

本ドキュメントは、jest-regex-utilパッケージの機能設計を記載する。jest-regex-utilは、正規表現で使用する文字列のエスケープ処理と、ファイルパスのプラットフォーム間での正規表現変換を提供するユーティリティパッケージである。

### 本機能の処理概要

jest-regex-utilは、文字列を正規表現パターンとして安全に使用できるようにエスケープする機能と、Windows/Unix間でのパスセパレータの違いを吸収する機能を提供する。

**業務上の目的・背景**：Jestではテストファイルのパスをパターンマッチングで検索したり、テスト名をフィルタリングしたりする際に正規表現を使用する。ユーザーが入力したパスや文字列には、正規表現の特殊文字（`*`, `+`, `.`など）が含まれる可能性があり、これらを適切にエスケープしないと予期しないマッチングが発生する。また、WindowsとUnixではパスセパレータが異なるため、クロスプラットフォームで動作する正規表現パターンを生成する必要がある。

**機能の利用シーン**：
- テストファイルパスのパターンマッチング（testMatch, testRegex設定）
- テスト名のフィルタリング（-t, --testNamePatternオプション）
- ファイル監視対象のパターン指定（watchPathIgnorePatterns設定）

**主要な処理内容**：
1. escapeStrForRegex: 正規表現特殊文字のエスケープ
2. escapePathForRegex: ファイルパスの正規表現用エスケープ
3. replacePathSepForRegex: パスセパレータのプラットフォーム対応変換

**関連システム・外部連携**：
- Node.js path モジュール: パスセパレータの取得に使用
- jest-config: 設定ファイルのパターン処理で使用
- @jest/core: テストファイル検索で使用

**権限による制御**：特になし（ユーティリティ関数のため権限制御は不要）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面に直接関連しないユーティリティパッケージ |

## 機能種別

ユーティリティ / 文字列処理

## 入力仕様

### 入力パラメータ

#### escapeStrForRegex関数

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| string | string | Yes | エスケープ対象の文字列 | - |

#### escapePathForRegex関数

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| dir | string | Yes | エスケープ対象のディレクトリパス | - |

#### replacePathSepForRegex関数

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| string | string | Yes | パスセパレータ変換対象の文字列 | - |

### 入力データソース

- Jest設定ファイルのパターン指定
- CLIオプションで指定されたパターン

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | string | エスケープまたは変換後の文字列（正規表現パターンとして使用可能） |

### 出力先

関数の戻り値として返却

## 処理フロー

### 処理シーケンス

```
1. escapeStrForRegex関数
   └─ 正規表現特殊文字をバックスラッシュでエスケープ
      └─ 対象文字: $ ( ) * + . ? [ \ ] ^ { | }

2. escapePathForRegex関数
   └─ Windowsの場合、\を/に一時的に置換
   └─ escapeStrForRegexで特殊文字をエスケープ
   └─ replacePathSepForRegexでパスセパレータを変換

3. replacePathSepForRegex関数
   └─ Windowsの場合のみ処理
   └─ /を\\\\に変換（正規表現でのバックスラッシュマッチング用）
   └─ 既存のエスケープシーケンスは保持
```

### フローチャート

```mermaid
flowchart TD
    A[escapePathForRegex開始] --> B{sep === '\\'?}
    B -->|Yes| C['\\'を'/'に置換]
    B -->|No| D[そのまま]
    C --> E[escapeStrForRegex呼び出し]
    D --> E
    E --> F[replacePathSepForRegex呼び出し]
    F --> G[結果を返却]

    H[escapeStrForRegex開始] --> I[特殊文字をエスケープ]
    I --> J[結果を返却]

    K[replacePathSepForRegex開始] --> L{sep === '\\'?}
    L -->|Yes| M[/を\\\\に変換]
    L -->|No| N[そのまま返却]
    M --> O[結果を返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 特殊文字エスケープ | 正規表現の特殊文字をバックスラッシュでエスケープする | 全プラットフォーム |
| BR-02 | Windowsパス変換 | Windowsではパスセパレータを正規表現用に変換 | path.sep === '\\' |
| BR-03 | Unixパス保持 | Unixではパスセパレータをそのまま保持 | path.sep === '/' |

### 計算ロジック

**エスケープ対象文字**：
```
$ ( ) * + . ? [ \ ] ^ { | }
```

**正規表現パターン**：
```javascript
/[$()*+.?[\\\]^{|}]/g
```

**Windows用パスセパレータ変換パターン**：
```javascript
/(\/|(.)?\\(?![$()*+.?[\\\]^{|}]))/g
```

## データベース操作仕様

該当なし（純粋な文字列処理関数）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | エラーは発生しない | - |

### リトライ仕様

該当なし

## トランザクション仕様

該当なし

## パフォーマンス要件

- 同期的に即座に結果を返すこと
- String.replaceAll()と同等のパフォーマンス

## セキュリティ考慮事項

- ユーザー入力をエスケープせずに正規表現として使用するとReDoS（正規表現DoS）攻撃のリスクがある
- 本パッケージを使用してユーザー入力を適切にエスケープすることでリスクを軽減

## 備考

- path.sepはNode.jsの実行プラットフォームに依存
- Windowsでは`\\`、Unix系では`/`が返される

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: 基本的なエスケープ関数を理解する

最も基本的な関数から理解を始める。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/jest-regex-util/src/index.ts` | escapeStrForRegex関数（20-21行目） |

**主要処理フロー**:
1. **20-21行目**: 正規表現特殊文字を検出し、バックスラッシュでエスケープ
2. 正規表現パターン `/[$()*+.?[\\\]^{|}]/g` で特殊文字を検出
3. `\\$&` で検出した文字の前にバックスラッシュを追加

**読解のコツ**:
- `$&` は正規表現の置換パターンで「マッチした文字列全体」を意味する
- `\\$&` は「バックスラッシュ + マッチした文字」となる

#### Step 2: パスセパレータ変換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/jest-regex-util/src/index.ts` | replacePathSepForRegex関数（23-31行目） |

**主要処理フロー**:
1. **24行目**: Windowsかどうかを判定（sep === '\\'）
2. **25-28行目**: Windows用の変換処理
   - `/` を `\\\\` に変換（正規表現でバックスラッシュをマッチさせるため）
   - 既存のエスケープシーケンスは保持
3. **30行目**: Unix系ではそのまま返却

**読解のコツ**:
- 正規表現内でのバックスラッシュは `\\` でエスケープが必要
- 文字列としてのバックスラッシュも `\\` でエスケープが必要
- よって、リテラルの `\` 1文字は `\\\\` となる

#### Step 3: パスエスケープ関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.ts | `packages/jest-regex-util/src/index.ts` | escapePathForRegex関数（11-18行目） |

**主要処理フロー**:
1. **12-16行目**: Windowsの場合、`\`を`/`に一時的に置換
   - これにより escapeStrForRegex でバックスラッシュがエスケープされるのを防ぐ
2. **17行目**: escapeStrForRegex と replacePathSepForRegex を順番に適用

### プログラム呼び出し階層図

```
escapePathForRegex (index.ts)
    │
    ├─ 条件: sep === '\\' (Windowsチェック)
    │      └─ String.replaceAll('\\', '/')
    │
    ├─ escapeStrForRegex (index.ts)
    │      └─ String.replaceAll(正規表現, '\\$&')
    │
    └─ replacePathSepForRegex (index.ts)
           └─ 条件: sep === '\\' (Windowsチェック)
                  └─ String.replaceAll(正規表現, callback)
```

### データフロー図

```
[入力]                        [処理]                           [出力]

Unix環境:
'/path/to/file.test.js' ──▶ escapePathForRegex() ──────▶ '/path/to/file\\.test\\.js'
                                   │
                                   ├─ そのまま
                                   ├─ escapeStrForRegex ──▶ .をエスケープ
                                   └─ replacePathSepForRegex ▶ そのまま

Windows環境:
'C:\\path\\to\\file.test.js' ▶ escapePathForRegex() ──▶ 'C:\\\\path\\\\to\\\\file\\.test\\.js'
                                   │
                                   ├─ \\を/に置換 ────▶ 'C:/path/to/file.test.js'
                                   ├─ escapeStrForRegex ──▶ 'C:/path/to/file\\.test\\.js'
                                   └─ replacePathSepForRegex ▶ 'C:\\\\path\\\\to\\\\file\\.test\\.js'
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/jest-regex-util/src/index.ts` | ソース | 全関数の実装 |
| package.json | `packages/jest-regex-util/package.json` | 設定 | パッケージ定義 |
| index.test.ts | `packages/jest-regex-util/src/__tests__/index.test.ts` | テスト | 各関数のテスト |
