UNPKG

@lucaspaganini/value-objects

Version:

TypeScript first validation and class creation library

133 lines 5.25 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.VOFloat = void 0; var utils_1 = require("../utils"); var errors_1 = require("./errors"); var makeIsInSet = function (values) { var set = new Set(values); return function (v) { return set.has(v); }; }; var PRECISION_TRIM_SET = ['floor', 'ceil', 'round']; var isPrecisionTrim = makeIsInSet(PRECISION_TRIM_SET); /** * Function to create a floating point number value object constructor. * * @param options Customizations for the returned class constructor * @return Class constructor that accepts a number for instantiation * and returns that number when {@link VOFloatInstance.valueOf} is called. * * @example * ```typescript * class MyFloat extends VOFloat() {} * * const float1 = new MyFloat(5); // OK * float1.valueOf(); // 5 * * const float2 = new MyFloat(5.0); // OK * float2.valueOf(); // 5 * * const float3 = new MyFloat(5.5); // OK * float3.valueOf(); // 5.5 * * const float4 = new MyFloat('5.5'); // Compilation error: Not a number * ``` * * @example * ```typescript * class PositiveNumber extends VOFloat({ min: 0 }) {} // OK * new PositiveNumber(0); // OK * new PositiveNumber(1000000); // Ok * new PositiveNumber(-1); // Runtime error: Too small * new PositiveNumber(1.5); // OK * ``` * * @example * ```typescript * class FloatWithValidRange extends VOFloat({ min: -100.5, max: 100.5 }) {} // OK * new FloatWithValidRange(-100); // OK * new FloatWithValidRange(100); // Ok * new FloatWithValidRange(-100.5); // OK * new FloatWithValidRange(-101); // Runtime error: Too small * new FloatWithValidRange(101); // Runtime error: Too big * ``` * * @example * ```typescript * class FloatWithInvalidRange extends VOFloat({ min: 100, max: -100 }) {} // Runtime error: Invalid logic (options.min should not be bigger than options.max) * ``` * * @example * ```typescript * class LimitedPrecisionFloat extends VOFloat({ * precision: 5, * precisionTrim: 'round' * }) {} // OK * const limited1 = new LimitedPrecisionFloat(0.123456789); * limited1.valueOf(); // 0.12346 => Only 5 precision digits and it's rounded * ``` * * @example * ```typescript * class LimitedPrecisionFloatWithRange extends VOFloat({ * min: 1, * max: 999.999, * precision: 2, * precisionTrim: 'ceil' * }) {} // OK * new LimitedPrecisionFloatWithRange(-100); // Runtime error: Too small * new LimitedPrecisionFloatWithRange(100); // Ok * new LimitedPrecisionFloatWithRange(0.9999); // OK (rounds to 1 and passes the minimum) * new LimitedPrecisionFloatWithRange(999.999); // Runtime error: Too big (rounds to 1000 and doesn't pass the maximum) * const limited2 = new LimitedPrecisionFloatWithRange(0.123456789); * limited2.valueOf(); // 0.13 => Only 2 precision digits and it's rounded up because we're using "ceil" * ``` */ var VOFloat = function (options) { var _a, _b; if (options === void 0) { options = {}; } if (utils_1.isDefined(options.min)) { if (utils_1.isNotNumber(options.min)) throw new errors_1.RawTypeError('number', typeof options.min, 'options.min'); } if (utils_1.isDefined(options.max)) { if (utils_1.isNotNumber(options.max)) throw new errors_1.RawTypeError('number', typeof options.max, 'options.max'); } if (utils_1.isDefined(options.min) && utils_1.isDefined(options.max)) { if (options.min > options.max) throw new errors_1.LogicError('options.min should not be bigger than options.max'); } if (utils_1.isDefined(options.precision)) { if (utils_1.isNotNumber(options.precision)) throw new errors_1.RawTypeError('number', typeof options.precision, 'options.precision'); if (!Number.isInteger(options.precision)) throw new errors_1.NotIntegerError(options.precision, 'options.precision'); if (options.precision < 0) throw new errors_1.MinSizeError(options.precision, 0); } if (utils_1.isDefined(options.precisionTrim)) { if (!isPrecisionTrim(options.precisionTrim)) throw new errors_1.NotInSetError(PRECISION_TRIM_SET, options.precisionTrim, 'options.precisionTrim'); } var precisionPower = Math.pow(10, ((_a = options.precision) !== null && _a !== void 0 ? _a : 0)); var precisionTrim = (_b = options.precisionTrim) !== null && _b !== void 0 ? _b : 'round'; return /** @class */ (function () { function class_1(raw) { if (utils_1.isNotNumber(raw)) throw new errors_1.RawTypeError('number', typeof raw, 'raw'); if (utils_1.isDefined(options.precision)) raw = Math[precisionTrim](raw * precisionPower) / precisionPower; if (utils_1.isDefined(options.min) && raw < options.min) throw new errors_1.MinSizeError(options.min, raw); if (utils_1.isDefined(options.max) && raw > options.max) throw new errors_1.MaxSizeError(options.max, raw); this._value = raw; } class_1.prototype.valueOf = function () { return this._value; }; return class_1; }()); }; exports.VOFloat = VOFloat; //# sourceMappingURL=float.js.map