# 機能設計書 22-path

## 概要

本ドキュメントは、Node.jsのpathモジュールの機能設計について記述する。pathモジュールは、ファイルパスとディレクトリパスの操作に関するユーティリティ関数を提供し、クロスプラットフォーム対応のパス処理を実現する。

### 本機能の処理概要

**業務上の目的・背景**：pathモジュールは、オペレーティングシステムによって異なるパス区切り文字（Windowsの`\`、POSIX系の`/`）やパス形式の違いを抽象化し、一貫したAPIでパス操作を行うことを目的としている。これにより、開発者はOSの違いを意識せずにファイルパスを操作でき、移植性の高いコードを書くことができる。

**機能の利用シーン**：
- ファイルパスからディレクトリ名、ファイル名、拡張子を抽出する際
- 複数のパスセグメントを結合して完全なパスを構築する際
- 相対パスを絶対パスに変換する際
- 2つのパス間の相対パスを計算する際
- パスを正規化して冗長な区切り文字や`.`、`..`を解決する際
- ファイルパスがグロブパターンにマッチするか確認する際

**主要な処理内容**：
1. `path.join()` - パスセグメントを結合
2. `path.resolve()` - 絶対パスを解決
3. `path.normalize()` - パスを正規化
4. `path.dirname()` - ディレクトリ名を取得
5. `path.basename()` - ファイル名を取得
6. `path.extname()` - 拡張子を取得
7. `path.parse()` - パスをオブジェクトに分解
8. `path.format()` - オブジェクトからパスを構築
9. `path.relative()` - 相対パスを計算
10. `path.isAbsolute()` - 絶対パスかどうかを判定
11. `path.toNamespacedPath()` - Windowsの長いパス形式に変換
12. `path.matchesGlob()` - グロブパターンマッチング

**関連システム・外部連携**：
- process.cwd() - 現在の作業ディレクトリの取得
- internal/fs/glob - グロブパターンマッチング機能

**権限による制御**：特になし。すべての機能は任意のユーザーコードから利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本モジュールはAPI機能であり、関連する画面はありません |

## 機能種別

ユーティリティ関数 / 文字列処理 / クロスプラットフォーム対応

## 入力仕様

### 入力パラメータ

#### join

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ...paths | string[] | Yes | 結合するパスセグメント | validateString |

#### resolve

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ...paths | string[] | Yes | 解決するパスセグメント | validateString |

#### normalize

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| path | string | Yes | 正規化するパス | validateString |

#### dirname / basename / extname

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| path | string | Yes | 対象パス | validateString |

#### basename（オプション付き）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| path | string | Yes | 対象パス | validateString |
| suffix | string | No | 除去する拡張子 | validateString |

#### parse

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| path | string | Yes | パースするパス | validateString |

#### format

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| pathObject | Object | Yes | パスオブジェクト | validateObject |

#### relative

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| from | string | Yes | 起点パス | validateString |
| to | string | Yes | 終点パス | validateString |

#### matchesGlob

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| path | string | Yes | 対象パス | - |
| pattern | string | Yes | グロブパターン | - |

### 入力データソース

プログラムコードからの直接呼び出し。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| join戻り値 | string | 結合されたパス |
| resolve戻り値 | string | 絶対パス |
| normalize戻り値 | string | 正規化されたパス |
| dirname戻り値 | string | ディレクトリパス |
| basename戻り値 | string | ファイル名（拡張子含む） |
| extname戻り値 | string | 拡張子（.を含む） |
| parse戻り値 | Object | {root, dir, base, name, ext} |
| format戻り値 | string | 構築されたパス |
| relative戻り値 | string | 相対パス |
| isAbsolute戻り値 | boolean | 絶対パスかどうか |
| matchesGlob戻り値 | boolean | マッチしたかどうか |

### 出力先

呼び出し元への戻り値として返却。

## 処理フロー

### 処理シーケンス

```
1. パスセグメントの入力
   └─ バリデーション（文字列チェック）
2. OS判定
   └─ Windows/POSIXに応じた処理分岐
3. パス処理実行
   └─ normalizeString関数による正規化
4. 結果返却
   └─ 処理済みパス文字列
```

### フローチャート

```mermaid
flowchart TD
    A[パス操作関数呼び出し] --> B{OS判定}
    B -->|Windows| C[win32実装]
    B -->|POSIX| D[posix実装]
    C --> E[パス区切り: \\]
    D --> F[パス区切り: /]
    E --> G[normalizeString処理]
    F --> G
    G --> H[.と..の解決]
    H --> I[結果パスを返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 空パスのデフォルト | 空のパスは'.'として扱う | normalize, join等 |
| BR-002 | Windowsドライブレター | C:等のドライブレターを正しく処理 | Windowsプラットフォーム |
| BR-003 | UNCパス対応 | \\\\server\\share形式を正しく処理 | Windowsプラットフォーム |
| BR-004 | 予約名ガード | CON、PRN等のWindows予約名を適切に処理 | Windows normalize |
| BR-005 | バックスラッシュ変換 | Windowsではforwardスラッシュもパス区切りとして認識 | Windowsプラットフォーム |

### 計算ロジック

#### normalizeString関数（92-154行目）
- `.`（カレントディレクトリ）を除去
- `..`（親ディレクトリ）を解決してパスを短縮
- 連続するパス区切り文字を1つに正規化

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

### 操作別データベース影響一覧

本モジュールはデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ERR_INVALID_ARG_TYPE | TypeError | pathが文字列でない | 文字列を渡す |

### リトライ仕様

リトライ処理は行わない。

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

トランザクション処理は行わない。

## パフォーマンス要件

- 軽量な文字列操作として設計
- process.cwd()呼び出しはresolve()でのみ使用され、必要な場合のみ実行

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

- CVE-2024-36139対応：normalizeでパストラバーサル攻撃を防ぐための修正（455-471行目）
- 予約デバイス名（CON、NUL等）の不正利用を防止

## 備考

- path.win32 / path.posixで明示的にプラットフォーム固有の実装を使用可能
- _makeLongはtoNamespacedPathの非推奨エイリアス（DEP0080）
- モジュールはデフォルトで実行環境のプラットフォームに応じた実装をエクスポート

---

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

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

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | path.js | `lib/path.js` | parseの戻り値構造（1065-1066行目） |

**読解のコツ**: `parse()`の戻り値オブジェクト `{ root, dir, base, name, ext }` の各フィールドの意味を理解することが重要。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | path.js | `lib/path.js` | モジュールエクスポート（1713行目） |

**主要処理フロー**:
1. **1713行目**: isWindowsに応じてwin32またはposixをエクスポート
2. **1706-1707行目**: win32.posix、posix.win32のクロス参照設定
3. **1710-1711行目**: _makeLong非推奨エイリアス

#### Step 3: normalizeString関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | path.js | `lib/path.js` | normalizeString実装（92-154行目） |

**主要処理フロー**:
- **97-98行目**: 状態変数の初期化（lastSlash, dots, lastSegmentLength）
- **106-146行目**: パス文字列をループで処理
- **109-137行目**: `..`（dots===2）の処理で親ディレクトリを解決
- **147-150行目**: ドットのカウント処理

#### Step 4: win32実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | path.js | `lib/path.js` | win32オブジェクト（184-1222行目） |

**主要処理フロー**:
- **190-344行目**: win32.resolve - 絶対パス解決（UNC、ドライブレター対応）
- **350-481行目**: win32.normalize - パス正規化（CVE-2024-36139対応含む）
- **506-598行目**: win32.join - パス結合（予約名対応含む）
- **803-892行目**: win32.dirname - ディレクトリ名取得

#### Step 5: posix実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | path.js | `lib/path.js` | posixオブジェクト（1239-1704行目） |

**主要処理フロー**:
- **1245-1287行目**: posix.resolve - 絶対パス解決
- **1293-1316行目**: posix.normalize - パス正規化
- **1332-1348行目**: posix.join - パス結合
- **1441-1464行目**: posix.dirname - ディレクトリ名取得

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

```
lib/path.js
    │
    ├─ normalizeString() [92-154行目]
    │      └─ パス正規化の共通ロジック
    │
    ├─ _format() [171-180行目]
    │      └─ pathObjectからパス文字列を生成
    │
    ├─ win32オブジェクト [184-1222行目]
    │      ├─ resolve() - 絶対パス解決
    │      ├─ normalize() - パス正規化
    │      ├─ isAbsolute() - 絶対パス判定
    │      ├─ join() - パス結合
    │      ├─ relative() - 相対パス計算
    │      ├─ dirname() - ディレクトリ名
    │      ├─ basename() - ファイル名
    │      ├─ extname() - 拡張子
    │      ├─ parse() - パス分解
    │      ├─ format() - パス構築
    │      ├─ toNamespacedPath() - 長いパス変換
    │      └─ matchesGlob() - グロブマッチ
    │
    ├─ posix オブジェクト [1239-1704行目]
    │      └─ (win32と同等の関数群)
    │
    └─ internal/fs/glob (matchesGlob用)
           └─ matchGlobPattern()
```

### データフロー図

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

パスセグメント群 ───▶ join/resolve ───▶ 完全パス
単一パス ───▶ normalize ───▶ 正規化パス
単一パス ───▶ parse ───▶ {root,dir,base,name,ext}
パスオブジェクト ───▶ format ───▶ パス文字列
from, to ───▶ relative ───▶ 相対パス
path, pattern ───▶ matchesGlob ───▶ boolean
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| path.js | `lib/path.js` | ソース | メインモジュール |
| internal/constants.js | `lib/internal/constants.js` | ソース | 文字コード定数 |
| internal/validators.js | `lib/internal/validators.js` | ソース | バリデーション関数 |
| internal/util.js | `lib/internal/util.js` | ソース | isWindows判定など |
| internal/fs/glob.js | `lib/internal/fs/glob.js` | ソース | グロブパターンマッチング |
