npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

smart-value-objects

v3.0.28

Published

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

Downloads

104

Readme

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;
  }