@lucaspaganini/value-objects
Version:
TypeScript first validation and class creation library
136 lines • 6.06 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.VOArray = void 0;
var utils_1 = require("../utils");
var errors_1 = require("./errors");
var functions_1 = require("./functions");
/**
* Function to create an array wrapper over a given value object constructor.
* Useful if you already have a class and you need an array of it.
*
* @template VOC Value object constructor to make an array wrapper of.
* @param VOC Value object constructor to make an array wrapper of.
* @param options Customizations for the returned class constructor.
* @return Class constructor that accepts an array of what the given
* value object constructor would accept. Calling {@link VOArrayInstance.valueOf}
* calls `valueOf()` for all it's inner instances and returns an array of the results.
*
* @example
* ```typescript
* class Email extends VOString({ ... }) {
* getHost(): string { ... }
* }
*
* class EmailsArray extends VOArray(Email) {}
* new EmailsArray(['me@lucaspaganini.com', 'test@example.com']); // OK
* new EmailsArray([123]); // Compilation error: Expects Array<string>
* new EmailsArray(['invalid-email']); // Runtime error: Value doesn't match pattern
*
* const emails = new EmailsArray(['me@lucaspaganini.com', 'test@example.com']);
* emails.valueOf(); // ['me@lucaspaganini.com', 'test@example.com']
* emails.toArray(); // [Email, Email]
* emails.toArray().map((email) => email.getHost()); // ['lucaspaganini.com', 'example.com']
* ```
*
* @example
* ```typescript
* class Test {
* constructor(shouldThrow: boolean) {
* if (shouldThrow) throw Error('I was instructed to throw');
* }
* }
* new Test(false); // OK
* new Test(true); // Runtime error: I was instructed to throw
*
* class TestsArray extends VOArray(Test, {
* minLength: 1,
* maxLength: 5,
* maxErrors: 2
* }) {}
* new TestsArray([false]); // OK
* new TestsArray([]); // Runtime error: Too short
* new TestsArray([false, false, false, false, false, false]); // Runtime error: Too long
* new TestsArray([true, true, true, true]); // Runtime error: ["I was instructed to throw", "I was instructed to throw"]
* ```
*/
var VOArray = function (VOC, options) {
var _a;
if (options === void 0) { options = {}; }
if (utils_1.isDefined(options.minLength)) {
if (utils_1.isNotNumber(options.minLength))
throw new errors_1.RawTypeError('number', typeof options.minLength, 'options.minLength');
if (!Number.isInteger(options.minLength))
throw new errors_1.NotIntegerError(options.minLength, 'options.minLength');
if (options.minLength < 0)
throw new errors_1.MinSizeError(options.minLength, 0);
}
if (utils_1.isDefined(options.maxLength)) {
if (utils_1.isNotNumber(options.maxLength))
throw new errors_1.RawTypeError('number', typeof options.maxLength, 'options.maxLength');
if (!Number.isInteger(options.maxLength))
throw new errors_1.NotIntegerError(options.maxLength, 'options.maxLength');
if (options.maxLength < 0)
throw new errors_1.MinSizeError(options.maxLength, 0);
}
if (utils_1.isDefined(options.minLength) && utils_1.isDefined(options.maxLength)) {
if (options.minLength > options.maxLength)
throw new errors_1.LogicError('options.minLength should not be bigger than options.maxLength');
}
if (utils_1.isDefined(options.maxErrors)) {
if (utils_1.isNotNumber(options.maxErrors))
throw new errors_1.RawTypeError('number', typeof options.maxErrors, 'options.maxErrors');
if (!Number.isInteger(options.maxErrors))
throw new errors_1.NotIntegerError(options.maxErrors, 'options.maxErrors');
if (options.maxErrors < 0)
throw new errors_1.MinSizeError(options.maxErrors, 0);
}
var maxErrors = (_a = options.maxErrors) !== null && _a !== void 0 ? _a : 1;
return /** @class */ (function () {
function class_1(raw) {
this._valueObjects = [];
if (!Array.isArray(raw))
throw new errors_1.RawTypeError('Array<Raw>', typeof raw);
if (options.minLength !== undefined && raw.length < options.minLength)
throw new errors_1.MinLengthError(options.minLength, raw.length);
if (utils_1.isDefined(options.maxLength) && raw.length > options.maxLength)
throw new errors_1.MaxLengthError(options.maxLength, raw.length);
var errors = [];
var fromRaw = functions_1.makeFromRawInit(VOC);
var _loop_1 = function (_i, _raw) {
var index = parseInt(_i);
var either = fromRaw(_raw);
if (utils_1.isLeft(either)) {
var errorsWithIndex = either.left.map(function (e) {
if (errors_1.VOError.is(e))
e.path.push(index);
return e;
});
errors.push.apply(errors, errorsWithIndex);
if (errors.length >= maxErrors)
throw errors;
}
else {
this_1._valueObjects.push(either.right);
}
};
var this_1 = this;
for (var _a = 0, _b = Object.entries(raw); _a < _b.length; _a++) {
var _c = _b[_a], _i = _c[0], _raw = _c[1];
_loop_1(_i, _raw);
}
if (errors.length > 0)
throw errors;
if (raw.length !== this._valueObjects.length)
throw new errors_1.VOError("Unknown error");
}
class_1.prototype.valueOf = function () {
return this._valueObjects.map(function (vo) { return vo.valueOf(); });
};
class_1.prototype.toArray = function () {
return [].concat(this._valueObjects);
};
return class_1;
}());
};
exports.VOArray = VOArray;
//# sourceMappingURL=array.js.map