@trademe/ensure
Version:
200 lines (189 loc) • 17.1 kB
JavaScript
/**
* @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) {
// This functions is explicitly *not* using the `=>` syntax so that
// the `this` values is bound to the instance being checked.
return ensure((value, key) => {
const /** @type {?} */ enumValue = enumValues[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 typeof enumValue === 'number' ? enumValue : value;
});
}
/**
* @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+IHtcbiAgICAgICAgY29uc3Qgd2hpdGVzcGFjZUNvdW50ID0gbi5zZWFyY2goL1xcUy8pO1xuICAgICAgICBpZiAod2hpdGVzcGFjZUNvdW50IDw9IDApIHtcbiAgICAgICAgICAgIHJldHVybiBwO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB3aGl0ZXNwYWNlQ291bnQgPCBwID8gd2hpdGVzcGFjZUNvdW50IDogcDtcbiAgICB9LCBJbmZpbml0eSk7XG5cbiAgICBjb25zdCBuZXdMaW5lcyA9IGxpbmVzLm1hcChsID0+IGwuc3Vic3RyKG1pbldoaXBlU3BhY2UpKTtcbiAgICByZXR1cm4gbmV3TGluZXMuam9pbignXFxuJyk7XG59XG4iLCIvLyBEZXBlbmRlbmNpZXM6XG5pbXBvcnQgeyBpc05vdE51bGwgfSBmcm9tICcuLi9ndWFyZHMvbm90LW51bGwnO1xuaW1wb3J0IHsgR3VhcmQgfSBmcm9tICcuLi9ndWFyZC9ndWFyZCc7XG5cbi8vIENvbnN0YW50czpcbmNvbnN0IFZBTFVFX0tFWSA9ICdfX3ZhbHVlXyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBWYWx1ZSAoLi4uZ3VhcmRzOiBBcnJheTxHdWFyZDxhbnk+IHwgQXJyYXk8R3VhcmQ8YW55Pj4+KTogUHJvcGVydHlEZWNvcmF0b3Ige1xuICAgIGNvbnN0IGd1YXJkc0FycmF5ID0gZ2V0R3VhcmRzQXJyYXkoZ3VhcmRzKTtcblxuICAgIGNvbnN0IGdldHRlcnMgPSBndWFyZHNBcnJheS5maWx0ZXIoYyA9PiBjLmlzR2V0dGVyKTtcbiAgICBjb25zdCBzZXR0ZXJzID0gZ3VhcmRzQXJyYXkuZmlsdGVyKGMgPT4gIWMuaXNHZXR0ZXIpO1xuXG4gICAgcmV0dXJuICh0YXJnZXQ6IGFueSwgcHJvcGVydHlLZXk6IHN0cmluZykgPT4ge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eUtleSwge1xuICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSAoUmVmbGVjdCBhcyBhbnkpLmdldE1ldGFkYXRhKGAke1ZBTFVFX0tFWX0ke3Byb3BlcnR5S2V5fWAsIHRoaXMpO1xuICAgICAgICAgICAgICAgIGdldHRlcnMuZm9yRWFjaChnZXR0ZXIgPT4ge1xuICAgICAgICAgICAgICAgICAgICBnZXR0ZXIuY2FsbCh0aGlzLCB2YWx1ZSwgcHJvcGVydHlLZXkpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGxldCBjYXN0VmFsdWUgPSB2YWx1ZTtcblxuICAgICAgICAgICAgICAgIGlmIChjYXN0VmFsdWUgPT09ICdudWxsJykge1xuICAgICAgICAgICAgICAgICAgICBjYXN0VmFsdWUgPSBudWxsO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChjYXN0VmFsdWUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBzZXR0ZXJzLmZvckVhY2goc2V0dGVyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc3RWYWx1ZSA9IHNldHRlci5jYWxsKHRoaXMsIGNhc3RWYWx1ZSwgcHJvcGVydHlLZXkpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgKFJlZmxlY3QgYXMgYW55KS5kZWZpbmVNZXRhZGF0YShgJHtWQUxVRV9LRVl9JHtwcm9wZXJ0eUtleX1gLCBjYXN0VmFsdWUsIHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBnZXRHdWFyZHNBcnJheSAoZ3VhcmRzOiBBcnJheTxHdWFyZDxhbnk+IHwgQXJyYXk8R3VhcmQ8YW55Pj4+KTogQXJyYXk8R3VhcmQ8YW55Pj4ge1xuICAgIC8vIEhhbmRsZSBvbGQgQFZhbHVlKFtndWFyZE9uZSwgZ3VhcmRUd29dKSBzeW50YXg6XG4gICAgY29uc3QgW2ZpcnN0R3VhcmRdID0gZ3VhcmRzO1xuICAgIHJldHVybiBBcnJheS5pc0FycmF5KGZpcnN0R3VhcmQpID8gZmlyc3RHdWFyZCBhcyBBcnJheTxHdWFyZDxhbnk+PiA6IGd1YXJkcyBhcyBBcnJheTxHdWFyZDxhbnk+Pjtcbn1cbiIsIi8vIERlcGVuZGVuY2llczpcbmltcG9ydCB7IEd1YXJkQ29uZmlnIH0gZnJvbSAnLi9ndWFyZC1jb25maWcnO1xuXG5leHBvcnQgdHlwZSBHdWFyZEZ1bmN0aW9uPFQgPSBhbnk+ID0gKHZhbHVlOiBhbnksIGtleTogc3RyaW5nKSA9PiBUO1xuZXhwb3J0IHR5cGUgR3VhcmQ8VCA9IGFueT4gPSB7IGlzR2V0dGVyOiBib29sZWFuIH0gJiBHdWFyZEZ1bmN0aW9uPFQ+O1xuXG5leHBvcnQgZnVuY3Rpb24gZW5zdXJlIDxUPiAoZ3VhcmQ6IEd1YXJkRnVuY3Rpb24sIGNvbmZpZz86IEd1YXJkQ29uZmlnKTogR3VhcmQ8VD4ge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShndWFyZCwgJ2lzR2V0dGVyJywge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiAhIWNvbmZpZyAmJiBjb25maWcuZ2V0dGVyO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGd1YXJkIGFzIEd1YXJkO1xufVxuIiwiLy8gRGVwZW5kZW5jaWVzOlxuaW1wb3J0IHsgRW5zdXJlRXJyb3IgfSBmcm9tICcuLi9lbnN1cmUtZXJyb3InO1xuaW1wb3J0IHsgZW5zdXJlIH0gZnJvbSAnLi4vZ3VhcmQvZ3VhcmQnO1xuXG5leHBvcnQgY29uc3QgaXNCb29sID0gZW5zdXJlKCh2YWx1ZTogYW55LCBrZXk6IHN0cmluZyk6IGJvb2xlYW4gPT4ge1xuICAgIGlmICh2YWx1ZSA9PT0gdHJ1ZSB8fCB2YWx1ZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICBpZiAodmFsdWUgPT09ICd0cnVlJyB8fCB2YWx1ZSA9PT0gJycpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmICh2YWx1ZSA9PT0gJ2ZhbHNlJykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVuc3VyZUVycm9yKGBcbiAgICAgICAgXCIke3ZhbHVlfVwiIGlzIG5vdCBhIHZhbGlkIHZhbHVlIGZvciAnJHtrZXl9Jy5cbiAgICAgICAgICAgIFRoZSBmb2xsb3dpbmcgdmFsdWVzIHdpbGwgZXZhbHVhdGUgdG8gdHJ1ZTogdHJ1ZSwgXCJ0cnVlXCIsIFwiXCIuXG4gICAgICAgICAgICBUaGUgZm9sbG93aW5nIHZhbHVlcyB3aWxsIGV2YWx1YXRlIHRvIGZhbHNlOiBmYWxzZSwgXCJmYWxzZVwiLlxuICAgIGApO1xufSk7XG4iLCIvLyBEZXBlbmRlbmNpZXM6XG5pbXBvcnQgeyBFbnN1cmVFcnJvciB9IGZyb20gJy4uL2Vuc3VyZS1lcnJvcic7XG5pbXBvcnQgeyBlbnN1cmUgfSBmcm9tICcuLi9ndWFyZC9ndWFyZCc7XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0VudW0gPFQ+IChlbnVtVmFsdWVzOiBUKTogRnVuY3Rpb24ge1xuICAgIC8vIFRoaXMgZnVuY3Rpb25zIGlzIGV4cGxpY2l0bHkgKm5vdCogdXNpbmcgdGhlIGA9PmAgc3ludGF4IHNvIHRoYXRcbiAgICAvLyB0aGUgYHRoaXNgIHZhbHVlcyBpcyBib3VuZCB0byB0aGUgaW5zdGFuY2UgYmVpbmcgY2hlY2tlZC5cbiAgICByZXR1cm4gZW5zdXJlPFQ+KCh2YWx1ZTogYW55LCBrZXk6IHN0cmluZyk6IFQgPT4ge1xuICAgICAgICBjb25zdCBlbnVtVmFsdWUgPSBlbnVtVmFsdWVzW3ZhbHVlXTtcbiAgICAgICAgaWYgKGVudW1WYWx1ZSA9PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRW5zdXJlRXJyb3IoYFxuICAgICAgICAgICAgICAgIFwiJHt2YWx1ZX1cIiBpcyBub3QgYSB2YWxpZCB2YWx1ZSBmb3IgJyR7a2V5fScuIFlvdSBjYW4gdXNlIG9uZSBvZiB0aGUgZm9sbG93aW5nOlxuICAgICAgICAgICAgICAgICAgICAke2dldFZhbHVlczxUPihlbnVtVmFsdWVzKX1cbiAgICAgICAgICAgIGApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0eXBlb2YgZW51bVZhbHVlID09PSAnbnVtYmVyJyA/IGVudW1WYWx1ZSA6IHZhbHVlO1xuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBnZXRWYWx1ZXM8VD4gKGVudW1UOiBUKTogc3RyaW5nIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMoZW51bVQpXG4gICAgLmZpbHRlcihrZXkgPT4gaXNOYU4oK2tleSkpXG4gICAgLm1hcChrZXkgPT4gYFwiJHtrZXl9XCJgKVxuICAgIC5qb2luKCcsXFxuICAgICAgICAgICAgICAgICAgICAnKTtcbn1cbiIsIi8vIERlcGVuZGVuY2llczpcbmltcG9ydCB7IEVuc3VyZUVycm9yIH0gZnJvbSAnLi4vZW5zdXJlLWVycm9yJztcbmltcG9ydCB7IGVuc3VyZSB9IGZyb20gJy4uL2d1YXJkL2d1YXJkJztcblxuZXhwb3J0IGNvbnN0IGlzTm90TnVsbCA9IGVuc3VyZSgodmFsdWU6IGFueSwga2V5OiBhbnkpOiBhbnkgPT4ge1xuICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgICAgIHRocm93IG5ldyBFbnN1cmVFcnJvcihgXG4gICAgICAgICAgICAnJHtrZXl9JyBtdXN0IG5vdCBiZSBcIm51bGxcIiBvciBcInVuZGVmaW5lZFwiLlxuICAgICAgICBgKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufSwge1xuICAgIGdldHRlcjogdHJ1ZVxufSk7XG4iLCIvLyBEZXBlbmRlbmNpZXM6XG5pbXBvcnQgeyBFbnN1cmVFcnJvciB9IGZyb20gJy4uL2Vuc3VyZS1lcnJvcic7XG5pbXBvcnQgeyBlbnN1cmUgfSBmcm9tICcuLi9ndWFyZC9ndWFyZCc7XG5cbmV4cG9ydCBjb25zdCBpc051bWJlciA9IGVuc3VyZSgodmFsdWU6IGFueSwga2V5OiBzdHJpbmcpOiBudW1iZXIgPT4ge1xuICAgIHZhbHVlID0gK3BhcnNlRmxvYXQodmFsdWUpO1xuICAgIGlmIChpc05hTih2YWx1ZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVuc3VyZUVycm9yKGBcbiAgICAgICAgICAgICcke2tleX0nIG11c3QgYmUgYSBudW1iZXIuXG4gICAgICAgIGApO1xuICAgIH1cbiAgICByZXR1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