UNPKG

@trademe/ensure

Version:

229 lines (218 loc) 19.4 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class EnsureError extends Error { /** * @param {?=} message */ constructor(message) { super(dedent(message)); Object.setPrototypeOf(this, new.target.prototype); } } /** * @param {?} str * @return {?} */ function dedent(str) { const /** @type {?} */ lines = str.split(/\n/); const /** @type {?} */ minWhipeSpace = lines.reduce((p, n) => { const /** @type {?} */ whitespaceCount = n.search(/\S/); if (whitespaceCount < 0) { return p; } return whitespaceCount < p ? whitespaceCount : p; }, Infinity); const /** @type {?} */ newLines = lines.map(l => l.substr(minWhipeSpace)); return newLines.join('\n'); } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ // Constants: const /** @type {?} */ VALUE_KEY = '__value_'; /** * @param {...?} guards * @return {?} */ function Value(...guards) { const /** @type {?} */ guardsArray = getGuardsArray(guards); const /** @type {?} */ getters = guardsArray.filter(c => c.isGetter); const /** @type {?} */ setters = guardsArray.filter(c => !c.isGetter); return (target, propertyKey) => { Object.defineProperty(target, propertyKey, { get: function () { const /** @type {?} */ value = (/** @type {?} */ (Reflect)).getMetadata(`${VALUE_KEY}${propertyKey}`, this); getters.forEach(getter => { getter.call(this, value, propertyKey); }); return value; }, set: function (value) { let /** @type {?} */ castValue = value; if (castValue === 'null') { castValue = null; } if (castValue != null) { setters.forEach(setter => { castValue = setter.call(this, castValue, propertyKey); }); } (/** @type {?} */ (Reflect)).defineMetadata(`${VALUE_KEY}${propertyKey}`, castValue, this); } }); }; } /** * @param {?} guards * @return {?} */ function getGuardsArray(guards) { // Handle old @Value([guardOne, guardTwo]) syntax: const [firstGuard] = guards; return Array.isArray(firstGuard) ? /** @type {?} */ (firstGuard) : /** @type {?} */ (guards); } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @template T * @param {?} guard * @param {?=} config * @return {?} */ function ensure(guard, config) { Object.defineProperty(guard, 'isGetter', { get: function () { return !!config && config.getter; } }); return /** @type {?} */ (guard); } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ const /** @type {?} */ isBool = ensure((value, key) => { if (value === true || value === false) { return value; } if (value === 'true' || value === '') { return true; } if (value === 'false') { return false; } throw new EnsureError(` "${value}" is not a valid value for '${key}'. The following values will evaluate to true: true, "true", "". The following values will evaluate to false: false, "false". `); }); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @template T * @param {?} enumValues * @return {?} */ function isEnum(enumValues) { // Prepare the enum values so lookups work in both directions, // with both number and string enums: const /** @type {?} */ flipped = flipEnum(enumValues); const /** @type {?} */ stripped = stripEnum(enumValues); return ensure((value, key) => { const /** @type {?} */ enumValue = stripped[value] != null ? stripped[value] : stripped[flipped[value]]; if (enumValue == null) { throw new EnsureError(` "${value}" is not a valid value for '${key}'. You can use one of the following: ${getValues(enumValues)} `); } return enumValue; }); } /** * @template T * @param {?} enumT * @return {?} */ function flipEnum(enumT) { const /** @type {?} */ flipped = {}; Object.keys(enumT).forEach(key => { flipped[key] = enumT[key]; flipped[enumT[key]] = key; }); return flipped; } /** * @template T * @param {?} enumT * @return {?} */ function stripEnum(enumT) { const /** @type {?} */ stripped = {}; Object.keys(enumT).forEach(key => { if (isNaN(parseInt(key, 10))) { stripped[key] = enumT[key]; } }); return stripped; } /** * @template T * @param {?} enumT * @return {?} */ function getValues(enumT) { return Object.keys(enumT) .filter(key => isNaN(+key)) .map(key => `"${key}"`) .join(',\n '); } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ const /** @type {?} */ isNotNull = ensure((value, key) => { if (value == null) { throw new EnsureError(` '${key}' must not be "null" or "undefined". `); } return value; }, { getter: true }); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ const /** @type {?} */ isNumber = ensure((value, key) => { value = +parseFloat(value); if (isNaN(value)) { throw new EnsureError(` '${key}' must be a number. `); } return value; }); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ export { EnsureError, dedent, Value, ensure, isBool, isEnum, isNotNull, isNumber }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhZGVtZS1lbnN1cmUuanMubWFwIiwic291cmNlcyI6WyJuZzovL0B0cmFkZW1lL2Vuc3VyZS9lbnN1cmUtZXJyb3IudHMiLCJuZzovL0B0cmFkZW1lL2Vuc3VyZS92YWx1ZS92YWx1ZS50cyIsIm5nOi8vQHRyYWRlbWUvZW5zdXJlL2d1YXJkL2d1YXJkLnRzIiwibmc6Ly9AdHJhZGVtZS9lbnN1cmUvZ3VhcmRzL2Jvb2wudHMiLCJuZzovL0B0cmFkZW1lL2Vuc3VyZS9ndWFyZHMvZW51bS50cyIsIm5nOi8vQHRyYWRlbWUvZW5zdXJlL2d1YXJkcy9ub3QtbnVsbC50cyIsIm5nOi8vQHRyYWRlbWUvZW5zdXJlL2d1YXJkcy9udW1iZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNsYXNzIEVuc3VyZUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBtZXNzYWdlPzogc3RyaW5nXG4gICAgKSB7XG4gICAgICAgIHN1cGVyKGRlZGVudChtZXNzYWdlKSk7XG4gICAgICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBuZXcudGFyZ2V0LnByb3RvdHlwZSk7XG4gICAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVkZW50IChzdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgbGluZXMgPSBzdHIuc3BsaXQoL1xcbi8pO1xuICAgIGNvbnN0IG1pbldoaXBlU3BhY2UgPSBsaW5lcy5yZWR1Y2UoKHAsIG4pID0+IHtcbiAgICAgICAgY29uc3Qgd2hpdGVzcGFjZUNvdW50ID0gbi5zZWFyY2goL1xcUy8pO1xuICAgICAgICBpZiAod2hpdGVzcGFjZUNvdW50IDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIHA7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHdoaXRlc3BhY2VDb3VudCA8IHAgPyB3aGl0ZXNwYWNlQ291bnQgOiBwO1xuICAgIH0sIEluZmluaXR5KTtcblxuICAgIGNvbnN0IG5ld0xpbmVzID0gbGluZXMubWFwKGwgPT4gbC5zdWJzdHIobWluV2hpcGVTcGFjZSkpO1xuICAgIHJldHVybiBuZXdMaW5lcy5qb2luKCdcXG4nKTtcbn1cbiIsIi8vIERlcGVuZGVuY2llczpcbmltcG9ydCB7IGlzTm90TnVsbCB9IGZyb20gJy4uL2d1YXJkcy9ub3QtbnVsbCc7XG5pbXBvcnQgeyBHdWFyZCB9IGZyb20gJy4uL2d1YXJkL2d1YXJkJztcblxuLy8gQ29uc3RhbnRzOlxuY29uc3QgVkFMVUVfS0VZID0gJ19fdmFsdWVfJztcblxuZXhwb3J0IGZ1bmN0aW9uIFZhbHVlICguLi5ndWFyZHM6IEFycmF5PEd1YXJkPGFueT4gfCBBcnJheTxHdWFyZDxhbnk+Pj4pOiBQcm9wZXJ0eURlY29yYXRvciB7XG4gICAgY29uc3QgZ3VhcmRzQXJyYXkgPSBnZXRHdWFyZHNBcnJheShndWFyZHMpO1xuXG4gICAgY29uc3QgZ2V0dGVycyA9IGd1YXJkc0FycmF5LmZpbHRlcihjID0+IGMuaXNHZXR0ZXIpO1xuICAgIGNvbnN0IHNldHRlcnMgPSBndWFyZHNBcnJheS5maWx0ZXIoYyA9PiAhYy5pc0dldHRlcik7XG5cbiAgICByZXR1cm4gKHRhcmdldDogYW55LCBwcm9wZXJ0eUtleTogc3RyaW5nKSA9PiB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5S2V5LCB7XG4gICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IChSZWZsZWN0IGFzIGFueSkuZ2V0TWV0YWRhdGEoYCR7VkFMVUVfS0VZfSR7cHJvcGVydHlLZXl9YCwgdGhpcyk7XG4gICAgICAgICAgICAgICAgZ2V0dGVycy5mb3JFYWNoKGdldHRlciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGdldHRlci5jYWxsKHRoaXMsIHZhbHVlLCBwcm9wZXJ0eUtleSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgbGV0IGNhc3RWYWx1ZSA9IHZhbHVlO1xuXG4gICAgICAgICAgICAgICAgaWYgKGNhc3RWYWx1ZSA9PT0gJ251bGwnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc3RWYWx1ZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGNhc3RWYWx1ZSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHNldHRlcnMuZm9yRWFjaChzZXR0ZXIgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzdFZhbHVlID0gc2V0dGVyLmNhbGwodGhpcywgY2FzdFZhbHVlLCBwcm9wZXJ0eUtleSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAoUmVmbGVjdCBhcyBhbnkpLmRlZmluZU1ldGFkYXRhKGAke1ZBTFVFX0tFWX0ke3Byb3BlcnR5S2V5fWAsIGNhc3RWYWx1ZSwgdGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG59XG5cbmZ1bmN0aW9uIGdldEd1YXJkc0FycmF5IChndWFyZHM6IEFycmF5PEd1YXJkPGFueT4gfCBBcnJheTxHdWFyZDxhbnk+Pj4pOiBBcnJheTxHdWFyZDxhbnk+PiB7XG4gICAgLy8gSGFuZGxlIG9sZCBAVmFsdWUoW2d1YXJkT25lLCBndWFyZFR3b10pIHN5bnRheDpcbiAgICBjb25zdCBbZmlyc3RHdWFyZF0gPSBndWFyZHM7XG4gICAgcmV0dXJuIEFycmF5LmlzQXJyYXkoZmlyc3RHdWFyZCkgPyBmaXJzdEd1YXJkIGFzIEFycmF5PEd1YXJkPGFueT4+IDogZ3VhcmRzIGFzIEFycmF5PEd1YXJkPGFueT4+O1xufVxuIiwiLy8gRGVwZW5kZW5jaWVzOlxuaW1wb3J0IHsgR3VhcmRDb25maWcgfSBmcm9tICcuL2d1YXJkLWNvbmZpZyc7XG5cbmV4cG9ydCB0eXBlIEd1YXJkRnVuY3Rpb248VD4gPSAodmFsdWU6IGFueSwga2V5OiBzdHJpbmcpID0+IFQ7XG5leHBvcnQgdHlwZSBHdWFyZDxUPiA9IHsgaXNHZXR0ZXI6IGJvb2xlYW4gfSAmIEd1YXJkRnVuY3Rpb248VD47XG5cbmV4cG9ydCBmdW5jdGlvbiBlbnN1cmUgPFQ+IChndWFyZDogR3VhcmRGdW5jdGlvbjxUPiwgY29uZmlnPzogR3VhcmRDb25maWcpOiBHdWFyZDxUPiB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGd1YXJkLCAnaXNHZXR0ZXInLCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuICEhY29uZmlnICYmIGNvbmZpZy5nZXR0ZXI7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gZ3VhcmQgYXMgR3VhcmQ8VD47XG59XG4iLCIvLyBEZXBlbmRlbmNpZXM6XG5pbXBvcnQgeyBFbnN1cmVFcnJvciB9IGZyb20gJy4uL2Vuc3VyZS1lcnJvcic7XG5pbXBvcnQgeyBlbnN1cmUgfSBmcm9tICcuLi9ndWFyZC9ndWFyZCc7XG5cbmV4cG9ydCBjb25zdCBpc0Jvb2wgPSBlbnN1cmUoKHZhbHVlOiBhbnksIGtleTogc3RyaW5nKTogYm9vbGVhbiA9PiB7XG4gICAgaWYgKHZhbHVlID09PSB0cnVlIHx8IHZhbHVlID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICAgIGlmICh2YWx1ZSA9PT0gJ3RydWUnIHx8IHZhbHVlID09PSAnJykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKHZhbHVlID09PSAnZmFsc2UnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRW5zdXJlRXJyb3IoYFxuICAgICAgICBcIiR7dmFsdWV9XCIgaXMgbm90IGEgdmFsaWQgdmFsdWUgZm9yICcke2tleX0nLlxuICAgICAgICAgICAgVGhlIGZvbGxvd2luZyB2YWx1ZXMgd2lsbCBldmFsdWF0ZSB0byB0cnVlOiB0cnVlLCBcInRydWVcIiwgXCJcIi5cbiAgICAgICAgICAgIFRoZSBmb2xsb3dpbmcgdmFsdWVzIHdpbGwgZXZhbHVhdGUgdG8gZmFsc2U6IGZhbHNlLCBcImZhbHNlXCIuXG4gICAgYCk7XG59KTtcbiIsIi8vIERlcGVuZGVuY2llczpcbmltcG9ydCB7IEVuc3VyZUVycm9yIH0gZnJvbSAnLi4vZW5zdXJlLWVycm9yJztcbmltcG9ydCB7IGVuc3VyZSwgR3VhcmQgfSBmcm9tICcuLi9ndWFyZC9ndWFyZCc7XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0VudW0gPFQ+IChlbnVtVmFsdWVzOiBUKTogR3VhcmQ8VD4ge1xuICAgIC8vIFByZXBhcmUgdGhlIGVudW0gdmFsdWVzIHNvIGxvb2t1cHMgd29yayBpbiBib3RoIGRpcmVjdGlvbnMsXG4gICAgLy8gd2l0aCBib3RoIG51bWJlciBhbmQgc3RyaW5nIGVudW1zOlxuICAgIGNvbnN0IGZsaXBwZWQgPSBmbGlwRW51bShlbnVtVmFsdWVzKTtcbiAgICBjb25zdCBzdHJpcHBlZCA9IHN0cmlwRW51bShlbnVtVmFsdWVzKTtcblxuICAgIHJldHVybiBlbnN1cmUoKHZhbHVlOiBhbnksIGtleTogc3RyaW5nKTogbnVtYmVyIHwgYW55ID0+IHtcbiAgICAgICAgY29uc3QgZW51bVZhbHVlID0gc3RyaXBwZWRbdmFsdWVdICE9IG51bGwgPyBzdHJpcHBlZFt2YWx1ZV0gOiBzdHJpcHBlZFtmbGlwcGVkW3ZhbHVlXV07XG4gICAgICAgIGlmIChlbnVtVmFsdWUgPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVuc3VyZUVycm9yKGBcbiAgICAgICAgICAgICAgICBcIiR7dmFsdWV9XCIgaXMgbm90IGEgdmFsaWQgdmFsdWUgZm9yICcke2tleX0nLiBZb3UgY2FuIHVzZSBvbmUgb2YgdGhlIGZvbGxvd2luZzpcbiAgICAgICAgICAgICAgICAgICAgJHtnZXRWYWx1ZXM8VD4oZW51bVZhbHVlcyl9XG4gICAgICAgICAgICBgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZW51bVZhbHVlO1xuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBmbGlwRW51bSA8VD4gKGVudW1UOiBUKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSB7XG4gICAgY29uc3QgZmxpcHBlZCA9IHt9O1xuICAgIE9iamVjdC5rZXlzKGVudW1UKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgIGZsaXBwZWRba2V5XSA9IGVudW1UW2tleV07XG4gICAgICAgIGZsaXBwZWRbZW51bVRba2V5XV0gPSBrZXk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGZsaXBwZWQ7XG59XG5cbmZ1bmN0aW9uIHN0cmlwRW51bSA8VD4gKGVudW1UOiBUKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSB7XG4gICAgY29uc3Qgc3RyaXBwZWQgPSB7fTtcbiAgICBPYmplY3Qua2V5cyhlbnVtVCkuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICBpZiAoaXNOYU4ocGFyc2VJbnQoa2V5LCAxMCkpKSB7XG4gICAgICAgICAgICBzdHJpcHBlZFtrZXldID0gZW51bVRba2V5XTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBzdHJpcHBlZDtcbn1cblxuZnVuY3Rpb24gZ2V0VmFsdWVzPFQ+IChlbnVtVDogVCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKGVudW1UKVxuICAgIC5maWx0ZXIoa2V5ID0+IGlzTmFOKCtrZXkpKVxuICAgIC5tYXAoa2V5ID0+IGBcIiR7a2V5fVwiYClcbiAgICAuam9pbignLFxcbiAgICAgICAgICAgICAgICAgICAgJyk7XG59XG4iLCIvLyBEZXBlbmRlbmNpZXM6XG5pbXBvcnQgeyBFbnN1cmVFcnJvciB9IGZyb20gJy4uL2Vuc3VyZS1lcnJvcic7XG5pbXBvcnQgeyBlbnN1cmUgfSBmcm9tICcuLi9ndWFyZC9ndWFyZCc7XG5cbmV4cG9ydCBjb25zdCBpc05vdE51bGwgPSBlbnN1cmUoKHZhbHVlOiBhbnksIGtleTogYW55KTogYW55ID0+IHtcbiAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgRW5zdXJlRXJyb3IoYFxuICAgICAgICAgICAgJyR7a2V5fScgbXVzdCBub3QgYmUgXCJudWxsXCIgb3IgXCJ1bmRlZmluZWRcIi5cbiAgICAgICAgYCk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbn0sIHtcbiAgICBnZXR0ZXI6IHRydWVcbn0pO1xuIiwiLy8gRGVwZW5kZW5jaWVzOlxuaW1wb3J0IHsgRW5zdXJlRXJyb3IgfSBmcm9tICcuLi9lbnN1cmUtZXJyb3InO1xuaW1wb3J0IHsgZW5zdXJlIH0gZnJvbSAnLi4vZ3VhcmQvZ3VhcmQnO1xuXG5leHBvcnQgY29uc3QgaXNOdW1iZXIgPSBlbnN1cmUoKHZhbHVlOiBhbnksIGtleTogc3RyaW5nKTogbnVtYmVyID0+IHtcbiAgICB2YWx1ZSA9ICtwYXJzZUZsb2F0KHZhbHVlKTtcbiAgICBpZiAoaXNOYU4odmFsdWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFbnN1cmVFcnJvcihgXG4gICAgICAgICAgICAnJHtrZXl9JyBtdXN0IGJlIGEgbnVtYmVyLlxuICAgICAgICBgKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufSk7XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLGlCQUF5QixTQUFRLEtBQUs7Ozs7SUFDbEMsWUFDSSxPQUFnQjtRQUVoQixLQUFLLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFDdkIsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztLQUNyRDtDQUNKOzs7OztBQUVELGdCQUF3QixHQUFXO0lBQy9CLHVCQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzlCLHVCQUFNLGFBQWEsR0FBRyxLQUFLLENBQUMsTUFB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