@wistia/utils 0.17.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +167 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +48 -45
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -12
- package/dist/index.cjs +0 -1921
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -1560
- package/dist/index.d.cts.map +0 -1
package/dist/index.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["candidate"],"sources":["../src/guards/isNull.ts","../src/guards/isUndefined.ts","../src/guards/isNil.ts","../src/guards/isNotNil.ts","../src/guards/isRecord.ts","../src/guards/isNonEmptyRecord.ts","../src/guards/hasKey.ts","../src/guards/isArray.ts","../src/guards/isFunction.ts","../src/guards/isAsyncFunction.ts","../src/guards/isBigInt.ts","../src/guards/isBoolean.ts","../src/guards/isDate.ts","../src/guards/isEmptyArray.ts","../src/guards/isEmptyRecord.ts","../src/guards/isString.ts","../src/guards/isEmptyString.ts","../src/guards/isError.ts","../src/guards/_falsyValues.ts","../src/guards/isFalsy.ts","../src/guards/isNumber.ts","../src/guards/isFiniteNumber.ts","../src/guards/isHtmlButtonElement.ts","../src/guards/isHtmlElement.ts","../src/guards/isHtmlInputElement.ts","../src/guards/isHtmlVideoElement.ts","../src/guards/isInteger.ts","../src/guards/isIterable.ts","../src/guards/isMap.ts","../src/guards/isMouseEvent.ts","../src/guards/isNaN.ts","../src/guards/isNonBlankString.ts","../src/guards/isNonEmptyArray.ts","../src/guards/isNonEmptyString.ts","../src/guards/isNonNaNNumber.ts","../src/guards/isNotArray.ts","../src/guards/isNotBoolean.ts","../src/guards/isNotFunction.ts","../src/guards/isNotNull.ts","../src/guards/isNotNumber.ts","../src/guards/isNotRecord.ts","../src/guards/isNotString.ts","../src/guards/isNotUndefined.ts","../src/guards/isVoid.ts","../src/guards/isNotVoid.ts","../src/guards/isPlainObject.ts","../src/guards/isPromise.ts","../src/guards/isRegExp.ts","../src/guards/isSet.ts","../src/guards/isSvgElement.ts","../src/guards/isSymbol.ts","../src/guards/isTextNode.ts","../src/guards/isTruthy.ts","../src/guards/isWeakMap.ts","../src/guards/isWeakSet.ts","../src/guards/readonlyArrayIncludes.ts","../src/utilities/asyncNoOpFn.ts","../src/utilities/_constants.ts","../src/utilities/buildTimeDuration.ts","../src/utilities/coerceToBoolean.ts","../src/utilities/_isInvalidDate.ts","../src/utilities/dateOnlyISOString.ts","../src/utilities/dateOnlyString.ts","../src/utilities/dateOnlyStringForSentence.ts","../src/utilities/dateOnlyStringNumeric.ts","../src/utilities/dateTimeToDate.ts","../src/utilities/dateTimeToISO.ts","../src/utilities/dateToDateTime.ts","../src/utilities/dateTimeRounded.ts","../src/utilities/dateTimeString.ts","../src/utilities/dateTimeStringForSentence.ts","../src/utilities/dateUTCOffset.ts","../src/utilities/dayOfWeekString.ts","../src/utilities/deepMerge.ts","../src/utilities/getObjectEntries.ts","../src/utilities/getObjectKeys.ts","../src/utilities/getObjectValues.ts","../src/utilities/isEmail.ts","../src/utilities/isUrl.ts","../src/utilities/_padTimeInteger.ts","../src/utilities/mediaDurationString.ts","../src/utilities/millisecondsToDurationISOString.ts","../src/utilities/monthDayStringNumeric.ts","../src/utilities/noOpFn.ts","../src/utilities/noOpFnReturningFalse.ts","../src/utilities/noOpFnReturningNull.ts","../src/utilities/parseDateString.ts","../src/utilities/sessionDurationString.ts","../src/utilities/stripExtension.ts","../src/utilities/_getLocalDateParts.ts","../src/utilities/_differenceInCalendarDays.ts","../src/utilities/timeAgoString.ts","../src/utilities/timeOnlyString.ts","../src/utilities/tupleIncludes.ts"],"sourcesContent":["/**\n * Checks if the provided value is null.\n *\n * @param value - The value to check.\n * @returns True if the value is null, false otherwise.\n *\n * @example\n * isNull(null); // true\n * isNull(undefined); // false\n *\n * @category Primitives\n */\nexport const isNull = (value: unknown): value is null => value === null;\n","/**\n * Checks if the provided value is undefined.\n *\n * @param value - The value to check.\n * @returns True if the value is undefined, false otherwise.\n *\n * @example\n * isUndefined(undefined); // true\n * isUndefined(null); // false\n *\n * @category Primitives\n */\nexport const isUndefined = (value: unknown): value is undefined => value === undefined;\n","import type { Nil } from '../types/Nil.js';\nimport { isNull } from './isNull.js';\nimport { isUndefined } from './isUndefined.js';\n\n/**\n * Checks if the provided value is null or undefined.\n *\n * @param value - The value to check.\n * @returns True if the value is null or undefined, false otherwise.\n *\n * @example\n * isNil(null); // true\n * isNil(0); // false\n *\n * @category Primitives\n */\nexport const isNil = (value: unknown): value is Nil => isNull(value) || isUndefined(value);\n","import type { Nil } from '../types/Nil.js';\nimport { isNil } from './isNil.js';\n\n/**\n * Checks if the provided value is neither null nor undefined.\n *\n * @param value - The value to check.\n * @returns True if the value is not null or undefined, false otherwise.\n *\n * @remarks\n * Common in `.filter(isNotNil)` to drop `null`/`undefined` from arrays\n * with narrowing.\n *\n * @example\n * isNotNil(0); // true\n * isNotNil(null); // false\n *\n * const items: (string | null)[] = ['a', null, 'b'];\n * const clean: string[] = items.filter(isNotNil); // ['a', 'b']\n *\n * @category Negated\n */\nexport const isNotNil = <T>(value: Nil | T): value is T => !isNil(value);\n","import { isNotNil } from './isNotNil.js';\n\n/**\n * Checks if the provided value is a non-null object that is not an array.\n *\n * @param value - The value to check.\n * @returns True if the value is an object (but not an array), false otherwise.\n *\n * @example\n * isRecord({}); // true\n * isRecord([]); // false\n *\n * @category Records\n */\nexport const isRecord = (value: unknown): value is Record<string, unknown> =>\n isNotNil(value) && typeof value === 'object' && !Array.isArray(value);\n","import { isRecord } from './isRecord.js';\n\n/**\n * Checks if the provided value is an object with at least one own property.\n *\n * @param value - The value to check.\n * @returns True if the value is a non-empty object, false otherwise.\n *\n * @example\n * isNonEmptyRecord({ a: 1 }); // true\n * isNonEmptyRecord({}); // false\n *\n * @category Records\n */\nexport const isNonEmptyRecord = (value: unknown): value is Record<string, unknown> =>\n isRecord(value) && Object.keys(value).length > 0;\n","import { isNonEmptyRecord } from './isNonEmptyRecord.js';\n\n/**\n * Curried function that tests if an input is an object\n * _and_ that a key that was passed in is a property of that object.\n *\n * @param value - The input object to test.\n * @param key - The key to test if it is a property of the input record.\n * @returns A function that takes an unknown input and then tests if the\n * input is an object and whether the key is a property of that object or not.\n *\n * @example\n * hasKey({ a: 1 }, 'a'); // true\n * hasKey({ a: 1 }, 'b'); // false\n *\n * @category Records\n */\nexport const hasKey = <Key extends string, Value>(\n value: unknown,\n key: Key,\n): value is Record<Key, Value> => isNonEmptyRecord(value) && key in value;\n","import { isNotNil } from './isNotNil.js';\n\n/**\n * Checks if the provided value is an array.\n *\n * @param value - The value to check.\n * @returns True if the value is an array, false otherwise.\n *\n * @example\n * isArray([1, 2]); // true\n * isArray('abc'); // false\n *\n * @category Arrays\n */\nexport const isArray = (value: unknown): value is unknown[] =>\n isNotNil(value) && typeof value === 'object' && Array.isArray(value);\n","import { isNotNil } from './isNotNil.js';\n\n/**\n * Checks if the provided value is a function.\n *\n * @param value - The value to check.\n * @returns True if the value is a function, false otherwise.\n *\n * @example\n * isFunction(() => {}); // true\n * isFunction({}); // false\n *\n * @category Primitives\n */\nexport const isFunction = (value: unknown): value is (...args: unknown[]) => unknown =>\n isNotNil(value) && typeof value === 'function';\n","import { isFunction } from './isFunction.js';\n\n/**\n * Checks if the provided value is an async function.\n *\n * @param value - The value to check.\n * @returns True if the value is an async function, false otherwise.\n *\n * @remarks\n * Detection relies on `constructor.name === 'AsyncFunction'` and is a\n * heuristic: async functions transpiled to regular functions return false,\n * async generator functions return false, and a forged `constructor`\n * property can fool the check. Bound async functions return true, since\n * `bind` preserves the prototype chain. Synchronous functions that return\n * promises also return false.\n *\n * @example\n * isAsyncFunction(async () => {}); // true\n * isAsyncFunction(() => {}); // false\n *\n * @category Primitives\n */\nexport const isAsyncFunction = (\n value: unknown,\n): value is (...args: unknown[]) => Promise<unknown> => {\n // `constructor` is undefined at runtime for functions with a nulled prototype.\n return isFunction(value) && value.constructor?.name === 'AsyncFunction'; // oxlint-disable-line typescript/no-unnecessary-condition\n};\n","/**\n * Checks if the provided value is a bigint.\n *\n * @param value - The value to check.\n * @returns True if the value is a bigint, false otherwise.\n *\n * @example\n * isBigInt(10n); // true\n * isBigInt(10); // false\n *\n * @category Primitives\n */\nexport const isBigInt = (value: unknown): value is bigint => typeof value === 'bigint';\n","import { isNotNil } from './isNotNil.js';\n\n/**\n * Checks if the provided value is a boolean.\n *\n * @param value - The value to check.\n * @returns True if the value is a boolean, false otherwise.\n *\n * @example\n * isBoolean(true); // true\n * isBoolean(1); // false\n *\n * @category Primitives\n */\nexport const isBoolean = (value: unknown): value is boolean =>\n isNotNil(value) && typeof value === 'boolean';\n","import { isNotNil } from './isNotNil.js';\n\n/**\n * Checks if the provided value is an instance of Date.\n *\n * @param value - The value to check.\n * @returns True if the value is a Date instance, false otherwise.\n *\n * @remarks\n * Matches `Date` instances only. Does not parse date strings or\n * accept numeric timestamps.\n *\n * @example\n * isDate(new Date()); // true\n * isDate('2024-01-01'); // false\n *\n * @category Primitives\n */\nexport const isDate = (value: unknown): value is Date => {\n return isNotNil(value) && value instanceof Date;\n};\n","import { isArray } from './isArray.js';\n\n/**\n * Checks if the provided value is an empty array.\n *\n * @param value - The value to check.\n * @returns True if the value is an empty array, false otherwise.\n *\n * @example\n * isEmptyArray([]); // true\n * isEmptyArray([1]); // false\n *\n * @category Arrays\n */\nexport const isEmptyArray = (value: unknown): value is never[] =>\n isArray(value) && value.length === 0;\n","import type { EmptyObject } from 'type-fest';\nimport { isRecord } from './isRecord.js';\n\n/**\n * Checks if the provided value is an object with no own properties.\n *\n * @param value - The value to check.\n * @returns True if the value is an empty object, false otherwise.\n *\n * @example\n * isEmptyRecord({}); // true\n * isEmptyRecord({ a: 1 }); // false\n *\n * @category Records\n */\nexport const isEmptyRecord = (value: unknown): value is EmptyObject =>\n isRecord(value) && Object.keys(value).length === 0;\n","/**\n * Checks if the provided value is a string.\n *\n * @param value - The value to check.\n * @returns True if the value is a string, false otherwise.\n *\n * @example\n * isString('hi'); // true\n * isString(42); // false\n *\n * @category Primitives\n */\nexport const isString = (value: unknown): value is string => typeof value === 'string';\n","import { isString } from './isString.js';\n\n/**\n * Checks if the provided value is an empty string.\n *\n * @param value - The value to check.\n * @returns True if the value is an empty string, false otherwise.\n *\n * @example\n * isEmptyString(''); // true\n * isEmptyString('a'); // false\n *\n * @category Strings\n */\nexport const isEmptyString = (value: unknown): value is '' => isString(value) && value === '';\n","import { isNotNil } from './isNotNil.js';\n\n/**\n * Checks if the provided value is an instance of Error.\n *\n * @param value - The value to check.\n * @returns True if the value is an Error instance, false otherwise.\n *\n * @remarks\n * Matches subclasses of `Error` too (e.g. `TypeError`, custom errors).\n *\n * @example\n * isError(new Error('boom')); // true\n * isError('boom'); // false\n *\n * @category Primitives\n */\nexport const isError = (value: unknown): value is Error => {\n return isNotNil(value) && value instanceof Error;\n};\n","export const FALSY_VALUES = [false, 0, -0, 0n, '', null, undefined, Number.NaN] as const;\n","import type { Falsy } from '../types/Falsy.js';\nimport { FALSY_VALUES } from './_falsyValues.js';\n\n/**\n * Checks if the provided value is falsy.\n *\n * @param value - The value to check.\n * @returns True if the value is falsy, false otherwise.\n *\n * @remarks\n * Returns true for `false`, `0`, `-0`, `0n`, `''`, `null`, `undefined`,\n * and `NaN`.\n *\n * @example\n * isFalsy(0); // true\n * isFalsy(1); // false\n *\n * @category Truthy / falsy\n */\nexport const isFalsy = (value: unknown): value is Falsy =>\n FALSY_VALUES.includes(value as Falsy) || Number.isNaN(value); // oxlint-disable-line typescript/no-unsafe-type-assertion\n","/**\n * Checks if the provided value is a number.\n *\n * @param value - The value to check.\n * @returns True if the value is a number, false otherwise.\n *\n * @remarks\n * `NaN` is a `number`, so `isNumber(NaN)` is true. Use `isInteger` or\n * combine with `!isNaN(value)` if you need a finite number.\n *\n * @example\n * isNumber(1); // true\n * isNumber('1'); // false\n *\n * @category Primitives\n */\nexport const isNumber = (value: unknown): value is number => typeof value === 'number';\n","import { isNumber } from './isNumber.js';\n\n/**\n * Checks if the provided value is a finite number.\n *\n * @param value - The value to check.\n * @returns True if the value is a finite number, false otherwise.\n *\n * @example\n * isFiniteNumber(42); // true\n * isFiniteNumber(Infinity); // false\n *\n * @category Primitives\n */\nexport const isFiniteNumber = (value: unknown): value is number =>\n isNumber(value) && Number.isFinite(value);\n","/**\n * Checks if the provided value is an HTMLButtonElement.\n *\n * @param value - The value to check.\n * @returns True if the value is an HTMLButtonElement, false otherwise.\n *\n * @example\n * isHtmlButtonElement(document.createElement('button')); // true\n * isHtmlButtonElement(document.createElement('div')); // false\n *\n * @category DOM\n */\nexport const isHtmlButtonElement = (value: unknown): value is HTMLButtonElement =>\n value instanceof HTMLButtonElement;\n","/**\n * Checks if the provided value is an HTMLElement.\n *\n * @param value - The value to check.\n * @returns True if the value is an HTMLElement, false otherwise.\n *\n * @example\n * isHtmlElement(document.body); // true\n * isHtmlElement('div'); // false\n *\n * @category DOM\n */\nexport const isHtmlElement = (value: unknown): value is HTMLElement => value instanceof HTMLElement;\n","/**\n * Checks if the provided value is an HTMLInputElement.\n *\n * @param value - The value to check.\n * @returns True if the value is an HTMLInputElement, false otherwise.\n *\n * @example\n * isHtmlInputElement(document.createElement('input')); // true\n * isHtmlInputElement(document.createElement('div')); // false\n *\n * @category DOM\n */\nexport const isHtmlInputElement = (value: unknown): value is HTMLInputElement =>\n value instanceof HTMLInputElement;\n","/**\n * Checks if the provided value is an HTMLVideoElement.\n *\n * @param value - The value to check.\n * @returns True if the value is an HTMLVideoElement, false otherwise.\n *\n * @example\n * isHtmlVideoElement(document.createElement('video')); // true\n * isHtmlVideoElement(document.createElement('div')); // false\n *\n * @category DOM\n */\nexport const isHtmlVideoElement = (value: unknown): value is HTMLVideoElement =>\n value instanceof HTMLVideoElement;\n","/**\n * Checks if the provided value is an integer.\n *\n * @param value - The value to check.\n * @returns True if the value is an integer, false otherwise.\n *\n * @remarks\n * Uses `Number.isInteger`, so non-finite values (`NaN`, `Infinity`)\n * return false.\n *\n * @example\n * isInteger(5); // true\n * isInteger(5.5); // false\n *\n * @category Primitives\n */\nexport const isInteger = (value: unknown): value is number => Number.isInteger(value);\n","import { isNotNil } from './isNotNil.js';\n\n/**\n * Checks if the provided value implements the iterable protocol.\n *\n * @param value - The value to check.\n * @returns True if the value is iterable, false otherwise.\n *\n * @remarks\n * Strings are iterable and return true. Plain objects without\n * `Symbol.iterator` return false.\n *\n * @example\n * isIterable([1, 2, 3]); // true\n * isIterable({}); // false\n *\n * @category Primitives\n */\nexport const isIterable = (value: unknown): value is Iterable<unknown> => {\n if (!isNotNil(value)) {\n return false;\n }\n\n const candidate = value as { [Symbol.iterator]?: unknown }; // oxlint-disable-line typescript/no-unsafe-type-assertion\n return typeof candidate[Symbol.iterator] === 'function';\n};\n","import { isNotNil } from './isNotNil.js';\n\n/**\n * Checks if the provided value is an instance of Map.\n *\n * @param value - The value to check.\n * @returns True if the value is a Map instance, false otherwise.\n *\n * @remarks\n * WeakMap instances return false.\n *\n * @example\n * isMap(new Map()); // true\n * isMap({}); // false\n *\n * @category Primitives\n */\nexport const isMap = (value: unknown): value is Map<unknown, unknown> => {\n return isNotNil(value) && value instanceof Map;\n};\n","/**\n * Checks if the provided value is a MouseEvent.\n *\n * @param value - The value to check.\n * @returns True if the value is a MouseEvent, false otherwise.\n *\n * @example\n * isMouseEvent(new MouseEvent('click')); // true\n * isMouseEvent(new Event('change')); // false\n *\n * @category DOM\n */\nexport const isMouseEvent = (value: unknown): value is MouseEvent => value instanceof MouseEvent;\n","/**\n * Checks if the provided value is NaN (Not a Number).\n *\n * @param value - The value to check.\n * @returns True if the value is NaN, false otherwise.\n *\n * @remarks\n * Uses `Number.isNaN` (not the coercive global `isNaN`), so only the\n * literal `NaN` value returns true.\n *\n * @example\n * isNaN(Number.NaN); // true\n * isNaN(0); // false\n *\n * @category Primitives\n */\nexport const isNaN = (value: unknown): value is number => Number.isNaN(value);\n","import { isString } from './isString.js';\n\n/**\n * Checks if the provided value is a non-blank string (not empty and not whitespace-only).\n * Use {@link isNonEmptyString} when whitespace-only strings are acceptable (e.g. preserving\n * intentional formatting).\n *\n * @param value - The value to check.\n * @returns True if the value is a string with at least one non-whitespace character, false otherwise.\n *\n * @example\n * isNonBlankString('a'); // true\n * isNonBlankString(' '); // false\n *\n * @category Strings\n */\nexport const isNonBlankString = (value: unknown): value is string =>\n isString(value) && value.trim() !== '';\n","import type { UnknownRecord } from 'type-fest';\nimport type { Nilable } from '../types/Nilable.js';\nimport type { NonEmptyArray } from '../types/NonEmptyArray.js';\nimport { isArray } from './isArray.js';\n\n/**\n * Checks if the provided value is a non-empty array.\n *\n * @param value - The value to check. Can be null or undefined.\n * @returns True if the value is a non-empty array, false otherwise.\n *\n * @example\n * isNonEmptyArray([1]); // true\n * isNonEmptyArray([]); // false\n *\n * @category Arrays\n */\nexport const isNonEmptyArray = <T>(\n value: Nilable<T[] | UnknownRecord>,\n): value is NonEmptyArray<T> => isArray(value) && value.length > 0;\n","import { isEmptyString } from './isEmptyString.js';\nimport { isString } from './isString.js';\n\n/**\n * Checks if the provided value is a non-empty string. Whitespace-only strings like `\" \"` pass.\n * Use {@link isNonBlankString} when whitespace-only strings should be rejected (e.g. user input\n * validation).\n *\n * @param value - The value to check.\n * @returns True if the value is a non-empty string, false otherwise.\n *\n * @example\n * isNonEmptyString('a'); // true\n * isNonEmptyString(''); // false\n *\n * @category Strings\n */\nexport const isNonEmptyString = (value: unknown): value is string =>\n isString(value) && !isEmptyString(value);\n","import { isNaN } from './isNaN.js';\nimport { isNumber } from './isNumber.js';\n\n/**\n * Checks if the provided value is a number that is not NaN.\n *\n * @param value - The value to check.\n * @returns True if the value is a number and not NaN, false otherwise.\n *\n * @example\n * isNonNaNNumber(42); // true\n * isNonNaNNumber(Number.NaN); // false\n *\n * @category Primitives\n */\nexport const isNonNaNNumber = (value: unknown): value is number => isNumber(value) && !isNaN(value);\n","import { isArray } from './isArray.js';\n\n/**\n * Checks if the provided value is not an array.\n *\n * @param value - The value to check.\n * @returns True if the value is not an array, false otherwise.\n *\n * @example\n * isNotArray('x'); // true\n * isNotArray([]); // false\n *\n * @category Negated\n */\nexport const isNotArray = (value: unknown): value is Exclude<unknown, unknown[]> => !isArray(value);\n","import { isBoolean } from './isBoolean.js';\n\n/**\n * Checks if the provided value is not a boolean.\n *\n * @param value - The value to check.\n * @returns True if the value is not a boolean, false otherwise.\n *\n * @example\n * isNotBoolean(1); // true\n * isNotBoolean(true); // false\n *\n * @category Negated\n */\nexport const isNotBoolean = (value: unknown): value is Exclude<unknown, boolean> =>\n !isBoolean(value);\n","import { isFunction } from './isFunction.js';\n\n/**\n * Checks if the provided value is not a function.\n *\n * @param value - The value to check.\n * @returns True if the value is not a function, false otherwise.\n *\n * @example\n * isNotFunction(1); // true\n * isNotFunction(() => {}); // false\n *\n * @category Negated\n */\nexport const isNotFunction = (\n value: unknown,\n): value is Exclude<unknown, (...args: unknown[]) => unknown> => !isFunction(value);\n","import { isNull } from './isNull.js';\n\n/**\n * Checks if the provided value is not null.\n *\n * @param value - The value to check.\n * @returns True if the value is not null, false otherwise.\n *\n * @example\n * isNotNull(undefined); // true\n * isNotNull(null); // false\n *\n * @category Negated\n */\nexport const isNotNull = <T>(value: unknown): value is Exclude<T, null> => !isNull(value);\n","import { isNumber } from './isNumber.js';\n\n/**\n * Checks if the provided value is not a number.\n *\n * @param value - The value to check.\n * @returns True if the value is not a number, false otherwise.\n *\n * @example\n * isNotNumber('1'); // true\n * isNotNumber(1); // false\n *\n * @category Negated\n */\nexport const isNotNumber = (value: unknown): value is Exclude<unknown, number> => !isNumber(value);\n","import { isRecord } from './isRecord.js';\n\n/**\n * Checks if the provided value is not an object.\n *\n * @param value - The value to check.\n * @returns True if the value is not a record (object), false otherwise.\n *\n * @example\n * isNotRecord([]); // true\n * isNotRecord({}); // false\n *\n * @category Negated\n */\nexport const isNotRecord = (value: unknown): value is Exclude<unknown, Record<string, unknown>> =>\n !isRecord(value);\n","import { isString } from './isString.js';\n\n/**\n * Checks if the provided value is not a string.\n *\n * @param value - The value to check.\n * @returns True if the value is not a string, false otherwise.\n *\n * @example\n * isNotString(1); // true\n * isNotString('a'); // false\n *\n * @category Negated\n */\nexport const isNotString = (value: unknown): value is Exclude<unknown, string> => !isString(value);\n","import type { Undefinable } from '../types/Undefinable.js';\nimport { isUndefined } from './isUndefined.js';\n\n/**\n * Checks if the provided value is not undefined.\n *\n * @param value - The value to check.\n * @returns True if the value is not undefined, false otherwise.\n *\n * @example\n * isNotUndefined(null); // true\n * isNotUndefined(undefined); // false\n *\n * @category Negated\n */\nexport const isNotUndefined = <T>(value: Undefinable<T>): value is Exclude<T, undefined> =>\n !isUndefined(value);\n","/**\n * Checks if the provided value is void.\n *\n * @param value - The value to check.\n * @returns True if the value is void (undefined), false otherwise.\n *\n * @example\n * isVoid(undefined); // true\n * isVoid(0); // false\n *\n * @category Primitives\n */\nexport const isVoid = (value: unknown): value is void => value === void 0; // oxlint-disable-line no-void, typescript/no-invalid-void-type\n","import { isVoid } from './isVoid.js';\n\n/**\n * Checks if the provided value is not void.\n *\n * @param value - The value to check.\n * @returns True if the value is not void (defined), false otherwise.\n *\n * @example\n * isNotVoid(0); // true\n * isNotVoid(undefined); // false\n *\n * @category Negated\n */\nexport const isNotVoid = (value: unknown): value is Exclude<unknown, void> => !isVoid(value);\n","import { isArray } from './isArray.js';\nimport { isNil } from './isNil.js';\n\n/**\n * Checks if the provided value is a plain object created with `{}` or `Object.create(null)`.\n * Returns false for arrays, `Date`, `Map`, `RegExp`, boxed primitives, and class instances.\n *\n * @param value - The value to check.\n * @returns True if the value is a plain object, false otherwise.\n *\n * @example\n * isPlainObject({}); // true\n * isPlainObject(new Date()); // false\n *\n * @category Records\n */\nexport const isPlainObject = (value: unknown): value is Record<string, unknown> => {\n if (isNil(value) || typeof value !== 'object') {\n return false;\n }\n\n if (isArray(value)) {\n return false;\n }\n\n const proto: unknown = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n};\n","import { isNotNil } from './isNotNil.js';\n\n/**\n * Checks if the provided value is a Promise, including promise-like objects\n * that implement `then`, `catch`, and `finally`.\n *\n * @param value - The value to check.\n * @returns True if the value is a Promise or promise-like object, false otherwise.\n *\n * @remarks\n * The full `Promise` method surface is required so the narrowed type is\n * accurate: `then`, `catch`, and `finally` must all be functions. Thenables\n * that only implement a subset are rejected.\n *\n * @example\n * isPromise(Promise.resolve()); // true\n * isPromise({ then: () => 1 }); // false\n *\n * @category Primitives\n */\nexport const isPromise = (value: unknown): value is Promise<unknown> => {\n if (!isNotNil(value)) {\n return false;\n }\n\n const candidate = value as { then?: unknown; catch?: unknown; finally?: unknown }; // oxlint-disable-line typescript/no-unsafe-type-assertion\n return (\n typeof candidate.then === 'function' &&\n typeof candidate.catch === 'function' &&\n typeof candidate.finally === 'function'\n );\n};\n","import { isNotNil } from './isNotNil.js';\n\n/**\n * Checks if the provided value is an instance of RegExp.\n *\n * @param value - The value to check.\n * @returns True if the value is a RegExp instance, false otherwise.\n *\n * @example\n * isRegExp(/abc/); // true\n * isRegExp('/abc/'); // false\n *\n * @category Primitives\n */\nexport const isRegExp = (value: unknown): value is RegExp => {\n return isNotNil(value) && value instanceof RegExp;\n};\n","import { isNotNil } from './isNotNil.js';\n\n/**\n * Checks if the provided value is an instance of Set.\n *\n * @param value - The value to check.\n * @returns True if the value is a Set instance, false otherwise.\n *\n * @remarks\n * WeakSet instances return false.\n *\n * @example\n * isSet(new Set()); // true\n * isSet([]); // false\n *\n * @category Primitives\n */\nexport const isSet = (value: unknown): value is Set<unknown> => {\n return isNotNil(value) && value instanceof Set;\n};\n","/**\n * Checks if the provided value is an SVGElement.\n *\n * @param value - The value to check.\n * @returns True if the value is an SVGElement, false otherwise.\n *\n * @example\n * isSvgElement(document.createElementNS('http://www.w3.org/2000/svg', 'svg')); // true\n * isSvgElement(document.createElement('div')); // false\n *\n * @category DOM\n */\nexport const isSvgElement = (value: unknown): value is SVGElement => value instanceof SVGElement;\n","/**\n * Checks if the provided value is a symbol.\n *\n * @param value - The value to check.\n * @returns True if the value is a symbol, false otherwise.\n *\n * @example\n * isSymbol(Symbol('a')); // true\n * isSymbol('symbol'); // false\n *\n * @category Primitives\n */\nexport const isSymbol = (value: unknown): value is symbol => typeof value === 'symbol';\n","/**\n * Checks if the provided value is a Text node.\n *\n * @param value - The value to check.\n * @returns True if the value is a Text node, false otherwise.\n *\n * @example\n * isTextNode(document.createTextNode('hi')); // true\n * isTextNode(document.createElement('div')); // false\n *\n * @category DOM\n */\nexport const isTextNode = (value: unknown): value is Text => (value as Text).nodeName === '#text'; // oxlint-disable-line typescript/no-unsafe-type-assertion\n","import type { Falsy } from '../types/Falsy.js';\nimport { FALSY_VALUES } from './_falsyValues.js';\n\n/**\n * Checks if the provided value is truthy.\n *\n * @param value - The value to check.\n * @returns True if the value is truthy, false otherwise.\n *\n * @remarks\n * The complement of `isFalsy`. Does not provide narrowing on its own;\n * use `isNotNil` or a specific positive guard when narrowing matters.\n *\n * @example\n * isTruthy(1); // true\n * isTruthy(0); // false\n *\n * @category Truthy / falsy\n */\nexport const isTruthy = (value: unknown): boolean =>\n !FALSY_VALUES.includes(value as Falsy) && !Number.isNaN(value); // oxlint-disable-line typescript/no-unsafe-type-assertion\n","import { isNotNil } from './isNotNil.js';\n\n/**\n * Checks if the provided value is an instance of WeakMap.\n *\n * @param value - The value to check.\n * @returns True if the value is a WeakMap instance, false otherwise.\n *\n * @remarks\n * Map instances return false. Narrows to `WeakMap<WeakKey, unknown>`, since\n * weak collections accept non-registered symbols as keys (ES2023).\n *\n * @example\n * isWeakMap(new WeakMap()); // true\n * isWeakMap(new Map()); // false\n *\n * @category Primitives\n */\nexport const isWeakMap = (value: unknown): value is WeakMap<WeakKey, unknown> => {\n return isNotNil(value) && value instanceof WeakMap;\n};\n","import { isNotNil } from './isNotNil.js';\n\n/**\n * Checks if the provided value is an instance of WeakSet.\n *\n * @param value - The value to check.\n * @returns True if the value is a WeakSet instance, false otherwise.\n *\n * @remarks\n * Set instances return false. Narrows to `WeakSet<WeakKey>`, since weak\n * collections accept non-registered symbols as members (ES2023).\n *\n * @example\n * isWeakSet(new WeakSet()); // true\n * isWeakSet(new Set()); // false\n *\n * @category Primitives\n */\nexport const isWeakSet = (value: unknown): value is WeakSet<WeakKey> => {\n return isNotNil(value) && value instanceof WeakSet;\n};\n","/**\n * Checks if a readonly array includes the given element, with type narrowing.\n *\n * @param arr - The readonly array to search.\n * @param elem - The element to search for.\n * @returns True if the array includes the element, false otherwise.\n *\n * @example\n * const arr = ['a', 'b'] as const;\n * readonlyArrayIncludes(arr, 'a'); // true\n * readonlyArrayIncludes(arr, 'z'); // false\n *\n * @category Arrays\n */\nexport const readonlyArrayIncludes = <T>(arr: readonly T[], elem: unknown): elem is T =>\n arr.includes(elem as T); // oxlint-disable-line typescript/no-unsafe-type-assertion\n","import type { NoOpFn } from './noOpFn.js';\n\nexport type AsyncNoOpFn = typeof asyncNoOpFn;\nexport type AsyncOrSyncNoOpFn = AsyncNoOpFn | NoOpFn;\n\n/**\n * An async function that does nothing. Useful as a default or placeholder\n * callback where a promise is expected.\n *\n * @returns A promise that resolves to `undefined`.\n *\n * @example\n * await asyncNoOpFn(); // undefined\n */\nexport const asyncNoOpFn = async (): Promise<void> => {};\n","export const defaultLocales: string[] = ['en-US'];\n// resolvedOptions().timeZone is always a non-empty IANA zone on supported\n// Node versions, so no fallback is needed.\nexport const defaultTimeZone: string = Intl.DateTimeFormat().resolvedOptions().timeZone;\n\nexport const secondsInMinute = 60;\nexport const minutesInHour = 60;\nexport const halfAnHourInMinutes = 30;\nexport const hoursInDay = 24;\nexport const milisecondsInSecond = 1000;\nexport const daysInWeek = 7;\nexport const millisecondsInDay: number =\n hoursInDay * minutesInHour * secondsInMinute * milisecondsInSecond;\n","import { milisecondsInSecond, secondsInMinute, minutesInHour } from './_constants.js';\n\nexport type TimeDuration = {\n seconds: number;\n minutes: number;\n hours: number;\n};\n\n/**\n * Returns an object representing a duration in seconds, minutes and hours.\n *\n * @param numberOfMilliseconds - The duration in milliseconds.\n * @returns The duration split into hours, minutes and seconds.\n *\n * @example\n * buildTimeDuration(3723000); // { hours: 1, minutes: 2, seconds: 3 }\n */\nexport const buildTimeDuration = (numberOfMilliseconds: number): TimeDuration => {\n const numberOfSeconds = Math.floor(numberOfMilliseconds / milisecondsInSecond);\n const numberOfMinutes = Math.floor(numberOfSeconds / secondsInMinute);\n const numberOfHours = Math.floor(numberOfMinutes / minutesInHour);\n const seconds = numberOfSeconds - numberOfMinutes * secondsInMinute;\n const minutes = numberOfMinutes - numberOfHours * minutesInHour;\n\n return { seconds, minutes, hours: numberOfHours };\n};\n","/**\n * Converts the boolean string values 'true' and 'false' into the\n * corresponding boolean. Any other value is coerced with `Boolean()`.\n *\n * @param value - The value to coerce.\n * @returns The value as a boolean.\n *\n * @example\n * coerceToBoolean('true'); // true\n * coerceToBoolean('false'); // false\n * coerceToBoolean(0); // false\n */\nexport const coerceToBoolean = (value: unknown): boolean => {\n if (value === 'true' || value === 'false') {\n return value === 'true';\n }\n return Boolean(value);\n};\n","import { isDate } from '../guards/isDate.js';\n\n/**\n * Checks whether a value is not a usable Date. Note that the Unix epoch\n * (getTime() === 0) is treated as invalid.\n *\n * @param date - The value to check.\n * @returns True if the value is not a Date, is an invalid Date, or is the Unix epoch.\n */\nexport const isInvalidDate = (date: unknown): boolean => {\n if (!isDate(date)) {\n return true;\n }\n const time = date.getTime();\n\n return time === 0 || Number.isNaN(time);\n};\n","import type { DateOnlyStringOptions } from './dateOnlyString.js';\nimport { isDate } from '../guards/isDate.js';\nimport { defaultTimeZone, defaultLocales } from './_constants.js';\nimport { isInvalidDate } from './_isInvalidDate.js';\n\n/**\n * Converts a Date object into a date only string formatted to ISO 8601,\n * e.g. '2021-06-03'.\n *\n * @param date - The Date to format; gracefully handles any value.\n * @param options - Formatting options.\n * @param options.timeZone - The time zone to display the date in. Defaults to the current time zone.\n * @returns The formatted date string, or '' for invalid input.\n *\n * @example\n * dateOnlyISOString(new Date(2011, 11, 15)); // '2011-12-15'\n */\nexport const dateOnlyISOString = (\n date: unknown,\n { timeZone = defaultTimeZone }: DateOnlyStringOptions = {},\n): string => {\n if (!isDate(date) || isInvalidDate(date)) {\n return '';\n }\n\n try {\n const formatter = new Intl.DateTimeFormat(defaultLocales, {\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n timeZone,\n });\n const parts = formatter.formatToParts(date);\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- year/month/day are always present for the requested options\n const partsAsObject = parts.reduce(\n (map: Partial<Record<Intl.DateTimeFormatPartTypes, string>>, obj) => {\n map[obj.type] = obj.value;\n return map;\n },\n {},\n ) as Record<Intl.DateTimeFormatPartTypes, string>;\n return `${partsAsObject.year}-${partsAsObject.month}-${partsAsObject.day}`;\n } catch (error: unknown) {\n console.error(error);\n return ''; // handle bad input\n }\n};\n","import { isDate } from '../guards/isDate.js';\nimport { defaultTimeZone, defaultLocales } from './_constants.js';\nimport { isInvalidDate } from './_isInvalidDate.js';\n\nexport type DateOnlyStringOptions = {\n timeZone?: string;\n /**\n * When set to true, the returned string will omit the year.\n * e.g. \"Jun 3\" instead of \"Jun 3, 2021\"\n */\n omitYear?: boolean;\n};\n\n/**\n * Converts a Date object into a date only string, e.g. 'Jun 3, 2021',\n * or 'Jun 3' if omitYear is true. Formats with the en-US locale.\n *\n * @param date - The Date to format; gracefully handles any value.\n * @param options - Formatting options.\n * @param options.timeZone - The time zone to display the date in. Defaults to the current time zone.\n * @param options.omitYear - If true, display the date without the year.\n * @returns The formatted date string, or '' for invalid input.\n *\n * @example\n * dateOnlyString(new Date(2011, 11, 15)); // 'Dec 15, 2011'\n */\nexport const dateOnlyString = (\n date: unknown,\n { timeZone = defaultTimeZone, omitYear = false }: DateOnlyStringOptions = {},\n): string => {\n if (!isDate(date) || isInvalidDate(date)) {\n return '';\n }\n\n // Conditionally build formatting options based on the omitYear flag.\n const formatOptions: Intl.DateTimeFormatOptions = omitYear\n ? { month: 'short', day: 'numeric', timeZone }\n : { dateStyle: 'medium', timeZone };\n\n try {\n return new Intl.DateTimeFormat(defaultLocales, formatOptions).format(date);\n } catch (error: unknown) {\n console.error(error);\n return ''; // handle bad input\n }\n};\n","import type { DateOnlyStringOptions } from './dateOnlyString.js';\nimport { isDate } from '../guards/isDate.js';\nimport { defaultTimeZone, defaultLocales } from './_constants.js';\nimport { isInvalidDate } from './_isInvalidDate.js';\n\n/**\n * Converts a Date object into a date only string for use in a sentence,\n * e.g. 'June 3, 2021'. Formats with the en-US locale.\n *\n * @param date - The Date to format; gracefully handles any value.\n * @param options - Formatting options.\n * @param options.timeZone - The time zone to display the date in. Defaults to the current time zone.\n * @returns The formatted date string, or '' for invalid input.\n *\n * @example\n * dateOnlyStringForSentence(new Date(2011, 11, 15)); // 'December 15, 2011'\n */\nexport const dateOnlyStringForSentence = (\n date: unknown,\n { timeZone = defaultTimeZone }: DateOnlyStringOptions = {},\n): string => {\n if (!isDate(date) || isInvalidDate(date)) {\n return '';\n }\n\n try {\n return new Intl.DateTimeFormat(defaultLocales, {\n dateStyle: 'long',\n timeZone,\n }).format(date);\n } catch (error: unknown) {\n console.error(error);\n return ''; // handle bad input\n }\n};\n","import type { DateOnlyStringOptions } from './dateOnlyString.js';\nimport { isDate } from '../guards/isDate.js';\nimport { defaultTimeZone, defaultLocales } from './_constants.js';\nimport { isInvalidDate } from './_isInvalidDate.js';\n\n/**\n * Converts a Date object into a date only string formatted numerically,\n * e.g. '06/03/2021'. Formats with the en-US locale.\n *\n * @param date - The Date to format; gracefully handles any value.\n * @param options - Formatting options.\n * @param options.timeZone - The time zone to display the date in. Defaults to the current time zone.\n * @returns The formatted date string, or '' for invalid input.\n *\n * @example\n * dateOnlyStringNumeric(new Date(2011, 11, 15)); // '12/15/2011'\n */\nexport const dateOnlyStringNumeric = (\n date: unknown,\n { timeZone = defaultTimeZone }: DateOnlyStringOptions = {},\n): string => {\n if (!isDate(date) || isInvalidDate(date)) {\n return '';\n }\n\n try {\n return new Intl.DateTimeFormat(defaultLocales, {\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n timeZone,\n }).format(date);\n } catch (error: unknown) {\n console.error(error);\n return ''; // handle bad input\n }\n};\n","import type { WistiaDateTimeObject } from './dateToDateTime.js';\n\n/**\n * Converts a plain object of date and time parts into a Date object.\n *\n * @param dateTime - The date parts to convert.\n * @returns The converted Date, or null if year, month, or dayOfMonth is missing.\n *\n * @example\n * dateTimeToDate({ year: 2015, month: 10, dayOfMonth: 7, hours: 4, minutes: 15 });\n * // new Date(2015, 10, 7, 4, 15)\n */\nexport const dateTimeToDate = (\n dateTime: Partial<WistiaDateTimeObject> | null | undefined,\n): Date | null => {\n const { year, month, dayOfMonth, hours, minutes } = dateTime ?? {};\n\n if (year !== undefined && month !== undefined && dayOfMonth !== undefined) {\n return new Date(year, month, dayOfMonth, hours ?? 0, minutes ?? 0);\n }\n return null;\n};\n","import type { WistiaDateTimeObject } from './dateToDateTime.js';\nimport { dateTimeToDate } from './dateTimeToDate.js';\n\n/**\n * Converts a plain object of date and time parts into an ISO-8601 string.\n *\n * @param dateTime - The date parts to convert.\n * @returns The ISO-8601 string, or null if year, month, or dayOfMonth is missing.\n *\n * @example\n * dateTimeToISO({ year: 2015, month: 10, dayOfMonth: 7, hours: 4, minutes: 15 });\n * // '2015-11-07T04:15:00.000Z' (in UTC)\n */\nexport const dateTimeToISO = (dateTime: Partial<WistiaDateTimeObject>): string | null =>\n dateTimeToDate(dateTime)?.toISOString() ?? null;\n","import { isDate } from '../guards/isDate.js';\n\nexport type WistiaDateTimeObject = {\n minutes: number;\n hours: number;\n dayOfMonth: number;\n year: number;\n month: number;\n};\n\n/**\n * Converts a Date object into a plain object of its local date and time parts.\n *\n * @param date - The Date object to convert.\n * @returns The date parts, or null if the value is not a Date.\n *\n * @example\n * dateToDateTime(new Date(2011, 11, 15, 3, 10));\n * // { year: 2011, month: 11, dayOfMonth: 15, hours: 3, minutes: 10 }\n */\nexport const dateToDateTime = (date: Date | null | undefined): WistiaDateTimeObject | null => {\n if (!isDate(date)) {\n return null;\n }\n\n return {\n year: date.getFullYear(),\n month: date.getMonth(),\n dayOfMonth: date.getDate(),\n hours: date.getHours(),\n minutes: date.getMinutes(),\n };\n};\n","import { halfAnHourInMinutes } from './_constants.js';\nimport { dateTimeToDate } from './dateTimeToDate.js';\nimport { dateTimeToISO } from './dateTimeToISO.js';\nimport { dateToDateTime } from './dateToDateTime.js';\n\nexport type DateTimeRoundedOverload = {\n (dateTime: Date, toISOString?: true): string | null;\n (dateTime: Date, toISOString: false): Date | null;\n};\n\n/**\n * Rounds a Date up to the next half hour boundary.\n *\n * @param dateTime - The Date to round.\n * @param toISOString - Whether to return an ISO-8601 string instead of a Date.\n * @returns The rounded value as a string or Date depending on toISOString.\n *\n * @example\n * dateTimeRounded(new Date(2015, 10, 7, 0, 10)); // '2015-11-07T00:30:00.000Z' (in UTC)\n * dateTimeRounded(new Date(2015, 10, 7, 0, 40), false); // new Date(2015, 10, 7, 1, 0)\n */\n// @ts-expect-error TS Compiler is having issues with the overload syntax here, but this should provide a good DX.\nexport const dateTimeRounded: DateTimeRoundedOverload = (\n dateTime: Date,\n toISOString = true,\n): string | Date | null => {\n const first30Min = dateTime.getMinutes() <= halfAnHourInMinutes;\n const hours = first30Min ? dateTime.getHours() : dateTime.getHours() + 1;\n const minutes = first30Min ? halfAnHourInMinutes : 0;\n\n const dateWithTime = {\n ...dateToDateTime(dateTime),\n hours,\n minutes,\n };\n\n if (toISOString) {\n return dateTimeToISO(dateWithTime);\n }\n\n return dateTimeToDate(dateWithTime);\n};\n","import type { DateOnlyStringOptions } from './dateOnlyString.js';\nimport { isNil } from '../guards/isNil.js';\nimport { defaultTimeZone, defaultLocales } from './_constants.js';\nimport { isInvalidDate } from './_isInvalidDate.js';\n\n/**\n * Converts a Date, timestamp, or date string into a date and time string,\n * e.g. 'Jun 3, 2021, 11:52 AM'. Formats with the en-US locale.\n *\n * NOTE: you should probably use timeAgoString when trying to display\n * an updated/created timestamp.\n *\n * @param date - The Date, timestamp, or date string to format; gracefully handles any value.\n * @param options - Formatting options.\n * @param options.timeZone - The time zone to display the date in. Defaults to the current time zone.\n * @param options.omitYear - If true, display the date without the year.\n * @returns The formatted date string, or '' for invalid input.\n *\n * @example\n * dateTimeString(new Date(2011, 11, 15, 7, 30)); // 'Dec 15, 2011, 7:30 AM'\n */\nexport const dateTimeString = (\n date: Date | number | string | null | undefined,\n { timeZone = defaultTimeZone, omitYear = false }: DateOnlyStringOptions = {},\n): string => {\n if (isNil(date)) {\n return '';\n }\n\n const formattedDate = new Date(date);\n\n if (isInvalidDate(formattedDate)) {\n return '';\n }\n\n try {\n const baseOptions: Intl.DateTimeFormatOptions = {\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n timeZone,\n };\n\n const options: Intl.DateTimeFormatOptions = omitYear\n ? baseOptions\n : { ...baseOptions, year: 'numeric' };\n\n return formattedDate.toLocaleDateString(defaultLocales, options);\n } catch (error: unknown) {\n console.error(error);\n return ''; // handle bad input\n }\n};\n","import type { DateOnlyStringOptions } from './dateOnlyString.js';\nimport { isDate } from '../guards/isDate.js';\nimport { defaultTimeZone, defaultLocales } from './_constants.js';\nimport { isInvalidDate } from './_isInvalidDate.js';\n\n/**\n * Converts a Date object into a date and time string for use in a sentence,\n * e.g. 'June 3, 2021, 11:52 AM'. Formats with the en-US locale.\n *\n * NOTE: you should probably use timeAgoString when trying to display\n * an updated/created timestamp.\n *\n * @param date - The Date to format; gracefully handles any value.\n * @param options - Formatting options.\n * @param options.timeZone - The time zone to display the date in. Defaults to the current time zone.\n * @returns The formatted date string, or '' for invalid input.\n *\n * @example\n * dateTimeStringForSentence(new Date(2011, 11, 15, 7, 30)); // 'December 15, 2011, 7:30 AM'\n */\nexport const dateTimeStringForSentence = (\n date: unknown,\n { timeZone = defaultTimeZone }: DateOnlyStringOptions = {},\n): string => {\n if (!isDate(date) || isInvalidDate(date)) {\n return '';\n }\n\n try {\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- the requested options guarantee every destructured part is present\n const { year, month, day, hour, minute, dayPeriod } = new Intl.DateTimeFormat(defaultLocales, {\n month: 'long',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n timeZone,\n })\n .formatToParts(date)\n .reduce<Partial<Record<Intl.DateTimeFormatPartTypes, string>>>((acc, part) => {\n if (part.type !== 'literal') {\n acc[part.type] = part.value;\n }\n return acc;\n }, {}) as Record<Intl.DateTimeFormatPartTypes, string>;\n return `${month} ${day}, ${year}, ${hour}:${minute} ${dayPeriod}`;\n } catch (error: unknown) {\n console.error(error);\n return ''; // handle bad input\n }\n};\n","import { minutesInHour } from './_constants.js';\n\n/**\n * Given a date, shows the UTC offset of the current time zone, e.g. '+02:00'.\n *\n * @param date - The Date to calculate the offset for.\n * @returns The UTC offset string.\n *\n * @example\n * dateUTCOffset(new Date(2011, 11, 15)); // '+00:00' (when run in UTC)\n */\nexport const dateUTCOffset = (date: Date): string => {\n const offsetInHours = (date.getTimezoneOffset() / minutesInHour) * -1;\n const hours = Math.round(offsetInHours);\n const minutes = (offsetInHours - hours) * minutesInHour;\n const prefix = hours >= 0 ? '+' : '';\n const hoursString = `${hours}`.padStart(2, '0');\n const minutesString = `${minutes}`.padStart(2, '0');\n\n return `${prefix}${hoursString}:${minutesString}`;\n};\n","import type { DateOnlyStringOptions } from './dateOnlyString.js';\nimport { defaultTimeZone, defaultLocales } from './_constants.js';\n\n/**\n * Converts a Date object into a day of the week string, e.g. 'Thursday'.\n * Formats with the en-US locale.\n *\n * @param date - The Date to format.\n * @param options - Formatting options.\n * @param options.timeZone - The time zone to display the date in. Defaults to the current time zone.\n * @returns The formatted day of the week, or '' for null or invalid input.\n *\n * @example\n * dayOfWeekString(new Date(2011, 11, 15)); // 'Thursday'\n */\nexport const dayOfWeekString = (\n date: Date | null,\n { timeZone = defaultTimeZone }: DateOnlyStringOptions = {},\n): string => {\n if (date === null) {\n return '';\n }\n\n try {\n return new Intl.DateTimeFormat(defaultLocales, {\n weekday: 'long',\n timeZone,\n }).format(date);\n } catch (error: unknown) {\n console.error(error);\n return ''; // handle bad input\n }\n};\n","import { isArray } from '../guards/isArray.js';\nimport { isPlainObject } from '../guards/isPlainObject.js';\n\n// Symbol keys are excluded because Object.keys skips them at runtime.\ntype AllKeys<T> = T extends unknown ? Extract<keyof T, string | number> : never;\n\ntype IndexValue<T, K extends PropertyKey> = T extends unknown\n ? K extends keyof T\n ? T[K]\n : never\n : never;\n\ntype MergeableFunction = (...args: never[]) => unknown;\n\n// Values that are overwritten whole rather than merged recursively.\ntype OverwrittenValues =\n | string\n | number\n | boolean\n | bigint\n | symbol\n | Date\n | RegExp\n | Map<unknown, unknown>\n | Set<unknown>\n | Error\n | Promise<unknown>\n | MergeableFunction;\n\nexport type DeepMerged<T> = [T] extends [unknown[]]\n ? { [K in keyof T]: DeepMerged<T[K]> }\n : [T] extends [OverwrittenValues]\n ? T\n : [T] extends [object]\n ? { [K in AllKeys<T>]: DeepMerged<IndexValue<T, K>> }\n : T;\n\ntype DeepMergeResult<T extends Record<string, unknown>[]> = [T[number]] extends [never]\n ? Record<string, never>\n : DeepMerged<T[number]>;\n\n// Own enumerable keys that could pollute Object.prototype when copied onto\n// the result (e.g. from JSON.parse'd input). These keys are silently dropped.\nconst UNSAFE_KEYS = new Set(['__proto__', 'constructor', 'prototype']);\n\nconst cloneIfArray = (value: unknown): unknown => (isArray(value) ? [...value] : value);\n\n/**\n * Deeply merges objects without mutating them, inferring the return type from\n * the inputs. Plain objects are merged recursively, arrays are concatenated\n * with duplicate items removed (by reference for object items), and all other\n * values (including class instances) are overwritten in the order of the\n * provided arguments. The prototype-polluting keys `__proto__`, `constructor`,\n * and `prototype` are dropped. Symbol-keyed properties are not merged.\n *\n * @param objects - The objects to merge.\n * @returns A new object containing the merged result.\n * @throws TypeError when an argument is an array.\n *\n * @example\n * deepMerge({ a: { b: 1 }, c: [1] }, { a: { d: 2 }, c: [2] });\n * // { a: { b: 1, d: 2 }, c: [1, 2] }\n */\nexport const deepMerge = <T extends Record<string, unknown>[]>(\n ...objects: T\n): DeepMergeResult<T> => {\n const result: Record<string, unknown> = {};\n\n for (const current of objects) {\n if (isArray(current)) {\n throw new TypeError('Arguments provided to deepMerge must be objects, not arrays.');\n }\n\n const safeKeys = Object.keys(current).filter((key) => !UNSAFE_KEYS.has(key));\n\n for (const key of safeKeys) {\n const existing = result[key];\n const incoming = current[key];\n\n if (isArray(existing) && isArray(incoming)) {\n result[key] = [...new Set([...existing, ...incoming])];\n } else if (isPlainObject(existing) && isPlainObject(incoming)) {\n result[key] = deepMerge(existing, incoming);\n } else if (isPlainObject(incoming)) {\n result[key] = deepMerge(incoming);\n } else {\n result[key] = cloneIfArray(incoming);\n }\n }\n }\n\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- the merged record matches the mapped type by construction\n return result as DeepMergeResult<T>;\n};\n","/**\n * Returns the entries of an object with strongly typed keys and values.\n *\n * @param obj - The object to get entries from.\n * @returns An array of [key, value] tuples.\n *\n * @example\n * getObjectEntries({ a: 1, b: 2 }); // [['a', 1], ['b', 2]]\n */\nexport const getObjectEntries = <T extends Record<string, unknown>>(\n obj: T,\n): [keyof T, T[keyof T]][] => (Object.keys(obj) as (keyof T)[]).map((key) => [key, obj[key]]);\n","/**\n * Returns the keys of an object with strongly typed key type.\n *\n * @param obj - The object to get keys from.\n * @returns An array of the object's keys.\n *\n * @example\n * getObjectKeys({ a: 1, b: 2 }); // ['a', 'b']\n */\nexport const getObjectKeys = <T extends Record<string, unknown>>(obj: T): (keyof T)[] =>\n Object.keys(obj);\n","/**\n * Returns the values of an object with strongly typed value type.\n *\n * @param obj - The object to get values from.\n * @returns An array of the object's values.\n *\n * @example\n * getObjectValues({ a: 1, b: 2 }); // [1, 2]\n */\nexport const getObjectValues = <T extends Record<string, unknown>>(obj: T): T[keyof T][] =>\n Object.values(obj) as T[keyof T][]; // oxlint-disable-line typescript/no-unsafe-type-assertion\n","/**\n * Loosely validates an email address string.\n *\n * @param value - The string to validate.\n * @returns True if the string appears to be an email address, false otherwise.\n *\n * @example\n * isEmail('user@example.com'); // true\n * isEmail('user@example'); // false\n */\nexport const isEmail = (value: string): boolean => /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value);\n","import { isString } from '../guards/isString.js';\n\n/**\n * Loosely validates a URL string.\n *\n * @param value - The value to validate.\n * @returns True if the value appears to be a URL, false otherwise.\n *\n * @example\n * isUrl('https://wistia.com'); // true\n * isUrl('not a url'); // false\n */\nexport const isUrl = (value: unknown): boolean => {\n // A URL must match #1 and then at least one of #2/#3\n // Use two levels of REs to avoid ReDoS\n // https://levelup.gitconnected.com/the-regular-expression-denial-of-service-redos-cheat-sheet-a78d0ed7d865\n const protocolAndDomain = /^(?:\\w+:)?\\/\\/(\\S+)$/;\n const localhostDomain = /^localhost[:?\\d]*(?:[^:?\\d]\\S*)?$/;\n const nonLocalhostDomain = /^[^\\s.]+\\.\\S{2,}$/;\n\n if (!isString(value)) {\n return false;\n }\n\n // part of the string that is not the protocol\n const remaining = protocolAndDomain.exec(value)?.[1];\n\n if (remaining === undefined) {\n return false;\n }\n\n return localhostDomain.test(remaining) || nonLocalhostDomain.test(remaining);\n};\n","/**\n * Pads an integer with a leading zero.\n *\n * @param num - The integer to pad.\n * @returns The integer as a string with padding.\n */\nexport const padTimeInteger = (num: number): string => num.toString().padStart(2, '0');\n","import { padTimeInteger } from './_padTimeInteger.js';\nimport { buildTimeDuration } from './buildTimeDuration.js';\n\n/**\n * A string representation of a duration for a media. Assumes most medias\n * are under an hour so only shows hours if media is over an hour.\n *\n * @param numberOfMilliseconds - The duration in milliseconds.\n * @returns The formatted duration string.\n *\n * @example\n * mediaDurationString(234230); // '3:54'\n * mediaDurationString(23423000); // '6:30:23'\n */\nexport const mediaDurationString = (numberOfMilliseconds: number): string => {\n const { hours, minutes, seconds } = buildTimeDuration(numberOfMilliseconds);\n\n if (hours < 1) {\n return `${minutes}:${padTimeInteger(seconds)}`;\n }\n\n return `${hours}:${padTimeInteger(minutes)}:${padTimeInteger(seconds)}`;\n};\n","import { buildTimeDuration } from './buildTimeDuration.js';\n\n/**\n * Given a number of milliseconds, returns the ISO 8601 duration string\n * rounded down from the number of seconds.\n *\n * @param numberOfMilliseconds - The duration in milliseconds.\n * @returns The ISO 8601 duration string.\n *\n * @example\n * millisecondsToDurationISOString(33000); // 'PT33S'\n * millisecondsToDurationISOString(3605000); // 'PT1H5S'\n */\nexport const millisecondsToDurationISOString = (numberOfMilliseconds: number): string => {\n const { seconds, minutes, hours } = buildTimeDuration(numberOfMilliseconds);\n\n let string = 'PT';\n\n if (hours) {\n string += `${hours}H`;\n }\n\n if (minutes) {\n string += `${minutes}M`;\n }\n\n if (seconds) {\n string += `${seconds}S`;\n }\n\n if (!(seconds || minutes || hours)) {\n string += '0S';\n }\n\n return string;\n};\n","import type { DateOnlyStringOptions } from './dateOnlyString.js';\nimport { isDate } from '../guards/isDate.js';\nimport { defaultTimeZone, defaultLocales } from './_constants.js';\nimport { isInvalidDate } from './_isInvalidDate.js';\n\n/**\n * Converts a Date object into a month and day string formatted numerically,\n * e.g. '06/03'. Formats with the en-US locale.\n *\n * @param date - The Date to format; gracefully handles any value.\n * @param options - Formatting options.\n * @param options.timeZone - The time zone to display the date in. Defaults to the current time zone.\n * @returns The formatted date string, or '' for invalid input.\n *\n * @example\n * monthDayStringNumeric(new Date(2011, 11, 15)); // '12/15'\n */\nexport const monthDayStringNumeric = (\n date: unknown,\n { timeZone = defaultTimeZone }: DateOnlyStringOptions = {},\n): string => {\n if (!isDate(date) || isInvalidDate(date)) {\n return '';\n }\n\n try {\n return new Intl.DateTimeFormat(defaultLocales, {\n month: '2-digit',\n day: '2-digit',\n timeZone,\n }).format(date);\n } catch (error: unknown) {\n console.error(error);\n return ''; // handle bad input\n }\n};\n","export type NoOpFn = typeof noOpFn;\n\n/**\n * A function that does nothing. Useful as a default or placeholder callback.\n *\n * @returns Nothing.\n *\n * @example\n * noOpFn(); // undefined\n */\nexport const noOpFn = (): void => {};\n","export type NoOpFnReturningFalse = typeof noOpFnReturningFalse;\n\n/**\n * A function that does nothing and returns `false`. Useful as a default or\n * placeholder callback where `false` is expected.\n *\n * @returns `false`.\n *\n * @example\n * noOpFnReturningFalse(); // false\n */\nexport const noOpFnReturningFalse = (): false => false;\n","export type NoOpFnReturningNull = typeof noOpFnReturningNull;\n\n/**\n * A function that does nothing and returns `null`. Useful as a default or\n * placeholder callback where `null` is expected.\n *\n * @returns `null`.\n *\n * @example\n * noOpFnReturningNull(); // null\n */\nexport const noOpFnReturningNull = (): null => null;\n","const MONTH_NAMES = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n];\n\n// First three letters match the en-US abbreviations (Jan ... Dec).\nconst MONTH_ABBREVIATIONS = MONTH_NAMES.map((name) => name.slice(0, 3));\n\n// Clears the time via setHours rather than reconstructing from parts, because\n// new Date(y, m, d) remaps years 0-99 to 1900+y (reachable via the native\n// fallback for ISO strings like \"0000-01-01\").\nconst startOfDay = (date: Date): Date => {\n const result = new Date(date);\n result.setHours(0, 0, 0, 0);\n return result;\n};\n\nconst startOfToday = (): Date => startOfDay(new Date());\n\nconst startOfTomorrow = (): Date => {\n const tomorrow = startOfToday();\n tomorrow.setDate(tomorrow.getDate() + 1);\n return tomorrow;\n};\n\ntype ParsedDateParts = {\n monthIndex: number;\n day: number;\n year: number | undefined;\n};\n\nconst monthIndexIn = (names: string[], value: string): number =>\n names.findIndex((name) => name.toLowerCase() === value.toLowerCase());\n\nconst toNumberOrUndefined = (value: string | undefined): number | undefined =>\n value === undefined ? undefined : Number(value);\n\n// Each regex is anchored to the whole string so trailing characters are\n// rejected, and year groups accept 1-4 digits read literally (\"25\" is year\n// 25, not 2025). The M-d pattern must precede yyyy-MM-dd, mirroring the\n// original format order. noUncheckedIndexedAccess types every destructured\n// group string | undefined; String() appears only where a plain string is\n// required and the group is guaranteed by the regex — Number(undefined) is\n// NaN, which toValidDate's round-trip check already rejects.\nconst DATE_PATTERNS: {\n regex: RegExp;\n toParts: (match: RegExpMatchArray) => ParsedDateParts;\n}[] = [\n {\n regex: new RegExp(`^(${MONTH_ABBREVIATIONS.join('|')}) (\\\\d{1,2})(?:, (\\\\d{1,4}))?$`, 'i'),\n toParts: ([, month, day, year]) => ({\n monthIndex: monthIndexIn(MONTH_ABBREVIATIONS, String(month)),\n day: Number(day),\n year: toNumberOrUndefined(year),\n }),\n },\n {\n regex: new RegExp(`^(${MONTH_NAMES.join('|')}) (\\\\d{1,2})(?:, (\\\\d{1,4}))?$`, 'i'),\n toParts: ([, month, day, year]) => ({\n monthIndex: monthIndexIn(MONTH_NAMES, String(month)),\n day: Number(day),\n year: toNumberOrUndefined(year),\n }),\n },\n {\n regex: /^(\\d{1,2})\\/(\\d{1,2})(?:\\/(\\d{1,4}))?$/,\n toParts: ([, month, day, year]) => ({\n monthIndex: Number(month) - 1,\n day: Number(day),\n year: toNumberOrUndefined(year),\n }),\n },\n {\n regex: /^(\\d{1,2})-(\\d{1,2})(?:-(\\d{1,4}))?$/,\n toParts: ([, month, day, year]) => ({\n monthIndex: Number(month) - 1,\n day: Number(day),\n year: toNumberOrUndefined(year),\n }),\n },\n {\n regex: /^(\\d{1,4})-(\\d{1,2})-(\\d{1,2})$/,\n toParts: ([, year, month, day]) => ({\n monthIndex: Number(month) - 1,\n day: Number(day),\n year: Number(year),\n }),\n },\n];\n\n// Builds a local-midnight Date, rejecting values that are not a real calendar\n// day (month out of range, Feb 30, day 0), instead of letting the Date constructor\n// roll them over. setFullYear is used because new Date(y, m, d) maps years 0-99 to 1900+y.\nconst toValidDate = (\n { monthIndex, day, year }: ParsedDateParts,\n referenceDate: Date,\n): Date | null => {\n // reject year 0, sending those inputs to the native fallback\n // (which reads them as year 2000); preserve that path.\n if (year === 0) {\n return null;\n }\n const resolvedYear = year ?? referenceDate.getFullYear();\n // The seed date is built at local midnight; setFullYear preserves the seed's\n // time of day, so results need no separate startOfDay call. Seeding from\n // new Date() would leak the current time into every parsed result.\n const date = new Date(referenceDate.getFullYear(), 0, 1);\n date.setFullYear(resolvedYear, monthIndex, day);\n const isRealCalendarDay =\n date.getFullYear() === resolvedYear && date.getMonth() === monthIndex && date.getDate() === day;\n return isRealCalendarDay ? date : null;\n};\n\n/**\n * Loosely parses a human-entered date string into a Date at local midnight.\n * Accepts 'today' and 'tomorrow', month name prefixes (resolved to the next\n * 1st of that month), and common numeric and month-name formats, with a\n * native Date fallback for anything else.\n *\n * @param str - The date string to parse.\n * @returns The parsed Date at local midnight, or null if unparseable.\n *\n * @example\n * parseDateString('Jan 5, 2025'); // Date for 2025-01-05 at local midnight\n * parseDateString('garbage'); // null\n */\nexport const parseDateString = (str: string): Date | null => {\n const trimmed = str.trim();\n if (!trimmed) {\n return null;\n }\n\n const lower = trimmed.toLowerCase();\n if (lower === 'today') {\n return startOfToday();\n }\n if (lower === 'tomorrow') {\n return startOfTomorrow();\n }\n\n const monthIndex = MONTH_NAMES.findIndex((name) => name.toLowerCase().startsWith(lower));\n if (monthIndex !== -1) {\n const today = startOfToday();\n let date = new Date(today.getFullYear(), monthIndex, 1);\n if (date.getTime() < Date.now()) {\n date = new Date(today.getFullYear() + 1, monthIndex, 1);\n }\n return date;\n }\n\n const referenceDate = new Date();\n for (const { regex, toParts } of DATE_PATTERNS) {\n const match = trimmed.match(regex);\n if (match) {\n const parsed = toValidDate(toParts(match), referenceDate);\n if (parsed !== null) {\n return parsed;\n }\n }\n }\n\n const native = new Date(trimmed);\n if (!Number.isNaN(native.getTime())) {\n return startOfDay(native);\n }\n\n return null;\n};\n","import { padTimeInteger } from './_padTimeInteger.js';\nimport { buildTimeDuration } from './buildTimeDuration.js';\n\n/**\n * A string representation of a duration for a user session. Assumes that\n * sessions may or may not be more than an hour. To prevent confusion all\n * times show hours, even those that are less than an hour.\n *\n * @param numberOfMilliseconds - The duration in milliseconds.\n * @returns The formatted duration string.\n *\n * @example\n * sessionDurationString(2342300); // '0:39:02'\n */\nexport const sessionDurationString = (numberOfMilliseconds: number): string => {\n const { hours, minutes, seconds } = buildTimeDuration(numberOfMilliseconds);\n\n return `${hours}:${padTimeInteger(minutes)}:${padTimeInteger(seconds)}`;\n};\n","/**\n * Removes the file extension from a string.\n *\n * @param str - The string to remove the file extension from.\n * @returns The string without its file extension.\n *\n * @example\n * stripExtension('config.yml'); // 'config'\n * stripExtension('example.test.ts'); // 'example.test'\n */\nexport const stripExtension = (str: string): string => (str || '').replace(/\\.[^/.]{1,4}$/, '');\n","import { defaultLocales, defaultTimeZone } from './_constants.js';\n\n/**\n * Get local year, month, day parts from a Date using Intl.DateTimeFormat.\n * This ignores the time of day (hours, minutes, etc.).\n *\n * @param date - The Date to extract parts from.\n * @returns The numeric year, month (1-based) and day.\n */\nexport const getLocalDateParts = (date: Date): { year: number; month: number; day: number } => {\n const parts = new Intl.DateTimeFormat(defaultLocales, {\n year: 'numeric',\n month: 'numeric',\n day: 'numeric',\n timeZone: defaultTimeZone,\n }).formatToParts(date);\n\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- year/month/day are always present for the requested options\n const partsAsObject = parts.reduce(\n (map: Partial<Record<Intl.DateTimeFormatPartTypes, string>>, part) => {\n map[part.type] = part.value;\n return map;\n },\n {},\n ) as Record<Intl.DateTimeFormatPartTypes, string>;\n\n const year = Math.trunc(Number(partsAsObject.year));\n const month = Math.trunc(Number(partsAsObject.month));\n const day = Math.trunc(Number(partsAsObject.day));\n\n return { year, month, day };\n};\n","import { isDate } from '../guards/isDate.js';\nimport { millisecondsInDay } from './_constants.js';\nimport { getLocalDateParts } from './_getLocalDateParts.js';\n\n/**\n * Returns the difference in calendar days between two dates in local time,\n * ignoring the time of day.\n *\n * @param dateLeft - The later date (or timestamp).\n * @param dateRight - The earlier date (or timestamp).\n * @returns The number of calendar days (can be negative).\n */\nexport const differenceInCalendarDays = (\n dateLeft: Date | number,\n dateRight: Date | number,\n): number => {\n const leftDate = isDate(dateLeft) ? dateLeft : new Date(dateLeft);\n const rightDate = isDate(dateRight) ? dateRight : new Date(dateRight);\n\n // if either is invalid, return NaN (rather than throwing RangeError)\n if (Number.isNaN(leftDate.getTime()) || Number.isNaN(rightDate.getTime())) {\n return Number.NaN;\n }\n\n const { year: y1, month: m1, day: d1 } = getLocalDateParts(leftDate);\n const { year: y2, month: m2, day: d2 } = getLocalDateParts(rightDate);\n\n // `start of day` in local time for each date (ie. midnight)\n const startOfDayLeft = new Date(y1, m1 - 1, d1).getTime();\n const startOfDayRight = new Date(y2, m2 - 1, d2).getTime();\n const msDiff = startOfDayLeft - startOfDayRight;\n\n // convert to calendar days and round (to handle DST shifts, etc.)\n return Math.round(msDiff / millisecondsInDay);\n};\n","import {\n defaultLocales,\n minutesInHour,\n secondsInMinute,\n milisecondsInSecond,\n daysInWeek,\n} from './_constants.js';\nimport { differenceInCalendarDays } from './_differenceInCalendarDays.js';\nimport { isInvalidDate } from './_isInvalidDate.js';\nimport { dateOnlyString } from './dateOnlyString.js';\nimport { dateTimeString } from './dateTimeString.js';\nimport { dayOfWeekString } from './dayOfWeekString.js';\n\nexport type TimeAgoOptions = {\n nowAnchor?: Date;\n includeTime?: boolean;\n};\n\n/**\n * Shows time ago relative to current time, e.g. '< 1 minute ago',\n * '33 minutes ago', 'Today, 3:30 PM', 'Yesterday, 6:22 AM',\n * 'Nov 11, 11:32 AM', or 'Feb 23, 2020, 1:55 PM'. When includeTime is\n * false: 'Today', 'Yesterday', 'on Thursday', 'Nov 11', 'Feb 23, 2020'.\n *\n * NOTE: timeAgoString doesn't support multiple time zones since doing so\n * would complicate calculations for whether to use \"Today\" or \"Yesterday\".\n *\n * @param date - The date relative to now.\n * @param options - Formatting options.\n * @param options.nowAnchor - The date used to calculate relative to now. Defaults to the current date but can be overwritten for tests.\n * @param options.includeTime - Whether to include the time in the output. Defaults to true.\n * @returns The relative date string, or '' for invalid input.\n *\n * @example\n * timeAgoString(new Date(Date.now() - 30_000)); // '< 1 minute ago'\n */\nexport const timeAgoString = (\n date: Date,\n { nowAnchor = new Date(), includeTime = true }: TimeAgoOptions = {},\n): string => {\n if (isInvalidDate(date)) {\n return '';\n }\n\n const minutesAgo =\n (nowAnchor.valueOf() - date.valueOf()) / (secondsInMinute * milisecondsInSecond);\n const minutesAgoRounded = Math.round(minutesAgo);\n const differenceInDays = differenceInCalendarDays(nowAnchor, date);\n const isSameYear = date.getFullYear() === nowAnchor.getFullYear();\n\n // handle edge case where date is in future\n if (minutesAgo < 0) {\n return dateTimeString(date);\n }\n\n if (minutesAgo < 1) {\n return '< 1 minute ago';\n }\n\n if (minutesAgoRounded < 2) {\n return '1 minute ago';\n }\n\n if (minutesAgoRounded <= minutesInHour) {\n return `${minutesAgoRounded} minutes ago`;\n }\n if (differenceInDays === 0) {\n return includeTime\n ? `Today, ${Intl.DateTimeFormat(defaultLocales, { hour: 'numeric', minute: '2-digit' }).format(date)}`\n : 'Today';\n }\n\n if (differenceInDays === 1) {\n return includeTime\n ? `Yesterday, ${Intl.DateTimeFormat(defaultLocales, { hour: 'numeric', minute: '2-digit' }).format(date)}`\n : 'Yesterday';\n }\n\n if (differenceInDays < daysInWeek && !includeTime) {\n return `on ${dayOfWeekString(date)}`;\n }\n\n return includeTime\n ? dateTimeString(date, { omitYear: isSameYear })\n : dateOnlyString(date, { omitYear: false });\n};\n","import type { DateOnlyStringOptions } from './dateOnlyString.js';\nimport { isDate } from '../guards/isDate.js';\nimport { defaultTimeZone, defaultLocales } from './_constants.js';\nimport { isInvalidDate } from './_isInvalidDate.js';\n\n/**\n * Converts a Date object into a time only string, e.g. '7:30 AM'.\n * Formats with the en-US locale.\n *\n * @param date - The Date to format; gracefully handles any value.\n * @param options - Formatting options.\n * @param options.timeZone - The time zone to display the time in. Defaults to the current time zone.\n * @returns The formatted time string, or '' for invalid input.\n *\n * @example\n * timeOnlyString(new Date(2011, 11, 15, 7, 30)); // '7:30 AM'\n */\nexport const timeOnlyString = (\n date: unknown,\n { timeZone = defaultTimeZone }: DateOnlyStringOptions = {},\n): string => {\n if (!isDate(date) || isInvalidDate(date)) {\n return '';\n }\n\n try {\n return new Intl.DateTimeFormat(defaultLocales, {\n timeStyle: 'short',\n timeZone,\n }).format(date);\n } catch (error: unknown) {\n console.error(error);\n return ''; // handle bad input\n }\n};\n","/**\n * Checks if a tuple includes the given item, with type narrowing.\n *\n * @param tuple - The tuple to search.\n * @param item - The item to search for.\n * @returns True if the tuple includes the item, false otherwise.\n *\n * @example\n * const tuple = ['x', 'y'] as const;\n * tupleIncludes(tuple, 'x'); // true\n * tupleIncludes(tuple, 'z'); // false\n */\nexport const tupleIncludes = <TTuple extends readonly TItem[], TItem>(\n tuple: TTuple,\n item: TItem,\n): item is TTuple[number] => tuple.includes(item);\n"],"mappings":"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"}
|