@cc-heart/utils
Version:
🔧 javascript common tools collection
964 lines (952 loc) • 31.4 kB
JavaScript
const _toString = Object.prototype.toString;
/**
* Checks if the given value is an object.
*
* @param val - The value to be checked.
* @returns Returns true if the value is an object, otherwise false.
*/
function isObject(val) {
return _toString.call(val) === '[object Object]';
}
/**
* Checks if the given value is an symbol.
*
* @param val - The value to be checked.
* @returns Returns true if the value is an object, otherwise false.
*/
function isSymbol(val) {
return typeof val === 'symbol';
}
/**
* Checks if the given value is a function.
*
* @param val - The value to be checked.
* @returns Returns true if the value is a function, false otherwise.
*/
function isFn(val) {
return typeof val === 'function';
}
/**
* Checks if the given value is a string.
*
* @param val - The value to be checked.
* @returns Returns true if the value is a string, false otherwise.
*/
function isStr(val) {
return typeof val === 'string';
}
/**
* Checks if the provided value is a boolean.
*
* @param val - The value to check.
* @returns Returns true if the value is a boolean, false otherwise.
*/
function isBool(val) {
return typeof val === 'boolean';
}
/**
* Checks if a value is undefined.
*
* @param val - The value to check.
* @returns Returns true if the value is undefined, otherwise false.
*/
function isUndef(val) {
return typeof val === 'undefined';
}
/**
* Checks if the given value is null.
*
* @param val - The value to check.
* @returns Returns true if the value is null, false otherwise.
*/
function isNull(val) {
return val === null;
}
const isNil = isNull;
/**
* Determines whether a value is a primitive.
*
* @param val - The value to check.
* @returns Returns `true` if the value is a primitive, `false` otherwise.
*/
function isPrimitive(val) {
return typeof val !== 'object' || val === null;
}
/**
* Checks if a value is falsy.
*
* @param val - The value to check.
* @returns Returns true if the value is falsy, otherwise false.
*/
function isFalsy(val) {
return !val;
}
/**
* Checks if the given value is a number.
*
* @param val - The value to be checked.
* @returns Returns true if the value is a number, false otherwise.
*/
function isNumber(val) {
return typeof val === 'number';
}
/**
* determines if it is a valid value other than NaN
* @param val
* @returns
*/
function isEffectiveNumber(val) {
if (!isNumber(val))
return false;
return !isNaN(val);
}
/**
* Checks if a value is a Promise.
*
* @param val - The value to check.
* @returns Returns `true` if the value is a Promise, else `false`.
*/
function isPromise(val) {
return (typeof val === 'object' &&
!isNull(val) &&
(_toString.call(val) === '[object Promise]' ||
isFn(Reflect.get(val, 'then'))));
}
/**
* Checks if the given object has its own property.
*
* @param obj - The object to check.
* @param prop - The property to check.
* @returns Returns true if the object has its own property, otherwise false.
*/
function hasOwn(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
/**
* An array is considered valid if it is an array and its length is greater than or equal to 0.
*
* @param arr - The array to be checked.
* @returns Returns true if the array is valid, false otherwise.
*/
function isValidArray(arr) {
return Array.isArray(arr) && arr.length > 0;
}
/**
* Checks if a given value is a valid PropertyKey.
* A PropertyKey is a string, number, or symbol that can be used as a property name.
*
* @param val - The value to check.
* @returns True if the value is a PropertyKey, false otherwise.
*/
function isPropertyKey(val) {
return isStr(val) || isNumber(val) || isSymbol(val);
}
/**
* Checks if a given date is valid.
*
* @param date - The date to check.
* @returns True if the date is valid, false otherwise.
*/
function isValidDate(date) {
return date.toString() !== 'Invalid Date';
}
const createDateWithoutTimezoneOffset = (...rest) => {
const date = new Date(...rest);
date.setMinutes(date.getMinutes() - date.getTimezoneOffset());
return date;
};
/**
* Returns the current time in ISO string format.
* @returns The current time in ISO string format.
*/
function getCurrentTimeISOString() {
return createDateWithoutTimezoneOffset().toISOString();
}
function formatDateString(date, maxLength) {
return String(date).padStart(maxLength, '0');
}
function formatDate(date, formatter = 'YYYY-MM-DD hh:mm:ss', utc = false) {
const year = formatDateString(date[utc ? 'getUTCFullYear' : 'getFullYear'](), 4);
const month = formatDateString(date[utc ? 'getUTCMonth' : 'getMonth']() + 1, 2);
const day = formatDateString(date[utc ? 'getUTCDate' : 'getDate'](), 2);
const hours = formatDateString(date[utc ? 'getUTCHours' : 'getHours'](), 2);
const minutes = formatDateString(date[utc ? 'getUTCMinutes' : 'getMinutes'](), 2);
const seconds = formatDateString(date[utc ? 'getUTCMinutes' : 'getSeconds'](), 2);
return formatter
.replace('YYYY', year)
.replace('MM', month)
.replace('DD', day)
.replace('hh', hours)
.replace('mm', minutes)
.replace('ss', seconds);
}
/**
* Formats a date based on a given timestamp.
*
* @param timeStamp - The timestamp to be formatted, in milliseconds.
* @param formatter - Optional. A specific format string to format the date. Defaults to 'YYYY-MM-DD HH:mm:ss'.
*
* @returns The formatted date string.
*
* @throws {Error} Throws an error if the timestamp is invalid or out of range.
*
* @example
* const timestamp = new Date().getTime();
* const formattedDate = formatDateByTimeStamp(timestamp);
* console.log(formattedDate);
*/
function formatDateByTimeStamp(timeStamp, formatter) {
const date = new Date(timeStamp);
if (timeStamp < 0 || !isValidDate(date)) {
console.warn('invalid timeStamp');
return 'Invalid Date';
}
return formatDate(date, formatter);
}
/**
* Formats a date string into a specified date time format
*
* @param dateString - A string representing the date.
* @param formatter - Optional. A specific format string to format the date. Defaults to 'YYYY-MM-DD HH:mm:ss'.
*
* @returns The formatted date string.
*
* @throws {Error} Throws an error if the date string is invalid or cannot be parsed into a Date object.
*
* @example
* const dateString = '2024-02-19T10:30:00Z';
* const formattedDateTime = formatDateTimeByString(dateString, 'MMMM D, YYYY, h:mm A');
* console.log(formattedDateTime);
*/
function formatDateTimeByString(dateString, formatter) {
const date = new Date(dateString);
if (!isValidDate(date)) {
console.warn('invalid date string');
return date.toString();
}
return formatDate(date, formatter);
}
/**
* Formats a date based on an array of numbers, with optional formatting string
*
* This function expects an array containing year, month, day, hour, minute, and second values. If the array is invalid or does not contain the necessary values, it logs a warning and returns 'Invalid Date'.
* The function uses the slice method to create a new array containing only the first six elements, and decrements the month value by 1 to convert it from a 1-based index to a 0-based index used by the Date object.
* It then creates a new Date object using the elements of the new array. If the date is invalid, it logs a warning and returns the date as a string.
* Finally, the function formats the date according to an optional formatting string and returns the formatted date string.
*
* @param array - The array representing the date. This array should contain year, month, day, hour, minute, and second values.
* @param formatter - Optional. A specific format string to format the date. Defaults to 'YYYY-MM-DD HH:mm:ss'.
*
* @returns The formatted date string.
*
* @throws {Error} Throws an error if the array is invalid or does not contain the necessary values.
*
* @example
* const dateArray = [2024, 2, 19, 10, 30, 0];
* const formattedDate = formatDateByArray(dateArray, 'MMMM D, YYYY, h:mm A');
* console.log(formattedDate);
*/
function formatDateByArray(array, formatter) {
if (!Array.isArray(array) || array.length < 2) {
console.warn('invalid date array');
return 'Invalid Date';
}
const newDateArray = array.slice(0, 6);
newDateArray[1] = newDateArray[1] - 1;
const date = new Date(...newDateArray);
if (!isValidDate(date)) {
console.warn(`Invalid date generated from array: ${newDateArray}`);
return date.toString();
}
return formatDate(date, formatter);
}
/**
* DefineDebounceFn is a function that creates a debounced function.
* @param fn - The function to be debounced.
* @param delay - The delay in milliseconds to wait before the debounced function is called. Default is 500ms.
* @param immediate - Whether the debounced function should be called immediately before the delay. Default is false.
* @returns - The debounce function.
*/
const defineDebounceFn = function (fn, delay = 500, immediate = false) {
let timer = null;
const debounced = function (...args) {
if (timer)
clearTimeout(timer);
if (immediate && !timer) {
immediate = false;
debounced._result = fn.apply(this, args);
}
else {
timer = setTimeout(() => {
debounced._result = fn.apply(this, args);
timer = null;
}, delay);
}
};
return debounced;
};
/**
* Creates a function that can only be called once.
*
* @param fn - The function to be called once.
* @returns - A new function that can only be called once.
*/
function defineOnceFn(fn) {
let __once = false;
let __cache;
if (!(fn instanceof Function)) {
throw new Error('first params must be a function');
}
return function (...args) {
if (!__once) {
__once = true;
__cache = fn.apply(this, args);
}
return __cache;
};
}
/**
* defineThrottleFn is a function that creates a throttled function.
* @param - The function to be throttled.
* @param - The delay in milliseconds to wait before the throttled function is called. Default is 500ms.
* @returns - The throttled function.
*/
function defineThrottleFn(fn, delay = 500) {
let startTimer = null;
let timer = null;
delay = Math.max(delay, 0);
const throttle = function (...args) {
const curTimer = Date.now();
const remainingTime = startTimer === null ? 0 : delay + startTimer - curTimer;
clearTimeout(timer);
if (remainingTime <= 0 || delay === 0) {
throttle._result = fn.apply(this, args);
startTimer = Date.now();
}
else {
timer = setTimeout(() => {
throttle._result = fn.apply(this, args);
}, remainingTime);
}
};
return throttle;
}
/**
* defineSinglePromiseFn ensures that the provided function can only be called once at a time.
* If the function is invoked while it's still executing, it returns the same promise, avoiding multiple calls.
*
* @param fn - The function to be wrapped, which returns a promise.
* @returns A function that ensures the provided function is only executed once and returns a promise.
*/
function defineSinglePromiseFn(fn) {
let ret = null;
return function () {
if (ret === null) {
ret = Promise.resolve(fn()).finally(() => {
ret = null;
});
}
return ret;
};
}
/**
* Generates a random integer between min (inclusive) and max (inclusive).
*
* @param min - The minimum value (inclusive).
* @param max - The maximum value (inclusive).
* @returns A random integer between min and max.
*/
function random(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
/**
* This function does nothing.
*
* @returns No return value.
*/
const noop = () => {
/** */
};
/**
* Sleeps for a given delay.
*
* @param delay - The delay, in milliseconds.
* @return A promise that resolves after the delay.
*/
const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay));
/**
* Capitalizes the first letter of a string.
*
* @param target - The string to be capitalized.
* @returns - The capitalized string.
*/
const capitalize = (target) => (target.charAt(0).toUpperCase() + target.slice(1));
/**
* Returns a new string with the first character converted to lowercase.
*
* @param target - The string to be unCapitalized.
* @returns - The unCapitalized string.
*/
const unCapitalize = (target) => (target.charAt(0).toLowerCase() + target.slice(1));
/**
* @description Add the number of cuts based on the original split and return all subsets after the cut
* @param str need to split of primitive string
* @param splitStr split params
* @param num split limit
* @returns a new split array, length is num + 1
*/
function mulSplit(str, splitStr, num = -1) {
const splitList = str.split(splitStr, num);
if (num === -1)
return splitList;
const originStr = splitList.join(splitStr);
if (originStr === str)
return splitList;
const endStr = str.slice(originStr.length + 1);
splitList.push(endStr);
return splitList;
}
/**
* Converts an underline-separated string to camel case.
* e.g. underlineToHump('hello_word') => 'helloWord'
*
* @param target - The underline-separated string to convert.
* @returns The camel case version of the input string.
*/
function underlineToHump(target) {
let isStartUnderline = true;
let prefixStr = null;
let str = '';
for (let i = 0; i < target.length; i++) {
if (target[i] === '_' &&
/[a-z]/.test(target[i + 1]) &&
!isStartUnderline &&
prefixStr !== '_') {
i++;
str += target[i].toUpperCase();
continue;
}
prefixStr = target[i];
if (isStartUnderline && target[i] !== '_') {
isStartUnderline = false;
}
str += target[i];
}
return str;
}
function parseKey(obj, key, value) {
const isArrayKey = key.includes('[') && key.includes(']');
if (isArrayKey) {
const keys = key.split(/[[\]]/).filter(Boolean);
let currentObj = obj;
for (let i = 0; i < keys.length; i++) {
let currentKey = keys[i];
if (currentKey.startsWith('.'))
currentKey = currentKey.split('.')[1];
if (i === keys.length - 1) {
if (Array.isArray(currentObj)) {
currentObj.push(value);
}
else {
currentObj[currentKey] = value;
}
}
else {
if (!currentObj[currentKey]) {
currentObj[currentKey] = keys[i + 1].match(/^\d+$/) ? [] : {};
}
currentObj = currentObj[currentKey];
}
}
}
else {
let nestedObj = obj;
const keyParts = key.split('.');
for (let i = 0; i < keyParts.length - 1; i++) {
const currentKey = keyParts[i];
if (!nestedObj[currentKey]) {
nestedObj[currentKey] = {};
}
nestedObj = nestedObj[currentKey];
}
nestedObj[keyParts[keyParts.length - 1]] = value;
}
}
/**
* Converts a query string to an object.
*
* @example `queryStringToObject('foo=1&bar=2&baz=3')`
* @example `queryStringToObject('foo=&bar=2&baz=3')`
* @example `queryStringToObject('foo[0]=1&foo[1]=2&baz=3')`
* @template T - The type of the URL string.
* @template U - The type of the object to return.
* @param {T} url - The URL string to convert.
* @returns {U} The object representation of the query string in `url`.
*/
function queryStringToObject(url) {
const result = {};
if (url) {
url.split('&').forEach((item) => {
const [rawKey, value] = item.split('=');
const key = decodeURIComponent(rawKey);
parseKey(result, key, decodeURIComponent(value));
});
}
return result;
}
/**
* Converts an object to a query string.
*
* @param data - The object to convert.
* @returns The query string representation of `data`.
*/
function objectToQueryString(data) {
const res = [];
for (const key in data) {
if (hasOwn(data, key)) {
if (Array.isArray(data[key])) {
res.push(arrayToQueryString(data[key], key));
}
else {
res.push(`${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`);
}
}
}
return res.join('&');
}
/**
* convert params routes to regular expressions
*
* @param path a params paths
* @returns null or An array contains the RegExp that matches the params and the path for each params parameter
*/
function convertParamsRouterToRegExp(path) {
const matcher = path.match(/:(.*?)(?:\/|$)/g);
if (matcher === null)
return null;
const reg = new RegExp(path.replace(/:(.*?)(\/|$)/g, '.*?$2'));
return [reg, matcher.map((val) => val.replace(/:(.*?)(\/|$)/g, '$1'))];
}
/**
* Returns the last portion of a path, similar to the Unix basename command.
* Trims the query string if it exists.
* Optionally, removes a suffix from the result.
*
* @param path - The path to get the basename from.
* @param [suffix] - An optional suffix to remove from the basename.
* @returns The basename of the path.
*/
function basename(path, suffix) {
const separator = '/';
const index = path.lastIndexOf(separator);
let str = path.slice(index + 1);
if (str) {
const querySeparator = str.lastIndexOf('?');
if (querySeparator !== -1) {
str = str.slice(0, querySeparator);
}
}
if (suffix) {
return str.replace(new RegExp(suffix + '$'), '');
}
return str;
}
/**
* Convert a multi-dimensional array to a query string.
* @param array The multi-dimensional array to convert.
* @param field The field name to use in the query string.
* @returns The generated query string.
*/
function arrayToQueryString(array, field) {
let queryString = '';
function buildQueryString(arr, prefix) {
arr.forEach((element, index) => {
if (Array.isArray(element)) {
buildQueryString(element, `${prefix}${encodeURIComponent(`[${index}]`)}`);
}
else if (isObject(element)) {
for (const key in element) {
if (hasOwn(element, key)) {
queryString += `${prefix}${encodeURIComponent(`[${index}]`)}.${encodeURIComponent(key)}=${encodeURIComponent(String(Reflect.get(element, key)))}&`;
}
}
}
else {
queryString += `${prefix}${encodeURIComponent(`[${index}]`)}=${encodeURIComponent(String(element))}&`;
}
});
}
buildQueryString(array, field);
// Remove the trailing '&' if present
queryString = queryString.slice(0, -1);
return queryString;
}
async function executeConcurrency(tasks, maxConcurrency) {
if (isUndef(maxConcurrency)) {
console.warn('maxConcurrency is undefined');
return null;
}
const ret = [];
const excluding = [];
for (let i = 0; i < tasks.length; i++) {
const res = tasks[i]();
ret.push(res);
if (maxConcurrency < tasks.length) {
const p = res.then(() => excluding.splice(excluding.indexOf(p), 1));
excluding.push(p);
if (excluding.length >= maxConcurrency) {
await Promise.race(excluding);
}
}
}
return Promise.all(ret);
}
/**
* Invokes a queue.
* @param {Array.<function(...any): any>} taskArray - An array of tasks to be executed.
* @returns {Promise<void>} - A promise that resolves when all tasks are completed.
*/
function executeQueue(taskArray) {
const taskQueue = taskArray.slice();
let index = 0;
return new Promise((resolve) => {
const loopFunc = () => {
if (index >= taskQueue.length) {
resolve();
return;
}
const fn = taskQueue[index++];
fn &&
Promise.resolve(fn?.()).finally(() => {
loopFunc();
});
};
loopFunc();
});
}
const definePrams = (params, index) => {
if (index === 0 && Array.isArray(params)) {
return params;
}
return [params];
};
/**
* Takes a series of functions and returns a new function that runs these functions in sequence.
* If a function returns a Promise, the next function is called with the resolved value.
*
* @param fns - The functions to pipe.
* @returns A new function that takes any number of arguments and pipes them through `fns`.
*/
function pipe(...fns) {
return (...args) => {
if (fns.length === 0)
return args[0];
return fns.reduce((arg, fn, index) => {
if (isPromise(arg)) {
return arg.then((res) => {
return fn(...definePrams(res, index));
});
}
return fn(...definePrams(arg, index));
}, args);
};
}
/**
* Takes a series of functions and returns a new function that runs these functions in reverse sequence.
* If a function returns a Promise, the next function is called with the resolved value.
*
* @param fns - The functions to compose.
* @returns A new function that takes any number of arguments and composes them through `fns`.
*/
function compose(...fns) {
return pipe(...fns.reverse());
}
/**
* Executes a given function repeatedly at a specified interval using setTimeout and clearTimeout.
*
* @param func - The function to be executed.
* @param delay - The interval (in milliseconds) at which the function should be executed.
* @returns A function that, when called, clears the interval and stops the execution of the given function.
*/
function setintervalByTimeout(func, delay) {
let timer = null;
let cancelTimer = null;
const fn = function () {
timer = setTimeout(async () => {
const res = func();
if (isPromise(res)) {
await res;
if (cancelTimer && cancelTimer === timer) {
return;
}
}
fn();
}, delay);
};
const clearInterval = () => {
if (timer) {
clearTimeout(timer);
cancelTimer = timer;
}
};
fn();
return clearInterval;
}
const setIntervalByTimeout = setintervalByTimeout;
const HTTP_STATUS = {
CONTINUE: 100,
SWITCHING_PROTOCOLS: 101,
PROCESSING: 102,
EARLYHINTS: 103,
OK: 200,
CREATED: 201,
ACCEPTED: 202,
NON_AUTHORITATIVE_INFORMATION: 203,
NO_CONTENT: 204,
RESET_CONTENT: 205,
PARTIAL_CONTENT: 206,
AMBIGUOUS: 300,
MOVED_PERMANENTLY: 301,
FOUND: 302,
SEE_OTHER: 303,
NOT_MODIFIED: 304,
TEMPORARY_REDIRECT: 307,
PERMANENT_REDIRECT: 308,
BAD_REQUEST: 400,
UNAUTHORIZED: 401,
PAYMENT_REQUIRED: 402,
FORBIDDEN: 403,
NOT_FOUND: 404,
METHOD_NOT_ALLOWED: 405,
NOT_ACCEPTABLE: 406,
PROXY_AUTHENTICATION_REQUIRED: 407,
REQUEST_TIMEOUT: 408,
CONFLICT: 409,
GONE: 410,
LENGTH_REQUIRED: 411,
PRECONDITION_FAILED: 412,
PAYLOAD_TOO_LARGE: 413,
URI_TOO_LONG: 414,
UNSUPPORTED_MEDIA_TYPE: 415,
REQUESTED_RANGE_NOT_SATISFIABLE: 416,
EXPECTATION_FAILED: 417,
I_AM_A_TEAPOT: 418,
MISDIRECTED: 421,
UNPROCESSABLE_ENTITY: 422,
FAILED_DEPENDENCY: 424,
PRECONDITION_REQUIRED: 428,
TOO_MANY_REQUESTS: 429,
INTERNAL_SERVER_ERROR: 500,
NOT_IMPLEMENTED: 501,
BAD_GATEWAY: 502,
SERVICE_UNAVAILABLE: 503,
GATEWAY_TIMEOUT: 504,
HTTP_VERSION_NOT_SUPPORTED: 505
};
const REQUEST_METHOD = {
GET: 'GET',
POST: 'POST',
PUT: 'PUT',
DELETE: 'DELETE',
PATCH: 'PATCH',
ALL: 'ALL',
OPTIONS: 'OPTIONS',
HEAD: 'HEAD',
SEARCH: 'SEARCH'
};
const MIME_TYPES = {
TXT: 'text/plain',
HTML: 'text/html',
HTM: 'text/html',
CSS: 'text/css',
CSV: 'text/csv',
XML: 'application/xml',
JSON: 'application/json',
JAVASCRIPT: 'application/javascript',
PNG: 'image/png',
JPG: 'image/jpeg',
JPEG: 'image/jpeg',
GIF: 'image/gif',
BMP: 'image/bmp',
WEBP: 'image/webp',
SVG: 'image/svg+xml',
ICO: 'image/vnd.microsoft.icon',
MP3: 'audio/mpeg',
WAV: 'audio/wav',
OGG: 'audio/ogg',
M4A: 'audio/mp4',
FLAC: 'audio/flac',
MP4: 'video/mp4',
AVI: 'video/x-msvideo',
MOV: 'video/quicktime',
WMV: 'video/x-ms-wmv',
FLV: 'video/x-flv',
WEBM: 'video/webm',
MKV: 'video/x-matroska',
ZIP: 'application/zip',
RAR: 'application/vnd.rar',
'7Z': 'application/x-7z-compressed',
TAR: 'application/x-tar',
GZ: 'application/gzip',
BZ2: 'application/x-bzip2',
PDF: 'application/pdf',
DOC: 'application/msword',
DOT: 'application/msword',
DOCX: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
DOTX: 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
XLS: 'application/vnd.ms-excel',
XLT: 'application/vnd.ms-excel',
XLSX: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
XLSM: 'application/vnd.ms-excel.sheet.macroEnabled.12',
PPT: 'application/vnd.ms-powerpoint',
POT: 'application/vnd.ms-powerpoint',
PPTX: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
POTX: 'application/vnd.openxmlformats-officedocument.presentationml.template',
PPSX: 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
EXE: 'application/vnd.microsoft.portable-executable',
DLL: 'application/vnd.microsoft.portable-executable',
MSI: 'application/x-msdownload',
BAT: 'application/x-msdownload',
WOFF: 'font/woff',
WOFF2: 'font/woff2',
TTF: 'font/ttf',
OTF: 'font/otf',
EOT: 'application/vnd.ms-fontobject',
JSONLD: 'application/ld+json',
MAP: 'application/json',
WASM: 'application/wasm',
TS: 'video/mp2t',
MPD: 'application/dash+xml',
M3U8: 'application/vnd.apple.mpegurl',
TORRENT: 'application/x-bittorrent',
SWF: 'application/x-shockwave-flash',
EPUB: 'application/epub+zip',
APK: 'application/vnd.android.package-archive',
DMG: 'application/x-apple-diskimage',
EML: 'message/rfc822',
MSG: 'application/vnd.ms-outlook',
DWG: 'application/acad',
DXF: 'application/vnd.dxf',
OBJ: 'application/octet-stream',
STL: 'application/sla',
PY: 'text/x-python',
JAVA: 'text/x-java-source',
C: 'text/x-csrc',
CPP: 'text/x-c++src',
CS: 'text/plain',
RB: 'application/x-ruby',
GO: 'text/plain',
PHP: 'application/x-httpd-php',
SWIFT: 'text/x-swift',
KT: 'text/plain',
RTF: 'application/rtf',
ALZ: 'application/x-alz',
'7ZIP': 'application/x-7z-compressed'
};
const LOG_LEVELS = {
START: -2,
SUCCESS: -1,
ERROR: 0,
WARN: 1,
INFO: 2,
DEBUG: 3,
TRACE: 4
};
const ANSI_COLORS = {
[LOG_LEVELS.START]: '\x1b[32m', // green
[LOG_LEVELS.SUCCESS]: '\x1b[32m', // green
[LOG_LEVELS.ERROR]: '\x1b[31m', // red
[LOG_LEVELS.WARN]: '\x1b[33m', // yellow
[LOG_LEVELS.INFO]: '\x1b[32m', // green
[LOG_LEVELS.DEBUG]: '\x1b[34m', // blue
[LOG_LEVELS.TRACE]: '\x1b[35m' // purple
};
const LOG_LEVEL_NAMES = {
[LOG_LEVELS.START]: 'success',
[LOG_LEVELS.SUCCESS]: 'success',
[LOG_LEVELS.ERROR]: 'error',
[LOG_LEVELS.WARN]: 'warn',
[LOG_LEVELS.INFO]: 'info',
[LOG_LEVELS.DEBUG]: 'debug',
[LOG_LEVELS.TRACE]: 'trace'
};
function isUnicodeSupported() {
// @ts-expect-error: expect error
return typeof window === 'undefined';
}
const unicode = isUnicodeSupported();
const s = (c, fallback) => (unicode ? c : fallback);
const TYPE_ICONS = {
error: s('✖', '×'),
warn: s('⚠', '‼'),
info: s('ℹ', 'i'),
debug: s('⚙', 'D'),
trace: s('→', '→'),
start: s('◐', 'o'),
success: s('✔', '√'),
log: ''
};
class Logger {
level;
constructor(level = LOG_LEVELS.TRACE) {
this.level = level;
}
setLevel(level) {
this.level = level;
}
log(level, ...message) {
if (level > this.level) {
return;
}
const color = ANSI_COLORS[level] || ANSI_COLORS[LOG_LEVELS.INFO];
const levelName = LOG_LEVEL_NAMES[level];
const icon = Reflect.get(TYPE_ICONS, levelName) || '';
const timestamp = new Date().toLocaleString();
const logMethod = level === LOG_LEVELS.ERROR ? 'error' : 'log';
console[logMethod](`${color}${icon}\x1b[0m [${levelName}] (${timestamp}) :`, ...message);
}
error(...message) {
this.log(LOG_LEVELS.ERROR, ...message);
}
warn(...message) {
this.log(LOG_LEVELS.WARN, ...message);
}
info(...message) {
this.log(LOG_LEVELS.INFO, ...message);
}
debug(...message) {
this.log(LOG_LEVELS.DEBUG, ...message);
}
trace(...message) {
this.log(LOG_LEVELS.TRACE, ...message);
}
start(...message) {
this.log(LOG_LEVELS.START, ...message);
}
success(...message) {
this.log(LOG_LEVELS.SUCCESS, ...message);
}
}
/**
* Formats an error object into a string representation.
* @param error - The error to format. It can be an `Error` instance, a string, or another object.
* @param [defaultErrorString=''] - The default error message if the error cannot be formatted.
* @param [opts={}] - Additional options.
* @param [opts.errorLimit=8] - The maximum number of stack trace lines to include.
* @returns The formatted error message.
*/
function formatErrorToString(error, defaultErrorString = '', opts = {
errorLimit: 8
}) {
if (error instanceof Error) {
Error.captureStackTrace(error, formatErrorToString);
const stackLines = error.stack?.split('\n').slice(0, opts.errorLimit) || [];
return stackLines.join('\n');
}
if (isStr(error))
return error;
if (isObject(error) && 'toString' in error && isFn(error.toString))
return error.toString();
return defaultErrorString;
}
export { HTTP_STATUS, Logger, MIME_TYPES, REQUEST_METHOD, _toString, arrayToQueryString, basename, capitalize, compose, convertParamsRouterToRegExp, defineDebounceFn, defineOnceFn, defineSinglePromiseFn, defineThrottleFn, executeConcurrency, executeQueue, formatDateByArray, formatDateByTimeStamp, formatDateTimeByString, formatErrorToString, getCurrentTimeISOString, hasOwn, isBool, isEffectiveNumber, isFalsy, isFn, isNil, isNull, isNumber, isObject, isPrimitive, isPromise, isPropertyKey, isStr, isSymbol, isUndef, isValidArray, isValidDate, mulSplit, noop, objectToQueryString, parseKey, pipe, queryStringToObject, random, setIntervalByTimeout, setintervalByTimeout, sleep, unCapitalize, underlineToHump };