selective-option
Version:
A simple selective option resolver
384 lines (368 loc) • 15 kB
JavaScript
function _arrayLikeToArray(r, a) {
(null == a || a > r.length) && (a = r.length);
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
return n;
}
function _arrayWithHoles(r) {
if (Array.isArray(r)) return r;
}
function _arrayWithoutHoles(r) {
if (Array.isArray(r)) return _arrayLikeToArray(r);
}
function _iterableToArray(r) {
if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
}
function _iterableToArrayLimit(r, l) {
var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (null != t) {
var e,
n,
i,
u,
a = [],
f = !0,
o = !1;
try {
if (i = (t = t.call(r)).next, 0 === l) {
if (Object(t) !== t) return;
f = !1;
} else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
} catch (r) {
o = !0, n = r;
} finally {
try {
if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
} finally {
if (o) throw n;
}
}
return a;
}
}
function _maybeArrayLike(r, a, e) {
if (a && !Array.isArray(a) && "number" == typeof a.length) {
var y = a.length;
return _arrayLikeToArray(a, void 0 !== e && e < y ? e : y);
}
return r(a, e);
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _slicedToArray(r, e) {
return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
}
function _toArray(r) {
return _arrayWithHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableRest();
}
function _toConsumableArray(r) {
return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
}
function _unsupportedIterableToArray(r, a) {
if (r) {
if ("string" == typeof r) return _arrayLikeToArray(r, a);
var t = {}.toString.call(r).slice(8, -1);
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
}
}
function createResult(keys, value) {
var entries = keys.map(function (key) {
return [key, value];
});
return Object.fromEntries(entries);
}
function deprecatedCreateResult(keys, value, input) {
var result = createResult(keys, value);
return Object.assign({}, input, result);
}
function createResultGetValue(keys, getValue) {
var entries = keys.map(function (key) {
var value = getValue(key);
return [key, value];
});
return Object.fromEntries(entries);
}
var isArray = Array.isArray;
function is(value, type) {
return typeof value === type;
}
function errorInvalidKey(key) {
return new Error("\"" + key + "\" is not a valid key");
}
function errorInvalidValue(value) {
var formattedValue = is(value, 'string') ? "\"" + value + "\"" : value;
return new Error(formattedValue + " is not a valid value");
}
function validateValue(value, isValidValue) {
// return "valid" result if value is valid
if (isValidValue(value)) return [true, value];
// return "nullish" result if value is nullish
if (value == null) return [false, value];
// return nothing (undefined) if value is invalid
// return;
}
function validateValueOrThrow(value, isValidValue) {
// resolve if value is valid or nullish
var resolved = validateValue(value, isValidValue);
// throw if not resolved
if (!resolved) throw errorInvalidValue(value);
// return resolved value
return resolved;
}
function createFunctionResolver(keys, isValidValue, defaultValue) {
// return function resolver
return function (input) {
// exit if input is not a function
if (!is(input, 'function')) return;
var getValue = function getValue(key) {
// get value from input
var value = input(key);
// get data from value if it's valid or nullish
var _validateValueOrThrow = validateValueOrThrow(value, isValidValue),
_validateValueOrThrow2 = _maybeArrayLike(_slicedToArray, _validateValueOrThrow, 2),
isValid = _validateValueOrThrow2[0],
validatedValue = _validateValueOrThrow2[1];
// return value if it's valid
if (isValid) return validatedValue;
// return default value if value is nullish
return defaultValue;
};
// return result
return createResultGetValue(keys, getValue);
};
}
function resolveKey(key, keys, special) {
if (keys.includes(key)) return [[key], false];
if (!special) return;
var specialResolved = special[key];
if (!specialResolved) return;
return [specialResolved, true];
}
var polarityPrefixes = ['!', '+', '-'];
function resolvePolarKey(key, keys, special) {
// throw if item is not a string
if (!is(key, 'string')) return;
// try to resolve positive key
var resolved = resolveKey(key, keys, special);
// return positive key result if resolved
if (resolved) {
var _resolved = _maybeArrayLike(_slicedToArray, resolved, 1),
_resolvedKeys = _resolved[0];
return [_resolvedKeys, true];
}
// get first character to test for key polarity
var sign = key.charAt(0);
// fail if first character in not a polarity prefix
if (!polarityPrefixes.includes(sign)) return;
// get key without polarity
var absoluteKey = key.slice(1);
// try to resolve key
var absoluteResolved = resolveKey(absoluteKey, keys, special);
// fail if it can't be resolved
if (!absoluteResolved) return;
// return key result with polarity
var _absoluteResolved = _maybeArrayLike(_slicedToArray, absoluteResolved, 1),
resolvedKeys = _absoluteResolved[0];
return [resolvedKeys, sign === '+'];
}
function resolveKeyOrThrow(key, keys, special) {
// try to resolve key
var resolvedKey = resolvePolarKey(key, keys, special);
// throw if it can't be resolved
if (!resolvedKey) throw errorInvalidKey(key);
// return resolved key
return resolvedKey;
}
function createKeyListResolver(keys, special) {
// return array resolver
return function (input) {
// exit if value is not an array
if (!isArray(input)) return;
// resolve to false if input array is empty
if (input.length === 0) return createResult(keys, false);
// get first key independently from the rest
var _input = _maybeArrayLike(_toArray, input),
first = _input[0],
rest = _input.slice(1);
// resolve first key
var _resolveKeyOrThrow = resolveKeyOrThrow(first, keys, special),
_resolveKeyOrThrow2 = _maybeArrayLike(_slicedToArray, _resolveKeyOrThrow, 2),
firstKeys = _resolveKeyOrThrow2[0],
firstPolarity = _resolveKeyOrThrow2[1];
// create result based on first key
var base = createResult(keys, !firstPolarity);
var override = createResult(firstKeys, firstPolarity);
var baseResult = Object.assign({}, base, override);
// extend base result according to the rest of the items
return rest.reduce(function (output, key) {
// resolve key
var _resolveKeyOrThrow3 = resolveKeyOrThrow(key, keys, special),
_resolveKeyOrThrow4 = _maybeArrayLike(_slicedToArray, _resolveKeyOrThrow3, 2),
resolvedKeys = _resolveKeyOrThrow4[0],
resolvedPolarity = _resolveKeyOrThrow4[1];
// return updated result
var override = createResult(resolvedKeys, resolvedPolarity);
return Object.assign({}, output, override);
}, baseResult);
};
}
function processInput(input, isValidValue, defaultValue, overrideKey, keys, special) {
// get input object keys
var objectKeys = Object.keys(input);
// return array containing processed data
return objectKeys.reduce(function (output, key) {
// get object key value
var value = input[key];
// get data from value if it's valid or nullish
var _validateValueOrThrow = validateValueOrThrow(value, isValidValue),
_validateValueOrThrow2 = _maybeArrayLike(_slicedToArray, _validateValueOrThrow, 2),
isValid = _validateValueOrThrow2[0],
validatedValue = _validateValueOrThrow2[1];
// return output without changes if value is nullish
if (!isValid) return output;
// destructure output array
var _output = _maybeArrayLike(_slicedToArray, output, 3),
override = _output[0],
keysData = _output[1],
specialData = _output[2];
// set override value if key equals override key
if (key === overrideKey) return [validatedValue, keysData, specialData];
var keyResolved__ = resolveKey(key, keys, special);
if (!keyResolved__) throw errorInvalidKey(key);
var _keyResolved__ = _maybeArrayLike(_slicedToArray, keyResolved__, 2),
keyResolved = _keyResolved__[0],
isSpecial = _keyResolved__[1];
var item = createResult(keyResolved, validatedValue);
if (isSpecial) {
var newSpecialData = [].concat(_maybeArrayLike(_toConsumableArray, specialData), [item]);
return [override, keysData, newSpecialData];
}
var newKeysData = [].concat(_maybeArrayLike(_toConsumableArray, keysData), [item]);
return [override, newKeysData, specialData];
// // try to resolve key as regular key
// const keyResolved = resolveKey(key, keys);
// // extend regular key data if regular key resolved
// if (keyResolved) {
// const item = createResult(keyResolved, validatedValue);
// const newKeysData = [...keysData, item];
// return [override, newKeysData, specialData];
// }
// // throw if special is not defined at this point
// if (!special) throw errorInvalidKey(key);
// // try to resolve key as special key
// const specialResolved = special[key as S] as K[] | undefined;
// // throw if key can't be resolved as special key
// if (!specialResolved) throw errorInvalidKey(key);
// // extend special key data if special key resolved
// const item = createResult(specialResolved, validatedValue);
// const newSpecialData = [...specialData, item];
// return [override, keysData, newSpecialData];
}, [defaultValue, [], []]);
}
function extendResolved(output, extension) {
return Object.assign({}, output, extension);
}
function createObjectResolver(keys, isValidValue, defaultValue, overrideKey, special) {
// return object resolver
return function (input) {
// exit if it's not an object
if (!input || !is(input, 'object') || isArray(input)) return;
// process input object
var _processInput = processInput(input, isValidValue, defaultValue, overrideKey, keys, special),
_processInput2 = _maybeArrayLike(_slicedToArray, _processInput, 3),
overrideValue = _processInput2[0],
keysData = _processInput2[1],
specialData = _processInput2[2];
// return result create from processed input object
return keysData.reduce(extendResolved, specialData.reduce(extendResolved, createResult(keys, overrideValue)));
};
}
function createKeyResolver(keys, special) {
// return string resolver
return function (input) {
// try to resolve value as key or special key
var resolvedInput = resolvePolarKey(input, keys, special);
// exit if it can't be resolved
if (!resolvedInput) return;
// get data from resolved input
var _resolvedInput = _maybeArrayLike(_slicedToArray, resolvedInput, 2),
resolvedKeys = _resolvedInput[0],
polarity = _resolvedInput[1];
// create base result
var base = createResult(keys, !polarity);
// create override result
var override = createResult(resolvedKeys, polarity);
// return result
return Object.assign({}, base, override);
};
}
function createValueResolver(keys, isValidValue, defaultValue) {
// return value resolver
return function (input) {
// check if value is valid or nullish
var validated = validateValue(input, isValidValue);
// exit if value is not valid nor nullish
if (!validated) return;
// get data from resolved value
var _validated = _maybeArrayLike(_slicedToArray, validated, 2),
isValid = _validated[0],
validatedValue = _validated[1];
// return result using value if it's valid
if (isValid) return createResult(keys, validatedValue);
// return result using default value
return createResult(keys, defaultValue);
};
}
function createResolver() {
for (var _len = arguments.length, resolvers = new Array(_len), _key = 0; _key < _len; _key++) {
resolvers[_key] = arguments[_key];
}
// return resolver
return function (input) {
// iterate through resolvers
for (var _i = 0, _resolvers = resolvers; _i < _resolvers.length; _i++) {
var resolve = _resolvers[_i];
// execute resolver
var result = resolve(input);
// return result if it's resolved
if (result) return result;
}
// throw Error if input can't be resolved
throw errorInvalidValue(input);
};
}
function wrapValueValidator(isValidValue) {
var isBoolean = function isBoolean(value) {
return value === true || value === false;
};
if (!isValidValue) return isBoolean;
var isValueOrBool = function isValueOrBool(value) {
return isValidValue(value) || isBoolean(value);
};
return isValueOrBool;
}
function createBoolBasedResolver(keys, isValidValue, defaultValue, overrideKey, special) {
// create boolean value validator
var isValueOrBool = wrapValueValidator(isValidValue);
// create potential resolvers
var resolveValue = createValueResolver(keys, isValueOrBool, defaultValue);
var resolveFunction = createFunctionResolver(keys, isValueOrBool, defaultValue);
var resolveSingleKey = createKeyResolver(keys, special);
var resolveKeyList = createKeyListResolver(keys, special);
var resolveObject = createObjectResolver(keys, isValueOrBool, defaultValue, overrideKey, special);
// return compiled resolver
return createResolver(resolveValue, resolveFunction, resolveSingleKey, resolveKeyList, resolveObject);
}
function createValueBasedResolver(keys, isValidValue, defaultValue, overrideKey, special) {
// create potential resolvers
var resolveValue = createValueResolver(keys, isValidValue, defaultValue);
var resolveFunction = createFunctionResolver(keys, isValidValue, defaultValue);
var resolveObject = createObjectResolver(keys, isValidValue, defaultValue, overrideKey, special);
// return compiled resolver
return createResolver(resolveValue, resolveFunction, resolveObject);
}
export { createBoolBasedResolver, createFunctionResolver, createKeyListResolver, createKeyResolver, createObjectResolver, createResolver, deprecatedCreateResult as createResult, createValueBasedResolver, createValueResolver };
//# sourceMappingURL=selective.mjs.map