3.0.28 • Published 21 days ago

smart-value-objects v3.0.28

Weekly downloads
-
License
ISC
Repository
github
Last release
21 days ago

smart-value-objects

A Typescript library of classes aimed to help developers using and undestanding immutable objects.

You are invited to build other value objects with me and together we can expand the scope of this lib. Feel free to contribute code or your opinions.

https://github.com/rtsarakaki/value-objects

Installation

yarn add smart-value-objects
or
npm install smart-value-objects

What are value objects?

Value Objects are immutable objects that represent a value within the application domain. They are used to encapsulate and validate values ​​that do not have their own identity. In other words, they are objects that represent a value but do not have a unique identifier.

See too: What are and when to use value objects?

👀 Usage example

import { GenericEntity } from 'smart-value-objects/dist/Types';
import { CompanyName, ISBN10, ISBN13, Language, PositiveNumber, SingleWord, Title, UUID, createUUID } from 'smart-value-objects/dist/ValueObjects';

export const BookInitial: BookModel = {
  id: '',
  title: '',
  isbn10: '',
  isbn13: '',
  pages: 0,
  language: '',
  publisher: '',
  publishedIn: new Date()
};

export type BookModel = {
  id: string;
  title: string;
  isbn10: string;
  isbn13: string;
  pages: number;
  language: string;
  publisher: string;
  publishedIn: Date
};

export default class Book extends GenericEntity {
  _id: UUID;
  _title: Title;
  _isbn10: ISBN10;
  _isbn13: ISBN13;
  _pages: PositiveNumber;
  _language: Language;
  _publisher: CompanyName;
  _publishedIn: Date

  constructor(public props: BookModel) {
    super();

    this._uid = this.initProp(this, createUUID(props?.id, 'Internal ID'));
    this._title = this.initProp(this, new SingleWord(props?.title, 'Title'));
    this._isbn10 = this.initProp(this, new ISBN10(props?.isbn10, 'ISBN 10'));
    this._isbn13 = this.initProp(this, new ISBN13(props?.isbn13, 'ISBN 13'));
    this._pages = this.initProp(this, new PositiveNumber(props?.pages, 'Title'));
    this._language = this.initProp(this, new Language(props?.language, 'Title'));
    this._publisher = this.initProp(this, new CompanyName(props?.publisher, 'Title'));
    this._publishedIn = props?.publishedIn;
  }

  get id() {
    return this._id.value;
  }

  get key() {
    return this.id;
  }

  get title() {
    return this._title.value;
  }

  get isbn10() {
    return this._isbn10.value;
  }

  get isbn13() {
    return this._isbn13.value;
  }

  get pages() {
    return this._pages.value;
  }

  get language() {
    return this._language.value;
  }

  get publisher() {
    return this._publishedIn;
  }

  get publishedIn() {
    return this._publisher.value;
  }


  toJson() {
    const fields = {
      id: this.uid,
      title: this.title,
      isbn10: this.this.isbn10,
      isbn13: this.isbn13,
      pages: this.pages,
      language: this.language,
      publisher: this.publisher,
      publishedIn: this.publishedIn,
      key: this.uid,
      sort: this.title,
    };
    return fields;
  }
}

Now, lets go in parts

Model DTO

When creating your entities using value objects, you will want to have DTOs to interact with the frontend. So, in this code snippet we create a model to transport and receive data.

export type BookModel = {
  id: string;
  title: string;
  isbn10: string;
  isbn13: string;
  pages: number;
  language: string;
  publisher: string;
  publishedIn: Date
};

Initial state

Now we need an object to set the initial state of entity.

export const BookInitial: BookModel = {
  id: '',
  title: '',
  isbn10: '',
  isbn13: '',
  pages: 0,
  language: '',
  publisher: '',
  publishedIn: new Date()
};

Class declaration

The entity must inherit GenericEntity, which will facilitate the validation of properties and return of errors found when filling out.

export default class Book extends GenericEntity {

Internal class properties

Here, we start using value objects to define the type of properties.

Note that not all properties need to be a value object. In this example, the _publishedIn property is not using a value object from the library, as we understand that a Date type is already an intelligent type and that validates its own content. This case can also be applied to Boolean values ​​that simply receive true or false, or other types that do not have validations or formatting.

  _id: UUID;
  _title: Title;
  _isbn10: ISBN10;
  _isbn13: ISBN13;
  _pages: PositiveNumber;
  _language: Language;
  _publisher: CompanyName;
  _publishedIn: Date

Initializing the entity

The class constructor must receive the object with data with the same type as the model and initialize each of the properties using the initProp method, which will validate the value object and accumulate errors in the entity's error collection. So after all properties are filled in you will have a list of all errors in the errors property.

If there is any error in this list, the entity's isValid property will be false and if there is no error in the list, then the entity will be valid.

  constructor(public props: BookModel) {
    super();

    this._uid = this.initProp(this, createUUID(props?.id, 'Internal ID'));
    this._title = this.initProp(this, new SingleWord(props?.title, 'Title'));
    this._isbn10 = this.initProp(this, new ISBN10(props?.isbn10, 'ISBN 10'));
    this._isbn13 = this.initProp(this, new ISBN13(props?.isbn13, 'ISBN 13'));
    this._pages = this.initProp(this, new PositiveNumber(props?.pages, 'Title'));
    this._language = this.initProp(this, new Language(props?.language, 'Title'));
    this._publisher = this.initProp(this, new CompanyName(props?.publisher, 'Title'));
    this._publishedIn = props?.publishedIn;
  }

Properties

For each of the properties, you can create a get to expose the value so they can be accessed.

  get title() {
    return this._title.value;
  }

Map properties to a json object

The toJson() method is used to map the entity's values ​​to a json that can be sent by use cases so that the data can be persisted or displayed in fronend.

    toJson() {
    const fields = {
      id: this.uid,
      title: this.title,
      isbn10: this.this.isbn10,
      isbn13: this.isbn13,
      pages: this.pages,
      language: this.language,
      publisher: this.publisher,
      publishedIn: this.publishedIn,
      key: this.uid,
      sort: this.title,
    };
    return fields;
  }
3.0.27

21 days ago

3.0.28

21 days ago

3.0.26

21 days ago

3.0.24

5 months ago

3.0.25

5 months ago

2.4.0

6 months ago

3.0.2

6 months ago

3.0.1

6 months ago

3.0.0

6 months ago

3.0.23

5 months ago

3.0.21

5 months ago

3.0.22

5 months ago

2.3.2

6 months ago

2.3.1

6 months ago

1.2.0

8 months ago

1.2.8

8 months ago

1.2.7

8 months ago

1.2.6

8 months ago

1.2.5

8 months ago

1.2.4

8 months ago

1.4.0

7 months ago

1.2.2

8 months ago

1.2.1

8 months ago

2.2.1

7 months ago

2.0.3

7 months ago

2.2.0

7 months ago

2.0.2

7 months ago

2.2.3

7 months ago

2.0.5

7 months ago

2.2.2

7 months ago

2.0.4

7 months ago

2.2.5

7 months ago

2.0.7

7 months ago

2.2.4

7 months ago

2.0.6

7 months ago

2.2.7

7 months ago

2.2.6

7 months ago

2.0.1

7 months ago

2.0.0

7 months ago

0.0.0-development

8 months ago

1.5.3

7 months ago

1.5.2

7 months ago

1.5.1

7 months ago

1.3.1

7 months ago

1.3.0

7 months ago

2.3.0

7 months ago

2.1.2

7 months ago

2.1.1

7 months ago

2.1.0

7 months ago

1.2.9

8 months ago

1.1.23

8 months ago

1.1.22

8 months ago

1.1.27

8 months ago

1.1.26

8 months ago

1.1.25

8 months ago

1.1.24

8 months ago

1.1.21

8 months ago

1.1.20

8 months ago

1.1.19

8 months ago

1.1.18

8 months ago

1.1.17

8 months ago

1.1.16

8 months ago

1.1.13

8 months ago

1.1.12

8 months ago

1.1.11

8 months ago

1.1.6

8 months ago

1.1.5

8 months ago

1.1.4

8 months ago

1.1.3

8 months ago

1.1.2

8 months ago

1.1.1

8 months ago