import {Meta} from '@storybook/addon-docs/blocks'

<Meta title='@dxtmisha/ru/scripts/Classes/PropertiesFile - Оркестратор путей файловой системы'/>

# Класс PropertiesFile

Класс `PropertiesFile` — это комплексная статическая утилита, предназначенная для оркестрации всех задач, связанных с файловой системой, в инструментарии дизайн-системы. Он предоставляет кроссплатформенный интерфейс для манипуляций с путями, синхронного ввода-вывода и рекурсивного управления директориями, гарантируя согласованность поиска файлов и сохранения данных в различных операционных системах и средах разработки.

## Ключевые особенности

- **Нормализация путей** — автоматически разрешает специфичные для ОС разделители путей и объединяет сегменты в стандартизированные строки.
- **Рекурсивный обход** — предоставляет специализированные методы для глубокого исследования структур директорий с дополнительной индексацией.
- **Синхронный ввод-вывод** — обрабатывает чтение (JSON/текст) и запись файлов с автоматическим созданием необходимых директорий.
- **Получение метаданных** — извлекает временные метки файлов и статистические данные для логики аннулирования кэша.
- **Безопасные операции** — включает встроенные проверки существования записей, их типа (файл или директория) и статуса модуля.

## Инициализация

Являясь статическим классом, `PropertiesFile` самоинициализируется и готов к использованию сразу после импорта.

```typescript
import { PropertiesFile } from '@dxtmisha/scripts'

// Проверка существования конфигурации
if (PropertiesFile.is('design-ui.json')) {
  const config = PropertiesFile.readFile('design-ui.json')
}

// Безопасное объединение путей
const fullPath = PropertiesFile.joinPath(['src', 'tokens', 'colors.json'])
```

## Методы проверки

- `is(path): boolean` — синхронно проверяет существование файла или директории.
- `isDir(path): boolean` — определяет, указывает ли путь на директорию.
- `isModule(): boolean` — определяет, подключен ли текущий пакет как внешний модуль.

## Методы работы с путями

### `joinPath`

Объединяет несколько сегментов пути в одну нормализованную строку пути, используя разделитель текущей ОС.

**Параметры:**
- `path: PropertiesFilePath` — массив сегментов или строка пути.

**Пример:**
```typescript
const path = PropertiesFile.joinPath(['src', 'styles', 'main.css'])
// Возвращает: "src/styles/main.css" (на Mac/Linux) или "src\styles\main.css" (на Windows)
```

**Возвращает:** `string` — объединенный и нормализованный путь.

### `joinPathByName`

Формирует полный путь к файлу, объединяя путь к директории, имя файла и расширение.

**Параметры:**
- `path: PropertiesFilePath` — путь к директории.
- `name: string` — имя файла.
- `extension: string` — расширение файла (по умолчанию `json`).

**Пример:**
```typescript
const filePath = PropertiesFile.joinPathByName('data', 'user-profile', 'json')
// Возвращает: "data/user-profile.json"
```

**Возвращает:** `string`

### `getPathDir`

Извлекает путь к директории из полного пути. Если передан путь к директории, возвращает его без изменений.

**Параметры:**
- `path: PropertiesFilePath` — путь к файлу или директории.

**Пример:**
```typescript
const dirOnly = PropertiesFile.getPathDir('src/classes/App.ts')
// Возвращает: "src/classes"
```

**Возвращает:** `string`

### `getPathFile`

Формирует массив сегментов пути к файлу.

**Параметры:**
- `path: PropertiesFilePath` — базовый путь.
- `name: string` — имя файла.
- `extension: string` — расширение (по умолчанию `json`).

**Пример:**
```typescript
const segments = PropertiesFile.getPathFile('dist', 'manifest')
// Возвращает: ["dist", "manifest.json"]
```

**Возвращает:** `string[]`

### `getRoot`

Возвращает текущий корневой путь проекта (`process.cwd()`).

**Пример:**
```typescript
const root = PropertiesFile.getRoot()
// Возвращает: "/Users/user/project"
```

**Возвращает:** `string`

### `getFileName`

Преобразует имя в kebab-case и добавляет расширение.

**Параметры:**
- `name: string` — имя элемента.
- `extension: string` — расширение (по умолчанию `json`).

**Пример:**
```typescript
const name = PropertiesFile.getFileName('UserProfile', 'ts')
// Возвращает: "user-profile.ts"
```

**Возвращает:** `string`

### `sep`

Возвращает системный разделитель путей (`/` или `\`).

**Пример:**
```typescript
const s = PropertiesFile.sep()
// Возвращает: "/"
```

**Возвращает:** `string`

## Методы чтения

### `readFile`

Синхронно читает и автоматически парсит содержимое файла. Если файл является JSON, возвращает объект, иначе — строку.

**Параметры:**
- `path: PropertiesFilePath` — путь к файлу.

**Пример:**
```typescript
const data = PropertiesFile.readFile<{ name: string }>('config.json')
// Возвращает: { name: "DXT" } (объект)
```

**Возвращает:** `R | undefined` — спарсенные данные или `undefined`, если файл не найден.

### `readFileOnly`

Читает содержимое файла как строку без преобразования.

**Параметры:**
- `path: PropertiesFilePath` — путь к файлу.

**Пример:**
```typescript
const text = PropertiesFile.readFileOnly('README.md')
// Возвращает: "# Project Title..." (строка)
```

**Возвращает:** `string | undefined`

### `readDir`

Читает содержимое директории (список имен элементов).

**Параметры:**
- `path: PropertiesFilePath` — путь к директории.

**Пример:**
```typescript
const items = PropertiesFile.readDir('src')
// Возвращает: ["index.ts", "classes", "types"]
```

**Возвращает:** `string[]`

### `readDirRecursive`

Рекурсивно читает все файлы в директории и её поддиректориях.

**Параметры:**
- `path: PropertiesFilePath` — путь к директории.

**Пример:**
```typescript
const allFiles = PropertiesFile.readDirRecursive('src')
// Возвращает: ["index.ts", "classes/App.ts", "classes/DB.ts", ...]
```

**Возвращает:** `string[]` — список путей ко всем найденным файлам.

## Методы модификации

### `write`

Записывает данные в файл, автоматически создавая необходимые директории.

**Параметры:**
- `path: PropertiesFilePath` — путь к директории.
- `name: string` — имя файла.
- `value: T` — данные для записи.
- `extension: string` — расширение (по умолчанию `json`).

**Пример:**
```typescript
PropertiesFile.write('dist/cache', 'data', { id: 1 })
// Создает dist/cache/data.json с JSON содержимым
```

**Возвращает:** `void`

### `writeByPath`

Записывает данные по точному пути.

**Параметры:**
- `path: PropertiesFilePath` — полный путь к файлу.
- `value: T` — данные.
- `transform: boolean` — нужно ли преобразовывать объект в JSON (по умолчанию `true`).

**Пример:**
```typescript
PropertiesFile.writeByPath('logs/error.log', 'Critical error', false)
// Пишет строку в файл без JSON-трансформации
```

**Возвращает:** `void`

### `createDir`

Рекурсивно создает директорию, если она не существует.

**Параметры:**
- `path: PropertiesFilePath` — путь для создания.

**Пример:**
```typescript
PropertiesFile.createDir('storage/images/2024')
// Создает всю цепочку папок
```

**Возвращает:** `void`

### `copy`

Копирует файл из одного места в другое.

**Параметры:**
- `path: PropertiesFilePath` — целевой путь.
- `pathsSrc: PropertiesFilePath` — исходный путь.

**Пример:**
```typescript
PropertiesFile.copy('backup/config.json', 'config.json')
```

**Возвращает:** `void`

### `removeFile`

Удаляет указанный файл.

**Параметры:**
- `path: PropertiesFilePath` — путь к файлу.

**Пример:**
```typescript
PropertiesFile.removeFile('temp.tmp')
```

**Возвращает:** `void`

### `removeDir`

Рекурсивно удаляет директорию со всем содержимым.

**Параметры:**
- `path: PropertiesFilePath` — путь к директории.

**Пример:**
```typescript
PropertiesFile.removeDir('dist/old-version')
```

**Возвращает:** `void`

## Операции

### Поток синхронизации путей и ввода-вывода

`PropertiesFile` выступает в качестве низкоуровневого слоя синхронизации для всей библиотеки:
1. **Нормализация путей**: Каждый метод внутренне вызывает `joinPath` и `toSep`, которые преобразуют все входящие косые черты в специфичный для ОС разделитель (например, `\` в Windows).
2. **Атомарная запись**: При вызове `write()` класс сначала определяет целевую директорию и выполняет `createDir()`, который рекурсивно создает любые недостающие папки перед записью содержимого через `fs.writeFileSync`.
3. **Рекурсивный контекст**: Специализированные рекурсивные методы (`readDirRecursive` и др.) позволяют движкам документации и токенов обнаруживать каждый файл в дереве компонентов без ручного управления глубиной или лимитами рекурсии.
4. **Разрешение корня**: Класс поддерживает внутреннее свойство `root` (на основе `process.cwd()`), чтобы сегменты относительных путей всегда разрешались относительно базовой директории проекта.
