@crysteam/dto (0.1.13)

Published 2025-06-05 18:57:19 +00:00 by Kiefe

Installation

@crysteam:registry=
npm install @crysteam/dto@0.1.13
"@crysteam/dto": "0.1.13"

About this package

Crysteam.DTO

Универсальная библиотека для работы с DTO (Data Transfer Objects) в TypeScript. Поддерживает группы полей, вложенные DTO, валидацию, версионирование и многое другое.

Установка

npm install @crysteam/dto

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

  • 🎯 Группировка полей для разных сценариев сериализации
  • 🔄 Вложенные DTO
  • Валидация полей
  • 📦 Версионирование DTO и полей
  • 🔄 Трансформация значений
  • ⚠️ Поддержка устаревших полей
  • 🎨 Гибкая настройка сериализации

Примеры использования

Базовое использование

import { DTO, Field } from '@crysteam/dto';

class UserDTO extends DTO {
    @Field()
    id: number;

    @Field()
    name: string;

    @Field()
    email: string;
}

// Создание DTO
const user = new UserDTO({
    id: 1,
    name: 'John Doe',
    email: 'john@example.com'
});

// Сериализация в объект
const data = user.toObject();
console.log(data);
// { id: 1, name: 'John Doe', email: 'john@example.com' }

Группы полей

import { DTO, Field } from '@crysteam/dto';

class UserDTO extends DTO {
    @Field()
    id: number;

    @Field({ groups: ['public'] })
    name: string;

    @Field({ groups: ['private'] })
    email: string;

    @Field({ groups: ['admin'] })
    password: string;
}

const user = new UserDTO({
    id: 1,
    name: 'John Doe',
    email: 'john@example.com',
    password: 'secret123'
});

// Сериализация с группой 'public'
console.log(user.toObject({ group: 'public' }));
// { id: 1, name: 'John Doe' }

// Сериализация с группой 'private'
console.log(user.toObject({ group: 'private' }));
// { id: 1, name: 'John Doe', email: 'john@example.com' }

Вложенные DTO

import { DTO, Field } from '@crysteam/dto';

class AddressDTO extends DTO {
    @Field()
    street: string;

    @Field()
    city: string;
}

class UserDTO extends DTO {
    @Field()
    id: number;

    @Field()
    name: string;

    @Field(() => AddressDTO)
    address: AddressDTO;
}

const user = new UserDTO({
    id: 1,
    name: 'John Doe',
    address: {
        street: '123 Main St',
        city: 'New York'
    }
});

console.log(user.toObject());
// {
//   id: 1,
//   name: 'John Doe',
//   address: {
//     street: '123 Main St',
//     city: 'New York'
//   }
// }

Вложенные DTO с группами

import { DTO, Field } from '@crysteam/dto';

class AddressDTO extends DTO {
    @Field()
    id: number;

    @Field({ groups: ['public'] })
    street: string;

    @Field({ groups: ['public'] })
    city: string;

    @Field({ groups: ['private'] })
    postalCode: string;

    @Field({ groups: ['admin'] })
    coordinates: {
        lat: number;
        lng: number;
    };
}

class UserDTO extends DTO {
    @Field()
    id: number;

    @Field({ groups: ['public'] })
    name: string;

    @Field({ groups: ['private'] })
    email: string;

    @Field(() => AddressDTO, { groups: ['public', 'private'] })
    address: AddressDTO;
}

const user = new UserDTO({
    id: 1,
    name: 'John Doe',
    email: 'john@example.com',
    address: {
        id: 1,
        street: '123 Main St',
        city: 'New York',
        postalCode: '10001',
        coordinates: {
            lat: 40.7128,
            lng: -74.0060
        }
    }
});

// Сериализация с группой 'public'
console.log(user.toObject({ group: 'public' }));
// {
//   id: 1,
//   name: 'John Doe',
//   address: {
//     id: 1,
//     street: '123 Main St',
//     city: 'New York'
//   }
// }

// Сериализация с группой 'private'
console.log(user.toObject({ group: 'private' }));
// {
//   id: 1,
//   name: 'John Doe',
//   email: 'john@example.com',
//   address: {
//     id: 1,
//     street: '123 Main St',
//     city: 'New York',
//     postalCode: '10001'
//   }
// }

// Сериализация с группой 'admin'
console.log(user.toObject({ group: 'admin' }));
// {
//   id: 1,
//   name: 'John Doe',
//   email: 'john@example.com',
//   address: {
//     id: 1,
//     street: '123 Main St',
//     city: 'New York',
//     postalCode: '10001',
//     coordinates: {
//       lat: 40.7128,
//       lng: -74.0060
//     }
//   }
// }

Валидация

import { DTO, Field } from '@crysteam/dto';

class UserDTO extends DTO {
    @Field({
        required: true,
        validate: (value) => value.length >= 3 || 'Name must be at least 3 characters'
    })
    name: string;

    @Field({
        required: true,
        validate: (value) => {
            const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
            return emailRegex.test(value) || 'Invalid email format';
        }
    })
    email: string;
}

const user = new UserDTO({
    name: 'Jo', // Слишком короткое имя
    email: 'invalid-email' // Неверный формат email
});

const validation = user.validate();
console.log(validation);
// {
//   isValid: false,
//   errors: [
//     {
//       field: 'name',
//       message: 'Name must be at least 3 characters',
//       value: 'Jo'
//     },
//     {
//       field: 'email',
//       message: 'Invalid email format',
//       value: 'invalid-email'
//     }
//   ]
// }

Версионирование

import { DTO, Field, Version } from '@crysteam/dto';

@Version(2)
class UserDTO extends DTO {
    @Field()
    id: number;

    @Field()
    name: string;

    @Field({ version: 2 })
    email: string;

    @Field({ version: 3 })
    phone: string;
}

const user = new UserDTO({
    id: 1,
    name: 'John Doe',
    email: 'john@example.com',
    phone: '+1234567890'
});

// Сериализация версии 1
console.log(user.toObject({ version: 1 }));
// { id: 1, name: 'John Doe' }

// Сериализация версии 2
console.log(user.toObject({ version: 2 }));
// { id: 1, name: 'John Doe', email: 'john@example.com' }

Трансформация значений

import { DTO, Field } from '@crysteam/dto';

class UserDTO extends DTO {
    @Field({
        transform: (value) => value.toLowerCase()
    })
    email: string;

    @Field({
        transform: (value) => new Date(value)
    })
    createdAt: Date;
}

const user = new UserDTO({
    email: 'JOHN@EXAMPLE.COM',
    createdAt: '2024-02-20T12:00:00Z'
});

console.log(user.toObject());
// {
//   email: 'john@example.com',
//   createdAt: Date
// }

Устаревшие поля

import { DTO, Field } from '@crysteam/dto';

class UserDTO extends DTO {
    @Field()
    id: number;

    @Field()
    name: string;

    @Field({ deprecated: true })
    oldField: string;
}W

const user = new UserDTO({
    id: 1,
    name: 'John Doe',
    oldField: 'old value'
});

// Обычная сериализация
console.log(user.toObject());
// { id: 1, name: 'John Doe' }

// Сериализация с включением устаревших полей
console.log(user.toObject({ includeDeprecated: true }));
// { id: 1, name: 'John Doe', oldField: 'old value' }

Дополнительные возможности

Клонирование DTO

const user = new UserDTO({
    id: 1,
    name: 'John Doe'
});

const clone = user.clone();

Статический метод создания

const user = UserDTO.from({
    id: 1,
    name: 'John Doe'
});

Указание групп для дочерних DTO при сериализации

import { DTO, Field } from '@crysteam/dto';

class OwnerDTO extends DTO {
    @Field({ groups: ['public'] })
    name: string;

    @Field({ groups: ['private'] })
    email: string;

    @Field({ groups: ['admin'] })
    phone: string;
}

class CardDTO extends DTO {
    @Field()
    id: number;

    @Field({ groups: ['public'] })
    number: string;

    @Field(() => OwnerDTO)
    owner: OwnerDTO;
}

const card = new CardDTO({
    id: 1,
    number: '1234-5678-9012-3456',
    owner: {
        name: 'John Doe',
        email: 'john@example.com',
        phone: '+1234567890'
    }
});

// Сериализация с разными группами для разных полей
console.log(card.toObject({ 
    group: 'public',
    childGroups: {
        'owner': 'private',  // owner будет сериализован с группой 'private'
        'otherField': 'admin' // другое поле с группой 'admin'
    }
}));
// {
//   id: 1,
//   number: '1234-5678-9012-3456',
//   owner: {
//     name: 'John Doe',
//     email: 'john@example.com'  // private группа для owner
//   }
// }

// Другой пример с разными группами
console.log(card.toObject({ 
    group: 'public',
    childGroups: {
        'owner': 'admin'  // owner будет сериализован с группой 'admin'
    }
}));
// {
//   id: 1,
//   number: '1234-5678-9012-3456',
//   owner: {
//     name: 'John Doe',
//     email: 'john@example.com',
//     phone: '+1234567890'  // admin группа для owner
//   }
// }

// Если группа не указана в childGroups, используется группа родительского DTO
console.log(card.toObject({ group: 'public' }));
// {
//   id: 1,
//   number: '1234-5678-9012-3456',
//   owner: {
//     name: 'John Doe'  // public группа для owner (та же, что и у CardDTO)
//   }
// }

В этом примере:

  1. Мы указываем группы для дочерних DTO при вызове toObject
  2. Используем опцию childGroups для определения групп
  3. Ключ в childGroups - это имя поля с дочерним DTO
  4. Значение - группа, которую нужно использовать для этого DTO
  5. Если группа не указана в childGroups, используется группа родительского DTO

Это позволяет:

  • Гибко управлять группами дочерних DTO при сериализации
  • Использовать разные группы для разных полей
  • Сохранять обратную совместимость

API Reference

Декораторы

@Field(options?: FieldOptions)

Декоратор для определения поля DTO.

Опции:

  • groups?: string[] - группы, к которым принадлежит поле
  • default?: any - значение по умолчанию
  • type?: () => any - тип поля (для вложенных DTO)
  • required?: boolean - обязательное ли поле
  • nullable?: boolean - может ли быть null
  • transform?: (value: any) => any - функция трансформации значения
  • validate?: (value: any) => boolean | string - функция валидации
  • version?: number - версия поля
  • deprecated?: boolean - устаревшее ли поле
  • description?: string - описание поля

@Version(version: number)

Декоратор для определения версии DTO.

Методы

constructor(partial: any, options?: SerializationOptions)

Создает новый экземпляр DTO.

toObject(options?: SerializationOptions): any

Сериализует DTO в объект.

Опции:

  • group?: string - группа для сериализации
  • version?: number - версия для сериализации
  • includeDeprecated?: boolean - включать ли устаревшие поля
  • transformNulls?: boolean - трансформировать ли null значения

validate(): ValidationResult

Валидирует DTO.

clone(): this

Создает клон DTO.

static from<T extends DTO>(data: any, options?: SerializationOptions): T

Статический метод для создания DTO.

Лицензия

MIT

Dependencies

Dependencies

ID Version
msgpackr ^1.11.4
reflect-metadata ^0.1.13

Development Dependencies

ID Version
@types/node ^22.15.29
@types/reflect-metadata ^0.1.0
ts-node ^10.9.2
typescript ^5.8.3
Details
npm
2025-06-05 18:57:19 +00:00
142
Crysteam
ISC
12 KiB
Assets (1)
Versions (16) View all
0.1.14 2025-06-25
0.1.13 2025-06-05
0.1.12 2025-06-05
0.1.11 2025-06-05
0.1.10 2025-06-05