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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@nestjslatam/ddd-valueobjects

v1.3.0

Published

Domain-Driven Design Value Objects library for NestJS

Readme

@nestjslatam/ddd-valueobjects

Twelve ready-made value objects for @nestjslatam/ddd-lib — email, money, phone, document IDs, dates and more, each with its rules, formatters and equality already written.

npm CI tests license

Quick start · What is in the box · FAQ · Contributing


npm install @nestjslatam/ddd-valueobjects @nestjslatam/ddd-lib

Quick start

import { Money, MoneyFormatter, Email, BirthDate, DocumentId } from '@nestjslatam/ddd-valueobjects';

// Most value objects throw on invalid input.
const price = Money.create(1999, 'USD');
new MoneyFormatter().format(price); // '$1,999.00'

Money.create(10, 'XYZ');
// Invalid Money: Property: currency, Message: Currency code 'XYZ' is not
// a commonly recognized ISO 4217 code

// Email and UUID are the two that return a Result instead of throwing.
const email = Email.create('[email protected]');
email.isSuccess; // true
email.getValue().getValue(); // '[email protected]'

Email.create('not-an-email').getError(); // 'Email format is invalid'

// Anything that depends on "now" takes an optional reference date.
BirthDate.create(new Date('1990-06-15')).getAge(new Date('2026-08-28')); // 36

DocumentId.create('12345678', 'DNI', 'PE').getValue();
// { value: '12345678', type: 'DNI', country: 'PE' }

That reference-date parameter is the detail worth stealing even if you write your own: getAge, isMinor, isAdult, getNextBirthday, getDaysUntilBirthday and isBirthdayToday all accept one, so their behaviour is testable without freezing the clock.

What is in the box

| | | | ---------------------- | ------------------------------------------------------------------ | | Identity & contact | Email, PhoneNumber, Url, UUID, Name | | Money & numbers | Money, Percentage | | Time | BirthDate, DateRange, Age | | Documents | DocumentId — DNI, passport, driver's licence, SSN, tax ID, other | | Text | Description |

Plus formatters (MoneyFormatter alone has format, formatWithoutSymbol, formatWithCode, formatAccounting, formatCompact and formatAsWords), and services — ZodiacCalculatorService scores compatibility between two signs, BirthdayCalendarService finds upcoming birthdays and milestones.

Document validation is pluggable

DocumentId dispatches to a strategy per document type, and the registry is open:

class PeruvianDni implements IDocumentValidatorStrategy {
  readonly type = 'DNI';

  clean(value: string): string {
    return value.replace(/\D/g, '');
  }

  validate(value: string) {
    const errors = /^\d{8}$/.test(value)
      ? []
      : [{ field: 'value', message: 'A Peruvian DNI is 8 digits' }];
    return { isValid: errors.length === 0, errors };
  }
}

DocumentValidatorRegistry.registerStrategy(new PeruvianDni());
DocumentValidatorRegistry.getRegisteredTypes();
// ['DNI', 'PASSPORT', 'SSN', 'TAX_ID', 'DRIVER_LICENSE', 'OTHER']

The strategy carries its own type, so registering it replaces the built-in rules for that document type. Six strategies ship. Writing one for a country whose format you actually live with is the easiest useful contribution here.

Requirements

Node >=20.11, and @nestjslatam/ddd-lib as a peer — you install it yourself:

@nestjslatam/ddd-lib  ^2.0.0 || ^3.0.0
@nestjs/common        ^10.0.0 || ^11.0.0
@nestjs/core          ^10.0.0 || ^11.0.0
reflect-metadata      ^0.1.13 || ^0.2.0
rxjs                  ^7.2.0

[!IMPORTANT] 1.1.0 and earlier declared ddd-lib as a regular dependency, so installing them beside [email protected] gave you two copies:

@nestjslatam/ddd-lib                                3.0.0   isValid -> getter
@nestjslatam/ddd-valueobjects/node_modules/ddd-lib  2.1.2   isValid -> method

Two class identities, two shapes, and instanceof failing across them. It is a peer dependency from 1.2.0 on, which resolves to your single copy. Upgrade if you are on 1.1.0 or earlier and using ddd-lib 3.x.

Tests

npm install
npm test        # 32 suites, 681 tests, ~15s

They pass on a clean checkout, and the release pipeline goes further: it packs the tarball, installs it into an empty scratch project with nothing hand-installed, and require()s it under node --no-experimental-require-module. That flag matters — modern Node loads ESM through require() transparently, which hides ESM-only dependencies that break real CommonJS consumers. A sibling package shipped exactly that bug and nobody noticed until it was published.

FAQ

ddd-lib is required; it is the library everything else builds on. This package is optional — it saves you writing Email, Money and friends by hand. ddd-cli is a dev tool. ddd-es-lib is for event sourcing on MongoDB.

Yes, from 1.2.0. The peer range is ^2.0.0 || ^3.0.0, and the full 681-test suite was re-run against [email protected] before that range was widened. On 1.1.0 or earlier, see the warning in Requirements — you will silently get two copies of the library.

History, not design. Email and UUID are the two that return a Result; everything else throws on invalid input. Unifying them is a breaking change nobody has taken yet — it is on the list.

Probably not — it validates against commonly recognised ISO 4217 codes and rejects anything else with a message naming the code. If a legitimate code is missing, that is a one-line fix and a welcome PR.

For Email, mostly the tests. The ones that earn their keep are the ones with real surface area: Money with six formatters and ISO 4217 validation, DocumentId with six pluggable country strategies, BirthDate and DateRange with the reference-date discipline, and PhoneNumber. Wiring cost is one import — they are ordinary ddd-lib value objects.

It is more thoroughly tested than its siblings — 681 tests — but it sits on ddd-lib, whose API is explicitly unstable. Pin exact versions of both.

NestJS 10 or 11 declared, Node >=20.11. Only NestJS 11 is exercised in CI.

Contributing

Concrete, and each verifiable in minutes:

  1. A document strategy for a country you know. DocumentValidatorRegistry.registerStrategy() is the extension point and six strategies already show the shape. Rules written by someone who actually lives with the format beat rules written from a spec.
  2. Fix Result's own error message. getValue() on a failed result says "Use errorValue instead", but the method is getError(). One line, in libs/ddd-valueobjects/src/core/result.ts.
  3. Unify create(). Email and UUID return a Result while the other ten throw. Pick one — it is breaking, so it needs a major and a migration note.
  4. Document Description and Url. Both have the richest option-driven APIs here and neither appears in this README.

Before opening a PR:

npm run lint && npm test

Commits follow Conventional Commits.

Building and publishing

npm run build uses nest build, which bundles with webpack and emits no declarations — not publishable. npm run build:lib compiles with tsc and derives the published manifest, and the package is published from dist/libs/ddd-valueobjects so subpath imports resolve without an exports map.

[!TIP] The CLI's full guide → — every command and flag, walked through by building a complete domain from nothing into ten type-checking files. Worth reading even if you never install the CLI: it is the clearest write-up of this library's idiom anywhere, because every claim in it was produced by running the tool.

Who is behind this

Built and maintained by BeyondNet Tech with the NestJS Latam community.

  • Evolith — executable architecture governance: a CLI, MCP server and REST API that check a repository against Rego/OPA rules, reporting a rule they could not evaluate as a failure rather than a silent pass.
  • Shell.ddd — the .NET counterpart of ddd-lib.

License

MIT — see LICENSE.


Powered by BeyondNetCode

Website · GitHub · NestJS Latam