Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/fdorantesm/ts-ddd

A Typescript Domain Driven Design library
https://github.com/fdorantesm/ts-ddd

clean-architecture clean-code ddd domain domain-driven-design entity software-architecture software-design software-engineering ts-ddd typescript uncle-bob value-object

Last synced: about 2 months ago
JSON representation

A Typescript Domain Driven Design library

Awesome Lists containing this project

README

        

Typescript Domain-Driven Design





A set of utilities for Domain-Driven Design


## Packages

| Packages | Link |
| --------------------- | ----------------------------------------------------------------- |
| @ts-ddd/common | [Go to package](https://npmjs.com/package/@ts-ddd/common) |
| @ts-ddd/entity | [Go to package](https://npmjs.com/package/@ts-ddd/entity) |
| @ts-ddd/state-machine | [Go to package](https://npmjs.com/package/@ts-ddd/state-machine) |
| @ts-ddd/value-object | [Go to package](https://npmjs.com/package/@ts-ddd/value-object) |

### Common

#### UUID generator

```ts
import { uuidGenerator } from '@ts-ddd/common';

const uuid = uuidGenerator() // -> b9ebc3ea-bfbd-4a86-8b7b-39995b47c631
```

#### Interfaces

| Interface | Properties |
| -------------- | ------------------------------------------ |
| WithActive | isActive |
| WithAudit | createdBy, updatedBy and deletedBy as date |
| WithDomain | domain |
| WithLocale | locale |
| WithNullable | isNullable |
| WithOwner | ownerId |
| WithScope | scope |
| WithStatus | status |
| WithTimestamps | createdAt and deletedAt |
| WithUser | userId |
| WithUuid | uuid |
| WithVersion | version |

#### Example

```ts
interface Post extends WithActive, WithUuid {
title: string;
body: string;
}

/*
{
uuid: string;
title: string;
body: string;
isActive: boolean;
}
*/
```

### Entity

Use to create domain entities using an interface as contract.

```ts
export interface IBook {
id: Identifier;
name: string;
year: number;
publisher: string;
}

```

```ts
import { uuidGenerator } from '@ts-ddd/common';
import { Identifier, Entity } from '@ts-ddd/entity';
import { IBook } from '../interfaces/book.interface';

export class Book extends Entity {
public static createToPrimitives(payload: Omit) {
return new Book({
id: uuidGenerator(),
...payload
})
}

public static createFromPrimitives(payload: IBook): Book {
return new Book(payload)
}
}
```

#### Getting an object from the data source

```ts
class BooksService {
constructor(private readonly booksRepository: BooksRepository) {}

public async findBookById(id: string): Promise {
const book = await this.booksRepository.findOne({ id });

if (book) {
return Book.createFromPrimitives(book)
}

return undefined;
}
}
```

#### Creating a book to store it in the data source

```ts
class CreateBookUseCase {
constructor(private readonly booksService: BooksService) {}

public async execute(payload: Omit): Promise {
const book = await this.booksRepository.create(
Book.createToPrimitives(payload)
);

return book;
}
}
```

### State Machine

```ts
import { StateMachine } from '@ts-ddd/state-machine';

enum LightTransitions {
RED = "red",
GREEN = "green",
PULSING_GREEN = "pulsing_green",
AMBER = "amber",
}

const transitions = {
[LightTransitions.RED]: [LightTransitions.GREEN],
[LightTransitions.GREEN]: [LightTransitions.PULSING_GREEN],
[LightTransitions.PULSING_GREEN]: [LightTransitions.AMBER],
[LightTransitions.AMBER]: [LightTransitions.RED],
}

const light = StateMachine.instance({
transitions,
currentState: LightTransitions.RED,
});

try {
light.setState(LightTransitions.GREEN);
} catch (error) {
// InvalidStateTransitionException
}
```

### Value Object

```ts
import { StringValue } from '@ts-ddd/value-object'
import { validate, v4 as uuid } from 'uuid';

export class Uuid extends StringValue {
constructor(value: string) {
super(value);
this.ensureIsValidUuid(value);
}

static generate(): Uuid {
return new Uuid(uuid());
}

private ensureIsValidUuid(value: string): void {
if (!validate(value)) {
throw new Error(`${value} is not a valid UUID`)
}
}
}
```

```ts
import { StringValue } from '@ts-ddd/value-object'

export class Title extends StringValue {}
```

```ts
import { PositiveNumberValue } from '@ts-ddd/value-object'

export class Year extends PositiveNumberValue {}
```

```ts
class BooksRepository {
public async getBook(id: string): Promise {
const book = await this.booksRepository.findOne({ id });

if (!book) {
return undefined;
}

return Book.createFromPrimitives({
id: new Uuid(book.id),
title: new Title(book.title),
year: new Year(book.year)
})
}
}
```




---






github


twitter


linkedin


youtube