/**
 * Copyright (c) 2020-present, Goldman Sachs
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { clone, cloneDeep as deepClone, isEqual as deepEqual, findLast, isEmpty, pickBy, uniqBy, uniq, debounce, throttle, type DebouncedFunc, shuffle } from 'lodash-es';
import { diff as deepDiff } from 'deep-object-diff';
export { clone, deepClone, deepEqual, deepDiff, findLast, isEmpty, pickBy, uniqBy, uniq, debounce, throttle, type DebouncedFunc, shuffle, };
export { v4 as uuid } from 'uuid';
/**
 * This is a dummy type that acts as a signal to say the type should be plain object with shape rather than prototype object of type
 * NOTE: This is useful in network client interface where we enforce that the input and output for the network call must be plain object,
 * so as to force proper handling (i.e. deserialize/serialize) but also signal from documentation perspective about the type/shape of the plain object
 */
export type PlainObject<T = unknown> = Record<PropertyKey, unknown>;
/**
 * This type allows modification of `readonly` attributes for class/interface
 * This is useful to set properties like `owner`, `parent` where we can't do so in the constructors
 *
 * See https://stackoverflow.com/questions/46634876/how-can-i-change-a-readonly-property-in-typescript
 */
export type Writable<T> = {
    -readonly [K in keyof T]: T[K];
};
export type Clazz<T> = {
    new (...args: any[]): T;
};
/**
 * As mentioned above for `Clazz<T>`, there is no good way to represent abstract class so
 * we will use `Function` in this case, this is a very loose check and will lose some benefit of type checking
 * during compile time, so refrain from using it extensively
 */
export type GenericClazz<T> = {
    new (...args: any[]): T;
} | Function;
export type SuperGenericFunction = (...args: any) => any;
export declare const getClass: <T>(obj: object) => Clazz<T>;
export declare const getSuperclass: <V>(_class: GenericClazz<unknown>) => GenericClazz<V> | undefined;
/**
 * Check if the specified class is either the same as, or is a superclass of the provided class.
 */
export declare const isClassAssignableFrom: (cls1: GenericClazz<unknown>, cls2: GenericClazz<unknown>) => boolean;
export declare const noop: () => (() => void);
/**
 * Recursively omit keys from an object
 */
export declare const recursiveOmit: <T extends object>(obj: T, 
/**
 * Checker function which returns `true` if the object field should be omit
 */
checker: (object: object, propKey: PropertyKey) => boolean) => T;
/**
 * Recursively remove fields with undefined values in object
 */
export declare const pruneObject: (obj: PlainObject) => PlainObject;
/**
 * Recursively remove fields with null values in object
 *
 * This is particularly useful in serialization, especially when handling response
 * coming from servers where `null` are returned for missing fields. We would like to
 * treat them as `undefined` instead, so we want to strip all the `null` values from the
 * plain JSON object.
 */
export declare const pruneNullValues: (obj: PlainObject) => PlainObject;
/**
 * Recursively sort object keys alphabetically
 */
export declare const sortObjectKeys: (value: PlainObject) => PlainObject;
export declare const parseNumber: (val: string) => number;
/**
 * Stringify object shallowly
 * See https://stackoverflow.com/questions/16466220/limit-json-stringification-depth
 */
export declare const shallowStringify: (object: unknown) => string;
export declare const generateEnumerableNameFromToken: (existingNames: string[], token: string, delim?: "whitespace" | "underscore") => string;
export declare const at: <T>(list: T[], idx: number, message?: string | undefined) => T;
/**
 * NOTE: This object mutates the input object (obj1)
 * To disable this behavior, set `createClone=true`
 */
export declare const mergeObjects: <T, V>(obj1: T, obj2: V, createClone: boolean) => T & V;
export declare const promisify: <T>(func: () => T) => Promise<T>;
export declare function sleep(duration: number): Promise<void>;
export declare const addUniqueEntry: <T>(array: T[], newEntry: T, comparator?: (val1: T, val2: T) => boolean) => boolean;
export declare const changeEntry: <T>(array: T[], oldEntry: T, newEntry: T, comparator?: (val1: T, val2: T) => boolean) => boolean;
export declare const swapEntry: <T>(array: T[], entryOne: T, entryTwo: T, comparator?: (val1: T, val2: T) => boolean) => boolean;
export declare const deleteEntry: <T>(array: T[], entryToDelete: T, comparator?: (val1: T, val2: T) => boolean) => boolean;
export type GeneratorFn<T> = Generator<Promise<unknown>, // force to manually handle casting for any promise called within the generator function
T>;
export declare const printObject: (value: unknown, options?: {
    deep?: boolean;
}) => string;
export declare const hasWhiteSpace: (val: string) => boolean;
//# sourceMappingURL=CommonUtils.d.ts.map