UNPKG

@harlem/utilities

Version:

Harlem utilities package

264 lines (243 loc) 6.06 kB
// src/function/identity.ts function identity(value) { return value; } // src/type/get-type.ts function getType(input) { return Object.prototype.toString.call(input).slice(8, -1).toLowerCase(); } // src/type/is-function.ts function isFunction(value) { return getType(value) === "function"; } // src/type/is-string.ts function isString(value) { return getType(value) === "string"; } // src/match/normalise.ts function normalise(matcher) { if (matcher === "*") { return () => true; } if (isFunction(matcher)) { return matcher; } const patterns = [].concat(matcher).map( (pattern) => isString(pattern) ? new RegExp(pattern) : pattern ); return (value) => patterns.some((pattern) => pattern.test(value)); } // src/match/get-filter.ts function getFilter({ include = "*", exclude = [] }) { const includeMatcher = normalise(include); const excludeMatcher = normalise(exclude); return (value) => includeMatcher(value) && !excludeMatcher(value); } // src/number/clamp.ts function clamp(value, lower, upper) { return Math.max(lower, Math.min(upper, value)); } // src/object/clone.ts import { unref } from "vue"; function cloneIdentity(input) { return input; } function cloneBasic(input) { return new input.constructor(input); } function cloneRegex(input) { const clonedRegex = new RegExp(input.source); clonedRegex.lastIndex = input.lastIndex; return clonedRegex; } function cloneSymbol(input) { return Object(Symbol.prototype.valueOf.call(input)); } function cloneObject(input) { const output = {}; for (const key in input) { output[key] = clone(input[key]); } return output; } function cloneArray(input) { return input.map(clone); } function cloneSet(input) { const output = /* @__PURE__ */ new Set(); input.forEach((value) => { output.add(clone(value)); }); return output; } function cloneMap(input) { const output = /* @__PURE__ */ new Map(); input.forEach((value, key) => { output.set(key, clone(value)); }); return output; } var CLONE_MAP = { default: cloneIdentity, // Primitives null: cloneIdentity, undefined: cloneIdentity, boolean: cloneBasic, // only for new Boolean() number: cloneBasic, // only for new Number() string: cloneBasic, // only for new String() // Objects error: cloneBasic, date: cloneBasic, regexp: cloneRegex, function: cloneIdentity, symbol: cloneSymbol, array: cloneArray, object: cloneObject, map: cloneMap, set: cloneSet }; function clone(value) { const input = unref(value); if (typeof input !== "object" || input === null) { return input; } const type = getType(input); const cloner = CLONE_MAP[type] || CLONE_MAP.default; return cloner(input); } // src/type/is-array.ts function isArray(value) { return getType(value) === "array"; } // src/object/from-path.ts function fromPath(value, path) { const nodes = isArray(path) ? path : path.split("/"); return nodes.reduce((branch, node) => branch[node], value); } // src/object/lock.ts function lock(input, exclusions) { return new Proxy(input, { get(target, prop) { if (exclusions.includes(prop)) { throw new Error(`Access to property '${prop}' is denied`); } const value = target[prop]; if (typeof value === "function") { return (...args) => Reflect.apply(value, target, args); } return value; } }); } // src/object/omit.ts function omit(value, matcher) { const output = {}; const filter = normalise(matcher); for (const key in value) { if (!filter(key)) { output[key] = value[key]; } } return output; } // src/object/overwrite.ts function overwrite(target, source) { if (typeof target !== "object" || typeof source !== "object") { return target; } for (const prop in target) { if (!(prop in source)) { delete target[prop]; } } return Object.assign(target, source); } // src/type/is-nil.ts function isNil(value) { return value == null; } // src/object/set.ts function setObjectValue(target, path, value) { const nodes = (isArray(path) ? path : path.split("/")).slice(); const key = nodes.pop(); if (isNil(key) || key === "") { return overwrite(target, value); } const parent = fromPath(target, nodes); parent[key] = value; } // src/object/to-path.ts function toPath(nodes) { return nodes.reduceRight((path, node) => { const nodeStr = node.toString(); const segment = isNaN(parseInt(nodeStr, 10)) ? `/${node.toString()}` : `[${node.toString()}]`; return segment + path.toString(); }, "").toString(); } // src/object/trace.ts function traceObjectPath(onAccess) { return new Proxy({}, { get(target, key) { onAccess(key); return traceObjectPath(onAccess); } }); } function traceObject() { const nodes = /* @__PURE__ */ new Set(); const value = traceObjectPath((key) => nodes.add(key)); const getNodes = () => Array.from(nodes); const resetNodes = () => nodes.clear(); return { value, getNodes, resetNodes }; } // src/type/is-any.ts function typeIsAny(value, types) { return types.includes(getType(value)); } // src/type/is-boolean.ts function isBoolean(value) { return getType(value) === "boolean"; } // src/type/is-object.ts function isObject(value) { return getType(value) === "object"; } // src/type/is-matchable.ts function isMatchable(value) { return isObject(value) && "include" in value && "exclude" in value; } export { identity as functionIdentity, getFilter as matchGetFilter, normalise as matchNormalise, clamp as numberClamp, clone as objectClone, fromPath as objectFromPath, lock as objectLock, omit as objectOmit, overwrite as objectOverwrite, setObjectValue as objectSet, toPath as objectToPath, traceObject as objectTrace, getType as typeGetType, typeIsAny, isArray as typeIsArray, isBoolean as typeIsBoolean, isFunction as typeIsFunction, isMatchable as typeIsMatchable, isNil as typeIsNil, isObject as typeIsObject, isString as typeIsString };