UNPKG

@thisisagile/easy

Version:

Straightforward library for building domain-driven microservice architectures

62 lines (45 loc) 2.1 kB
import { validate } from './Validate'; import { Results } from '../types/Results'; import { Constructor } from '../types/Constructor'; import { Get, ofGet, Predicate } from '../types/Get'; import { isDefined, isEmpty, isIn } from '../types/Is'; import { toArray } from '../types/Array'; import { ErrorOrigin } from '../types/ErrorOrigin'; import { reject, resolve } from '../utils/Promise'; import { Exception } from '../types/Exception'; export class When<W> { constructor( readonly subject: W, readonly valid = true, private results?: Results ) {} get not(): When<W> { return this.clone(!this.valid); } get and(): When<W> { return this.clone(this.valid); } get isDefined(): When<W> { return this.clone(this.valid === isDefined(this.subject)); } get isEmpty(): When<W> { return this.clone(this.valid === isEmpty(this.subject)); } get isTrue(): When<W> { return this.clone(this.valid === !!this.subject); } get isValid(): When<W> { this.results = validate(this.subject); return this.clone(this.valid === this.results.isValid); } isInstance = <U>(c: Constructor<U>): When<W> => this.clone(this.valid === this.subject instanceof c); with = (pred: Predicate<W>): When<W> => this.clone(this.valid === ofGet(pred, this.subject)); contains = (property: (w: W) => unknown): When<W> => this.clone(this.valid === isDefined(ofGet(property, this.subject))); in = (...items: W[]): When<W> => this.clone(this.valid === isIn(this.subject, toArray(...items))); is = (item: W): When<W> => this.clone(this.valid === (this.subject === item)); reject = (error?: Get<ErrorOrigin, W>): Promise<NonNullable<W>> => !this.valid ? resolve(this.subject as NonNullable<W>) : reject(ofGet(error, this.subject) ?? this.results ?? Exception.Unknown); recover = (f: (item: W) => W | Promise<W>): Promise<W> => resolve(!this.valid ? this.subject : f(this.subject)); protected clone = (result = true): When<W> => new When(this.subject, result, this.results); } export const when = <T>(subject: T): When<T> => new When<T>(subject);