npm package: @pjts/core
Description: Piotr Józefów DDD utility package
Author: Piotr Józefów
Latest version: 0.0.81

# Domain-Driven Design TypeScript Utilities / Core

Collection of decorators and utility classes for building TypeScript Web Apps following DDD tactical design patterns.

## Installation

```bash
npm install @pjts/core
```

## Core Features

### HTTP Module and Service Decorators

The package provides decorators for building HTTP APIs with TypeScript:

```typescript
import { HttpModule, AppService, Post, Body } from '@pjts/core';

@HttpModule('/api/v1')
class UserModule {
  public get userService() {
    return new UserService()
  }
}
```

```typescript
@AppService
class UserService {
  @Post
  createUser(@Body user: CreateUserDto) {
    // Implementation
  }
}
```

#### HTTP Method Decorators
- `@Get()` - Marks a method as a GET endpoint
- `@Post()` - Marks a method as a POST endpoint
- `@Put()` - Marks a method as a PUT endpoint
- `@Patch()` - Marks a method as a PATCH endpoint
- `@Delete()` - Marks a method as a DELETE endpoint

#### Parameter Decorators
- `@QueryParam` - Retrieves a single query parameter
- `@QueryParams` - Retrieves all query parameters as an object
- `@UrlParam` - Retrieves URL path parameters
- `@Body` - Retrieves request body
- `@File` - Handles file uploads
- `@Header(key?)` - Retrieves HTTP header
- `@Auth` - Retrieves authorization header
- `@Middleware(key?)` - Registers middleware
- `@Ip` - Retrieves IP requester's IP address

### Domain Primitives

The package provides decorators for creating type-safe domain primitives:

```typescript
import { StringDomainPrimitive, NumberDomainPrimitive } from '@pjts/core';

@StringDomainPrimitive
class Email {
  constructor(public readonly value: string) {
    if (!value.includes('@')) throw new Error('Invalid email');
  }
}

@NumberDomainPrimitive
class Age {
  constructor(public readonly value: number) {
    if (value < 0) throw new Error('Age cannot be negative');
  }
}
```

#### Domain Primitive Decorators
- `@StringDomainPrimitive` - Creates string-based value objects
- `@NumberDomainPrimitive` - Creates number-based value objects
- `@ObjectDomainPrimitive` - Creates complex object value objects
- `@StringArrayDomainPrimitive` - Creates string array value objects
- `@NullBoolDomainPrimitive` - Creates nullable boolean value objects

### Data Transfer Objects (DTOs)

The package supports class-validator for DTO validation:

```typescript
import { Dto } from '@pjts/core';
import { IsString, IsEmail, Length } from 'class-validator';

@Dto
class CreateUserDto {
  @IsString()
  @Length(2, 50)
  name!: string;

  @IsEmail()
  email!: string;
}
```

### Trackable Entities

The `@trackable` decorator and its utility functions help track changes in your domain entities:

```typescript
import { trackable, isChanged, getChangedProperties } from '@pjts/core';

@trackable
class User {
  constructor(public name: string) {}
}
```

#### Trackable API

- `markAsRestored<T>(instance: T): T` - Marks an entity instance as restored from persistence
- `isNew(instance: any): boolean` - Checks if an entity is newly created
- `getVersion(instance: any): number | null` - Gets the version of an entity
- `setVersion(instance: any, record: any): void` - Sets the version of an entity
- `getChangedProperties<T>(instance: T): Partial<T>` - Returns changed properties of a trackable entity
- `isChanged(instance: any): boolean` - Checks if a trackable entity has been modified

### Event Sourcing

The `EventSourceable` base class provides event sourcing capabilities:

```typescript
import { EventSourceable, Message } from '@pjts/core';

class UserEvent implements Message {
  uuid!: string;
  aggregateId!: string;
  timestamp!: Date;
}

class User extends EventSourceable<UserEvent> {
  protected id: string;
  
  protected apply(event: UserEvent): void {
    // Apply event logic
  }
}
```

#### Event Sourcing API

- `getPublishedEvents<E extends Message>(instance: EventSourceable<E>): E[]` - Retrieves all published events
- `applyEvents<E extends Message>(instance: EventSourceable<E>, events: E[])` - Applies a list of events to an entity
- `EventSourceable` abstract class methods:
  - `protected emit(events: EventBody<EventType>[] | EventBody<EventType>): void` - Emits new events
  - `protected apply(event: EventType): void` - Abstract method to handle event application
  - `protected uuidFrom(uuid: string): string` - Generates a deterministic UUID

### Error Handling

The package provides a standardized error handling system:

```typescript
import { AppError } from '@pjts/core';

// Usage examples
throw AppError.notFound('User not found');
throw AppError.badRequest('Invalid input');
throw AppError.unauthorizedAccess();
```

#### Error Types
- `AppError.notFound(message)` - 404 Not Found
- `AppError.badRequest(message)` - 400 Bad Request
- `AppError.illegalParameter(key?)` - 400 Bad Request for invalid parameters
- `AppError.unauthorizedAccess()` - 403 Unauthorized
- `AppError.internalServerError(message)` - 500 Internal Server Error
- `AppError.badGateway(message?)` - 502 Bad Gateway
- `AppError.notImplemented()` - 500 Not Implemented

### OpenAPI Integration

The package automatically generates OpenAPI schemas for your DTOs and domain primitives:

```typescript
import { getOpenAPISchemas } from '@pjts/core';

// Get OpenAPI schemas for all registered types
const schemas = getOpenAPISchemas();
```

## License

MIT License - see LICENSE file for details