rambdax
Version:
Extended version of Rambda - a lightweight, faster alternative to Ramda
1,788 lines (1,673 loc) • 108 kB
JavaScript
'use strict';
function type(input) {
if (input === null) {
return 'Null';
} else if (input === undefined) {
return 'Undefined';
} else if (Number.isNaN(input)) {
return 'NaN';
}
const typeResult = Object.prototype.toString.call(input).slice(8, -1);
return typeResult === 'AsyncFunction' ? 'Promise' : typeResult;
}
const {
isArray
} = Array;
function isTruthy(x) {
if (isArray(x)) {
return x.length > 0;
}
if (type(x) === 'Object') {
return Object.keys(x).length > 0;
}
return Boolean(x);
}
function allFalse(...inputs) {
let counter = 0;
while (counter < inputs.length) {
const x = inputs[counter];
if (type(x) === 'Function') {
if (isTruthy(x())) {
return false;
}
} else if (isTruthy(x)) {
return false;
}
counter++;
}
return true;
}
function isFalsy$1(x) {
if (isArray(x)) {
return x.length === 0;
}
if (type(x) === 'Object') {
return Object.keys(x).length === 0;
}
return !x;
}
function allTrue(...inputs) {
let counter = 0;
while (counter < inputs.length) {
const x = inputs[counter];
if (type(x) === 'Function') {
if (isFalsy$1(x())) {
return false;
}
} else if (isFalsy$1(x)) {
return false;
}
counter++;
}
return true;
}
function allType(targetType) {
return (...inputs) => {
let counter = 0;
while (counter < inputs.length) {
if (type(inputs[counter]) !== targetType) {
return false;
}
counter++;
}
return true;
};
}
function anyFalse(...inputs) {
let counter = 0;
while (counter < inputs.length) {
const x = inputs[counter];
if (type(x) === 'Function') {
if (isFalsy$1(x())) {
return true;
}
} else if (isFalsy$1(x)) {
return true;
}
counter++;
}
return false;
}
function anyTrue(...inputs) {
let counter = 0;
while (counter < inputs.length) {
const x = inputs[counter];
if (type(x) === 'Function') {
if (isTruthy(x())) {
return true;
}
} else if (isTruthy(x)) {
return true;
}
counter++;
}
return false;
}
function anyType(targetType) {
return (...inputs) => {
let counter = 0;
while (counter < inputs.length) {
if (type(inputs[counter]) === targetType) {
return true;
}
counter++;
}
return false;
};
}
function ownKeys(e, r) {
var t = Object.keys(e);
if (Object.getOwnPropertySymbols) {
var o = Object.getOwnPropertySymbols(e);
r && (o = o.filter(function (r) {
return Object.getOwnPropertyDescriptor(e, r).enumerable;
})), t.push.apply(t, o);
}
return t;
}
function _objectSpread2(e) {
for (var r = 1; r < arguments.length; r++) {
var t = null != arguments[r] ? arguments[r] : {};
r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
_defineProperty(e, r, t[r]);
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
});
}
return e;
}
function _toPrimitive(t, r) {
if ("object" != typeof t || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var i = e.call(t, r || "default");
if ("object" != typeof i) return i;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return ("string" === r ? String : Number)(t);
}
function _toPropertyKey(t) {
var i = _toPrimitive(t, "string");
return "symbol" == typeof i ? i : i + "";
}
function _defineProperty(obj, key, value) {
key = _toPropertyKey(key);
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _isInteger(n) {
return n << 0 === n;
}
const isInteger = Number.isInteger || _isInteger;
const isIndexInteger = index => Number.isInteger(Number(index));
function createPath(path, delimiter = '.') {
return typeof path === 'string' ? path.split(delimiter).map(x => isInteger(x) ? Number(x) : x) : path;
}
const cloneList = list => Array.prototype.slice.call(list);
function curry(fn, args = []) {
return (..._args) => (rest => rest.length >= fn.length ? fn(...rest) : curry(fn, rest))([...args, ..._args]);
}
function assocFn(prop, newValue, obj) {
return Object.assign({}, obj, {
[prop]: newValue
});
}
const assoc = curry(assocFn);
function assocPathFn(path, newValue, input) {
const pathArrValue = createPath(path);
if (pathArrValue.length === 0) return newValue;
const index = pathArrValue[0];
if (pathArrValue.length > 1) {
const condition = typeof input !== 'object' || input === null || !input.hasOwnProperty(index);
const nextInput = condition ? isIndexInteger(pathArrValue[1]) ? [] : {} : input[index];
newValue = assocPathFn(Array.prototype.slice.call(pathArrValue, 1), newValue, nextInput);
}
if (isIndexInteger(index) && isArray(input)) {
const arr = cloneList(input);
arr[index] = newValue;
return arr;
}
return assocFn(index, newValue, input);
}
const assocPath = curry(assocPathFn);
function pathFn(pathInput, obj) {
let willReturn = obj;
let counter = 0;
const pathArrValue = createPath(pathInput);
while (counter < pathArrValue.length) {
if (willReturn === null || willReturn === undefined) {
return undefined;
}
if (willReturn[pathArrValue[counter]] === null) return undefined;
willReturn = willReturn[pathArrValue[counter]];
counter++;
}
return willReturn;
}
function path(pathInput, obj) {
if (arguments.length === 1) return _obj => path(pathInput, _obj);
if (obj === null || obj === undefined) {
return undefined;
}
return pathFn(pathInput, obj);
}
const ALLOWED_OPERATIONS = ['remove', 'add', 'update'];
function removeAtPath(path, obj) {
const p = createPath(path);
const len = p.length;
if (len === 0) return;
if (len === 1) return delete obj[p[0]];
if (len === 2) return delete obj[p[0]][p[1]];
if (len === 3) return delete obj[p[0]][p[1]][p[2]];
if (len === 4) return delete obj[p[0]][p[1]][p[2]][p[3]];
if (len === 5) return delete obj[p[0]][p[1]][p[2]][p[3]][p[4]];
if (len === 6) return delete obj[p[0]][p[1]][p[2]][p[3]][p[4]][p[5]];
if (len === 7) return delete obj[p[0]][p[1]][p[2]][p[3]][p[4]][p[5]][p[6]];
if (len === 8) return delete obj[p[0]][p[1]][p[2]][p[3]][p[4]][p[5]][p[6]][p[7]];
if (len === 9) return delete obj[p[0]][p[1]][p[2]][p[3]][p[4]][p[5]][p[6]][p[7]][p[8]];
if (len === 10) return delete obj[p[0]][p[1]][p[2]][p[3]][p[4]][p[5]][p[6]][p[7]][p[8]][p[9]];
}
function applyDiff(rules, obj) {
if (arguments.length === 1) return _obj => applyDiff(rules, _obj);
let clone = _objectSpread2({}, obj);
rules.forEach(({
op,
path: path$1,
value
}) => {
if (!ALLOWED_OPERATIONS.includes(op)) return;
if (op === 'add' && path$1 && value !== undefined) {
if (path(path$1, obj)) return;
clone = assocPathFn(path$1, value, clone);
return;
}
if (op === 'remove') {
if (path(path$1, obj) === undefined) return;
removeAtPath(path$1, clone);
return;
}
if (op === 'update' && path$1 && value !== undefined) {
if (path(path$1, obj) === undefined) return;
clone = assocPathFn(path$1, value, clone);
}
});
return clone;
}
class ReduceStopper {
constructor(value) {
this.value = value;
}
}
function reduceFn(reducer, acc, list) {
if (list == null) {
return acc;
}
if (!isArray(list)) {
throw new TypeError('reduce: list must be array or iterable');
}
let index = 0;
const len = list.length;
while (index < len) {
acc = reducer(acc, list[index], index, list);
if (acc instanceof ReduceStopper) {
return acc.value;
}
index++;
}
return acc;
}
const reduce = curry(reduceFn);
const reduceStopper = value => new ReduceStopper(value);
function pipeAsync(...fnList) {
return startArgument => reduce(async (value, fn) => fn(await value), startArgument, fnList);
}
function composeAsync(...fnList) {
return pipeAsync(...fnList.reverse());
}
function construct(foo, bar) {
if (arguments.length === 1) {
return _bar => construct(foo, _bar);
}
return;
}
function constructN(foo, bar) {
if (arguments.length === 1) {
return _bar => constructN(foo, _bar);
}
return;
}
function _lastIndexOf(valueToFind, list) {
if (!isArray(list)) throw new Error(`Cannot read property 'indexOf' of ${list}`);
const typeOfValue = type(valueToFind);
if (!['Array', 'NaN', 'Object', 'RegExp'].includes(typeOfValue)) return list.lastIndexOf(valueToFind);
const {
length
} = list;
let index = length;
let foundIndex = -1;
while (--index > -1 && foundIndex === -1) if (equals(list[index], valueToFind)) foundIndex = index;
return foundIndex;
}
function _indexOf(valueToFind, list) {
if (!isArray(list)) throw new Error(`Cannot read property 'indexOf' of ${list}`);
const typeOfValue = type(valueToFind);
if (!['Array', 'NaN', 'Object', 'RegExp'].includes(typeOfValue)) return list.indexOf(valueToFind);
let index = -1;
let foundIndex = -1;
const {
length
} = list;
while (++index < length && foundIndex === -1) if (equals(list[index], valueToFind)) foundIndex = index;
return foundIndex;
}
function _arrayFromIterator(iter) {
const list = [];
let next;
while (!(next = iter.next()).done) list.push(next.value);
return list;
}
function _compareSets(a, b) {
if (a.size !== b.size) return false;
const aList = _arrayFromIterator(a.values());
const bList = _arrayFromIterator(b.values());
const filtered = aList.filter(aInstance => _indexOf(aInstance, bList) === -1);
return filtered.length === 0;
}
function compareErrors(a, b) {
if (a.message !== b.message) return false;
if (a.toString !== b.toString) return false;
return a.toString() === b.toString();
}
function parseDate(maybeDate) {
if (!maybeDate.toDateString) return [false];
return [true, maybeDate.getTime()];
}
function parseRegex(maybeRegex) {
if (maybeRegex.constructor !== RegExp) return [false];
return [true, maybeRegex.toString()];
}
function equals(a, b) {
if (arguments.length === 1) return _b => equals(a, _b);
if (Object.is(a, b)) return true;
const aType = type(a);
if (aType !== type(b)) return false;
if (aType === 'Function') return a.name === undefined ? false : a.name === b.name;
if (['NaN', 'Null', 'Undefined'].includes(aType)) return true;
if (['BigInt', 'Number'].includes(aType)) {
if (Object.is(-0, a) !== Object.is(-0, b)) return false;
return a.toString() === b.toString();
}
if (['Boolean', 'String'].includes(aType)) return a.toString() === b.toString();
if (aType === 'Array') {
const aClone = Array.from(a);
const bClone = Array.from(b);
if (aClone.toString() !== bClone.toString()) return false;
let loopArrayFlag = true;
aClone.forEach((aCloneInstance, aCloneIndex) => {
if (loopArrayFlag) if (aCloneInstance !== bClone[aCloneIndex] && !equals(aCloneInstance, bClone[aCloneIndex])) loopArrayFlag = false;
});
return loopArrayFlag;
}
const aRegex = parseRegex(a);
const bRegex = parseRegex(b);
if (aRegex[0]) return bRegex[0] ? aRegex[1] === bRegex[1] : false;else if (bRegex[0]) return false;
const aDate = parseDate(a);
const bDate = parseDate(b);
if (aDate[0]) return bDate[0] ? aDate[1] === bDate[1] : false;else if (bDate[0]) return false;
if (a instanceof Error) {
if (!(b instanceof Error)) return false;
return compareErrors(a, b);
}
if (aType === 'Set') return _compareSets(a, b);
if (aType === 'Object') {
const aKeys = Object.keys(a);
if (aKeys.length !== Object.keys(b).length) return false;
let loopObjectFlag = true;
aKeys.forEach(aKeyInstance => {
if (loopObjectFlag) {
const aValue = a[aKeyInstance];
const bValue = b[aKeyInstance];
if (aValue !== bValue && !equals(aValue, bValue)) loopObjectFlag = false;
}
});
return loopObjectFlag;
}
return false;
}
function contains(target, toCompare) {
if (arguments.length === 1) {
return _toCompare => contains(target, _toCompare);
}
let willReturn = true;
Object.keys(target).forEach(prop => {
if (!willReturn) return;
if (toCompare[prop] === undefined || !equals(target[prop], toCompare[prop])) {
willReturn = false;
}
});
return willReturn;
}
function debounce(func, ms, immediate = false) {
let timeout;
return function (...input) {
const later = function () {
timeout = null;
if (!immediate) {
return func.apply(null, input);
}
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, ms);
if (callNow) {
return func.apply(null, input);
}
};
}
const DELAY = 'RAMBDAX_DELAY';
function delay(ms) {
return new Promise(resolve => {
setTimeout(() => {
resolve(DELAY);
}, ms);
});
}
function includes$1(valueToFind, iterable) {
if (arguments.length === 1) return _iterable => includes$1(valueToFind, _iterable);
if (typeof iterable === 'string') {
return iterable.includes(valueToFind);
}
if (!iterable) {
throw new TypeError(`Cannot read property \'indexOf\' of ${iterable}`);
}
if (!isArray(iterable)) return false;
return _indexOf(valueToFind, iterable) > -1;
}
function excludes(valueToFind, input) {
if (arguments.length === 1) return _input => excludes(valueToFind, _input);
return includes$1(valueToFind, input) === false;
}
function filterObject(predicate, obj) {
const willReturn = {};
for (const prop in obj) {
if (predicate(obj[prop], prop, obj)) {
willReturn[prop] = obj[prop];
}
}
return willReturn;
}
function filterArray(predicate, list, indexed = false) {
let index = 0;
const len = list.length;
const willReturn = [];
while (index < len) {
const predicateResult = indexed ? predicate(list[index], index) : predicate(list[index]);
if (predicateResult) {
willReturn.push(list[index]);
}
index++;
}
return willReturn;
}
function filter(predicate, iterable) {
if (arguments.length === 1) return _iterable => filter(predicate, _iterable);
if (!iterable) {
throw new Error('Incorrect iterable input');
}
if (isArray(iterable)) return filterArray(predicate, iterable, false);
return filterObject(predicate, iterable);
}
async function mapAsyncFn(fn, listOrObject) {
if (isArray(listOrObject)) {
const willReturn = [];
let i = 0;
for (const a of listOrObject) {
willReturn.push(await fn(a, i++));
}
return willReturn;
}
const willReturn = {};
for (const prop in listOrObject) {
willReturn[prop] = await fn(listOrObject[prop], prop);
}
return willReturn;
}
function mapAsync(fn, listOrObject) {
if (arguments.length === 1) {
return async _listOrObject => mapAsyncFn(fn, _listOrObject);
}
return new Promise((resolve, reject) => {
mapAsyncFn(fn, listOrObject).then(resolve).catch(reject);
});
}
function filterAsyncFn(predicate, listOrObject) {
return new Promise((resolve, reject) => {
mapAsync(predicate, listOrObject).then(predicateResult => {
if (isArray(predicateResult)) {
const filtered = listOrObject.filter((_, i) => predicateResult[i]);
return resolve(filtered);
}
const filtered = filter((_, prop) => predicateResult[prop], listOrObject);
return resolve(filtered);
}).catch(reject);
});
}
function filterAsync(predicate, listOrObject) {
if (arguments.length === 1) {
return async _listOrObject => filterAsyncFn(predicate, _listOrObject);
}
return new Promise((resolve, reject) => {
filterAsyncFn(predicate, listOrObject).then(resolve).catch(reject);
});
}
function filterIndexed(predicate, iterable) {
if (arguments.length === 1) return _iterable => filterIndexed(predicate, _iterable);
if (!iterable) return [];
if (isArray(iterable)) return filterArray(predicate, iterable, true);
return filterObject(predicate, iterable);
}
function findAsyncFn(predicate, list) {
return new Promise((resolve, reject) => {
let canContinue = true;
let found;
const predicateFn = async (x, i) => {
if (!canContinue) return false;
try {
const result = await predicate(x, i);
if (result) {
canContinue = false;
found = x;
}
} catch (error) {
reject(error);
}
};
mapAsync(predicateFn, list).then(() => resolve(found)).catch(reject);
});
}
function findAsync(predicate, list) {
if (arguments.length === 1) {
return async _list => findAsync(predicate, _list);
}
return new Promise((resolve, reject) => {
findAsyncFn(predicate, list).then(resolve).catch(reject);
});
}
const INCORRECT_ITERABLE_INPUT = 'Incorrect iterable input';
const {
keys: keys$1
} = Object;
function mapArray(fn, list, isIndexed = false) {
let index = 0;
const willReturn = Array(list.length);
while (index < list.length) {
willReturn[index] = isIndexed ? fn(list[index], index) : fn(list[index]);
index++;
}
return willReturn;
}
function mapObject(fn, obj) {
if (arguments.length === 1) {
return _obj => mapObject(fn, _obj);
}
let index = 0;
const objKeys = keys$1(obj);
const len = objKeys.length;
const willReturn = {};
while (index < len) {
const key = objKeys[index];
willReturn[key] = fn(obj[key], key, obj);
index++;
}
return willReturn;
}
const mapObjIndexed = mapObject;
function map(fn, iterable) {
if (arguments.length === 1) return _iterable => map(fn, _iterable);
if (!iterable) {
throw new Error(INCORRECT_ITERABLE_INPUT);
}
if (isArray(iterable)) return mapArray(fn, iterable);
return mapObject(fn, iterable);
}
function mapIndexed(fn, iterable) {
if (arguments.length === 1) {
return _iterable => mapIndexed(fn, _iterable);
}
if (iterable === undefined) return [];
if (isArray(iterable)) return mapArray(fn, iterable, true);
return mapObject(fn, iterable);
}
function forEachIndexed(fn, iterable) {
if (arguments.length === 1) {
return _iterable => forEachIndexed(fn, _iterable);
}
mapIndexed(fn, iterable);
return iterable;
}
function mergeRight(target, newProps) {
if (arguments.length === 1) return _newProps => mergeRight(target, _newProps);
return Object.assign({}, target || {}, newProps || {});
}
function pick(propsToPick, input) {
if (arguments.length === 1) return _input => pick(propsToPick, _input);
if (input === null || input === undefined) {
return undefined;
}
const keys = createPath(propsToPick, ',');
const willReturn = {};
let counter = 0;
while (counter < keys.length) {
if (keys[counter] in input) {
willReturn[keys[counter]] = input[keys[counter]];
}
counter++;
}
return willReturn;
}
let holder = {};
function getter(key) {
const typeKey = type(key);
if (typeKey === 'String') return holder[key];
if (typeKey === 'Array') return pick(key, holder);
return holder;
}
function setter(maybeKey, maybeValue) {
const typeKey = type(maybeKey);
const typeValue = type(maybeValue);
if (typeKey === 'String') {
if (typeValue === 'Function') {
return holder[maybeKey] = maybeValue(holder[maybeKey]);
}
return holder[maybeKey] = maybeValue;
}
if (typeKey !== 'Object') return;
holder = mergeRight(holder, maybeKey);
}
function reset() {
holder = {};
}
function glue(input, glueChar) {
return input.split('\n').filter(x => x.trim().length > 0).map(x => x.trim()).join(glueChar === undefined ? ' ' : glueChar);
}
function createThenable(fn) {
return async function (...input) {
return fn(...input);
};
}
function ifElseAsync(condition, ifFn, elseFn) {
return (...inputs) => new Promise((resolve, reject) => {
const conditionPromise = createThenable(condition);
const ifFnPromise = createThenable(ifFn);
const elseFnPromise = createThenable(elseFn);
conditionPromise(...inputs).then(conditionResult => {
const promised = conditionResult === true ? ifFnPromise : elseFnPromise;
promised(...inputs).then(resolve).catch(reject);
}).catch(reject);
});
}
const getOccurrences = input => input.match(/{{\s*.+?\s*}}/g);
const getOccurrenceProp = occurrence => occurrence.replace(/{{\s*|\s*}}/g, '');
const replace$1 = ({
inputHolder,
prop,
replacer
}) => {
const regexBase = `{{${prop}}}`;
const regex = new RegExp(regexBase, 'g');
return inputHolder.replace(regex, replacer);
};
function interpolate(input, templateInput) {
if (arguments.length === 1) {
return _templateInput => interpolate(input, _templateInput);
}
const occurrences = getOccurrences(input);
if (occurrences === null) return input;
let inputHolder = input;
for (const occurrence of occurrences) {
const prop = getOccurrenceProp(occurrence);
inputHolder = replace$1({
inputHolder,
prop,
replacer: templateInput[prop]
});
}
return inputHolder;
}
function isPromise(x) {
return type(x) === 'Promise';
}
function isType(xType, x) {
if (arguments.length === 1) {
return xHolder => isType(xType, xHolder);
}
return type(x) === xType;
}
function all(predicate, list) {
if (arguments.length === 1) return _list => all(predicate, _list);
for (let i = 0; i < list.length; i++) {
if (!predicate(list[i])) return false;
}
return true;
}
function any(predicate, list) {
if (arguments.length === 1) return _list => any(predicate, _list);
let counter = 0;
while (counter < list.length) {
if (predicate(list[counter], counter)) {
return true;
}
counter++;
}
return false;
}
function baseSlice(array, start, end) {
let index = -1;
let {
length
} = array;
end = end > length ? length : end;
if (end < 0) {
end += length;
}
length = start > end ? 0 : end - start >>> 0;
start >>>= 0;
const result = Array(length);
while (++index < length) {
result[index] = array[index + start];
}
return result;
}
function init(listOrString) {
if (typeof listOrString === 'string') return listOrString.slice(0, -1);
return listOrString.length ? baseSlice(listOrString, 0, -1) : [];
}
function test(pattern, str) {
if (arguments.length === 1) return _str => test(pattern, _str);
if (typeof pattern === 'string') {
throw new TypeError(`R.test requires a value of type RegExp as its first argument; received "${pattern}"`);
}
return str.search(pattern) !== -1;
}
function toLower(str) {
return str.toLowerCase();
}
function isPrototype(input) {
const currentPrototype = input.prototype;
const list = [Number, String, Boolean, Promise];
let toReturn = false;
let counter = -1;
while (++counter < list.length && !toReturn) {
if (currentPrototype === list[counter].prototype) toReturn = true;
}
return toReturn;
}
function prototypeToString(input) {
const currentPrototype = input.prototype;
const list = [Number, String, Boolean, Promise];
const translatedList = ['Number', 'String', 'Boolean', 'Promise'];
let found;
let counter = -1;
while (++counter < list.length) {
if (currentPrototype === list[counter].prototype) found = counter;
}
return translatedList[found];
}
const typesWithoutPrototype = ['any', 'promise', 'async', 'function'];
function fromPrototypeToString(rule) {
if (isArray(rule) || rule === undefined || rule === null || rule.prototype === undefined || typesWithoutPrototype.includes(rule)) {
return {
rule,
parsed: false
};
}
if (String.prototype === rule.prototype) {
return {
rule: 'string',
parsed: true
};
}
if (Boolean.prototype === rule.prototype) {
return {
rule: 'boolean',
parsed: true
};
}
if (Number.prototype === rule.prototype) {
return {
rule: 'number',
parsed: true
};
}
return {
rule: type(rule.prototype).toLowerCase(),
parsed: true
};
}
function getRuleAndType(schema, requirementRaw) {
const ruleRaw = schema[requirementRaw];
const typeIs = type(ruleRaw);
const {
rule,
parsed
} = fromPrototypeToString(ruleRaw);
return {
rule,
ruleType: parsed ? 'String' : typeIs
};
}
function isValid({
input,
schema
}) {
if (input === undefined || schema === undefined) return false;
let flag = true;
const boom = boomFlag => {
if (!boomFlag) {
flag = false;
}
};
for (const requirementRaw in schema) {
if (flag) {
const isOptional = requirementRaw.endsWith('?');
const requirement = isOptional ? init(requirementRaw) : requirementRaw;
const {
rule,
ruleType
} = getRuleAndType(schema, requirementRaw);
const inputProp = input[requirement];
const inputPropType = type(input[requirement]);
const ok = isOptional && inputProp !== undefined || !isOptional;
if (!ok || rule === 'any' && inputProp != null || rule === inputProp) continue;
if (ruleType === 'Object') {
const isValidResult = isValid({
input: inputProp,
schema: rule
});
boom(isValidResult);
} else if (ruleType === 'String') {
boom(toLower(inputPropType) === rule);
} else if (typeof rule === 'function') {
boom(rule(inputProp));
} else if (ruleType === 'Array' && inputPropType === 'String') {
boom(includes$1(inputProp, rule));
} else if (ruleType === 'Array' && rule.length === 1 && inputPropType === 'Array') {
const [currentRule] = rule;
const currentRuleType = type(currentRule);
boom(currentRuleType === 'String' || currentRuleType === 'Object' || isPrototype(currentRule));
if (currentRuleType === 'Object' && flag) {
const isValidResult = all(inputPropInstance => isValid({
input: inputPropInstance,
schema: currentRule
}), inputProp);
boom(isValidResult);
} else if (flag) {
const actualRule = currentRuleType === 'String' ? currentRule : prototypeToString(currentRule);
const isInvalidResult = any(inputPropInstance => type(inputPropInstance).toLowerCase() !== actualRule.toLowerCase(), inputProp);
boom(!isInvalidResult);
}
} else if (ruleType === 'RegExp' && inputPropType === 'String') {
boom(test(rule, inputProp));
} else {
boom(false);
}
}
}
return flag;
}
function forEachObjIndexedFn(fn, obj) {
let index = 0;
const listKeys = keys$1(obj);
const len = listKeys.length;
while (index < len) {
const key = listKeys[index];
fn(obj[key], key, obj);
index++;
}
return obj;
}
function forEachObjIndexed(fn, list) {
if (arguments.length === 1) return _list => forEachObjIndexed(fn, _list);
if (list === undefined) return;
return forEachObjIndexedFn(fn, list);
}
function forEach(fn, iterable) {
if (arguments.length === 1) return _list => forEach(fn, _list);
if (iterable === undefined) return;
if (isArray(iterable)) {
let index = 0;
const len = iterable.length;
while (index < len) {
fn(iterable[index]);
index++;
}
} else return forEachObjIndexedFn(fn, iterable);
return iterable;
}
async function isValidAsync({
schema,
input
}) {
const asyncSchema = {};
const simpleSchema = {};
forEach((rule, prop) => {
if (isPromise(rule)) {
asyncSchema[prop] = rule;
} else {
simpleSchema[prop] = rule;
}
}, schema);
if (Object.keys(asyncSchema).length === 0) return isValid({
input,
schema
});
if (!isValid({
input,
schema: simpleSchema
})) return false;
let toReturn = true;
for (const singleRuleProp in asyncSchema) {
if (toReturn) {
const validated = await asyncSchema[singleRuleProp](input[singleRuleProp]);
if (!validated) toReturn = false;
}
}
return toReturn;
}
const Const = x => ({
x,
map: fn => Const(x)
});
function view(lens, target) {
if (arguments.length === 1) return _target => view(lens, _target);
return lens(Const)(target).x;
}
function lensEqFn(lens, target, input) {
return equals(view(lens, input), target);
}
const lensEq = curry(lensEqFn);
function lensSatisfiesFn(predicate, lens, input) {
return Boolean(predicate(view(lens, input)));
}
const lensSatisfies = curry(lensSatisfiesFn);
function mapKeys(changeKeyFn, obj) {
if (arguments.length === 1) return _obj => mapKeys(changeKeyFn, _obj);
const toReturn = {};
Object.keys(obj).forEach(prop => toReturn[changeKeyFn(prop)] = obj[prop]);
return toReturn;
}
async function mapParallelAsyncFn(fn, arr) {
const promised = arr.map((a, i) => fn(a, i));
return Promise.all(promised);
}
function mapParallelAsync(fn, arr) {
if (arguments.length === 1) {
return async holder => mapParallelAsyncFn(fn, holder);
}
return new Promise((resolve, reject) => {
mapParallelAsyncFn(fn, arr).then(resolve).catch(reject);
});
}
function splitEvery(sliceLength, listOrString) {
if (arguments.length === 1) {
return _listOrString => splitEvery(sliceLength, _listOrString);
}
if (sliceLength < 1) {
throw new Error('First argument to splitEvery must be a positive integer');
}
const willReturn = [];
let counter = 0;
while (counter < listOrString.length) {
willReturn.push(listOrString.slice(counter, counter += sliceLength));
}
return willReturn;
}
async function mapParallelAsyncWithLimitFn(iterable, limit, list) {
if (list.length < limit) return mapParallelAsync(iterable, list);
const slices = splitEvery(limit, list);
let toReturn = [];
for (const slice of slices) {
const iterableResult = await mapParallelAsyncFn(iterable, slice);
toReturn = [...toReturn, ...iterableResult];
}
return toReturn;
}
function mapParallelAsyncWithLimit(iterable, limit, list) {
if (arguments.length === 2) {
return async _list => mapParallelAsyncWithLimitFn(iterable, limit, _list);
}
return new Promise((resolve, reject) => {
mapParallelAsyncWithLimitFn(iterable, limit, list).then(resolve).catch(reject);
});
}
function mergeAll(arr) {
let willReturn = {};
map(val => {
willReturn = mergeRight(willReturn, val);
}, arr);
return willReturn;
}
function schemaToString(schema) {
if (type(schema) !== 'Object') {
return fromPrototypeToString(schema).rule;
}
return map(x => {
const {
rule,
parsed
} = fromPrototypeToString(x);
const xType = type(x);
if (xType === 'Function' && !parsed) return 'Function';
return parsed ? rule : xType;
}, schema);
}
function check(singleInput, schema) {
return isValid({
input: {
singleInput
},
schema: {
singleInput: schema
}
});
}
function ok(...inputs) {
return (...schemas) => {
let failedSchema;
const anyError = any((singleInput, i) => {
const schema = schemas[i] === undefined ? schemas[0] : schemas[i];
const checked = check(singleInput, schema);
if (!checked) {
failedSchema = JSON.stringify({
input: singleInput,
schema: schemaToString(schema)
});
}
return !checked;
}, inputs);
if (anyError) {
const errorMessage = inputs.length > 1 ? glue(`
Failed R.ok -
reason: ${failedSchema}
all inputs: ${JSON.stringify(inputs)}
all schemas: ${JSON.stringify(schemas.map(schemaToString))}
`, '\n') : `Failed R.ok - ${failedSchema}`;
throw new Error(errorMessage);
}
};
}
function mapToObject(fn, list) {
if (arguments.length === 1) {
return listHolder => mapToObject(fn, listHolder);
}
ok(type(fn), type(list))('Function', 'Array');
return mergeAll(map(fn, list));
}
async function mapToObjectAsyncFn(fn, list) {
let toReturn = {};
const innerIterable = async x => {
const intermediateResult = await fn(x);
if (intermediateResult === false) return;
toReturn = _objectSpread2(_objectSpread2({}, toReturn), intermediateResult);
};
await mapAsync(innerIterable, list);
return toReturn;
}
function mapToObjectAsync(fn, list) {
if (arguments.length === 1) {
return async _list => mapToObjectAsyncFn(fn, _list);
}
return new Promise((resolve, reject) => {
mapToObjectAsyncFn(fn, list).then(resolve).catch(reject);
});
}
function mapcat(tranformFn, listOfLists) {
if (arguments.length === 1) {
return _listOfLists => mapcat(tranformFn, _listOfLists);
}
let willReturn = [];
const intermediateResult = listOfLists.map(list => list.map(x => tranformFn(x)));
intermediateResult.forEach(transformedList => {
willReturn = [...willReturn, ...transformedList];
});
return willReturn;
}
function maybe(ifRule, whenIf, whenElse) {
const whenIfInput = ifRule && type(whenIf) === 'Function' ? whenIf() : whenIf;
const whenElseInput = !ifRule && type(whenElse) === 'Function' ? whenElse() : whenElse;
return ifRule ? whenIfInput : whenElseInput;
}
function _arity(n, fn) {
switch (n) {
case 0:
return function () {
return fn.apply(this, arguments);
};
case 1:
return function (_1) {
return fn.apply(this, arguments);
};
case 2:
return function (_1, _2) {
return fn.apply(this, arguments);
};
case 3:
return function (_1, _2, _3) {
return fn.apply(this, arguments);
};
case 4:
return function (_1, _2, _3, _4) {
return fn.apply(this, arguments);
};
case 5:
return function (_1, _2, _3, _4, _5) {
return fn.apply(this, arguments);
};
case 6:
return function (_1, _2, _3, _4, _5, _6) {
return fn.apply(this, arguments);
};
case 7:
return function (_1, _2, _3, _4, _5, _6, _7) {
return fn.apply(this, arguments);
};
case 8:
return function (_1, _2, _3, _4, _5, _6, _7, _8) {
return fn.apply(this, arguments);
};
case 9:
return function (_1, _2, _3, _4, _5, _6, _7, _8, _9) {
return fn.apply(this, arguments);
};
default:
return function (_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) {
return fn.apply(this, arguments);
};
}
}
function _pipe(f, g) {
return function () {
return g.call(this, f.apply(this, arguments));
};
}
function pipe() {
if (arguments.length === 0) {
throw new Error('pipe requires at least one argument');
}
return _arity(arguments[0].length, reduceFn(_pipe, arguments[0], Array.prototype.slice.call(arguments, 1, Infinity)));
}
function compose() {
if (arguments.length === 0) {
throw new Error('compose requires at least one argument');
}
return pipe.apply(this, Array.prototype.slice.call(arguments, 0).reverse());
}
function replaceFn(pattern, replacer, str) {
return str.replace(pattern, replacer);
}
const replace = curry(replaceFn);
function sort(sortFn, list) {
if (arguments.length === 1) return _list => sort(sortFn, _list);
return cloneList(list).sort(sortFn);
}
function take(howMany, listOrString) {
if (arguments.length === 1) return _listOrString => take(howMany, _listOrString);
if (howMany < 0) return listOrString.slice();
if (typeof listOrString === 'string') return listOrString.slice(0, howMany);
return baseSlice(listOrString, 0, howMany);
}
const cache = {};
const normalizeObject = obj => {
const sortFn = (a, b) => a > b ? 1 : -1;
const willReturn = {};
compose(map(prop => willReturn[prop] = obj[prop]), sort(sortFn))(Object.keys(obj));
return willReturn;
};
const stringify = a => {
const aType = type(a);
if (aType === 'String') {
return a;
} else if (['Function', 'Promise'].includes(aType)) {
const compacted = replace(/\s{1,}/g, ' ', a.toString());
return replace(/\s/g, '_', take(15, compacted));
} else if (aType === 'Object') {
return JSON.stringify(normalizeObject(a));
}
return JSON.stringify(a);
};
const generateProp = (fn, ...inputArguments) => {
let propString = '';
inputArguments.forEach(inputArgument => {
propString += `${stringify(inputArgument)}_`;
});
return `${propString}${stringify(fn)}`;
};
function memoize(fn, ...inputArguments) {
if (arguments.length === 1) {
return (...inputArgumentsHolder) => memoize(fn, ...inputArgumentsHolder);
}
const prop = generateProp(fn, ...inputArguments);
if (prop in cache) return cache[prop];
if (type(fn) === 'Async') {
return new Promise(resolve => {
fn(...inputArguments).then(result => {
cache[prop] = result;
resolve(result);
});
});
}
const result = fn(...inputArguments);
cache[prop] = result;
return result;
}
function memoizeWith(keyGen, fn) {
if (arguments.length === 1) {
return _fn => memoizeWith(keyGen, _fn);
}
const cache = new Map();
return function () {
const key = keyGen.apply(this, arguments);
if (!cache.has(key)) {
cache.set(key, fn.apply(this, arguments));
}
return cache.get(key);
};
}
function nextIndex(index, list) {
return index >= list.length - 1 ? 0 : index + 1;
}
function noop() {}
function clone(input) {
const out = isArray(input) ? Array(input.length) : {};
if (input && input.getTime) return new Date(input.getTime());
for (const key in input) {
const v = input[key];
out[key] = typeof v === 'object' && v !== null ? v.getTime ? new Date(v.getTime()) : clone(v) : v;
}
return out;
}
function mergeDeepRight(target, source) {
if (arguments.length === 1) {
return sourceHolder => mergeDeepRight(target, sourceHolder);
}
const willReturn = clone(target);
Object.keys(source).forEach(key => {
if (type(source[key]) === 'Object') {
if (type(target[key]) === 'Object') {
willReturn[key] = mergeDeepRight(target[key], source[key]);
} else {
willReturn[key] = source[key];
}
} else {
willReturn[key] = source[key];
}
});
return willReturn;
}
function partialObject(fn, input) {
return nextInput => fn(mergeDeepRight(nextInput, input));
}
async function whenObject(predicate, input) {
const yes = {};
const no = {};
Object.entries(input).forEach(([prop, value]) => {
if (predicate(value, prop)) {
yes[prop] = value;
} else {
no[prop] = value;
}
});
return [yes, no];
}
async function partitionAsyncFn(predicate, input) {
if (!isArray(input)) return whenObject(predicate, input);
const yes = [];
const no = [];
for (const i in input) {
const predicateResult = await predicate(input[i], Number(i));
if (predicateResult) {
yes.push(input[i]);
} else {
no.push(input[i]);
}
}
return [yes, no];
}
function partitionAsync(predicate, list) {
if (arguments.length === 1) {
return async _list => partitionAsyncFn(predicate, _list);
}
return new Promise((resolve, reject) => {
partitionAsyncFn(predicate, list).then(resolve).catch(reject);
});
}
function partitionObject(predicate, iterable) {
const yes = {};
const no = {};
Object.entries(iterable).forEach(([prop, value]) => {
if (predicate(value, prop)) {
yes[prop] = value;
} else {
no[prop] = value;
}
});
return [yes, no];
}
function partitionArray(predicate, list, indexed = false) {
const yes = [];
const no = [];
let counter = -1;
while (counter++ < list.length - 1) {
if (indexed ? predicate(list[counter], counter) : predicate(list[counter])) {
yes.push(list[counter]);
} else {
no.push(list[counter]);
}
}
return [yes, no];
}
function partition(predicate, iterable) {
if (arguments.length === 1) {
return listHolder => partition(predicate, listHolder);
}
if (!isArray(iterable)) return partitionObject(predicate, iterable);
return partitionArray(predicate, iterable);
}
function partitionIndexed(predicate, iterable) {
if (arguments.length === 1) {
return listHolder => partitionIndexed(predicate, listHolder);
}
if (!isArray(iterable)) return partitionObject(predicate, iterable);
return partitionArray(predicate, iterable, true);
}
function pass(...inputs) {
return (...schemas) => any((x, i) => {
const schema = schemas[i] === undefined ? schemas[0] : schemas[i];
return !check(x, schema);
}, inputs) === false;
}
function piped(...inputs) {
const [input, ...fnList] = inputs;
return pipe(...fnList)(input);
}
function pipedAsync(input, ...fnList) {
return pipeAsync(...fnList)(input);
}
function prevIndex(index, list) {
return index === 0 ? list.length - 1 : index - 1;
}
function produce(rules, input) {
if (arguments.length === 1) {
return _input => produce(rules, _input);
}
return map(singleRule => type(singleRule) === 'Object' ? produce(singleRule, input) : singleRule(input), rules);
}
function promisify({
condition,
input,
prop
}) {
return new Promise((resolve, reject) => {
if (type(condition) !== 'Promise') {
return resolve({
type: prop,
payload: condition(input)
});
}
condition(input).then(result => {
resolve({
type: prop,
payload: result
});
}).catch(err => reject(err));
});
}
function produceFn(conditions, input) {
let asyncConditionsFlag = false;
for (const prop in conditions) {
if (asyncConditionsFlag === false && type(conditions[prop]) === 'Promise') {
asyncConditionsFlag = true;
}
}
if (asyncConditionsFlag === false) {
const willReturn = {};
for (const prop in conditions) {
willReturn[prop] = conditions[prop](input);
}
return Promise.resolve(willReturn);
}
const promised = [];
for (const prop in conditions) {
const condition = conditions[prop];
promised.push(promisify({
input,
condition,
prop
}));
}
return new Promise((resolve, reject) => {
Promise.all(promised).then(results => {
const willReturn = {};
map(result => willReturn[result.type] = result.payload, results);
resolve(willReturn);
}).catch(err => reject(err));
});
}
function produceAsync(conditions, input) {
if (arguments.length === 1) {
return async _input => produceFn(conditions, _input);
}
return new Promise((resolve, reject) => {
produceFn(conditions, input).then(resolve).catch(reject);
});
}
function random(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function rejectIndexed(predicate, iterable) {
if (arguments.length === 1) return _iterable => rejectIndexed(predicate, _iterable);
if (!iterable) throw new Error(`"${iterable}" is not iterable`);
if (isArray(iterable)) return filterArray((x, i) => !predicate(x, i), iterable, true);
return filterObject((x, prop) => !predicate(x, prop), iterable);
}
function remove(inputs, text) {
if (arguments.length === 1) {
return textHolder => remove(inputs, textHolder);
}
if (type(text) !== 'String') {
throw new Error(`R.remove requires string not ${type(text)}`);
}
if (type(inputs) !== 'Array') {
return replace(inputs, '', text);
}
let textCopy = text;
inputs.forEach(singleInput => {
textCopy = replace(singleInput, '', textCopy).trim();
});
return textCopy;
}
function compare(a, b) {
return String(a) === String(b);
}
function includes(a, list) {
let index = -1;
const {
length
} = list;
while (++index < length) if (compare(list[index], a)) return true;
return false;
}
function omit(propsToOmit, obj) {
if (arguments.length === 1) return _obj => omit(propsToOmit, _obj);
if (obj === null || obj === undefined) return undefined;
const propsToOmitValue = createPath(propsToOmit, ',');
const willReturn = {};
for (const key in obj) if (!includes(key, propsToOmitValue)) willReturn[key] = obj[key];
return willReturn;
}
function renameProps(conditions, inputObject) {
if (arguments.length === 1) {
return inputObjectHolder => renameProps(conditions, inputObjectHolder);
}
const renamed = {};
Object.keys(conditions).forEach(condition => {
if (Object.keys(inputObject).includes(condition)) {
renamed[conditions[condition]] = inputObject[condition];
}
});
return mergeRight(renamed, omit(Object.keys(conditions), inputObject));
}
function replaceAllFn(patterns, replacer, input) {
ok(patterns, replacer, input)(Array, String, String);
let text = input;
patterns.forEach(singlePattern => {
text = text.replace(singlePattern, replacer);
});
return text;
}
const replaceAll = curry(replaceAllFn);
function shuffle(arrayRaw) {
const array = arrayRaw.concat();
let counter = array.length;
while (counter > 0) {
const index = Math.floor(Math.random() * counter);
counter--;
const temp = array[counter];
array[counter] = array[index];
array[index] = temp;
}
return array;
}
function sortBy(sortFn, list) {
if (arguments.length === 1) return _list => sortBy(sortFn, _list);
const clone = cloneList(list);
return clone.sort((a, b) => {
const aSortResult = sortFn(a);
const bSortResult = sortFn(b);
if (aSortResult === bSortResult) return 0;
return aSortResult < bSortResult ? -1 : 1;
});
}
function sortByPath(sortPath, list) {
if (arguments.length === 1) return _list => sortByPath(sortPath, _list);
return sortBy(path(sortPath), list);
}
function singleSort(a, b, sortPaths) {
let toReturn = 0;
sortPaths.forEach(singlePath => {
if (toReturn !== 0) return;
const aResult = path(singlePath, a);
const bResult = path(singlePath, b);
if ([aResult, bResult].includes(undefined)) return;
if (aResult === bResult) return;
toReturn = aResult > bResult ? 1 : -1;
});
return toReturn;
}
function sortByProps(sortPaths, list) {
if (arguments.length === 1) return _list => sortByProps(sortPaths, _list);
const clone = list.slice();
clone.sort((a, b) => singleSort(a, b, sortPaths));
return clone;
}
function sortObject(predicate, obj) {
if (arguments.length === 1) {
return _obj => sortObject(predicate, _obj);
}
const keys = Object.keys(obj);
const sortedKeys = sort((a, b) => predicate(a, b, obj[a], obj[b]), keys);
const toReturn = {};
sortedKeys.forEach(singleKey => {
toReturn[singleKey] = obj[singleKey];
});
return toReturn;
}
const NO_MATCH_FOUND = Symbol ? Symbol('NO_MATCH_FOUND') : undefined;
const getMatchingKeyValuePair = (cases, testValue, defaultValue) => {
let iterationValue;
for (let index = 0; index < cases.length; index++) {
iterationValue = cases[index].test(testValue);
if (iterationValue !== NO_MATCH_FOUND) {
return iterationValue;
}
}
return defaultValue;
};
const isEqual = (testValue, matchValue) => {
const willReturn = typeof testValue === 'function' ? testValue(matchValue) : equals(testValue, matchValue);
return willReturn;
};
const is$1 = (testValue, matchResult = true) => ({
key: testValue,
test: matchValue => isEqual(testValue, matchValue) ? matchResult : NO_MATCH_FOUND
});
class Switchem {
constructor(defaultValue, cases, willMatch) {
if (cases === undefined && willMatch === undefined) {
this.cases = [];
this.defaultValue = undefined;
this.willMatch = defaultValue;
} else {
this.cases = cases;
this.defaultValue = defaultValue;
this.willMatch = willMatch;
}
return this;
}
default(defaultValue) {
const holder = new Switchem(defaultValue, this.cases, this.willMatch);
return holder.match(this.willMatch);
}
is(testValue, matchResult) {
return new Switchem(this.defaultValue, [...this.cases, is$1(testValue, matchResult)], this.willMatch);
}
match(matchValue) {
return getMatchingKeyValuePair(this.cases, matchValue, this.defaultValue);
}
}
function switcher(input) {
return new Switchem(input);
}
function takeUntil(predicate, list) {
const toReturn = [];
let stopFlag = false;
let counter = -1;
while (stopFlag === false && counter++ < list.length - 1) {
if (predicate(list[counter])) {
stopFlag = true;
} else {
toReturn.push(list[counter]);
}
}
return toReturn;
}
async function tapAsyncFn(fn, input) {
await fn(input);
return input;
}
function tapAsync(fn, input) {
if (arguments.length === 1) {
return async _input => tapAsyncFn(fn, _input);
}
return new Promise((resolve, reject) => {
tapAsyncFn(fn, input).then(resolve).catch(reject);
});
}
function throttle(fn, ms) {
let wait = false;
let result;
return function (...input) {
if (!wait) {
result = fn.apply(null, input);
wait = true;
setTimeout(() => {
wait = false;
}, ms);
}
return result;
};
}
function toDecimal(number, charsAfterDecimalPoint = 2) {
return Number(parseFloat(String(number)).toFixed(charsAfterDecimalPoint));
}
function tryCatchAsync(fn, fallback) {
return (...inputs) => new Promise(resolve => {
fn(...inputs).then(resolve).catch(err => {
if (type(fallback) !== 'Function') {
return resolve(fallback);
}
if (type(fallback) !== 'Promise') {
return resolve(fallback(err, ...inputs));
}
fallback(err, ...inputs).then(resolve).catch(resolve);
});
});
}
function updateObject(rules, obj) {
if (arguments.length === 1) return _obj => updateObject(rules, _obj);
let clone = _objectSpread2({}, obj);
rules.forEach(([objectPath, newValue]) => {
clone = assocPath(objectPath, newValue, clone);
});
return clone;
}
function isFalsy(input) {
return input === undefined || input === null || Number.isNaN(input) === true;
}
function defaultTo(defaultArgument, input) {
if (arguments.length === 1) {
return _input => defaultTo(defaultArgument, _input);
}
return isFalsy(input) ? defaultArgument : input;
}
function viewOrFn(fallback, lens, input) {
return defaultTo(fallback, view(lens, input)