npm package: @napopravku/adapter-utils
Description: TypeScript utilities for safe type conversion and data transformation. Perfect for API responses, forms, and any data validation needs.
Author: Napopravku
Latest version: 1.0.1

# Adapter Utils

Набор утилит для безопасного преобразования типов данных в TypeScript. Идеально подходит для работы с API responses, формами и любыми данными, требующими валидации и преобразования.

## Установка

```bash
npm install @napopravku/adapter-utils
```

## Основные возможности

- ✅ **Безопасное преобразование типов** - обработка `null`, `undefined` и невалидных значений
- 🎯 **TypeScript-first** - полная поддержка типов из коробки
- 🚀 **Tree-shakeable** - импортируйте только то, что нужно
- 📦 **Легковесная** - минимальный размер бандла
- 🔨 **Функциональный подход** - чистые функции без классов и наследования

## API

### Boolean - Преобразование в boolean

```typescript
import { 
  BooleanOrUndefined, 
  BooleanOrTrue, 
  BooleanOrFalse,
  BooleanFromNumericString 
} from 'adapter-utils';

BooleanOrUndefined(1)        // true
BooleanOrUndefined(0)        // false
BooleanOrUndefined(null)     // undefined

BooleanOrTrue(1)             // true
BooleanOrTrue(null)          // true (default)
BooleanOrTrue(undefined)     // true (default)

BooleanOrFalse(0)            // false
BooleanOrFalse(null)         // false (default)
BooleanOrFalse(undefined)    // false (default)

BooleanFromNumericString("1") // true
BooleanFromNumericString("0") // false
```

### String - Преобразование в string

```typescript
import { 
  StringOrUndefined, 
  StringOrNull, 
  StringOrEmpty, 
  StringTrimmedOrUndefined 
} from 'adapter-utils';

StringOrUndefined(123)       // "123"
StringOrUndefined(null)      // undefined
StringOrUndefined("")        // ""

StringOrNull("hello")        // "hello"
StringOrNull("")             // null
StringOrNull(null)           // null

StringOrEmpty("hello")       // "hello"
StringOrEmpty(null)          // ""
StringOrEmpty(undefined)     // ""

StringTrimmedOrUndefined("  hello  ")  // "hello"
StringTrimmedOrUndefined("   ")        // undefined
StringTrimmedOrUndefined(null)         // undefined
```

### Number - Преобразование в number

```typescript
import { NumberOrUndefined, NumberOrNull } from 'adapter-utils';

NumberOrUndefined("123")     // 123
NumberOrUndefined("abc")     // undefined (NaN → undefined)
NumberOrUndefined(null)      // undefined

NumberOrNull("456")          // 456
NumberOrNull("abc")          // null (NaN → null)
NumberOrNull(null)           // null
```

### Array - Преобразование в массив

```typescript
import { 
  ArrayOrEmptyArray, 
  ArrayOrUndefined, 
  ArrayOrNull 
} from 'adapter-utils';

// Базовое использование
ArrayOrEmptyArray(5)               // [5]
ArrayOrEmptyArray([1, 2, 3])       // [1, 2, 3]
ArrayOrEmptyArray(null)            // []

ArrayOrUndefined([1, 2])           // [1, 2]
ArrayOrUndefined(null)             // undefined
ArrayOrUndefined([])               // undefined (пустой массив)

ArrayOrNull([1, 2])                // [1, 2]
ArrayOrNull(null)                  // null

// С преобразователем
ArrayOrEmptyArray("5", Number)           // [5]
ArrayOrEmptyArray(["1", "2"], Number)    // [1, 2]
```

### Object - Работа с объектами

```typescript
import { 
  ObjectInstanceOrUndefined, 
  ObjectNonEmptyOrUndefined 
} from 'adapter-utils';

ObjectInstanceOrUndefined({ id: 1 })    // { id: 1 }
ObjectInstanceOrUndefined(null)         // undefined

ObjectNonEmptyOrUndefined({ id: 1 })    // { id: 1 }
ObjectNonEmptyOrUndefined({})           // undefined
ObjectNonEmptyOrUndefined({ a: undefined })  // undefined

// С преобразователем
class User {
  constructor(public name: string) {}
}

ObjectInstanceOrUndefined(
  { name: "John" },
  (data) => new User(data.name)
)  // User { name: "John" }
```

## Практический пример

### До (без adapter-utils):

```typescript
interface Raw {
  [key: string]: any;
}

class ShortService {
  public id: number;
  public type: string;
  public name: string | null;
  public price: number | undefined;
  public isCategory: boolean;
  public isActive: boolean;
  public isAutogen: boolean;
  public isReception: boolean;
  public tags: string[];
  public metadata: object | undefined;

  constructor(raw: Raw) {
    // Много повторяющегося кода и нет обработки edge cases
    this.id = Number(raw['id']);
    this.type = String(raw['type']);
    this.name = raw['name'] ? String(raw['name']) : null;
    this.price = raw['price'] ? Number(raw['price']) : undefined;
    this.isCategory = Boolean(raw['is_category']);
    this.isActive = Boolean(raw['is_active']);
    this.isAutogen = Boolean(raw['is_autogen_index']);
    this.isReception = Boolean(raw['is_reception']);
    
    // Проблема: что если raw['tags'] не массив?
    this.tags = Array.isArray(raw['tags']) ? raw['tags'] : [];
    
    // Нет проверки на пустой объект
    this.metadata = raw['metadata'] || undefined;
  }
}
```

### После (с adapter-utils):

```typescript
import {
  NumberOrUndefined,
  StringOrEmpty,
  StringOrNull,
  BooleanOrFalse,
  ArrayOrEmptyArray,
  ObjectNonEmptyOrUndefined,
} from 'adapter-utils';

interface Raw {
  [key: string]: any;
}

class ShortService {
  public id: number;
  public type: string;
  public name: string | null;
  public price: number | undefined;
  public isCategory: boolean;
  public isActive: boolean;
  public isAutogen: boolean;
  public isReception: boolean;
  public tags: string[];
  public metadata: object | undefined;

  constructor(raw: Raw) {
    // Чистый, безопасный и читаемый код
    this.id = NumberOrUndefined(raw['id']) ?? 0;
    this.type = StringOrEmpty(raw['type']);
    this.name = StringOrNull(raw['name']);
    this.price = NumberOrUndefined(raw['price']);
    this.isCategory = BooleanOrFalse(raw['is_category']);
    this.isActive = BooleanOrFalse(raw['is_active']);
    this.isAutogen = BooleanOrFalse(raw['is_autogen_index']);
    this.isReception = BooleanOrFalse(raw['is_reception']);
    this.tags = ArrayOrEmptyArray(raw['tags']);
    this.metadata = ObjectNonEmptyOrUndefined(raw['metadata']);
  }
}
```

## Преимущества

### 📖 Читаемость
- Явное указание fallback-значений (`OrTrue`, `OrFalse`, `OrEmpty`)
- Код самодокументируется

### 🔧 Гибкость
- Поддержка кастомных преобразователей для массивов и объектов
- Работает с любыми структурами данных

### ⚡ Производительность
- Минимальный overhead
- Tree-shakeable - в бандл попадает только используемый код

## TypeScript

Библиотека написана на TypeScript и полностью типизирована. Все функции имеют точные типы:

```typescript
// Boolean функции
import {
  BooleanOrUndefined,
  BooleanOrTrue,
  BooleanOrFalse,
  BooleanFromNumericString,
} from 'adapter-utils';

// String функции
import {
  StringOrUndefined,
  StringOrNull,
  StringOrEmpty,
  StringTrimmedOrUndefined,
  isUndefined,  // утилита для проверки null/undefined
} from 'adapter-utils';

// Number функции
import {
  NumberOrUndefined,
  NumberOrNull,
} from 'adapter-utils';

// Array функции
import {
  ArrayOrEmptyArray,
  ArrayOrUndefined,
  ArrayOrNull,
} from 'adapter-utils';

// Object функции
import {
  ObjectInstanceOrUndefined,
  ObjectNonEmptyOrUndefined,
} from 'adapter-utils';

// Вспомогательные функции
import {
  isUndefined,      // проверка на null/undefined
  toArray,          // преобразование в массив
  applyConverter,   // применение функции-конвертера
} from 'adapter-utils';
```

## Вспомогательные функции

Библиотека также экспортирует вспомогательные функции, которые вы можете использовать напрямую:

### isUndefined

Проверяет, является ли значение `null` или `undefined`:

```typescript
import { isUndefined } from 'adapter-utils';

isUndefined(null);      // true
isUndefined(undefined); // true
isUndefined(0);         // false
isUndefined("");        // false
```

### toArray

Преобразует значение в массив с опциональным конвертером:

```typescript
import { toArray } from 'adapter-utils';

toArray(5);                    // [5]
toArray([1, 2, 3]);            // [1, 2, 3]
toArray(null);                 // []
toArray("5", Number);          // [5]
toArray(["1", "2"], Number);   // [1, 2]
```

### applyConverter

Применяет функцию преобразования к значению:

```typescript
import { applyConverter } from 'adapter-utils';

applyConverter(10, (x) => x * 2);  // 20
applyConverter(10);                // 10 (без конвертера)
```