@lucaspaganini/value-objects
Version:
TypeScript first validation and class creation library
121 lines • 4.81 kB
JavaScript
;
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