@plurid/plurid-functions
Version:
General Utility Functions for Plurid Applications
998 lines (889 loc) • 26.8 kB
JavaScript
const range = (start, end) => {
const length = end - start;
return Array.from({
length: length
}, ((_, i) => start + i));
};
const equal = (a, b) => {
if (a === b) return true;
if (a == null || b == null) return false;
if (a.length !== b.length) return false;
for (let i = 0; i < a.length; i++) {
if (a[i] !== b[i]) return false;
}
return true;
};
const move = (items, from, to) => {
const newItems = [ ...items ];
newItems.splice(to, 0, newItems.splice(from, 1)[0]);
return newItems;
};
const swap = (items, a, b) => {
const newItems = [ ...items ];
[newItems[a], newItems[b]] = [ newItems[b], newItems[a] ];
return newItems;
};
const unique = (array, identifier = "id") => {
const result = [];
const map = new Map;
for (const item of array.reverse()) {
if (!map.has(item[identifier])) {
map.set(item[identifier], true);
result.push(Object.assign({}, item));
}
}
return result.reverse();
};
const shuffle$1 = values => {
const array = [ ...values ];
let m = array.length;
let i;
let temporary;
while (m) {
i = Math.floor(Math.random() * m--);
temporary = array[m];
array[m] = array[i];
array[i] = temporary;
temporary = undefined;
}
return array;
};
var index$i = Object.freeze({
__proto__: null,
range: range,
equal: equal,
move: move,
swap: swap,
unique: unique,
shuffle: shuffle$1
});
const copy = text => {
const el = document.createElement("textarea");
el.value = text;
el.setAttribute("readonly", "");
el.style.position = "absolute";
el.style.left = "-9999px";
document.body.appendChild(el);
const selected = document.getSelection().rangeCount > 0 ? document.getSelection().getRangeAt(0) : false;
el.select();
document.execCommand("copy");
document.body.removeChild(el);
if (selected) {
document.getSelection().removeAllRanges();
document.getSelection().addRange(selected);
}
};
var index$h = Object.freeze({
__proto__: null,
copy: copy
});
const parse = value => {
if (!value) {
return;
}
try {
const data = JSON.parse(value);
return data;
} catch (error) {
return;
}
};
const parseFromString = value => {
try {
const data = JSON.parse(value);
return data;
} catch (error) {
return value;
}
};
const stringifyOrDefault = data => {
if (typeof data === "undefined") {
return undefined;
}
if (typeof data === "string") {
return data;
}
return JSON.stringify(data, ((_, value) => typeof value === "undefined" ? null : value));
};
var index$g = Object.freeze({
__proto__: null,
parse: parse,
parseFromString: parseFromString,
stringifyOrDefault: stringifyOrDefault
});
const placeCaretAtEnd = el => {
el.focus();
if (typeof window.getSelection != "undefined" && typeof document.createRange != "undefined") {
const range = document.createRange();
range.selectNodeContents(el);
range.collapse(false);
const sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (typeof document.body.createTextRange !== "undefined") {
var textRange = document.body.createTextRange();
textRange.moveToElementText(el);
textRange.collapse(false);
textRange.select();
}
};
const getEventPath = event => {
if (event.composedPath) {
return event.composedPath();
}
return event["path"] || [];
};
const verifyPathInputElement = path => {
if (!path) {
return false;
}
let input = false;
path.some((element => {
if (element.tagName === "INPUT" || element.tagName === "TEXTAREA" || element.contentEditable === "true") {
input = true;
return true;
}
return false;
}));
return input;
};
const verifyEventInput = event => {
const path = getEventPath(event);
return verifyPathInputElement(path);
};
const downloadContent = (filename, content, dataString = "data:text/plain;charset=utf-8,") => {
const element = document.createElement("a");
element.setAttribute("href", dataString + encodeURIComponent(content));
element.setAttribute("download", filename);
element.style.display = "none";
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
};
var index$f = Object.freeze({
__proto__: null,
placeCaretAtEnd: placeCaretAtEnd,
getEventPath: getEventPath,
verifyPathInputElement: verifyPathInputElement,
verifyEventInput: verifyEventInput,
downloadContent: downloadContent
});
const deleteTypenames = data => {
let dataObject = null;
if (Array.isArray(data)) {
dataObject = [ ...data ];
} else {
dataObject = Object.assign({}, data);
}
for (const property in dataObject) {
if (property === "__typename") {
delete dataObject[property];
}
if (typeof dataObject[property] === "object" && dataObject[property] !== null) {
const dataObjectProperty = deleteTypenames(dataObject[property]);
dataObject[property] = dataObjectProperty;
}
}
return dataObject;
};
var index$e = Object.freeze({
__proto__: null,
deleteTypenames: deleteTypenames
});
const load = (url, anonymous = true) => new Promise((response => {
const image = new Image;
image.onload = () => response(image);
if (anonymous) {
image.crossOrigin = "anonymous";
}
image.src = url;
}));
var index$d = Object.freeze({
__proto__: null,
load: load
});
const isBrowser = typeof window !== "undefined" && {}.toString.call(window) === "[object Window]";
const isNode = typeof global !== "undefined" && {}.toString.call(global) === "[object global]";
var index$c = Object.freeze({
__proto__: null,
isBrowser: isBrowser,
isNode: isNode
});
const v4Browser = (separator = "") => ([ 1e7 ] + separator + 1e3 + separator + 4e3 + separator + 8e3 + separator + 1e11).replace(/[018]/g, (c => (((c ^ crypto.getRandomValues(new Uint8Array(1))[0]) & 15) >> c / 4).toString(16)));
const v4Node = (separator = "") => {
const crypto = eval("require")("crypto");
const id = crypto.randomBytes(16).toString("hex");
if (!separator) {
return id;
}
return id.slice(0, 8) + separator + id.slice(8, 12) + separator + id.slice(12, 16) + separator + id.slice(16, 20) + separator + id.slice(20);
};
const generate = (separator = "", version = "v4") => {
if (version === "v4") {
if (isBrowser) {
return v4Browser(separator);
}
if (isNode) {
return v4Node(separator);
}
}
return "";
};
const multiple = (count = 2, separator) => {
let value = "";
for (let i = 0; i < count; i++) {
value += generate(separator);
}
return value;
};
var index$b = Object.freeze({
__proto__: null,
v4Browser: v4Browser,
v4Node: v4Node,
generate: generate,
multiple: multiple
});
const identify = (items, idEntity) => {
const idProperty = idEntity || "id";
const identifiedItems = items.map((item => {
const idValue = item[idProperty] || generate();
const identifiedItem = Object.assign({}, item);
identifiedItem[idProperty] = idValue;
return identifiedItem;
}));
return identifiedItems;
};
function create(items, type, idKey) {
const id = idKey || "id";
const typeProperty = type || "object";
switch (typeProperty) {
case "map":
{
const mappedItems = new Map;
items.map((item => {
const idValue = item[id] || generate();
mappedItems.set(idValue, item);
}));
return mappedItems;
}
case "object":
{
const indexedItems = {};
for (const item of items) {
const itemID = item[id];
if (!itemID) {
continue;
}
indexedItems[itemID] = item;
}
return indexedItems;
}
}
return;
}
var index$a = Object.freeze({
__proto__: null,
identify: identify,
create: create
});
var OPERATION_TYPES;
(function(OPERATION_TYPES) {
OPERATION_TYPES["SUM"] = "SUM";
OPERATION_TYPES["PRODUCT"] = "PRODUCT";
OPERATION_TYPES["DIFFERENCE"] = "DIFFERENCE";
})(OPERATION_TYPES || (OPERATION_TYPES = {}));
const operation = (type, values, index) => {
const _index = typeof index === "number" ? index : values.length;
if (_index === 0) {
return 0;
}
if (_index > values.length) {
throw "sum(): Index Out of Bounds.";
}
const _values = values.slice(0, _index);
return _values.reduce(((total, val) => {
switch (type) {
case OPERATION_TYPES.SUM:
return total + val;
case OPERATION_TYPES.PRODUCT:
return total * val;
case OPERATION_TYPES.DIFFERENCE:
return total - val;
default:
return total + val;
}
}));
};
const sum = (values, index) => {
const value = operation(OPERATION_TYPES.SUM, values, index);
return value;
};
const product = (values, index) => {
const value = operation(OPERATION_TYPES.PRODUCT, values, index);
return value;
};
var arithmetic = Object.freeze({
__proto__: null,
get OPERATION_TYPES() {
return OPERATION_TYPES;
},
operation: operation,
sum: sum,
product: product
});
const tau = Math.PI * 2;
var constants = Object.freeze({
__proto__: null,
tau: tau
});
const toDegrees = angle => angle * (180 / Math.PI);
const toRadians = angle => angle * (Math.PI / 180);
var geometry = Object.freeze({
__proto__: null,
toDegrees: toDegrees,
toRadians: toRadians
});
const checkIntegerNonUnit = value => {
if (Number.isInteger(value) && value !== 1) {
return true;
}
return false;
};
const normalizeBetween = (value, lower, upper) => {
if (value < lower) {
return lower;
}
if (value > upper) {
return upper;
}
return value;
};
var numbers = Object.freeze({
__proto__: null,
checkIntegerNonUnit: checkIntegerNonUnit,
normalizeBetween: normalizeBetween
});
const number = (maximum = 1, minimum = 0, integer = false, closedInterval = true) => {
const value = Math.random() * (maximum - minimum);
if (!integer) {
return value + minimum;
}
if (!closedInterval) {
return Math.floor(value) + minimum;
}
const randomInterval = Math.random();
return Math.floor(value) + minimum + Math.round(randomInterval);
};
var random = Object.freeze({
__proto__: null,
number: number
});
var index$9 = Object.freeze({
__proto__: null,
arithmetic: arithmetic,
constants: constants,
geometry: geometry,
numbers: numbers,
random: random
});
const debounce = (func, wait, immediate = false) => {
let timeout;
return function() {
let context = this;
let args = arguments;
let later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
let callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
function debouncedCallback(callback, wait) {
let argsRef;
let timeout;
function cleanup() {
if (timeout) {
clearTimeout(timeout);
}
}
return function debouncedCallback(...args) {
argsRef = args;
cleanup();
timeout = setTimeout((() => {
if (argsRef) {
callback(...argsRef);
}
}), wait);
};
}
var index$8 = Object.freeze({
__proto__: null,
debounce: debounce,
debouncedCallback: debouncedCallback
});
const ipv4Regex = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$/;
const ipv6Regex = /(([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4})/;
const originRegex = /https?:\/\/(?:w{1,3}\.)?[^\s.]+(?:\.[a-z]+)*(?::\d+)?((?:\/\w+)|(?:-\w+))*\/?(?![^<]*(?:<\/\w+>|\/))/;
const isIPv4 = value => {
if (typeof value !== "string") {
return false;
}
return ipv4Regex.test(value);
};
const isIPv6 = value => {
if (typeof value !== "string") {
return false;
}
return ipv6Regex.test(value);
};
const isIP = value => {
const ipv4 = isIPv4(value);
if (ipv4) {
return "ipv4";
}
const ipv6 = isIPv6(value);
if (ipv6) {
return "ipv6";
}
return;
};
const isOrigin = value => {
if (typeof value !== "string") {
return false;
}
return originRegex.test(value);
};
var index$7 = Object.freeze({
__proto__: null,
isIPv4: isIPv4,
isIPv6: isIPv6,
isIP: isIP,
isOrigin: isOrigin
});
const isObject = entity => {
if (typeof entity === "object" && !Array.isArray(entity) && entity !== null) {
return true;
}
return false;
};
const getNested = (data, path, separator = ".") => {
try {
return path.replace("[", separator).replace("]", "").split(separator).reduce(((obj, property) => obj[property]), data);
} catch (err) {
return undefined;
}
};
const updateNested = (data, path, update, separator = ".") => {
try {
const split = path.split(separator);
let current = data;
while (split.length > 1) {
const part = split.shift();
if (!part) {
return;
}
const parent = current;
current = current[part];
if (undefined === current) {
parent[part] = {};
current = parent[part];
}
}
if (split.length === 1) {
const part = split.shift();
if (!part) {
return;
}
current[part] = update;
}
return data;
} catch (err) {
return;
}
};
const deepClone = (obj, hash = new WeakMap) => {
if (Object(obj) !== obj) return obj;
if (hash.has(obj)) return hash.get(obj);
const result = obj instanceof Set ? new Set(obj) : obj instanceof Map ? new Map(Array.from(obj, (([key, val]) => [ key, deepClone(val, hash) ]))) : obj instanceof Date ? new Date(obj) : obj instanceof RegExp ? new RegExp(obj.source, obj.flags) : obj.constructor ? new obj.constructor : Object.create(null);
hash.set(obj, result);
return Object.assign(result, ...Object.keys(obj).map((key => ({
[key]: deepClone(obj[key], hash)
}))));
};
const clone = (data, type) => {
if (!type || type === "json") {
const cloned = JSON.parse(JSON.stringify(data));
return cloned;
}
const deepCloned = deepClone(data);
return deepCloned;
};
const mapToObject = map => {
let obj = {};
for (let [key, value] of map) {
obj[key] = value;
}
return obj;
};
const clean = (object, onlyUndefined = false) => {
const clonedObject = clone(object, "any");
for (const [key, value] of Object.entries(clonedObject)) {
if (typeof value === "undefined") {
delete clonedObject[key];
}
if (!onlyUndefined) {
if (value === null) {
delete clonedObject[key];
}
}
if (isObject(value)) {
clonedObject[key] = clean(value, onlyUndefined);
}
}
return clonedObject;
};
const flip = obj => Object.entries(obj).reduce(((flip, entry) => {
const [key, value] = entry;
if (typeof value !== "string" && typeof value !== "number") {
return flip;
}
flip[value] = key;
return flip;
}), {});
const merge = (object, target, resolvers = {}, trunk) => {
const result = {};
const keysObject = trunk ? getNested(object, trunk) : object;
for (const key in keysObject) {
const path = trunk ? trunk + "." + key : key;
const resolver = resolvers[path];
if (resolver) {
if (typeof resolver === "function") {
const value = resolver();
result[key] = value;
continue;
}
result[key] = resolver;
continue;
}
const field = getNested(object, path);
if (isObject(field)) {
const value = merge(object, target, resolvers, path);
result[key] = value;
continue;
}
const targetField = getNested(target, path);
if (typeof targetField !== "undefined") {
result[key] = targetField;
continue;
}
result[key] = field;
}
return result;
};
const equals = (object, target, trunk) => {
const keysObject = trunk ? getNested(object, trunk) : object;
for (const key in keysObject) {
const path = trunk ? trunk + "." + key : key;
const valueObject = getNested(object, path);
const valueTarget = getNested(target, path);
if (isObject(valueObject)) {
const equal = equals(object, target, path);
if (!equal) {
return false;
}
continue;
}
if (valueObject !== valueTarget) {
return false;
}
}
return true;
};
const omit = (object, keys, trunk) => {
const result = {};
const keysObject = trunk ? getNested(object, trunk) : object;
for (const key in keysObject) {
const path = trunk ? trunk + "." + key : key;
if (typeof keys === "string") {
if (keys === path) {
continue;
}
} else if (keys.includes(path)) {
continue;
}
const field = getNested(object, path);
if (isObject(field)) {
const value = omit(object, keys, path);
result[key] = value;
continue;
}
result[key] = field;
}
return result;
};
var index$6 = Object.freeze({
__proto__: null,
isObject: isObject,
getNested: getNested,
updateNested: updateNested,
clone: clone,
mapToObject: mapToObject,
clean: clean,
flip: flip,
merge: merge,
equals: equals,
omit: omit
});
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) {
return value instanceof P ? value : new P((function(resolve) {
resolve(value);
}));
}
return new (P || (P = Promise))((function(resolve, reject) {
function fulfilled(value) {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
}
function rejected(value) {
try {
step(generator["throw"](value));
} catch (e) {
reject(e);
}
}
function step(result) {
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
}
step((generator = generator.apply(thisArg, _arguments || [])).next());
}));
}
const browserDigestMessage = (message, algorithm = "sha256") => __awaiter(void 0, void 0, void 0, (function*() {
algorithm = algorithm.toUpperCase().replace("SHA", "SHA-");
const msgUint8 = (new TextEncoder).encode(message);
const hashBuffer = yield window.crypto.subtle.digest(algorithm, msgUint8);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map((b => b.toString(16).padStart(2, "0"))).join("");
return hashHex;
}));
const compute = (data, algorithm = "sha256") => __awaiter(void 0, void 0, void 0, (function*() {
if (typeof window !== "undefined") {
return yield browserDigestMessage(data, algorithm);
}
const crypto = eval("require")("crypto");
return crypto.createHash(algorithm).update(data).digest("hex");
}));
var index$5 = Object.freeze({
__proto__: null,
compute: compute
});
const humanFormat = (size, binary = false) => {
const block = binary ? 1024 : 1e3;
if (size < block) {
return size + " B";
}
const i = Math.floor(Math.log(size) / Math.log(block));
let num = size / Math.pow(block, i);
const round = Math.round(num);
num = round < 10 ? num.toFixed(2) : round < 100 ? num.toFixed(1) : round;
const binaryText = binary ? "i" : "";
const prefix = "KMGTPEZY"[i - 1] + binaryText;
return `${num} ${prefix}B`;
};
var index$4 = Object.freeze({
__proto__: null,
humanFormat: humanFormat
});
const loadState = name => {
try {
const serializedState = localStorage.getItem(name);
if (serializedState === null) {
return;
}
return JSON.parse(serializedState);
} catch (error) {
return;
}
};
const saveState = (state, name) => {
try {
const serializedState = JSON.stringify(state);
localStorage.setItem(name, serializedState);
} catch (error) {
return;
}
};
var index$3 = Object.freeze({
__proto__: null,
loadState: loadState,
saveState: saveState
});
const removeWhitespace = value => {
if (!value) {
return "";
}
return value.replace(/\s+/g, " ").trim();
};
const capitalize = value => value.charAt(0).toUpperCase() + value.slice(1);
const capitalizeAll = value => {
const splits = value.split(" ");
const capitalizedSplits = splits.map((split => capitalize(split)));
return capitalizedSplits.join(" ");
};
const truncate = (value, length = 50, ending = "…") => {
if (!value) {
return "";
}
if (value.length <= length) {
return value;
}
return value.slice(0, length) + ending;
};
const trimMiddle = (value, length = 6, middle = "…", startLength, endLength) => {
if (!value) {
return "";
}
const lengthSum = (startLength !== null && startLength !== void 0 ? startLength : length) + (endLength !== null && endLength !== void 0 ? endLength : length);
if (value.length < lengthSum + middle.length) {
return value;
}
const start = value.slice(0, startLength !== null && startLength !== void 0 ? startLength : length);
const end = value.slice(value.length - (endLength !== null && endLength !== void 0 ? endLength : length));
const trim = start + middle + end;
return trim;
};
const removeLastWord = text => {
const wordsArray = text.split(" ");
if (wordsArray.length === 1) {
return "";
}
const removedLastWordArray = wordsArray.slice(0, wordsArray.length - 1);
const words = removedLastWordArray.join(" ");
return words;
};
const pascalCaseToDotNotation = (value, lowercase = true) => {
let newValue = "";
for (let i = 0; i < value.length; i++) {
const letter = value[i];
if (letter === letter.toUpperCase()) {
if (i !== 0) {
newValue += ".";
}
if (lowercase) {
newValue += letter.toLowerCase();
} else {
newValue += letter;
}
} else {
newValue += letter;
}
}
return newValue;
};
const pascalCaseToSnakeCase = value => {
const snakeCase = value.replace(/([A-Z][a-z])/g, " $1").trim().split(" ").join("_");
return snakeCase;
};
const snakeCaseToPascalCase = value => {
const pascalCase = value.toLowerCase().split("_").map((word => word.charAt(0).toUpperCase() + word.slice(1))).join("");
return pascalCase;
};
const toCamelCase = value => value.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, ((_, character) => character.toUpperCase()));
const shuffle = text => {
const shuffled = shuffle$1(text.split(""));
return shuffled.join("");
};
const trimStart = (value, character, count = 1) => {
if (count = 0) {
return value;
}
if (value[0] === character) {
return trimStart(value.slice(1), character, count - 1);
}
return value;
};
const trimEnd = (value, character, count = 1) => {
if (count = 0) {
return value;
}
if (value[value.length - 1] === character) {
return trimEnd(value.slice(0, value.length - 1), character, count - 1);
}
return value;
};
function pluralize(value, text, overload) {
if (typeof value !== "number" || typeof text !== "string") {
return "";
}
let end = "s";
let replace;
if (typeof overload === "string") {
end = overload;
} else {
replace = overload.replace;
}
const space = " ";
if (value === 1) {
return value + space + text;
}
if (replace) {
return value + space + replace;
}
return value + space + text + end;
}
var index$2 = Object.freeze({
__proto__: null,
removeWhitespace: removeWhitespace,
capitalize: capitalize,
capitalizeAll: capitalizeAll,
truncate: truncate,
trimMiddle: trimMiddle,
removeLastWord: removeLastWord,
pascalCaseToDotNotation: pascalCaseToDotNotation,
pascalCaseToSnakeCase: pascalCaseToSnakeCase,
snakeCaseToPascalCase: snakeCaseToPascalCase,
toCamelCase: toCamelCase,
shuffle: shuffle,
trimStart: trimStart,
trimEnd: trimEnd,
pluralize: pluralize
});
const now = () => Math.floor(Date.now() / 1e3);
const stamp = () => {
const date = new Date;
return `${date.toLocaleTimeString()} - ${date.toLocaleDateString()}`;
};
const delay = (value = 500) => __awaiter(void 0, void 0, void 0, (function*() {
yield new Promise((resolve => {
setTimeout((() => {
resolve(true);
}), value);
}));
}));
var index$1 = Object.freeze({
__proto__: null,
now: now,
stamp: stamp,
delay: delay
});
const removeTrailingSlash = value => {
if (!value) {
return "";
}
if (value.endsWith("/")) {
return removeTrailingSlash(value.slice(0, value.length - 1));
}
return value;
};
var index = Object.freeze({
__proto__: null,
removeTrailingSlash: removeTrailingSlash
});
export { index$i as arrays, index$h as clipboard, index$g as data, index$f as dom, index$e as graphql, index$d as image, index$a as indexing, index$9 as mathematics, index$8 as meta, index$7 as network, index$6 as objects, index$c as runtime, index$5 as sha, index$4 as size, index$3 as storage, index$2 as strings, index$1 as time, index as url, index$b as uuid };
//# sourceMappingURL=index.es.js.map