UNPKG

@lucaspaganini/value-objects

Version:

TypeScript first validation and class creation library

121 lines 4.81 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.VOOptional = void 0; var utils_1 = require("../utils"); var errors_1 = require("./errors"); var NONEABLES = [undefined, null]; var isNoneable = function (v) { return NONEABLES.includes(v); }; var expectedNoneableTypes = function (nones) { return Array.from(new Set(nones.map(function (v) { return (utils_1.isUndefined(v) ? 'undefined' : 'null'); }))); }; /** * Function to create an optional value object constructor. * * @template VOC Value object constructor to make optional. * @template None Values that represent nothing. Defaults to `undefined`. * @param VOC Value object constructor to make optional. * @param nones Values that represent nothing. Defaults to `[undefined]`. * @returns Class constructor that accepts a None or the given * value object raw initial value for instantiation and returns * that value or the None value when {@link VOOptionalInstance.valueOf} is called. * * * The class created by `VOOptional` ({@link VOOptionalInstance}) wraps the * inner class and exposes it through the `value` property when it's instantiated. * Calling {@link VOOptionalInstance.valueOf} will either return the `None` value * or the `valueOf()` from the inner class. * * @example * ```typescript * class Name extends VOString({ trim: true, maxLength: 256, minLength: 1 }) {} * new Name('Lucas Paganini'); // OK * new Name(undefined); // Compilation error: Not a string * new Name(null); // Compilation error: Not a string * * class OptionalName extends VOOptional(Name) {} * new OptionalName('Lucas Paganini'); // OK * new OptionalName(undefined); // OK * new OptionalName(null); // Compilation error: Expects string | undefined * * const name = new Name('Lucas Paganini'); // OK * name.valueOf(); // "Lucas Paganini" * * const optional1 = new OptionalName('Lucas Paganini'); // OK * optional1.value; // Name instance * optional1.valueOf(); // "Lucas Paganini" * * const optional2 = new OptionalName(undefined); // OK * optional2.value; // undefined * optional2.valueOf(); // undefined * ``` * * This function has no options but it does accept a second parameter which * indicates what values should be considered nothing. * For default, it only accepts `undefined`, but you can change that to * _also_ accept `null` or maybe to _just_ accept `null`. * * @example * ```typescript * class Name extends VOString({ trim: true, maxLength: 256, minLength: 1 }) {} * new Name('Lucas Paganini'); // OK * new Name(undefined); // Compilation error: Not a string * new Name(null); // Compilation error: Not a string * * class OptionalName1 extends VOOptional(Name) {} * new OptionalName1('Lucas Paganini'); // OK * new OptionalName1(undefined); // OK * new OptionalName1(null); // Compilation error: Expects string | undefined * * class OptionalName2 extends VOOptional(Name, [undefined, null]) {} * new OptionalName2('Lucas Paganini'); // OK * new OptionalName2(undefined); // OK * new OptionalName2(null); // OK * * class OptionalName3 extends VOOptional(Name, [null]) {} * new OptionalName3('Lucas Paganini'); // OK * new OptionalName3(undefined); // Compilation error: Expects string | null * new OptionalName3(null); // OK * ``` */ var VOOptional = function (VOC, nones) { var _nones = nones !== null && nones !== void 0 ? nones : [undefined]; for (var _i = 0, _a = Object.entries(_nones); _i < _a.length; _i++) { var _b = _a[_i], i = _b[0], v = _b[1]; if (!isNoneable(v)) throw new errors_1.RawTypeError(NONEABLES.join(' | '), v, "nones[" + i + "]"); } var isInNones = function (v) { return _nones.includes(v); }; var expectedTypes = expectedNoneableTypes(_nones); return /** @class */ (function () { function class_1(raw) { if (isInNones(raw)) { this.value = raw; return; } try { var valueObject = new VOC(raw); this.value = valueObject; } catch (err) { if (errors_1.RawTypeError.is(err)) { ; err.expected += ' | ' + expectedTypes.join(' | '); } throw err; } } class_1.prototype.isSome = function () { return !this.isNone(); }; class_1.prototype.isNone = function () { return isInNones(this.value); }; class_1.prototype.valueOf = function () { var _a; return this.isNone() ? this.value : (_a = this.value) === null || _a === void 0 ? void 0 : _a.valueOf(); }; return class_1; }()); }; exports.VOOptional = VOOptional; //# sourceMappingURL=optional.js.map