UNPKG

@v4fire/core

Version:
1,777 lines (1,590 loc) 114 kB
/*! * V4Fire Core * https://github.com/V4Fire/Core * * Released under the MIT license * https://github.com/V4Fire/Core/blob/master/LICENSE */ /* eslint-disable max-lines, @typescript-eslint/unified-signatures */ /** * [[include:core/prelude/README.md]] * @packageDocumentation */ declare namespace TB { type Cast<X, Y> = X extends Y ? X : Y; type Type<A extends any, ID extends string> = A & { [K in 'symbol']: ID; }; type Length<T extends any[]> = T['length']; type Head<T extends any[]> = T extends [infer H, ...any[]] ? H : never; type Tail<T extends any[]> = T extends [any, ...infer TT] ? TT : []; type HasTail<T extends any[]> = Length<T> extends 0 | 1 ? false : true; type Last<T extends any[]> = HasTail<T> extends true ? Last<Tail<T>> : Head<T>; type Prepend<E, T extends any[]> = [E, ...T]; type Drop<N extends number, T extends any[], I extends any[] = []> = Length<I> extends N ? T : Drop<N, Tail<T>, Prepend<any, I>>; type Pos<I extends any[]> = Length<I>; type Next<I extends any[]> = Prepend<any, I>; type Prev<I extends any[]> = Tail<I>; type Reverse<T extends any[], R extends any[] = [], I extends any[] = []> = Pos<I> extends Length<T> ? R : Reverse<T, Prepend<T[Pos<I>], R>, Next<I>>; type Concat<T1 extends any[], T2 extends any[]> = Reverse<Cast<Reverse<T1>, any[]>, T2>; type Append<E, T extends any[]> = Concat<T, [E]>; type __ = Type<{}, 'x'>; type GapOf<T1 extends any[], T2 extends any[], TN extends any[], I extends any[]> = T1[Pos<I>] extends __ ? Append<T2[Pos<I>], TN> : TN; type GapsOf<T1 extends any[], T2 extends any[], TN extends any[] = [], I extends any[] = []> = Pos<I> extends Length<T1> ? Concat<TN, Cast<Drop<Pos<I>, T2>, any[]>> : GapsOf<T1, T2, Cast<GapOf<T1, T2, TN, I>, any[]>, Next<I>>; type PartialGaps<T extends any[]> = { [K in keyof T]?: T[K] | __; }; type CleanedGaps<T extends any[]> = { [K in keyof T]: NonNullable<T[K]>; }; type Gaps<T extends any[]> = CleanedGaps<PartialGaps<T>> extends [...infer A] ? A : never; type Curry<F extends ((...args: any) => any)> = <T extends any[]>(...args: Cast<T, Gaps<Parameters<F>>>) => GapsOf<T, Parameters<F>> extends [any, ...any[]] ? Curry<(...args: Cast<GapsOf<T, Parameters<F>>, any[]>) => ReturnType<F>> : ReturnType<F>; } declare const DEBUG: boolean; declare const IS_PROD: boolean; declare const APP_NAME: string; declare const API_URL: CanUndef<string>; declare const LOCALE: Language; declare const REGION: CanUndef<Region>; type Language = 'be' | 'en' | 'kk' | 'ru' | 'tr' | 'tt' | 'uk' | 'id' | 'uz' | 'es' | 'de' | 'hy' | 'ka' | 'ky' | 'sr' | 'fr' | 'lv' | 'lt' | 'ro' | 'fi' | 'az' | 'zh' | 'he' | 'et' | 'no' | 'sv' | 'pt' | 'ar' | 'sw'; /** * ISO 3166-1 * @see https://en.wikipedia.org/wiki/ISO_3166-1 */ type Region = 'AD' | 'AE' | 'AF' | 'AG' | 'AI' | 'AL' | 'AM' | 'AO' | 'AQ' | 'AR' | 'AS' | 'AT' | 'AU' | 'AW' | 'AX' | 'AZ' | 'BA' | 'BB' | 'BD' | 'BE' | 'BF' | 'BG' | 'BH' | 'BI' | 'BJ' | 'BL' | 'BM' | 'BN' | 'BO' | 'BQ' | 'BR' | 'BS' | 'BT' | 'BV' | 'BW' | 'BY' | 'BZ' | 'CA' | 'CC' | 'CD' | 'CF' | 'CG' | 'CH' | 'CI' | 'CK' | 'CL' | 'CM' | 'CN' | 'CO' | 'CR' | 'CU' | 'CV' | 'CW' | 'CX' | 'CY' | 'CZ' | 'DE' | 'DJ' | 'DK' | 'DM' | 'DO' | 'DZ' | 'EC' | 'EE' | 'EG' | 'EH' | 'ER' | 'ES' | 'ET' | 'FI' | 'FJ' | 'FK' | 'FM' | 'FO' | 'FR' | 'GA' | 'GB' | 'GD' | 'GE' | 'GF' | 'GG' | 'GH' | 'GI' | 'GL' | 'GM' | 'GN' | 'GP' | 'GQ' | 'GR' | 'GS' | 'GT' | 'GU' | 'GW' | 'GY' | 'HK' | 'HM' | 'HN' | 'HR' | 'HT' | 'HU' | 'ID' | 'IE' | 'IL' | 'IM' | 'IN' | 'IO' | 'IQ' | 'IR' | 'IS' | 'IT' | 'JE' | 'JM' | 'JO' | 'JP' | 'KE' | 'KG' | 'KH' | 'KI' | 'KM' | 'KN' | 'KP' | 'KR' | 'KW' | 'KY' | 'KZ' | 'LA' | 'LB' | 'LC' | 'LI' | 'LK' | 'LR' | 'LS' | 'LT' | 'LU' | 'LV' | 'LY' | 'MA' | 'MC' | 'MD' | 'ME' | 'MF' | 'MG' | 'MH' | 'MK' | 'ML' | 'MM' | 'MN' | 'MO' | 'MP' | 'MQ' | 'MR' | 'MS' | 'MT' | 'MU' | 'MV' | 'MW' | 'MX' | 'MY' | 'MZ' | 'NA' | 'NC' | 'NE' | 'NF' | 'NG' | 'NI' | 'NL' | 'NO' | 'NP' | 'NR' | 'NU' | 'NZ' | 'OM' | 'PA' | 'PE' | 'PF' | 'PG' | 'PH' | 'PK' | 'PL' | 'PM' | 'PN' | 'PR' | 'PS' | 'PT' | 'PW' | 'PY' | 'QA' | 'RE' | 'RO' | 'RS' | 'RU' | 'RW' | 'SA' | 'SB' | 'SC' | 'SD' | 'SE' | 'SG' | 'SH' | 'SI' | 'SJ' | 'SK' | 'SL' | 'SM' | 'SN' | 'SO' | 'SR' | 'SS' | 'ST' | 'SV' | 'SX' | 'SY' | 'SZ' | 'TC' | 'TD' | 'TF' | 'TG' | 'TH' | 'TJ' | 'TK' | 'TL' | 'TM' | 'TN' | 'TO' | 'TR' | 'TT' | 'TV' | 'TW' | 'TZ' | 'UA' | 'UG' | 'UM' | 'US' | 'UY' | 'UZ' | 'VA' | 'VC' | 'VE' | 'VG' | 'VI' | 'VN' | 'VU' | 'WF' | 'WS' | 'YE' | 'YT' | 'ZA' | 'ZM' | 'ZW'; /** * Converts the specified unknown value to any * @param obj */ declare function Any(obj: any): any; /** * STDERR wrapper * @param err */ declare function stderr(err: any): void; /** * Creates a function to internationalize strings in an application based on the given locale and keyset. * Keyset allows you to share the same keys in different contexts. * For example, the key "Next" may have a different value in different components of the application, therefore, * we can use the name of the component as a keyset value. * * @param keysetNameOrNames - the name of keyset or array with names of keysets to use. * If passed as an array, the priority of the cases will be arranged in the order of the elements, * the first one will have the highest priority. * * @param [customLocale] - the locale used to search for translations (the default is taken from * the application settings) */ declare function i18n( keysetNameOrNames: CanArray<string>, customLocale?: Language ): (key: string | TemplateStringsArray, params?: I18nParams) => string; /** * Parameters for the internationalization function */ type I18nParams = { count?: number | StringPluralizationForms; } & { [key: string]: string | number; }; /** * String pluralization constants that can be used instead of numbers */ type StringPluralizationForms = 'one' | 'two' | 'few' | 'many' | 'other' | 'zero'; declare function setImmediate(fn: AnyFunction): number; declare function clearImmediate(id: number): void; declare function structuredClone<T>(obj: T): T; interface Headers { keys(): IterableIterator<string>; values(): IterableIterator<string>; entries(): IterableIterator<[string, string]>; [Symbol.iterator]: IterableIterator<[string, string]>; } type Primitive = string | symbol | number | bigint | boolean | undefined | null; type JSONLikeValue = string | number | boolean | null | JSONLikeValue[] | Dictionary<JSONLikeValue>; type CanPromise<T> = T | Promise<T>; type CanPromiseLike<T> = T | PromiseLike<T>; type CanArray<T> = T | T[]; type CanUndef<T> = T | undefined; type Nullable<T> = T | null | undefined; // eslint-disable-next-line @typescript-eslint/no-invalid-void-type type CanVoid<T> = T | void; type AnyToIgnore = any; type AnyToBoolean = any; interface AnyFunction<ARGS extends any[] = any[], R = any> extends Function { (...args: ARGS): R; } interface AnyOneArgFunction<ARG = any, R = any> extends Function { (arg: ARG): R; } type ClassConstructor<ARGS extends any[] = any[], R = any> = new (...args: ARGS) => R; interface StrictDictionary<T = unknown> { [key: PropertyKey]: T; } interface Dictionary<T = unknown> { [key: PropertyKey]: CanUndef<T>; } interface Maybe<T = unknown> extends Promise<T> { readonly type: 'Maybe'; } interface Either<T = unknown> extends Promise<T> { readonly type: 'Either'; } type NewPromise<K, V> = K extends Maybe ? Maybe<V> : K extends Either ? Either<V> : Promise<V>; type PromiseType<T> = T extends Maybe<infer V> ? NonNullable<V> : T extends Promise<infer V> ? V : T; /** * Wraps the specified function to return a value as Promise * * @typeparam T - any function * * @example * ```typescript * type A = typeof () => null; * * // () => Promise<null> * type B = ReturnPromise<A>; * ``` */ type ReturnPromise<T extends AnyFunction<any[], unknown>> = (...args: Parameters<T>) => Promise<ReturnType<T>>; type DictionaryType<T extends Dictionary> = T extends Dictionary<infer V> ? NonNullable<V> : T; type AnyIterable<T = unknown> = Iterable<T> | AsyncIterable<T>; type IterableType<T extends Iterable<any> | AsyncIterable<any>> = T extends Iterable<infer V> ? V : T extends AsyncIterable<infer V> ? V : T; /** * Creates an interface based on the specified type or interface but every property can be edited */ type Writable<T> = { -readonly [K in keyof T]: T[K]; }; /** * Overrides properties of the specified type or interface. * Don't use this helper if you simply extend one type from another, i.e. without overriding properties. * * @template T - original type * @template U - type with the overridden properties * * @example * ```typescript * type A = { * x: number; * y: number; * }; * * // {x:number; y: string} * type B = Overwrite<A, {y: string}>; * ``` */ type Overwrite<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U; /** * Returns a new non-abstract class from the specified abstract class where methods can have the default implementation. * The default implementations are taken from the static methods that match by names with the class's methods. * * @example * ```typescript * abstract class iFoo { * static bar(self: object): string { * return self.bla.toString(); * } * * bar(): string { * return Object.throw(); * } * * abstract bar(): number; * } * * // class { bar(): string; } * Trait<typeof bFoo> * ``` */ type Trait<C extends Function, I extends C['prototype'] = C['prototype']> = { [K in Extract<keyof C, keyof I>]: I[K]; }; /** * Returns a new function based on the specified with adding as the first parameter the passed object * * @example * ```typescript * // (self: bFoo, a: number) => string * AddSelf<(a: number) => string, bFoo> * ``` */ type AddSelf<M extends Function, S extends object> = M extends (...args: infer A) => infer R ? (self: S, ...args: A) => R : never; interface JSONCb { (key: string, value: unknown): unknown; } interface FastCloneOptions { /** * Replacer function for `JSON.stringify` * @see [[JSON.stringify]] */ replacer?: JSONCb; /** * Reviver function for `JSON.parse` * @see [[JSON.parse]] */ reviver?: JSONCb; /** * If false the object freeze/seal state won't be copy * @default `true` */ freezable?: boolean; } interface ObjectMixinOptions<V = unknown, K = unknown, D = unknown> { /** * If true, then object properties are copied recursively. * Also, this mode enables copying properties from a prototype. * * @default `false` * @example * ```js * // {a: {c: 2}} * Object.mixin({deep: false}, {a: {b: 1}}, {a: {c: 2}}); * * // {a: {b: 1, c: 2}} * Object.mixin({deep: true}, {a: {b: 1}}, {a: {c: 2}}); * * // {a: {c: 2}} * Object.mixin({deep: true}, {}, {__proto__: {a: {c: 2}}}); * ``` */ deep?: boolean; /** * Strategy to resolve collisions of properties when merging: * 1. `'all'` - all properties are merged in spite of possible collisions (by default) * 2. `'new'` - properties with collisions aren't merged * 3. `'exist'` - properties without collisions aren't merged * * @default `'all'` * @example * ```js * // {a: 2, b: 3} * Object.mixin({propsToCopy: 'all'}, {a: 1}, {a: 2, b: 3}); * * // {a: 1, b: 3} * Object.mixin({propsToCopy: 'new'}, {a: 1}, {a: 2, b: 3}); * * // {a: 2} * Object.mixin({propsToCopy: 'exist'}, {a: 1}, {a: 2, b: 3}); * ``` */ propsToCopy?: 'new' | 'exist' | 'all'; /** * Function to filter values that shouldn't be copied * * @param el - element value * @param key - element key * @param data - element container * * @example * ```js * // {a: 1, b: 2} * Object.mixin({deep: true}, {a: 1}, {b: 2}); * * // {a: 1} * Object.mixin({deep: true, filter: (el, key) => key !== 'b'}, {a: 1}, {b: 2}); * ``` */ filter?(el: V, key: K, data: D): AnyToBoolean; /** * Function to filter values that support deep extending * (works only with the `deep` mode) * * @param el - element value * @param key - element key * @param data - element container * * @example * ```js * // {a: {a: 1, b: 2}} * Object.mixin({deep: true}, {a: {a: 1}}, {a: {b: 2}}); * * // {a: {b: 2}} * Object.mixin({deep: true, extendFilter: (el) => !el.b}, {a: {a: 1}}, {a: {b: 2}}); * ``` */ extendFilter?(el: unknown, key: K, data: V): AnyToBoolean; /** * If true, all properties with undefined value aren't copied * * @default `true` * @example * ```js * // {a: 1} * Object.mixin({skipUndefs: true}, {a: 1}, {a: undefined}); * * // {a: undefined} * Object.mixin({skipUndefs: false}, {a: 1}, {a: undefined}); * ``` */ skipUndefs?: boolean; /** * If true, the function will merge all object properties, but not only enumerable. * Non-enumerable properties from a prototype are ignored. * * @default `false` * @example * ```js * const obj = {a: 1}; * * Object.defineProperty(obj, 'b', {value: 2}); * * // {a: 1, b: 2} * Object.mixin({withNonEnumerables: true}, {}, obj); * ``` */ withNonEnumerables?: boolean; /** * Should or shouldn't copy property descriptors too. * If passed `onlyAccessors`, the descriptor properties like `enumerable` or `configurable` are ignored. * * @default `false` */ withDescriptors?: boolean | 'onlyAccessors'; /** * If true, then merging preserve prototypes of properties * (works only with the `deep` mode) * * @default `false` * @example * ```js * const proto = { * a: { * b: 2 * }, * * c: 3 * }; * * const obj = Object.create(proto); * Object.mixin({deep: true, withProto: false}, obj, {c: 2, a: {d: 4}}); * * // 2 * // 4 * // 2 * // true * // true * console.log( * obj.c, * obj.a.d, * obj.a.b, * obj.a.hasOwnProperty('d'), * obj.a.hasOwnProperty('b') * ); * * const obj2 = Object.create(proto); * Object.mixin({deep: true, withProto: true}, obj2, {c: 2, a: {d: 4}}); * * // 2 * // 4 * // 2 * // true * // false * console.log( * obj2.c, * obj2.a.d, * obj2.a.b, * obj2.a.hasOwnProperty('d'), * obj2.a.hasOwnProperty('b') * ); * ``` */ withProto?: boolean; /** * If true, then to merge two arrays will be used a concatenation strategy (works only with the `deep` mode). * Also, the parameter can be passed as a function to concatenate arrays. * * @default `false` * @example * ```js * // {a: [2]} * Object.mixin({deep: true, concatArrays: false}, {a: [1]}, {a: [2]}); * * // {a: [1, 2]} * Object.mixin({deep: true, concatArrays: true}, {a: [1]}, {a: [2]}); * * // {a: [1, 1, 2]} * Object.mixin({deep: true, concatArrays: true}, {a: [1]}, {a: [1, 2]}); * * // {a: [1, 2]} * Object.mixin({deep: true, concatArrays: (a, b) => a.union(b)}, {a: [1]}, {a: [1, 2]}); * ``` */ concatArrays?: boolean | ((a: unknown[], b: unknown[], key: K) => unknown[]); /** * @deprecated * @see [[ObjectMixinOptions.concatArrays]] */ concatArray?: boolean; /** * @deprecated * @see [[ObjectMixinOptions.concatArrays]] */ concatFn?(a: unknown[], b: unknown[], key: K): unknown[]; /** * @deprecated * @see [[ObjectMixinOptions.propsToCopy]] */ onlyNew?: boolean | -1; /** * @deprecated * @see [[ObjectMixinOptions.propsToCopy]] */ traits?: boolean | -1; /** * @deprecated * @see [[ObjectMixinOptions.skipUndefs]] */ withUndef?: boolean; /** * @deprecated * @see [[ObjectMixinOptions.withDescriptors]] */ withDescriptor?: boolean; /** * @deprecated * @see [[ObjectMixinOptions.withDescriptors]] */ withAccessors?: boolean; } interface ObjectGetOptions { /** * Character to declare the path * * @example * ```js * Object.get({a: {b: 1}}, 'a:b', {separator: ':'}) * ``` */ separator?: string; } interface ObjectSetOptions extends ObjectGetOptions { /** * If true, then a new value will be concatenated with the old * * @example * ```js * const obj = {a: {b: 1}}; * Object.set(obj, 'a.b', 2, {concat: true}) * console.log(obj); // [1, 2] * ``` */ concat?: boolean; /** * Function to set a value * * @param obj * @param key * @param value */ setter?(obj: unknown, key: unknown, value: unknown); } interface ObjectForEachOptions { /** * If true, then the callback function takes an element descriptor instead of a value * * @default `false` * @example * ```js * Object.forEach({a: 1}, {showDescriptor: true}, (el) => { * // {configurable: true, enumerable: true, writable: true, value: 1} * console.log(el); * }); * ``` */ passDescriptor?: boolean; /** * Strategy to iterate object properties: * 1. `'own'` - the object iterates only own properties (by default) * 2. `'inherited'` - the object iterates only inherited properties * (for-in with the negative `hasOwnProperty` check) * * 3. `'all'` - the object iterates inherited properties too (for-in without the `hasOwnProperty` check) * * @example * ```js * const obj = {a: 1, __proto__: {b: 2}}; * * Object.forEach(obj, (el) => { * console.log(el); // 1 * }); * * Object.forEach(obj, {propsToIterate: 'all'}, (el) => { * console.log(el); // 1 2 * }); * * Object.forEach(obj, {propsToIterate: 'inherited'}, (el) => { * console.log(el); // 2 * }); * ``` */ propsToIterate?: 'own' | 'inherited' | 'all'; /** * If true, the function will iterate all object properties, but not only enumerable. * Non-enumerable properties from a prototype are ignored. * * @default `false` * @example * ```js * const obj = {a: 1}; * * Object.defineProperty(obj, 'b', {value: 2}); * * // 1 * // 2 * Object.forEach(obj, {withNonEnumerables: true}, (el) => { * console.log(el); * }); * ``` */ withNonEnumerables?: boolean; /** * @deprecated * @see [[ObjectForEachOptions.passDescriptor]] */ withDescriptor?: boolean; /** * @deprecated * @see [[ObjectForEachOptions.propsToIterate]] */ notOwn?: boolean | -1; } interface ObjectForEachPropertyDescriptor<V = unknown> { configurable?: boolean; enumerable?: boolean; value?: V; writable?: boolean; get?(): unknown; set?(v: unknown): void; } interface ObjectFromArrayOptions<T = boolean> { /** * Function that returns a key value * * @param el - element value * @param i - element index */ key?(el: unknown, i: number): PropertyKey; /** * @deprecated * @see [[ObjectFromArrayOptions.key]] */ keyConverter?(i: number, el: unknown): PropertyKey; /** * Function that returns an element value * * @param el - element value * @param i - element index */ value?(el: unknown, i: number): T; /** * @deprecated * @see [[ObjectFromArrayOptions.value]] */ valueConverter?(el: unknown, i: number): T; } type ObjectPropertyPath = string | any[]; interface ObjectPropertyFilter<K = string, V = unknown> { (key: K, el: V): AnyToBoolean; } interface ObjectConstructor { /** * Returns a value from the passed object by the specified path. * Returns undefined if the specified path doesn't exist in the object. * The method can access properties through promises. * * @param obj * @param path * @param [opts] - additional options */ get<T = unknown>(obj: any, path: ObjectPropertyPath, opts?: ObjectGetOptions): CanUndef<T>; /** * Returns a function that returns a value from the passed object, which the function takes, by the specified path. * The function returns undefined if the specified path doesn't exist in the object. * * @param path * @param [opts] - additional options */ get<T = unknown>(path: ObjectPropertyPath, opts?: ObjectGetOptions): (obj: any) => CanUndef<T>; /** * Returns a function that returns a value from the specified object by a path that the function takes. * The function returns undefined if the specified path doesn't exist in the object. * * @param obj * @param [opts] - additional options */ get<T = unknown>(obj: any, opts?: ObjectGetOptions): (path: ObjectPropertyPath) => CanUndef<T>; /** * Returns true if an object has a property by the specified path * * @param obj * @param path * @param [opts] - additional options */ has(obj: any, path: ObjectPropertyPath, opts?: ObjectGetOptions): boolean; /** * Returns a function that returns true if an object, which the function takes, has a value by the specified path * * @param path * @param [opts] - additional options */ has(path: ObjectPropertyPath, opts?: ObjectGetOptions): (obj: any) => boolean; /** * Returns a function that returns true if the specified object has a value by a path that the function takes * * @param obj * @param [opts] - additional options */ has(obj: any, opts?: ObjectGetOptions): (path: ObjectPropertyPath) => boolean; /** * Returns a function that returns true if the passed object, which the function takes, * has own property by the specified key * * @param key */ hasOwnProperty(key: PropertyKey): (obj: any) => boolean; /** * Returns a function that returns true if the specified object has own property by a key that the function takes * @param obj */ hasOwnProperty(obj: any): (key: PropertyKey) => boolean; /** * Returns true if the passed object has an own property by the specified key * * @param obj * @param key */ hasOwnProperty(obj: any, key: PropertyKey): boolean; /** * Sets the passed symbol property to the given object. * The character is set as non-enumerable to avoid implicit copying when using the spread operation. * * @param obj * @param symbol * @param value * */ defineSymbol<T>(obj: T, symbol: symbol, value: any): T; /** * Sets a value to the passed object by the specified path. * The final function returns a value that was added. * * @param obj * @param path * @param value * @param [opts] - additional options */ set<T>(obj: any, path: ObjectPropertyPath, value: T, opts?: ObjectSetOptions): CanUndef<T>; /** * Returns a function that sets a value to an object, which the function takes, by the specified path. * The final function returns a link to the object. * * @param path * @param [opts] - additional options * @param [value] */ set(path: ObjectPropertyPath, opts?: ObjectSetOptions, value?: any): <T>(obj: T, value?: any) => CanUndef<T>; /** * Returns a function that sets a value to the specified object by a path that the function takes. * The final function returns a link to the object. * * @param obj * @param [opts] - additional options * @param [value] */ set<T>(obj: T, opts?: ObjectSetOptions, value?: any): (path: ObjectPropertyPath, value?: any) => CanUndef<T>; /** * Deletes a value from an object by the specified path * * @param obj * @param path * @param [opts] - additional options */ delete(obj: any, path: ObjectPropertyPath, opts?: ObjectGetOptions): boolean; /** * Returns a function that deletes a value from an object, which the function takes, by the specified path * * @param path * @param [opts] - additional options */ delete(path: ObjectPropertyPath, opts?: ObjectGetOptions): (obj: any) => boolean; /** * Returns a function that deletes a value from the specified object by a path that the function takes * * @param obj * @param [opts] - additional options */ delete(obj: any, opts?: ObjectGetOptions): (path: ObjectPropertyPath) => boolean; /** * Returns size/length of the specified object * * @param obj * * @example * ```js * // 1 * Object.size({a: 1}); * * // 2 * Object.size([1, 2]); * * // 2 * Object.size(new Set([1, 2])); * * // 2 * Object.size((a, b) => a + b)); * * // 1 * Object.size(1); * * // 0 * Object.size(NaN); * Object.size(null); * Object.size(undefined); * ``` */ size(obj: any): number; /** * Returns true if size/length of the specified entity is 0. * The algorithm for determining whether the entity is empty depends on the type of the entity. * - For Objects: The method counts the number of enumerable properties in the object. If the count is 0, the method considers the object as empty. * - For Arrays and Strings: The method uses the length property of the array or string. If the length is 0, the method considers the array or string as empty. * - For Maps and Sets: The method uses the size property of the map or set. If the size is 0, the method considers the map or set as empty. * - For Numbers: The method uses the value of the number. If the value is 0, the method considers the number as empty. * * @param obj * * @example * ```js * // true * Object.isEmpty({}); * * // false * Object.isEmpty({a: 1}); * * // true * Object.isEmpty(new Set()); * * // false * Object.isEmpty(new Set([1, 2])); * * // false * Object.isEmpty(1); * * // true * Object.isEmpty(0); * Object.isEmpty(NaN); * Object.isEmpty(null); * Object.isEmpty(undefined); * ``` */ isEmpty(obj: any): boolean; /** * Iterates over the specified dictionary * * @param obj - object to iterate * @param opts - additional options * @param cb - callback function that is called on each of object elements */ forEach<V>( obj: Dictionary<V>, opts: ObjectForEachOptions & {withDescriptors: true}, cb: (el: ObjectForEachPropertyDescriptor<V>, key: string, data: Dictionary<V>) => any ): void; /** * Iterates over the specified dictionary * * @param obj - object to iterate * @param opts - additional options * @param cb - callback function that is called on each of object elements */ forEach<V>( obj: Dictionary<V>, opts: ObjectForEachOptions & ({propsToIterate: 'all' | 'notOwn'} | {withDescriptors: false}), cb: (el: V, key: string, data: Dictionary<V>) => any ): void; /** * Iterates over the specified Map object * * @param obj - object to iterate * @param opts - additional options * @param cb - callback function that is called on each of object elements */ forEach<V, K>( obj: Map<K, V>, opts: ObjectForEachOptions, cb: (el: V, key: K, data: Map<K, V>) => any ): void; /** * Iterates over the specified Map object * * @param obj - object to iterate * @param cb - callback function that is called on each of object elements * @param [opts] - additional options */ forEach<V, K>( obj: Map<K, V>, cb: (el: V, key: K, data: Map<K, V>) => any, opts?: ObjectForEachOptions ): void; /** * Iterates over the specified Set object * * @param obj - object to iterate * @param opts - additional options * @param cb - callback function that is called on each of object elements */ forEach<V>( obj: Set<V>, opts: ObjectForEachOptions, cb: (el: V, i: V, data: Set<V>) => any ): void; /** * Iterates over the specified Set object * * @param obj - object to iterate * @param cb - callback function that is called on each of object elements * @param [opts] - additional options */ forEach<V>( obj: Set<V>, cb: (el: V, i: V, data: Set<V>) => any, opts?: ObjectForEachOptions ): void; /** * Iterates over the specified array * * @param obj - object to iterate * @param opts - additional options * @param cb - callback function that is called on each of object elements */ forEach<V>( obj: V[], opts: ObjectForEachOptions, cb: (el: V, i: number, data: V[]) => any ): void; /** * Iterates over the specified array * * @param obj - object to iterate * @param cb - callback function that is called on each of object elements * @param [opts] - additional options */ forEach<V>( obj: V[], cb: (el: V, i: number, data: V[]) => any, opts?: ObjectForEachOptions ): void; /** * Iterates over the specified array-like object * * @param obj - object to iterate * @param opts - additional options * @param cb - callback function that is called on each of object elements */ forEach<V>( obj: ArrayLike<V>, opts: ObjectForEachOptions, cb: (el: V, i: number, data: ArrayLike<V>) => any, ): void; /** * Iterates over the specified array-like object * * @param obj - object to iterate * @param cb - callback function that is called on each of object elements * @param [opts] - additional options */ forEach<V>( obj: ArrayLike<V>, cb: (el: V, i: number, data: ArrayLike<V>) => any, opts?: ObjectForEachOptions ): void; /** * Iterates over the specified iterable object * * @param obj - object to iterate * @param opts - additional options * @param cb - callback function that is called on each of object elements */ forEach<V>( obj: Iterable<V>, opts: ObjectForEachOptions, cb: (el: V, key: null, data: Iterable<V>) => any ): void; /** * Iterates over the specified iterable object * * @param obj - object to iterate * @param cb - callback function that is called on each of object elements * @param [opts] - additional options */ forEach<V>( obj: Iterable<V>, cb: (el: V, key: null, data: Iterable<V>) => any, opts?: ObjectForEachOptions ): void; /** * Iterates over the specified object * * @param obj - object to iterate * @param opts - additional options * @param cb - callback function that is called on each of object elements */ forEach<V>( obj: Dictionary<V>, opts: ObjectForEachOptions, cb: (el: V, key: string, data: Dictionary<V>) => any ): void; /** * Iterates over the specified object * * @param obj - object to iterate * @param cb - callback function that is called on each of object elements * @param [opts] - additional options */ forEach<V>( obj: Dictionary<V>, cb: (el: V, key: string, data: Dictionary<V>) => any, opts?: ObjectForEachOptions ): void; /** * Iterates over the specified object * * @param obj - object to iterate * @param opts - additional options * @param cb - callback function that is called on each of object elements */ forEach<V = unknown, K = unknown, D = any>( obj: D, opts: ObjectForEachOptions, cb: (el: V, key: K, data: D) => any ): void; /** * Iterates over the specified object * * @param obj - object to iterate * @param cb - callback function that is called on each of object elements * @param [opts] - additional options */ forEach<V = unknown, K = unknown, D = any>( obj: D, cb: (el: V, key: K, data: D) => any, opts?: ObjectForEachOptions ): void; /** * Returns a curried version of `Object.fastCompare` for one argument * @param a */ fastCompare(a: any): (b: any) => boolean; /** * Compares two specified objects by using a naive but fast `JSON.stringify/parse` strategy and * returns true if they are equal. * * Mind, that this method uses non-stable version `JSON.stringify`, i.e., * it can work incorrectly with object like `{a: 1, b: 2}` and `{b: 2, a: 1}`. * * Be careful with comparing `undefined` and `NaN` values, as they can be converted to `null` due to * the nature of `JSON.stringify`. * * @param a * @param b */ fastCompare<T>(a: any, b: T): a is T; /** * Returns a curried version of `Object.fastClone` * * @param obj * @param opts - additional options */ fastClone(obj: undefined, opts: FastCloneOptions): <T>(obj: T) => T; /** * Clones the specified object using the `structuredClone` method if possible and returns a new object. * Otherwise, the method will use a naive but fast `JSON.stringify/parse` strategy. * * Be careful with cloning `undefined` and `NaN` values, as they can be converted to `null` due to * the nature of `JSON.stringify/parse`. * * @param obj * @param [opts] - additional options */ fastClone<T>(obj: T, opts?: FastCloneOptions): T; /** * Returns a string representation of the specified object by using a naive but fast `JSON.stringify/parse` strategy. * * Mind, that this method uses non-stable version `JSON.stringify`, i.e., * it can work incorrectly with object like `{a: 1, b: 2}` and `{b: 2, a: 1}`. * * Be careful with comparing `undefined` and `NaN` values, as they can be converted to `null` due to * the nature of `JSON.stringify`. * * @param obj */ fastHash(obj: any): string; /** * Returns a curried version of `Object.mixin` for one argument * @param opts - if true, then properties will be copied recursively, or additional options to extend */ mixin(opts: ObjectMixinOptions | boolean): <B, O1>(base: B, obj1: O1) => B & O1; /** * Returns a curried version of `Object.mixin` for one argument * @param opts - if true, then properties will be copied recursively, or additional options to extend */ mixin(opts: ObjectMixinOptions | boolean): <R = unknown>(...objects: any[]) => R; /** * Returns a curried version of `Object.mixin` for two arguments * * @param opts - if true, then properties will be copied recursively, or additional options to extend * @param target - target object */ mixin<B>(opts: ObjectMixinOptions | boolean, target: B): <O1>(obj1: O1) => B & O1; /** * Returns a curried version of `Object.mixin` for two arguments * * @param opts - if true, then properties will be copied recursively, or additional options to extend * @param target - target object */ mixin(opts: ObjectMixinOptions | boolean, target: any): <R = unknown>(...objects: any[]) => R; /** * Extends the specified object by another objects. * If the base value is not an object, a new object will be created with a type similar to the first extension object. * * @param opts - if true, then properties will be copied recursively, or additional options to extend * @param target - target object * @param obj1 - object for extending */ mixin<B, O1>(opts: ObjectMixinOptions | boolean, target: B, obj1: O1): B & O1; /** * Extends the specified object by another objects. * If the base value is not an object, a new object will be created with a type similar to the first extension object. * * @param opts - if true, then properties will be copied recursively, or additional options to extend * @param target - target object * @param obj1 - object for extending * @param obj2 - object for extending */ mixin<B, O1, O2>(opts: ObjectMixinOptions | boolean, target: B, obj1: O1, obj2: O2): B & O1 & O2; /** * Extends the specified object by another objects. * If the base value is not an object, a new object will be created with a type similar to the first extension object. * * @param opts - if true, then properties will be copied recursively, or additional options to extend * @param target - target object * @param obj1 - object for extending * @param obj2 - object for extending * @param obj3 - object for extending */ mixin<B, O1, O2, O3>(opts: ObjectMixinOptions | boolean, target: B, obj1: O1, obj2: O2, obj3: O3): B & O1 & O2 & O3; /** * Extends the specified object by another objects. * If the base value is not an object, a new object will be created with a type similar to the first extension object. * * @param opts - if true, then properties will be copied recursively, or additional options to extend * @param target - target object * @param objects - objects for extending */ mixin<R = unknown>(opts: ObjectMixinOptions | boolean, target?: any, ...objects: any[]): R; /** * Returns a curried version of `Object.serialize` * @param replacer - replacer function to serialize */ trySerialize(replacer?: JSONCb): <V>(value: V) => string | V; /** * Tries to serialize the specified value into a string. * * If the value is an array, dictionary, or string or has the predefined `toJSON` method, it is serialized using * `JSON.stringify`. In other cases, the value isn't serialized and will be returned by the function. * Also, in the case of error during serialization, the function returns the original value. * * @param value * @param [replacer] - replacer function to serialize */ trySerialize<V>(value: V, replacer?: JSONCb): string | V; /** * Returns a curried version of `Object.parse` * @param reviver - reviver function to parse */ parse(reviver?: JSONCb): <V, R = unknown>(value: V) => V extends string ? R : V; /** * Parses the specified value as a JSON/JS object and returns the result of parsing. * If the value isn't a string or can't be parsed, the function returns the original value. * * @param value * @param [reviver] - reviver function to parse */ parse<V, R = unknown>(value: V, reviver?: JSONCb): V extends string ? R : V; /** * Creates a hash table without any prototype and returns it * * @example * ```js * Object.createDict() // {__proto__: null} * ``` */ createDict<V = unknown>(): Dictionary<V>; /** * Creates a hash table without any prototype and returns it * * @param objects - extension objects: * all keys from these objects are merged to the target * * @example * ```js * Object.createDict({a: 1}, {b: 2}) // {a: 1, b: 2, __proto__: null} * ``` */ createDict<D extends object>(...objects: Array<Nullable<D>>): Pick<D, keyof D>; /** * Takes the enum-like object and converts it to a dictionary: * number values from the object are skipped * * @param obj */ convertEnumToDict<D extends object>(obj: Nullable<D>): {[K in keyof D]: K}; /** * Creates an object which has the similar structure to the TS enum and returns it * * @param obj - base object: it can be a dictionary or an array * @example * ```js * Object.createEnumLike({a: 1}) // {a: 1, 1: 'a', __proto__: null} * ``` */ createEnumLike<D extends object, K extends keyof D>(obj: Nullable<D>): D extends Array<infer E> ? Dictionary<E | number> : D & {[I: string]: K}; /** * @deprecated * @see ObjectConstructor.createEnumLike */ createMap<D extends object, K extends keyof D>(obj: Nullable<D>): D extends Array<infer E> ? Dictionary<E | number> : D & {[I: string]: K}; /** * Creates an object from the specified array * * @param arr * @param [opts] - additional options * * @example * ```js * // {foo: true, bar: true} * Object.fromArray(['foo', 'bar']); * * // {foo: 0, bar: 1} * Object.fromArray(['foo', 'bar'], {value: (val, i) => i}); * ``` */ fromArray<T>(arr: Nullable<any[]>, opts?: ObjectFromArrayOptions<T>): Dictionary<T>; /** * Returns a curried version of `Object.select` * @param condition - regular expression to filter by keys */ select(condition: RegExp | ObjectPropertyFilter): <D extends object>(obj: Nullable<D>) => {[K in keyof D]?: D[K]}; /** * Returns a curried version of `Object.select` * @param condition - whitelist of keys to filter */ select(condition: []): <D extends object>(obj: D) => D; /** * Returns a curried version of `Object.select` * @param condition - whitelist of keys to filter */ select<C extends string>(condition: C | [C]): <D extends object>(obj: Nullable<D>) => Pick<D, Extract<keyof D, C>>; /** * Returns a curried version of `Object.select` * @param condition - whitelist of keys to filter */ select< C1 extends string, C2 extends string >(condition: [C1, C2]): <D extends object>(obj: Nullable<D>) => Pick<D, Extract<keyof D, C1 | C2>>; /** * Returns a curried version of `Object.select` * @param condition - whitelist of keys to filter */ select< C1 extends string, C2 extends string, C3 extends string, >(condition: [C1, C2, C3]): <D extends object>(obj: Nullable<D>) => Pick<D, Extract<keyof D, C1 | C2 | C3>>; /** * Returns a curried version of `Object.select` * @param condition - whitelist of keys to filter */ select< C1 extends string, C2 extends string, C3 extends string, C4 extends string >(condition: [C1, C2, C3, C4]): <D extends object>(obj: Nullable<D>) => Pick<D, Extract<keyof D, C1 | C2 | C3 | C4>>; /** * Returns a curried version of `Object.select` * @param condition - whitelist of keys to filter */ select< C1 extends string, C2 extends string, C3 extends string, C4 extends string, C5 extends string >(condition: [C1, C2, C3, C4, C5]): <D extends object>(obj: Nullable<D>) => Pick<D, Extract<keyof D, C1 | C2 | C3 | C4 | C5>>; /** * Returns a curried version of `Object.select` * @param condition - whitelist of keys to filter */ select(condition: Iterable<any>): <D extends object>(obj: Nullable<D>) => {[K in keyof D]?: D[K]}; /** * Returns a curried version of `Object.select` * @param condition - map of keys to filter */ select<C extends object>(condition: C): <D extends object>(obj: Nullable<D>) => Pick<D, Extract<keyof D, keyof C>>; /** * Returns a new object based on the specified, but only with fields that match to the specified condition * * @param obj * @param condition - regular expression to filter by keys */ select<D extends object>(obj: Nullable<D>, condition: RegExp | ObjectPropertyFilter): {[K in keyof D]?: D[K]}; /** * Returns a new object based on the specified, but only with fields that match to the specified condition * * @param obj * @param condition - whitelist of keys to filter */ select<D extends object>(obj: Nullable<D>, condition: []): D; /** * Returns a new object based on the specified, but only with fields that match to the specified condition * * @param obj * @param condition - whitelist of keys to filter */ select<D extends object, C extends string>(obj: Nullable<D>, condition: C | [C]): Pick<D, Extract<keyof D, C>>; /** * Returns a new object based on the specified, but only with fields that match to the specified condition * * @param obj * @param condition - whitelist of keys to filter */ select< D extends object, C1 extends string, C2 extends string >(obj: Nullable<D>, condition: [C1, C2]): Pick<D, Extract<keyof D, C1 | C2>>; /** * Returns a new object based on the specified, but only with fields that match to the specified condition * * @param obj * @param condition - whitelist of keys to filter */ select< D extends object, C1 extends string, C2 extends string, C3 extends string >(obj: Nullable<D>, condition: [C1, C2, C3]): Pick<D, Extract<keyof D, C1 | C2 | C3>>; /** * Returns a new object based on the specified, but only with fields that match to the specified condition * * @param obj * @param condition - whitelist of keys to filter */ select< D extends object, C1 extends string, C2 extends string, C3 extends string, C4 extends string >(obj: Nullable<D>, condition: [C1, C2, C3, C4]): Pick<D, Extract<keyof D, C1 | C2 | C3 | C4>>; /** * Returns a new object based on the specified, but only with fields that match to the specified condition * * @param obj * @param condition - whitelist of keys to filter */ select< D extends object, C1 extends string, C2 extends string, C3 extends string, C4 extends string, C5 extends string, >(obj: Nullable<D>, condition: [C1, C2, C3, C4, C5]): Pick<D, Extract<keyof D, C1 | C2 | C3 | C4 | C5>>; /** * Returns a new object based on the specified, but only with fields that match to the specified condition * * @param obj * @param condition - whitelist of keys to filter */ select<D extends object>(obj: Nullable<D>, condition: Iterable<any>): {[K in keyof D]?: D[K]}; /** * Returns a new object based on the specified, but only with fields that match to the specified condition * * @param obj * @param condition - map of keys to filter */ select<D extends object, C extends object>(obj: Nullable<D>, condition: C): Pick<D, Extract<keyof D, keyof C>>; /** * Returns a curried version of `Object.reject` * @param condition - regular expression to filter by keys */ reject(condition: RegExp | ObjectPropertyFilter): <D extends object>(obj: Nullable<D>) => {[K in keyof D]?: D[K]}; /** * Returns a curried version of `Object.reject` * @param condition - whitelist of keys to filter */ reject<C>(condition: []): <D extends object>(obj: Nullable<D>) => D; /** * Returns a curried version of `Object.reject` * @param condition - whitelist of keys to filter */ reject<C extends string>(condition: C | [C]): <D extends object>(obj: Nullable<D>) => Omit<D, C>; /** * Returns a curried version of `Object.reject` * @param condition - whitelist of keys to filter */ reject< C1 extends string, C2 extends string >(condition: [C1, C2]): <D extends object>(obj: Nullable<D>) => Omit<D, C1 | C2>; /** * Returns a curried version of `Object.reject` * @param condition - whitelist of keys to filter */ reject< C1 extends string, C2 extends string, C3 extends string >(condition: [C1, C2, C3]): <D extends object>(obj: Nullable<D>) => Omit<D, C1 | C2 | C3>; /** * Returns a curried version of `Object.reject` * @param condition - whitelist of keys to filter */ reject< C1 extends string, C2 extends string, C3 extends string, C4 extends string >(condition: [C1, C2, C3, C4]): <D extends object>(obj: Nullable<D>) => Omit<D, C1 | C2 | C3 | C4>; /** * Returns a curried version of `Object.reject` * @param condition - whitelist of keys to filter */ reject< C1 extends string, C2 extends string, C3 extends string, C4 extends string, C5 extends string >(condition: [C1, C2, C3, C4, C5]): <D extends object>(obj: Nullable<D>) => Omit<D, C1 | C2 | C3 | C4 | C5>; /** * Returns a curried version of `Object.reject` * @param condition - whitelist of keys to filter */ reject(condition: Iterable<any>): <D extends object>(obj: Nullable<D>) => {[K in keyof D]?: D[K]}; /** * Returns a curried version of `Object.reject` * @param condition - map of keys to filter */ reject<C extends object>(condition: C): <D extends object>(obj: Nullable<D>) => Omit<D, keyof C>; /** * Returns a new object based on the specified, but without fields that match to the specified condition * * @param obj * @param condition - regular expression to filter by keys */ reject<D extends object>(obj: Nullable<D>, condition: RegExp | ObjectPropertyFilter): {[K in keyof D]?: D[K]}; /** * Returns a new object based on the specified, but without fields that match to the specified condition * * @param obj * @param condition - whitelist of keys to filter */ reject<D extends object>(obj: Nullable<D>, condition: []): D; /** * Returns a new object based on the specified, but without fields that match to the specified condition * * @param obj * @param condition - whitelist of keys to filter */ reject<D extends object, C extends string>(obj: Nullable<D>, condition: C | [C]): Omit<D, C>; /** * Returns a new object based on the specified, but without fields that match to the specified condition * * @param obj * @param condition - whitelist of keys to filter */ reject< D extends object, C1 extends string, C2 extends string >(obj: Nullable<D>, condition: [C1, C2]): Omit<D, C1 | C2>; /** * Returns a new object based on the specified, but without fields that match to the specified condition * * @param obj * @param condition - whitelist of keys to filter */ reject< D extends object, C1 extends string, C2 extends string, C3 extends string >(obj: Nullable<D>, condition: [C1, C2, C3]): Omit<D, C1 | C2 | C3>; /** * Returns a new object based on the specified, but without fields that match to the specified condition * * @param obj * @param condition - whitelist of keys to filter */ reject< D extends object, C1 extends string, C2 extends string, C3 extends string, C4 extends string >(obj: Nullable<D>, condition: [C1, C2, C3, C4]): Omit<D, C1 | C2 | C3 | C4>; /** * Returns a new object based on the specified, but without fields that match to the specified condition * * @param obj * @param condition - whitelist of keys to filter */ reject< D extends object, C1 extends string, C2 extends string, C3 extends string, C4 extends string, C5 extends string >(obj: Nullable<D>, condition: [C1, C2, C3, C4, C5]): Omit<D, C1 | C2 | C3 | C4 | C5>; /** * Returns a new object based on the specified, but without fields that match to the specified condition * * @param obj * @param condition - whitelist of keys to filter */ reject<D extends object>(obj: Nullable<D>, condition: Iterable<any>): {[K in keyof D]?: D[K]}; /** * Returns a new object based on the specified, but without fields that match to the specified condition * * @param obj * @param condition - map of keys to filter */ reject<D extends object, C extends object>(obj: Nullable<D>, condition: C): Omit<D, keyof C>; /** * Wraps the specified value into the Either structure. * If the value is equal to null or undefined, the value is rejected. * * @example * ```typescript * function toLowerCase(str: string): string { * return str.toLowerCase(); * } * * Object.Option(toLowerCase)(null).catch((err) => err === null); * Object.Option(null).catch((err) => err === null); * * Object.Option(toLowerCase)('FOO').then((value) => value === 'foo'); * Object.Option('foo').then((value) => value === 'foo'); * ``` */ Option<R>(value: () => R): AnyFunction<any[], Maybe<R>>; /** * Wraps the specified value into the Either structure. * If the value is equal to null or undefined, the value is rejected. * * @example * ```typescript * function toLowerCase(str: string): string { * return str.toLowerCase(); * } * * Object.Option(toLowerCase)(null).catch((err) => err === null); * Object.Option(null).catch((err) => err === null); * * Object.Option(toLowerCase)('FOO').then((value) => value === 'foo'); * Object.Option('foo').then((value) => value === 'foo'); * ``` */ Option<A1, A extends any[], R>(value: (a