UNPKG

typedash

Version:

modern, type-safe collection of utility functions

985 lines (906 loc) 26.6 kB
'use strict'; // src/functions/compact/compact.ts function compact(array) { return array?.filter(Boolean) ?? []; } // src/functions/assert/assert.ts function assert(condition, message) { if (arguments.length === 0) { return; } if (!condition) { throw new AssertionError(message); } } var AssertionError = class extends Error { constructor(message) { super( compact([ `Assertion not satisfied`, message ? `: "${message}"` : "" ]).join("") ); } }; // src/functions/assertNever/assertNever.ts function assertNever(inclusive, noThrow = false) { if (noThrow) { return void 0; } throw new Error(`Unexpected inclusive value: ${inclusive}`); } // src/functions/capitalize/capitalize.ts function capitalize(string) { return `${string.charAt(0).toUpperCase()}${string.slice(1)}`; } // src/functions/camelCase/camelCase.ts function camelCase(string) { if (!/[a-z]+/i.test(string)) { return string; } const words = string.trim().split(wordsRegex); return words.map((word, index) => index === 0 ? word.toLowerCase() : capitalize(word)).join(""); } var wordsRegex = /[\s_-]+|(?<=[a-z])(?=[A-Z])/; // src/functions/isArray/isArray.ts var isArray = Array.isArray; // src/functions/castArrayIfDefined/castArrayIfDefined.ts function castArrayIfDefined(value) { if (value == null) { return value; } if (isArray(value)) { return value; } return [value]; } // src/functions/castArray/castArray.ts function castArray(value) { return castArrayIfDefined(value ?? []); } // src/functions/chunk/chunk.ts function chunk(array, size) { if (array == null) { return []; } const chunks = []; for (let index = 0; index < array.length; index += size) { chunks.push(array.slice(index, index + size)); } return chunks; } var chunkArray = chunk; // src/functions/clamp/clamp.ts function clamp(value, range2, options) { const [min2, max2] = range2; if (min2 > max2) { throw new RangeError(`Invalid range: [${min2},${max2}]`); } const { inclusive = true } = options ?? {}; return { true: () => Math.max(min2, Math.min(max2, value)), false: () => Math.max(min2 + 1, Math.min(max2 - 1, value)), min: () => Math.max(min2, Math.min(max2 - 1, value)), max: () => Math.max(min2 + 1, Math.min(max2, value)) }[inclusive](); } // src/functions/constantCase/constantCase.ts function constantCase(string) { if (!/[a-z]+/i.test(string)) { return ""; } return string.replace(/([a-z])([A-Z])/g, "$1_$2").replace(/[\s-]+/g, "_").toUpperCase(); } // src/functions/_internal/filterIterable/filterIterable.ts function filter(source, predicate) { if (source == null) { return void 0; } const relevantItems = predicate == null ? [...source] : ( // eslint-disable-next-line unicorn/no-array-callback-reference -- this is fine, we want to use the same predicate [...source].filter(predicate) ); return relevantItems; } // src/functions/count/count.ts function count(source, predicate) { const relevantItems = filter(source, predicate); return relevantItems?.length ?? 0; } // src/functions/createTypeGuard/createTypeGuard.ts function createTypeGuard(values) { const setValues = new Set(values); return function predicate(v) { return setValues.has(v); }; } // src/functions/debounce/debounce.ts function debounce(func, delay, options = {}) { let timeoutId = null; let isCalled = false; let latestArguments; function debouncedFunction(...args) { latestArguments = args; if (options.leading && !isCalled) { func(...args); isCalled = true; } if (timeoutId !== null) { clearTimeout(timeoutId); } timeoutId = setTimeout(() => { if (!options.leading) { func(...args); } isCalled = false; }, delay); } debouncedFunction.flush = () => { if (timeoutId !== null) { clearTimeout(timeoutId); } func(...latestArguments); }; debouncedFunction.clear = () => { if (timeoutId !== null) { clearTimeout(timeoutId); } }; return debouncedFunction; } // src/functions/negate/negate.ts function negate(func) { return (...args) => { const result = func(...args); return !result; }; } // src/functions/difference/difference.ts function difference(array1, array2, comparator) { if (!comparator) { const isArray2Item = createTypeGuard(array2); return array1.filter(negate(isArray2Item)); } return array1.filter( (a1) => !array2.some((a2) => comparator(a1, a2)) ); } // src/functions/ensurePrefix/ensurePrefix.ts function ensurePrefix(string, prefix) { if (string.startsWith(prefix)) { return string; } return `${prefix}${string}`; } // src/functions/ensureSuffix/ensureSuffix.ts function ensureSuffix(string, suffix) { if (string.endsWith(suffix)) { return string; } return `${string}${suffix}`; } // src/functions/hasKey/hasKey.ts function hasKey(value, key) { if (typeof value !== "object" || value == null) { return false; } return key in value; } // src/functions/get/get.ts function get(object, path) { const keys = isArray(path) ? path : path.split("."); return keys.reduce((value, key) => { if (hasKey(value, key)) { return value[key]; } return void 0; }, object); } // src/functions/groupBy/groupBy.ts function groupBy(array, getter) { return (array ?? []).reduce( (draftGroups, currentItem) => { const key = getter(currentItem); draftGroups[key] ??= []; draftGroups[key].push(currentItem); return draftGroups; }, {} ); } // src/functions/identity/identity.ts function identity(value) { return value; } // src/functions/inRange/inRange.ts function inRange(value, range2, options) { const [start, end] = range2; const { inclusive = "start" } = options ?? {}; if (start > end) { throw new RangeError(`Invalid range: [${start},${end}]`); } return { true: () => value >= start && value <= end, false: () => value > start && value < end, start: () => value >= start && value < end, end: () => value > start && value <= end }[inclusive](); } // src/functions/intersection/intersection.ts function intersection(array1, array2, comparator) { if (!comparator) { const isArray2Item = createTypeGuard(array2); return array1.filter(isArray2Item); } return array1.filter( (a1) => array2.some((a2) => comparator(a1, a2)) ); } // src/functions/invert/invert.ts function invert(object) { return Object.fromEntries( Object.entries(object).map(([key, value]) => [value, key]) ); } // src/functions/isEmpty/isEmpty.ts function isEmpty(value) { if (value == null) { return true; } if (isArray(value) || typeof value === "string") { return value.length === 0; } if (value instanceof Map || value instanceof Set) { return value.size === 0; } if (typeof value === "number") { return !value; } if (typeof value === "object") { return Object.keys(value).length === 0; } return false; } // src/functions/zip/zip.ts function zip(first, second) { const result = []; for (let index = 0; index < Math.min(first.length, second.length); index++) { result.push([first[index], second[index]]); } return result; } // src/functions/isEqual/_internal/array/areArraysEqual.ts function areArraysEqual(array1, array2, context) { if (array1.length !== array2.length) { return false; } for (const [index, [element1, element2]] of zip(array1, array2).entries()) { if (!context.equals(element1, element2, index, index, array1, array2, context)) { return false; } } return true; } // src/functions/isEqual/_internal/createIsCircularTypeEqualityComparator.ts function createIsCircularTypeEqualityComparator(areItemsEqual) { return function isCircular(a, b, context) { if (!a || !b || typeof a !== "object" || typeof b !== "object") { return areItemsEqual(a, b, context); } const { cache } = context; const cachedA = cache.get(a); const cachedB = cache.get(b); if (cachedA && cachedB) { return cachedA === b && cachedB === a; } cache.set(a, b); cache.set(b, a); const result = areItemsEqual(a, b, context); cache.delete(a); cache.delete(b); return result; }; } // src/functions/isEqual/_internal/date/areDatesEqual.ts function areDatesEqual(value1, value2) { return Object.is(value1.getTime(), value2.getTime()); } // src/functions/isEqual/_internal/date/dateTag.ts var DATE_TAG = "[object Date]"; // src/functions/isEqual/_internal/map/areMapsEqual.ts function areMapsEqual(value1, value2, context) { if (value1.size !== value2.size) { return false; } const matchedIndices = {}; let index = 0; for (const [aKey, aValue] of value1) { let hasMatch = false; let matchIndex = 0; for (const [bKey, bValue] of value2) { if (!hasMatch && !matchedIndices[matchIndex] && // eslint-disable-next-line no-cond-assign (hasMatch = context.equals( aKey, bKey, index, matchIndex, value1, value2, context ) && context.equals(aValue, bValue, aKey, bKey, value1, value2, context))) { matchedIndices[matchIndex] = true; } matchIndex++; } if (!hasMatch) { return false; } index++; } return true; } // src/functions/isEqual/_internal/react/reactOwnerPropertyName.ts var REACT_OWNER_PROPERTY_NAME = "_owner"; // src/functions/isEqual/_internal/object/getObjectProperties.ts function getObjectProperties(object) { return [ ...Object.getOwnPropertyNames(object), ...Object.getOwnPropertySymbols(object) ]; } // src/functions/isEqual/_internal/object/areObjectsEqual.ts function areObjectsEqual(value1, value2, context) { const properties = getObjectProperties(value1); if (getObjectProperties(value2).length !== properties.length) { return false; } for (const property of properties) { if (property === REACT_OWNER_PROPERTY_NAME && (value1.$$typeof || value2.$$typeof) && value1.$$typeof !== value2.$$typeof) { return false; } if (!Object.hasOwn(value2, property)) { return false; } if (!context.equals( value1[property], value2[property], property, property, value1, value2, context )) { return false; } } return true; } // src/functions/isEqual/_internal/primitiveWrappers/arePrimitiveWrappersEqual.ts function arePrimitiveWrappersEqual(value1, value2) { return Object.is(value1.valueOf(), value2.valueOf()); } // src/functions/isEqual/_internal/regExp/areRegExpsEqual.ts function areRegExpsEqual(value1, value2) { return value1.source === value2.source && value1.flags === value2.flags; } // src/functions/isEqual/_internal/regExp/regExpTag.ts var REG_EXP_TAG = "[object RegExp]"; // src/functions/isEqual/_internal/set/areSetsEqual.ts function areSetsEqual(set1, set2, context) { if (set1.size !== set2.size) { return false; } const matchedIndices = {}; for (const element1 of set1) { let hasMatch = false; let matchIndex = 0; for (const element2 of set2) { if (!hasMatch && !matchedIndices[matchIndex] && // eslint-disable-next-line no-cond-assign (hasMatch = context.equals( element1, element2, element1, element2, set1, set2, context ))) { matchedIndices[matchIndex] = true; } matchIndex++; } if (!hasMatch) { return false; } } return true; } // src/functions/isEqual/_internal/set/setTag.ts var SET_TAG = "[object Set]"; // src/functions/isEqual/_internal/typedArray/areTypedArraysEqual.ts function areTypedArraysEqual(array1, array2) { if (array1.length !== array2.length) { return false; } for (const [element1, element2] of zip(array1, array2)) { if (element1 !== element2) { return false; } } return true; } // src/functions/isEqual/_internal/typedArray/isTypedArray.ts var isTypedArray = typeof ArrayBuffer === "function" && ArrayBuffer.isView ? ArrayBuffer.isView : null; // src/functions/isEqual/_internal/comparator.ts var ARGUMENTS_TAG = "[object Arguments]"; var BOOLEAN_TAG = "[object Boolean]"; var MAP_TAG = "[object Map]"; var NUMBER_TAG = "[object Number]"; var OBJECT_TAG = "[object Object]"; var STRING_TAG = "[object String]"; var getTag = Object.prototype.toString.call.bind( Object.prototype.toString ); function createEqualityComparatorConfig() { return { areDatesEqual, areRegExpsEqual, arePrimitiveWrappersEqual, areArraysEqual: createIsCircularTypeEqualityComparator(areArraysEqual), areMapsEqual: createIsCircularTypeEqualityComparator(areMapsEqual), areObjectsEqual: createIsCircularTypeEqualityComparator(areObjectsEqual), areSetsEqual: createIsCircularTypeEqualityComparator(areSetsEqual), areTypedArraysEqual }; } function createInternalEqualityComparator(compare) { return function internalEqualityComparator(value1, value2, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, context) { return compare(value1, value2, context); }; } function createIsEqual({ comparator, equals }) { return function isEqual2(value1, value2) { return comparator(value1, value2, { cache: /* @__PURE__ */ new WeakMap(), equals }); }; } // src/functions/isEqual/_internal/createEqualityComparator.ts function createEqualityComparator({ areArraysEqual: areArraysEqual2, areDatesEqual: areDatesEqual2, areMapsEqual: areMapsEqual2, areObjectsEqual: areObjectsEqual2, arePrimitiveWrappersEqual: arePrimitiveWrappersEqual2, areRegExpsEqual: areRegExpsEqual2, areSetsEqual: areSetsEqual2, areTypedArraysEqual: areTypedArraysEqual2 }) { return function comparator(value1, value2, context) { if (Object.is(value1, value2) || value1 === value2) { return true; } if (value1?.constructor !== value2?.constructor) { return false; } if (value1.constructor === Object) { return areObjectsEqual2(value1, value2, context); } if (isArray(value1)) { return areArraysEqual2(value1, value2, context); } if (isTypedArray?.(value1)) { return areTypedArraysEqual2(value1, value2, context); } if (value1.constructor === Date) { return areDatesEqual2(value1, value2, context); } if (value1.constructor === RegExp) { return areRegExpsEqual2(value1, value2, context); } if (value1.constructor === Map) { return areMapsEqual2(value1, value2, context); } if (value1.constructor === Set) { return areSetsEqual2(value1, value2, context); } const tag = getTag(value1); switch (tag) { case DATE_TAG: { return areDatesEqual2(value1, value2, context); } case REG_EXP_TAG: { return areRegExpsEqual2(value1, value2, context); } case MAP_TAG: { return areMapsEqual2(value1, value2, context); } case SET_TAG: { return areSetsEqual2(value1, value2, context); } case OBJECT_TAG: { return ( // eslint-disable-next-line unicorn/consistent-destructuring // eslint-disable-next-line unicorn/consistent-destructuring typeof value1.then !== "function" && typeof value2.then !== "function" && areObjectsEqual2(value1, value2, context) ); } case ARGUMENTS_TAG: { return areObjectsEqual2(value1, value2, context); } case BOOLEAN_TAG: case NUMBER_TAG: case STRING_TAG: { return arePrimitiveWrappersEqual2(value1, value2, context); } default: { return false; } } }; } // src/functions/isEqual/isEqual.ts var isEqual = createCustomEqual(); function createCustomEqual() { const config = createEqualityComparatorConfig(); const comparator = createEqualityComparator(config); const equals = createInternalEqualityComparator(comparator); return createIsEqual({ comparator, equals }); } // src/functions/isNonNullable/isNonNullable.ts function isNonNullable(value) { return value != null; } // src/functions/join/join.ts function join(elements, separator) { const emptySeparator = Symbol("emptySeparator"); const separatorFunction = typeof separator === "function" ? separator : () => separator; return elements.flatMap((element, index, array) => [ element, index < array.length - 1 ? separatorFunction(index) : emptySeparator ]).filter((item) => item !== emptySeparator); } // src/functions/kebabCase/kebabCase.ts function kebabCase(string) { if (!/[a-z]+/i.test(string)) { return string; } return string.match(KEBAB_REGEX)?.map((x) => x.toLowerCase()).join("-"); } var KEBAB_REGEX = /[A-Z]{2,}(?=[A-Z][a-z]+\d*|\b)|[A-Z]?[a-z]+\d*|[A-Z]|\d+/g; // src/functions/keyBy/keyBy.ts function keyBy(array, keyGetter) { return array.reduce( (draftObject, currentItem) => { const key = keyGetter(currentItem); draftObject[key] = currentItem; return draftObject; }, {} ); } // src/functions/objectEntries/objectEntries.ts var objectEntries = Object.entries; // src/functions/objectFromEntries/objectFromEntries.ts var objectFromEntries = Object.fromEntries; // src/functions/mapKeys/mapKeys.ts function mapKeys(object, mapperFunction) { return objectFromEntries( objectEntries(object).map(([key, value]) => [ mapperFunction(key, value, object), value ]) ); } // src/functions/mapValues/mapValues.ts function mapValues(object, mapperFunction) { return objectFromEntries( objectEntries(object).map(([key, value]) => [ key, mapperFunction(value, key) ]) ); } // src/functions/max/max.ts function max(array, valueExtractor = (value) => value) { if (array == null || array.length === 0) { return void 0; } return Math.max(...array.map((element) => valueExtractor(element))); } // src/functions/memoize/memoize.ts function memoize(fn, cacheKeyResolver) { const cache = /* @__PURE__ */ new Map(); return function memoizedFunction(...args) { const cacheKey = cacheKeyResolver ? cacheKeyResolver(...args) : args[0]; if (cache.has(cacheKey)) { return cache.get(cacheKey); } const result = fn(...args); cache.set(cacheKey, result); return result; }; } // src/functions/min/min.ts function min(array, valueExtractor = (value) => value) { if (array == null || array.length === 0) { return void 0; } return Math.min(...array.map((element) => valueExtractor(element))); } // src/functions/noop/noop.ts function noop(...args) { } // src/functions/objectKeys/objectKeys.ts var objectKeys = Object.keys; // src/functions/_internal/filterObject/createObjectPredicate.ts function createObjectPredicate(propertiesOrPredicate) { return typeof propertiesOrPredicate === "function" ? propertiesOrPredicate : createPropertiesPredicate(propertiesOrPredicate); } function createPropertiesPredicate(properties) { const isKnownProperty = createTypeGuard(castArray(properties)); return (_value, key) => isKnownProperty(key); } // src/functions/_internal/filterObject/filterObject.ts function filterObject(object, predicate) { if (object == null) { return {}; } return Object.fromEntries( objectEntries(object).filter( ([key, value]) => predicate( value, key, object ) ) ); } // src/functions/omit/omit.ts function omit(object, propertiesOrPredicate) { return filterObject( object, negate(createObjectPredicate(propertiesOrPredicate)) ); } // src/functions/once/once.ts function once(fn) { let result; let hasBeenCalled = false; return (...args) => { if (!hasBeenCalled) { result = fn(...args); hasBeenCalled = true; } return result; }; } // src/functions/orderBy/orderBy.ts function orderBy(array, iterators, orders) { if (array == null) return []; const normalizedIteratees = castArray(iterators).map( (iteratee) => typeof iteratee === "function" ? iteratee : (value) => value[iteratee] ); const normalizedOrders = castArray(orders); return [...array].sort((a, b) => { for (const [index, iteratee] of normalizedIteratees.entries()) { const normalizedOrder = normalizedOrders[index] ?? "asc"; const order = normalizedOrder === "desc" ? -1 : 1; const aValue = iteratee(a); const bValue = iteratee(b); if (aValue < bValue) return -1 * order; if (aValue > bValue) return 1 * order; } return 0; }); } // src/functions/partition/partition.ts function partition(array, predicate) { if (array == null) { return [[], []]; } const equals = []; const notEquals = []; for (const item of array) { if (predicate(item)) { equals.push(item); } else { notEquals.push(item); } } return [equals, notEquals]; } // src/functions/pick/pick.ts function pick(object, propertiesOrPredicate) { return filterObject(object, createObjectPredicate(propertiesOrPredicate)); } // src/functions/pipe/pipe.ts function pipe(o1, ...operations) { return (...argsP) => operations.reduce((acc, f) => f(acc), o1(...argsP)); } // src/functions/range/range.ts function range(startOrEnd, end, step = 1) { if (step <= 0) { return []; } const calculatedStart = end == null ? 0 : startOrEnd; const calculatedEnd = end ?? startOrEnd; const result = []; for (let index = calculatedStart; index < calculatedEnd; index += step) { result.push(index); } return result; } // src/functions/sample/sample.ts function sample(source, count2 = 1) { if (source == null) { return void 0; } const sourceArray = [...source]; if (sourceArray.length === 0) { return void 0; } const sampleCount = Math.min(count2, sourceArray.length); const indices = /* @__PURE__ */ new Set(); while (indices.size < sampleCount) { indices.add(Math.floor(Math.random() * sourceArray.length)); } const result = []; for (const index of indices) { result.push(sourceArray[index]); } if (result.length === 1) { return result[0]; } return result; } // src/functions/_internal/isMaliciousObjectPath.ts var isMaliciousObjectProperty = createTypeGuard( Object.getOwnPropertyNames(Object.getPrototypeOf({})) ); // src/functions/set/set.ts function set(object, path, value) { const segments = path.match(pathSegmentsRegex); assert(segments !== null, "Invalid path"); assert( segments.every((segment) => isMaliciousObjectProperty(segment) === false), "Potentially malicious path" ); let currentObject = object; for (let index = 0; index < segments.length - 1; index++) { const segment = segments[index]; if (segment in currentObject === false) { currentObject[segment] = {}; } currentObject = currentObject[segment]; } currentObject[segments.at(-1)] = value; } var pathSegmentsRegex = /[\w-]+/g; // src/functions/single/single.ts function single(source, predicate) { const relevantItems = filter(source, predicate); return relevantItems?.length === 1 ? relevantItems[0] : void 0; } // src/functions/sum/sum.ts function sum(array, mapper) { if (array == null) { return 0; } const numbers = array.map((value, index, array_) => { const result = mapper?.(value, index, array_) ?? // if there's no iteratee, we're in the overload of `sum` that only takes an array of numbers (value ?? 0); return result; }); return numbers.reduce((draft, value) => draft + value, 0); } // src/functions/take/take.ts function take(array, count2) { if (count2 <= 0) { return []; } return array?.slice(0, count2) ?? []; } // src/functions/toObject/toObject.ts function toObject(array) { return objectFromEntries(array.map((value) => [value, value])); } // src/functions/unique/unique.ts function unique(iterable, comparator = defaultComparator) { if (comparator === defaultComparator) { return [...new Set(iterable)]; } const result = []; for (const value of iterable ?? []) { if (!result.some((other) => comparator(value, other))) { result.push(value); } } return result; } var defaultComparator = Object.is; // src/functions/uniqueId/uniqueId.ts function uniqueId(prefix = "") { const suffix = generateUUID(); return `${prefix}${suffix}`; } function generateUUID() { if (typeof crypto === "object" && typeof crypto.randomUUID === "function") { return crypto.randomUUID(); } return pseudoRandomUUID(); } function pseudoRandomUUID() { const random = Math.random(); return random.toString(36).slice(2, 11); } // src/functions/without/without.ts function without(array, itemsToExclude) { const isItemToExclude = createTypeGuard(itemsToExclude); return array.filter((item) => !isItemToExclude(item)); } exports.AssertionError = AssertionError; exports.assert = assert; exports.assertNever = assertNever; exports.camelCase = camelCase; exports.capitalize = capitalize; exports.castArray = castArray; exports.castArrayIfDefined = castArrayIfDefined; exports.chunk = chunk; exports.chunkArray = chunkArray; exports.clamp = clamp; exports.compact = compact; exports.constantCase = constantCase; exports.count = count; exports.createTypeGuard = createTypeGuard; exports.debounce = debounce; exports.difference = difference; exports.ensurePrefix = ensurePrefix; exports.ensureSuffix = ensureSuffix; exports.get = get; exports.groupBy = groupBy; exports.hasKey = hasKey; exports.identity = identity; exports.inRange = inRange; exports.intersection = intersection; exports.invert = invert; exports.isArray = isArray; exports.isEmpty = isEmpty; exports.isEqual = isEqual; exports.isNonNullable = isNonNullable; exports.join = join; exports.kebabCase = kebabCase; exports.keyBy = keyBy; exports.mapKeys = mapKeys; exports.mapValues = mapValues; exports.max = max; exports.memoize = memoize; exports.min = min; exports.negate = negate; exports.noop = noop; exports.objectEntries = objectEntries; exports.objectFromEntries = objectFromEntries; exports.objectKeys = objectKeys; exports.omit = omit; exports.once = once; exports.orderBy = orderBy; exports.partition = partition; exports.pick = pick; exports.pipe = pipe; exports.range = range; exports.sample = sample; exports.set = set; exports.single = single; exports.sum = sum; exports.take = take; exports.toObject = toObject; exports.unique = unique; exports.uniqueId = uniqueId; exports.without = without; exports.zip = zip; //# sourceMappingURL=out.js.map //# sourceMappingURL=index.cjs.map