UNPKG

@bassist/utils

Version:

Opinionated collection of common JavaScript / TypeScript utils by @chengpeiquan .

1,082 lines (1,062 loc) 27 kB
/** * @category interactive */ type WritableElement = HTMLInputElement | HTMLTextAreaElement; /** * @category interactive */ type CopyableElement = HTMLElement | WritableElement; /** * Extensions based on the Clipboard API and with fallback mechanism * * @category interactive */ declare class ClipboardInstance { /** * Determine whether the clipboard is supported */ isSupported: boolean; constructor(); /** * Copy the text passed in or the text of the specified DOM element * * @example * * ``` * clipboard.copy(document.querySelector('.foo')) * ``` */ copy(el: CopyableElement): Promise<boolean>; /** * Cut the text passed in or the text of the specified DOM element * * @example * * ``` * clipboard.cut(document.querySelector('.foo')) * ``` */ cut(el: WritableElement): Promise<boolean>; /** * Read the text content of the clipboard */ read(): Promise<string>; /** * Write text content to clipboard */ write(text: string): Promise<boolean>; } /** * Initialized Clipboard Instance * * @category interactive */ declare const clipboard: ClipboardInstance; /** * @category storage */ type StorageType = 'localStorage' | 'sessionStorage'; /** * BaseStorage class provides a wrapper for browser storage or fallback storage. * * @category storage */ declare class BaseStorage { prefix: string; private storage; /** * Creates an instance of BaseStorage * * @param prefix - The prefix to be added to the storage keys. * @param storageType - The type of storage to use (localStorage or sessionStorage) */ constructor(prefix: string, storageType: StorageType); /** * Read stored data * @tips The `key` doesn't need to be prefixed * @returns The data in the format before storage */ get(key: string): any; /** * Set storage data */ set(key: string, value: any): void; /** * Remove the specified storage data under the current prefix */ remove(key: string): void; /** * Clear all stored data under the current prefix */ clear(): void; /** * Count the number of storage related to the current prefix */ count(): number; /** * List storage keys associated under the current prefix * @tips All keys without prefix */ list(): string[]; } /** * localStorage that supports prefixes * * @category storage */ declare class LocalStorage extends BaseStorage { constructor(prefix: string); } /** * sessionStorage that supports prefixes * * @category storage */ declare class SessionStorage extends BaseStorage { constructor(prefix: string); } /** * The preferred color scheme for the appearance of the user interface * * @category appearance */ type PrefersColorScheme = 'light' | 'dark'; /** * Dark mode media query * * @category appearance */ declare const darkMediaQuery: MediaQueryList | undefined; /** * Checks if the user's preferred color scheme is dark * * @category appearance */ declare function isDark(): boolean; /** * Light mode media query * * @category appearance */ declare const lightMediaQuery: MediaQueryList | undefined; /** * Checks if the user's preferred color scheme is light * * @category appearance */ declare function isLight(): boolean; /** * Retrieves the user's preferred color scheme * * @category appearance */ declare function getPrefersColorScheme(): PrefersColorScheme | undefined; /** * Portrait orientation media query * * @category appearance */ declare const portraitMediaQuery: MediaQueryList | undefined; /** * Check whether the current screen is in portrait mode * * @category appearance */ declare function isPortrait(): boolean; /** * Landscape orientation media query * * @category appearance */ declare const landscapeMediaQuery: MediaQueryList | undefined; /** * Check whether the current screen is in landscape mode * * @category appearance */ declare function isLandscape(): boolean; /** * The actual type of the data * * @category data */ type DataType = 'Array' | 'ArrayBuffer' | 'AsyncFunction' | 'BigInt' | 'Blob' | 'Boolean' | 'Date' | 'Error' | 'File' | 'Function' | 'Map' | 'Math' | 'Null' | 'Number' | 'Object' | 'Promise' | 'Set' | 'String' | 'Symbol' | 'RegExp' | 'Undefined' | 'WeakMap' | 'WeakSet'; /** * Get the real data type * * @description Solve the judgment error of the value wrapped in an Object * e.g. Object(1n), Object(1) * * @category data */ declare function getDataType(target: any): DataType; /** * Wrapper for `Array.isArray`, determine whether the data is Array * * @category data */ declare function isArray(value: unknown): value is any[]; /** * Determine whether the data is ArrayBuffer * * @category data */ declare function isArrayBuffer(value: unknown): value is ArrayBuffer; /** * Determine whether the data is AsyncFunction * * @category data */ declare function isAsyncFunction(value: unknown): value is (...args: any) => Promise<any>; /** * Determine whether the data is BigInt * * @category data */ declare function isBigInt(value: unknown): value is bigint; /** * Determine whether the data is Blob * * @category data */ declare function isBlob(value: unknown): value is Blob; /** * Determine whether the data is Boolean * * @category data */ declare function isBoolean(value: unknown): value is boolean; /** * Determine whether the data is Date * * @category data */ declare function isDate(value: unknown): value is Date; /** * Determine whether the data is Error * * @category data */ declare function isError(value: unknown): value is Error; /** * Determine whether the data is Even * * @category data */ declare function isEven(value: unknown): value is number; /** * Determine whether the data is File * * @category data */ declare function isFile(value: unknown): value is File; /** * Wrapper for `Number.isFinite`, determine whether the data is finite * @category data */ declare function isFinite(value: unknown): value is number; /** * Determine whether the data is Function * * @category data */ declare function isFunction(value: unknown): value is (...args: any) => any; /** * Wrapper for `Number.isInteger`, determine whether the data is Integer * @category data */ declare function isInteger(value: unknown): value is number; /** * Determine whether the data is Map * * @category data */ declare function isMap(value: unknown): value is Map<any, any>; /** * Determine whether the data is Math * * @category data */ declare function isMath(value: unknown): value is Math; /** * Wrapper for `Number.isNaN`, determine whether the data is NaN * @category data */ declare function isNaN(value: unknown): value is number; /** * Determine whether the data is Null * * @category data */ declare function isNull(value: unknown): value is null; /** * Determine whether the data is Number * * @category data */ declare function isNumber(value: unknown): value is number; /** * Determine whether the data is Odd * * @category data */ declare function isOdd(value: unknown): value is number; /** * Determine whether the data is Object * * @category data */ declare function isObject(value: unknown): value is Record<any, any>; /** * Determine whether the data is Promise * * @category data */ declare function isPromise(value: unknown): value is Promise<any>; /** * Wrapper for `Number.isSafeInteger`, determine whether the data is Safe Integer * @category data */ declare function isSafeInteger(value: unknown): value is number; /** * Determine whether the data is Promise * * @category data */ declare function isSet(value: unknown): value is Set<any>; /** * Determine whether the data is String * * @category data */ declare function isString(value: unknown): value is string; /** * Determine whether the data is Symbol * * @category data */ declare function isSymbol(value: unknown): value is symbol; /** * Determine whether the data is Undefined * * @category data */ declare function isUndefined(value: unknown): value is undefined; /** * Determine whether the data is WeakMap * * @category data */ declare function isWeakMap(value: unknown): value is WeakMap<any, any>; /** * Determine whether the data is WeakSet * * @category data */ declare function isWeakSet(value: unknown): value is WeakSet<any>; /** * Determine whether the data is RegExp * * @category data */ declare function isRegExp(value: unknown): value is RegExp; /** * Determine whether the specified key exists on the object * * @category data */ declare function hasKey<T, K extends keyof T>(obj: T, key: K): key is K; declare const hasOwnProperty: typeof hasKey; /** * String to byte stream * * @category data */ declare function getBytes(value: string): Uint8Array; /** * @category data */ interface InRangeOptions { num: number; min: number; max: number; includeMin?: boolean; includeMax?: boolean; } /** * Checks if a number is between minimum and maximum * * @category data */ declare function inRange({ num, min, max, includeMin, includeMax, }: InRangeOptions): boolean; /** * No operation function type * * @category data */ type NoOperationFunction = (...args: any) => void; /** * A no operation function * * @category data */ declare const noop: NoOperationFunction; /** * Promisify No operation function type * * @category data */ type PromisifyNoOperationFunction = (...args: any) => Promise<void>; /** * A promisify no operation function * * @category data */ declare const pnoop: PromisifyNoOperationFunction; /** * Checks if the code is being executed in a browser environment * * @category device */ declare const isBrowser: boolean; /** * Checks if the code is being executed in a server environment * * @category device */ declare const isServer: boolean; /** * Regular expression pattern to match mobile device user agents * * @category device */ declare const mobileDevicesRegExp: RegExp; /** * Checks if the code is being executed on a mobile device * * @category device */ declare function isMobile(): boolean; /** * Regular expression pattern to match tablet device user agents * * @category device */ declare const tabletDevicesRegExp: RegExp; /** * Checks if the code is being executed on a tablet device * * @category device */ declare function isTablet(): boolean; /** * Checks if the code is being executed on a desktop device * * @category device */ declare function isDesktop(): boolean; /** * Regular expression pattern to match apple device user agents * * @category device */ declare const appleDevicesRegExp: RegExp; /** * Checks if the code is being executed on an apple device * * @category device */ declare function isAppleDevice(): boolean; /** * Checks if the code is running on an Android device * * @category device */ declare const isAndroid: boolean; /** * Checks if the code is running on an iOS device * * @category device */ declare const isIOS: boolean; /** * Checks if the code is running in a Uni-App environment * * @category device */ declare const isUniApp: boolean; /** * Checks if the code is running in a WeChat (Weixin) environment * * @category device */ declare const isWeixin: boolean; /** * Checks if the code is running in a QQ environment * * @category device */ declare const isQQ: boolean; /** * Checks if the code is running in a QQ Browser environment * * @category device */ declare const isQQBrowser: boolean; /** * Checks if the code is running in a Qzone environment * * @category device */ declare const isQzone: boolean; /** * Checks if the code is running in a Weibo environment * * @category device */ declare const isWeibo: boolean; /** * Checks if the code is running in a Baidu Box App environment * * @category device */ declare const isBaidu: boolean; /** * @category device */ interface DeviceResizeWatcherOptions { immediate: boolean; } /** * Watches for page resize or orientation change events and executes the callback * * @param callback - The callback function to be executed * * @param options - The options for the resize watcher * `immediate`: Determines whether the callback should be immediately executed on page load * * @category device */ declare function watchResize(callback: () => void, { immediate }?: DeviceResizeWatcherOptions): void; /** * Get file info via `mime` package * * @category file */ declare class FileInfo { mime: any; constructor(theMimePackageInstance: any); getMimeType(path: string): any; getExtensionFromMimeType(mimeType: string): any; getExtension(path: string): any; } /** * Extract numbers from text * * @param text - Text to be processed * * @param startsWithZero - Preserve the 0-starting format like `002` * * @category format */ declare function extractNumber(text: string | number, startsWithZero?: boolean): string; /** * Format amount with two decimal places * * @param amount - Amount to be processed * * @category format */ declare function formatAmount(amount: string | number): string; /** * Add ellipses to words that are out of length * * @param word - The sentence to be processed * * @param limit - The upper limit * * @returns The processed word * * @category format */ declare function ellipsis(word: string, limit: number): string; /** * Capitalize the first letter * * @category format */ declare function capitalize([first, ...rest]: string): string; /** * Formatted in `kebab-case` style * * @category format */ declare function kebabCase(word: string): string; /** * Formatted in `camelCase` style * * @category format */ declare function camelCase([first, ...rest]: string): string; /** * Formatted in `PascalCase` style * * @category format */ declare function pascalCase(word: string): string; /** * Escaping special characters for regular expressions * * @copyright lodash.escaperegexp * * @category format */ declare function escapeRegExp(name: string): string; /** * Sort the keys of an object * * @category format */ declare function sortKeys(target: any): any; /** * @category format */ interface UniqueOptions<T> { /** * The key used to determine if there are duplicate values */ primaryKey: keyof T; /** * he original data list */ list: T[]; } /** * Deduplicate an array containing objects * * @category format */ declare function unique<T>({ primaryKey, list }: UniqueOptions<T>): T[]; /** * Exclude specified fields from the object * * @tips Only handle first-level fields * * @param object - An object as data source * * @param fields - Field names to exclude * * @returns A processed new object * * @category format */ declare function excludeFields(object: Record<string, any>, fields: string[]): Record<string, any>; /** * Format the time as `yyyy-MM-dd HH:mm:ss` * * @description Note: * If the date separator is `-`, it will be parsed as * a standard ISO 8601 formatted date string (e.g. 2023-01-01) * * If the date separator is `/`, it will be parsed according to * the non-standard date string format (e.g. 2023/01/01 ) * * This will result in inconsistent processing, please be aware of such cases. * e.g. `+new Date('2023/01/01') !== +new Date('2023-01-01')` * * @param time - A timestamp or a date object * * @param dateOnly - If `true` , only returns `yyyy-MM-dd` * * @category format */ declare function formatTime(time: number | Date, dateOnly?: boolean): string; /** * @category format */ interface FormatDurationUnit { days: string; hours: string; minutes: string; seconds: string; } /** * Generally used to format the display of two time gaps, such as countdown * * @param timestamp - Timestamp with two time gaps * * @param units - Time units, * different languages can be passed in when i18n is needed, * the default is Simplified Chinese * * @category format */ declare function formatDuration(timestamp: number, units?: FormatDurationUnit): string; /** * Remove HTML tags * * @param content HTML Codes * * @category format */ declare function removeHtmlTags(content: string): string; /** * Remove HTML tags and escape sequence * * @param content HTML Codes * * @category format */ declare function html2text(content: string): string; /** * Make sure the data you get is an array * * @category format */ declare function toArray<T>(value?: T | T[]): T[]; /** * Ensure prefix of a string * * @category format */ declare function ensurePrefix(prefix: string, str: string): string; /** * Ensure suffix of a string * * @category format */ declare function ensureSuffix(suffix: string, str: string): string; /** * @category network */ type ResourcesSupportedWithLoadRes = 'js' | 'css' | 'style'; /** * @category network */ interface LoadResOptions { type: ResourcesSupportedWithLoadRes; id: string; resource: string; } /** * Dynamic loading of resources * * @category network */ declare function loadRes({ type, id, resource }: LoadResOptions): Promise<unknown>; /** * JSON with Padding * * @description Note: * JSONP is a method for sending JSON data without worrying about cross-domain issues. * JSONP does not use the XMLHttpRequest or Fetch, it uses the `<script />` tag instead. * * @see https://en.wikipedia.org/wiki/JSONP * * @param url - The Resource script URL. * * @param callback - The Callback function name, Optional, * it will be an attribute name of `window`, so needs to be unique, * If not passed, a random function name will be automatically generated. * * @example * * ```ts * interface Res { * code: number * data: string[] * msg: string * } * * // The default and server-side agreement is to use `callback` Query * const url = `https://example.com/data` * * // When no `callback` param passed, a random function name is created * // Equivalent to `https://example.com/data?callback=randomCallbackName` * // Pass the type of response as a generic to get a typed return value * const res = await jsonp<Res>(url) * * // You can also specify the `callback` function name * const callback = 'jsonp_callback_123456' * const res2 = await jsonp<Res>(url, callback) * * // If the server does not agree on the `callback` Query, * // you can specify other valid Query in this way. * const urlWithCallback = `https://example.com/data?cb=${callback}` * const res3 = await jsonp<Res>(urlWithCallback) * ``` * * @category network */ declare function jsonp<T>(url: string, callback?: string): Promise<T>; /** * Load a batch of images in concurrent mode * * @category network */ declare function concurrentLoadImages(images: string[]): Promise<unknown[]>; /** * Load a batch of images in serial mode * * @category network */ declare function serialLoadImages(images: string[]): Promise<void>; /** * Preload images * * @description It can be used to preload large images in advance, * or wait for the image to be loaded before ending Loading * and other usage scenarios. * * @param images - An array containing image urls * * @param mode - concurrent mode is used by default. * If there are too many pictures, * you can choose serial mode. * * @example * * ```ts * const images = [ * 'https://example.com/1.jpg', * 'https://example.com/2.jpg', * 'https://example.com/3.jpg', * ] * * // Start loading, Show loading icon etc. * setLoading(true) * * // Wait for the images to be pre-rendered * await preloadImages(images) * * // End loading state * setLoading(false) * ``` * * @category network */ declare function preloadImages(images: string[], mode?: 'concurrent' | 'serial'): Promise<void>; /** * Put the program to sleep for a while * * @category performance */ declare function sleep(ms: number): Promise<void>; /** * When an event is triggered frequently, * only execute the event processing function once. * * @category performance */ declare function debounce<T extends (...args: any[]) => void>(func: T, wait?: number): (...args: Parameters<T>) => void; /** * Can control how often a function is called within a specified time interval * * @category performance */ declare function throttle<T extends (...args: any[]) => void>(func: T, wait: number): (this: ThisParameterType<T>, ...args: Parameters<T>) => void; /** * @category query */ type QueryInfo = Record<string, string>; /** * @category query */ type QueryInfoObject = Record<string, string | number | boolean | undefined | null>; /** * Parse URL Query parameters * * @param url - By default, it is extracted from the browser URL, * and this parameter can be parsed from the specified URL * * @returns Query parameter object, * will convert `key1=value1&key2=value2` into an object * * @category query */ declare function parseQuery(url?: string): QueryInfo; /** * Extract parameter information from URL Query * * @returns An object containing the request path and parameters object * `path`: Jump path, the same as the routing name in the Web App * `params`: Parameters other than path * * @category query */ declare function extractQueryInfo(url?: string): { path: string; params: QueryInfo; }; /** * Get the specified Query parameter * * @param key - The parameter key name to get * * @param url - By default, it is extracted from the browser URL, * and this parameter can be parsed from the specified URL * * @category query */ declare function getQuery(key: string, url?: string): string; /** * Serialize Query parameters information * * @param queryInfoObject - The object of the Query parameter to use for serialization * * @category query */ declare function stringifyQuery(queryInfoObject: QueryInfoObject): string; /** * Generate random number * * @param min - The minimum value in the range * * @param max - The maximum value in the range * * @param roundingType - Round the result * * @category random */ declare function randomNumber(min?: number, max?: number, roundingType?: 'round' | 'ceil' | 'floor'): number; /** * Generate random string * * @param length - The length of the string to be returned * * @category random */ declare function randomString(length?: number): string; /** * Generate random boolean * * @category random */ declare function randomBoolean(): boolean; /** * Shuffle the array and sort it randomly * * @category random */ declare function shuffle(arr: any[]): any[]; /** * Randomly returns a mocked UA * * @param device - Get a random UA on the specified device type * * @category random */ declare function randomUserAgent(device?: 'desktop' | 'mobile'): string; /** * Verify the mobile phone number format in mainland China * * @category regexp */ declare function isMob(phoneNumber: number | string): boolean; /** * Verify email format * * @category regexp */ declare function isEmail(email: string): boolean; /** * Verify url format * * @category regexp */ declare function isUrl(url: string): boolean; /** * Verify the ID card number format in mainland China * * @category regexp */ declare function isIdCard(idCardNumber: string): boolean; /** * Verify the bank card number format in mainland China * * @category regexp */ declare function isBankCard(bankCardNumber: string): boolean; /** * Verify the IP is IPv4 * * @category regexp */ declare function isIPv4(ip: string): boolean; /** * Verify the IP is IPv6 * * @category regexp */ declare function isIPv6(ip: string): boolean; /** * Common runtime environment types * * @category runtime */ type RuntimeEnv = 'dev' | 'development' | 'test' | 'prod' | 'production'; /** * Get current runtime environment * * @precondition The `cross-env` package is installed * * @category runtime */ declare function getRuntimeEnv(): RuntimeEnv | undefined; /** * Current runtime environment * * @category runtime */ declare const runtimeEnv: RuntimeEnv | undefined; /** * Determine whether the specified runtime environment is currently * * @precondition The `cross-env` package is installed * * @category runtime */ declare function checkRuntimeEnv(runtimeEnv: unknown): runtimeEnv is RuntimeEnv; /** * Determine whether the current runtime is development * * @category runtime */ declare const isDevRuntime: boolean; /** * Determine whether the current runtime is test * * @category runtime */ declare const isTestRuntime: boolean; /** * Determine whether the current runtime is production * * @category runtime */ declare const isProdRuntime: boolean; /** * Current user agent * * @category network */ declare function getUserAgent(): string; /** * User agents of desktop device by mock * * @category network */ declare const desktopUserAgents: string[]; /** * User agents of mobile device by mock * * @category network */ declare const mobileUserAgents: string[]; /** * User agents by mock * * @category network */ declare const userAgents: string[]; export { ClipboardInstance, type CopyableElement, type DataType, FileInfo, type InRangeOptions, type LoadResOptions, LocalStorage, type NoOperationFunction, type PrefersColorScheme, type PromisifyNoOperationFunction, type ResourcesSupportedWithLoadRes, type RuntimeEnv, SessionStorage, type WritableElement, appleDevicesRegExp, camelCase, capitalize, checkRuntimeEnv, clipboard, concurrentLoadImages, darkMediaQuery, debounce, desktopUserAgents, ellipsis, ensurePrefix, ensureSuffix, escapeRegExp, excludeFields, extractNumber, extractQueryInfo, formatAmount, formatDuration, formatTime, getBytes, getDataType, getPrefersColorScheme, getQuery, getRuntimeEnv, getUserAgent, hasKey, hasOwnProperty, html2text, inRange, isAndroid, isAppleDevice, isArray, isArrayBuffer, isAsyncFunction, isBaidu, isBankCard, isBigInt, isBlob, isBoolean, isBrowser, isDark, isDate, isDesktop, isDevRuntime, isEmail, isError, isEven, isFile, isFinite, isFunction, isIOS, isIPv4, isIPv6, isIdCard, isInteger, isLandscape, isLight, isMap, isMath, isMob, isMobile, isNaN, isNull, isNumber, isObject, isOdd, isPortrait, isProdRuntime, isPromise, isQQ, isQQBrowser, isQzone, isRegExp, isSafeInteger, isServer, isSet, isString, isSymbol, isTablet, isTestRuntime, isUndefined, isUniApp, isUrl, isWeakMap, isWeakSet, isWeibo, isWeixin, jsonp, kebabCase, landscapeMediaQuery, lightMediaQuery, loadRes, mobileDevicesRegExp, mobileUserAgents, noop, parseQuery, pascalCase, pnoop, portraitMediaQuery, preloadImages, randomBoolean, randomNumber, randomString, randomUserAgent, removeHtmlTags, runtimeEnv, serialLoadImages, shuffle, sleep, sortKeys, stringifyQuery, tabletDevicesRegExp, throttle, toArray, unique, userAgents, watchResize };