import type { ConditionalSimplifyDeep } from 'type-fest/source/conditional-simplify.js' /* eslint-disable */ export type RemoveIndex = { [K in keyof T as string extends K ? never : number extends K ? never : K]: T[K] } export const uppercase = (str: S): Uppercase => str.toUpperCase() as Uppercase export const callOrIdentity = (value: MaybeLazy) => { return typeof value === `function` ? (value as () => T)() : value } export type MaybeLazy = T | (() => T) export const zip = (a: A[], b: B[]): [A, B | undefined][] => a.map((k, i) => [k, b[i]]) export const HeadersInitToPlainObject = (headers?: HeadersInit): Record => { let oHeaders: Record = {} if (headers instanceof Headers) { oHeaders = HeadersInstanceToPlainObject(headers) } else if (Array.isArray(headers)) { headers.forEach(([name, value]) => { if (name && value !== undefined) { oHeaders[name] = value } }) } else if (headers) { oHeaders = headers } return oHeaders } export const HeadersInstanceToPlainObject = (headers: Response['headers']): Record => { const o: Record = {} headers.forEach((v, k) => { o[k] = v }) return o } export const tryCatch = <$Return, $Throw extends Error = Error>( fn: () => $Return, ): $Return extends Promise ? Promise | $Throw> : $Return | $Throw => { try { const result = fn() as any if (isPromiseLikeValue(result)) { return result.catch((error) => { return errorFromMaybeError(error) }) as any } return result } catch (error) { return errorFromMaybeError(error) as any } } /** * Ensure that the given value is an error and return it. If it is not an error than * wrap it in one, passing the given value as the error message. */ export const errorFromMaybeError = (maybeError: unknown): Error => { if (maybeError instanceof Error) return maybeError return new Error(String(maybeError)) } export const isPromiseLikeValue = (value: unknown): value is Promise => { return ( typeof value === `object` && value !== null && `then` in value && typeof value.then === `function` && `catch` in value && typeof value.catch === `function` && `finally` in value && typeof value.finally === `function` ) } export const casesExhausted = (value: never): never => { throw new Error(`Unhandled case: ${String(value)}`) } export const isPlainObject = (value: unknown): value is Record => { return typeof value === `object` && value !== null && !Array.isArray(value) } export const entries = >(obj: T) => Object.entries(obj) as [keyof T, T[keyof T]][] export const values = >(obj: T): T[keyof T][] => Object.values(obj) as T[keyof T][] // dprint-ignore export type Exact<$Value, $Constraint> = ( $Value extends unknown ? $Constraint extends $Value ? {} extends $Value ? $Constraint : { [K in keyof $Value]: Exact<$Value[K], $Constraint[K]> } : $Constraint : never ) | ($Value extends Narrowable ? $Value : never) // dprint-ignore // export type ExactObjectNonEmpty<$Value, $Constraint> = // ( // $Value extends unknown ? $Constraint extends $Value ? keyof $Value extends never ? ({ 'TypeScript Error: You must supply at least one key.': true } & $Constraint) : // { [K in keyof $Value]: Exact<$Value[K], $Constraint[K]> } : // $Constraint : // never // ) // | ($Value extends Narrowable ? $Value : never) export type Narrowable = string | number | bigint | boolean | [] export type Letter = LetterLower | LetterUpper export type Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' export type LetterLower = | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' export type LetterUpper = | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' export type StringNonEmpty = `${Letter}${string}` export type MaybeList = T | T[] export type NotEmptyObject = keyof T extends never ? never : T export type Values = T[keyof T] export type GetKeyOr = Key extends keyof T ? T[Key] : Or export type SimplifyDeep = ConditionalSimplifyDeep | Date, object> export type As = U extends T ? U : never export type UnionToIntersection = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never export type LastOf = UnionToIntersection T : never> extends () => infer R ? R : never // TS4.0+ export type Push = [...T, V] // TS4.1+ export type UnionToTuple, N = [T] extends [never] ? true : false> = true extends N ? [] : Push>, L> export type CountKeys = keyof T extends never ? 0 : UnionToTuple['length'] export type IsMultipleKeys = IsMultiple> export type IsMultiple = T extends 0 ? false : T extends 1 ? false : true export type ExcludeNull = Exclude export const mapValues = < $Obj extends Record, $Fn extends (value: $Obj[keyof $Obj], key: keyof $Obj) => any, >( object: $Obj, fn: $Fn, ): Record> => { return Object.fromEntries( Object.entries(object).map(([key, value]) => { return [key, fn(value, key)] }), ) as Record> } export type SetProperty<$Obj extends object, $Prop extends keyof $Obj, $Type extends $Obj[$Prop]> = & Omit<$Obj, $Prop> & { [_ in $Prop]: $Type } export const lowerCaseFirstLetter = (s: string) => { return s.charAt(0).toLowerCase() + s.slice(1) } export function assertArray(v: unknown): asserts v is unknown[] { if (!Array.isArray(v)) throw new Error(`Expected array. Got: ${String(v)}`) } export function assertObject(v: unknown): asserts v is object { if (v === null || typeof v !== `object`) throw new Error(`Expected object. Got: ${String(v)}`) } export type StringKeyof = keyof T & string export type MaybePromise = T | Promise export const capitalizeFirstLetter = (string: string) => string.charAt(0).toUpperCase() + string.slice(1) export type SomeAsyncFunction = (...args: unknown[]) => Promise export type SomeMaybeAsyncFunction = (...args: unknown[]) => MaybePromise export type Deferred = { promise: Promise isResolved: () => boolean resolve: (value: T) => void reject: (error: unknown) => void } export const createDeferred = <$T>(options?: { strict?: boolean }): Deferred<$T> => { let isResolved = false let resolve: (value: $T) => void let reject: (error: unknown) => void const promise = new Promise<$T>(($resolve, $reject) => { resolve = $resolve reject = $reject }) return { promise, isResolved: () => isResolved, resolve: (value) => { isResolved = true if (options?.strict && isResolved) { throw new Error(`Deferred is already resolved. Attempted to resolve with: ${JSON.stringify(value)}`) } resolve(value) }, reject: (error) => reject(error), } } export const debug = (...args: any[]) => { if (process.env[`DEBUG`]) { console.log(...args) } } export const debugSub = (...args: any[]) => (...subArgs: any[]) => { debug(...args, ...subArgs) } export type PlusOneUpToTen = n extends 0 ? 1 : n extends 1 ? 2 : n extends 2 ? 3 : n extends 3 ? 4 : n extends 4 ? 5 : n extends 5 ? 6 : n extends 6 ? 7 : n extends 7 ? 8 : n extends 8 ? 9 : n extends 9 ? 10 : never export type MinusOneUpToTen = n extends 10 ? 9 : n extends 9 ? 8 : n extends 8 ? 7 : n extends 7 ? 6 : n extends 6 ? 5 : n extends 5 ? 4 : n extends 4 ? 3 : n extends 3 ? 2 : n extends 2 ? 1 : n extends 1 ? 0 : never export type findIndexForValue = findIndexForValue_ type findIndexForValue_ = value extends list[i] ? i : findIndexForValue_> export type FindValueAfter = list[PlusOneUpToTen>] export type ValueOr = value extends undefined ? orValue : value export type FindValueAfterOr = ValueOr< list[PlusOneUpToTen>], orValue > export type GetLastValue = T[MinusOneUpToTen] export type IsLastValue = value extends GetLastValue ? true : false export type Include = T extends U ? T : never export const partitionErrors = (array: T[]): [Exclude[], Include[]] => { const errors: Include[] = [] const values: Exclude[] = [] for (const item of array) { if (item instanceof Error) { errors.push(item as any) } else { values.push(item as any) } } return [values, errors] }