snoby-utils
Version:
A javascrpt utils.
1 lines • 23.7 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","sources":["../src/install.ts","../src/isType.ts","../src/data.ts","../src/enum/index.ts","../src/time.ts","../src/file.ts","../src/common.ts"],"sourcesContent":["// bem\r\n// block\r\n// element\r\n// modifier\r\n// state isCheck 动态添加\r\n\r\n// const bem = createNameSpace('icon')\r\n\r\nexport function createNameSpace(name: string) {\r\n const prefixName = `sno-${name}`;\r\n return createBEM(prefixName);\r\n}\r\n\r\nfunction _bem(prefixName: string, blockSuffix: string, element: string, modifier: string) {\r\n if (blockSuffix) {\r\n prefixName += `-${blockSuffix}`;\r\n }\r\n if (element) {\r\n prefixName += `__${element}`;\r\n }\r\n if (modifier) {\r\n prefixName += `--${modifier}`;\r\n }\r\n return prefixName;\r\n}\r\n\r\nfunction createBEM(prefixName: string) {\r\n const b = (blockSuffix: string) => _bem(prefixName, blockSuffix, '', '');\r\n const e = (element: string) => _bem(prefixName, '', element, '');\r\n const m = (modifier: string) => _bem(prefixName, '', '', modifier);\r\n\r\n const be = (blockSuffix: string, element: string) => _bem(prefixName, blockSuffix, element, '');\r\n const bm = (blockSuffix: string, modifier: string) => _bem(prefixName, blockSuffix, '', modifier);\r\n const em = (element: string, modifier: string) => _bem(prefixName, '', element, modifier);\r\n\r\n const bem = (blockSuffix: string, element: string, modifier: string) =>\r\n _bem(prefixName, blockSuffix, element, modifier);\r\n\r\n const is = (name: string, state: string) => `is-${state}`;\r\n\r\n return {\r\n b,\r\n e,\r\n m,\r\n be,\r\n bm,\r\n bem,\r\n em,\r\n is,\r\n };\r\n}\r\n","/**\n * @description: 判断值是否未某个类型\n */\nexport function is(val: unknown, type: string) {\n return Object.prototype.toString.call(val) === `[object ${type}]`;\n}\n\n/**\n * @description: 是否为函数\n */\nexport function isFunction<T = Function>(val: unknown): val is T {\n return is(val, 'Function');\n}\n\n/**\n * @description: 是否已定义\n */\nexport const isDef = <T = unknown>(val?: T): val is T => {\n return typeof val !== 'undefined';\n};\n\n/**\n * @description: 是否未定义\n */\nexport const isUnDef = <T = unknown>(val?: T): val is T => {\n return !isDef(val);\n};\n\n/**\n * @description: 是否为对象\n */\nexport const isObject = (val: any): val is Record<any, any> => {\n return val !== null && is(val, 'Object');\n};\n\n/**\n * @description: 是否为时间\n */\nexport function isDate(val: unknown): val is Date {\n return is(val, 'Date');\n}\n\n/**\n * @description: 是否为数值\n */\nexport function isNumber(val: unknown): val is number {\n return is(val, 'Number');\n}\n\n/**\n * @description: 是否为AsyncFunction\n */\nexport function isAsyncFunction<T = any>(val: unknown): val is Promise<T> {\n return is(val, 'AsyncFunction');\n}\n\n/**\n * @description: 是否为promise\n */\nexport function isPromise<T = any>(val: unknown): val is Promise<T> {\n return is(val, 'Promise') && isObject(val) && isFunction(val.then) && isFunction(val.catch);\n}\n\n/**\n * @description: 是否为字符串\n */\nexport function isString(val: unknown): val is string {\n return is(val, 'String');\n}\n\n/**\n * @description: 是否为boolean类型\n */\nexport function isBoolean(val: unknown): val is boolean {\n return is(val, 'Boolean');\n}\n\n/**\n * @description: 是否为数组\n */\nexport function isArray(val: any): val is Array<any> {\n return val && Array.isArray(val);\n}\n\n/**\n * @description: 是否客户端\n */\nexport const isClient = () => {\n return typeof window !== 'undefined';\n};\n\n/**\n * @description: 是否为浏览器\n */\nexport const isWindow = (val: any): val is Window => {\n return typeof window !== 'undefined' && is(val, 'Window');\n};\n\n/**\n * @description: 是否为 element 元素\n */\nexport const isElement = (val: unknown): val is Element => {\n return isObject(val) && !!val.tagName;\n};\n\n/**\n * @description: 是否为 null\n */\nexport function isNull(val: unknown): val is null {\n return val === null;\n}\n\n/**\n * @description: 是否为 null || undefined\n */\nexport function isNullOrUnDef(val: unknown): val is null | undefined {\n return isUnDef(val) || isNull(val);\n}\n\n/**\n * @description: 是否为 16 进制颜色\n */\nexport const isHexColor = (str: string) => {\n return /^#?([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/.test(str);\n};\n\n/** 判断值是否为undefined */\nexport const isUndefined = (value: undefined) => {\n return is(value, 'Undefined');\n};\n","import { isObject } from './isType';\n\n/**\n * 合并对象,并返回新对象\n * @param sourceData 源对象\n * @param target 目标合并对象\n * @param keyTransfor 对象属性转换规则\n * @returns 合并后的新对象\n */\nexport const transformKeysAndMerge = (\n sourceData: Record<string, any>,\n target: Record<string, any>,\n keyTransfor = (key: string) => key.toUpperCase()\n) => {\n const newProperties: Record<string, any> = {};\n for (let key in sourceData) {\n if (Object.prototype.hasOwnProperty.call(sourceData, key)) {\n newProperties[keyTransfor(key)] = sourceData[key];\n }\n }\n\n return {\n ...target,\n ...newProperties,\n };\n};\n\n/**\n * 将传入对象的所有键名提取为一个字符串数组或数字数组\n *\n * @param obj 需要提取键名的对象\n * @returns 如果传入的对象是对象类型,则返回该对象的所有键名组成的数组;否则返回一个空数组\n */\nexport function objectKeys(obj: Record<string, any>): string[] | number[] {\n return isObject(obj) ? Object.keys(obj) : [];\n}\n\n/**\n * 将对象中的值转换为字符串数组或数字数组\n *\n * @param obj 要转换的对象\n * @returns 如果传入的对象非空且是对象类型,则返回其值的数组(字符串或数字数组);否则返回空数组\n */\nexport function objectValues(obj: Record<string, any>): string[] | number[] {\n return isObject(obj) ? Object.values(obj) : [];\n}\n","export const SIMPLE_DATE_FORMAT = \"YYYY-MM-DD\";\nexport const FULL_DATE_FORMAT = \"YYYY-MM-DD HH:mm\";\nexport const COMPACT_DATE_FORMAT = \"MM-DD HH:mm\";\n","import dayjs, { Dayjs } from 'dayjs';\nimport { FULL_DATE_FORMAT } from './enum';\n\n/**\n * 判断是00:00\n * @param date 需要检验的时间\n * @returns 是否是 00:00\n *\n *\n * @example\n * ```ts\n * is0000(dayjs('2025-01-01T00:00')) // true\n * is0000(dayjs('2025-01-01T08:00')) // false\n * ```\n */\nexport function is0000(date: string | Date | Dayjs): boolean {\n const d = dayjs(date);\n if (!d.isValid()) return false;\n return d.hour() === 0 && d.minute() === 0;\n}\n\n/**\n * 判断是24:00\n * @param date 需要检验的时间\n * @returns 是否是 24:00\n *\n *\n * @example\n * ```ts\n * is2400(dayjs('2025-01-01T00:00')) // false\n * is2400(dayjs('2025-01-01T24:00')) // true\n * ```\n */\nexport function is2400(date: string | Date | Dayjs): boolean {\n const d = dayjs(date);\n if (!d.isValid()) return false;\n return d.hour() === 24 && d.minute() === 0;\n}\n\n/**\n * 将输入的时间字符串对齐到最近的指定分钟间隔\n * @param inputTime - 时间字符串,例如 '2025-06-29T23:59:00'\n * @param interval - 分钟间隔,必须是 [5, 10, 15, 30, 60] 中的一个\n * @returns 格式化后的时间字符串,如 '2025-06-30 00:15'\n */\nexport function mapToNearest15MinInterval(dateTime: string, interval: number = 15): string {\n const time = dayjs(dateTime);\n\n if (!time.isValid()) {\n throw new Error('Invalid date format');\n }\n\n // 四舍五入到最近的 interval 倍数\n const timestamp = time.unix(); // 获取秒级时间戳\n const secondsPerInterval = interval * 60;\n const roundedTimestamp = Math.round(timestamp / secondsPerInterval) * secondsPerInterval;\n const mappedDateTime = dayjs.unix(roundedTimestamp);\n // 构造新时间:从当天 00:00 开始加 roundedMinutes 分钟\n\n // 返回格式化后的字符串\n return mappedDateTime.format(FULL_DATE_FORMAT);\n}\n\n/**\n * 生成指定数量的小时字符串数组(默认 24 小时)\n *\n * @param count - 要生成的小时数,默认 24\n * @returns 小时字符串数组,如 [\"00\", \"01\", ..., \"23\"]\n */\nexport function generateHourOptions(count: number = 24): string[] {\n return Array.from({ length: count }, (_, i) => String(i).padStart(2, '0'));\n}\n\n/**\n * 生成带分钟粒度的时间选项(如每 30 分钟一个)\n * @param totalMinutesInDay - 分钟总数,默认 24 * 60\n * @param step - 分钟步长,默认 15(即每15分钟一个)\n * @returns 时间字符串数组,如 [\"00:00\", \"00:30\", \"01:00\", ...]\n */\nexport function generateTimeOptionsWithStep(\n totalMinutesInDay: number = 24 * 60,\n step: number = 15\n): string[] {\n const result: string[] = [];\n for (let i = 0; i < totalMinutesInDay; i += step) {\n const hour = Math.floor(i / 60);\n const minute = i % 60;\n result.push(`${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}`);\n }\n return result;\n}\n\n/**\n * 计算两个时间戳之间相差的自然日,每满 24 小时就算一天\n * @param timestamp1 时间戳1\n * @param timestamp2 时间戳2\n * @returns\n */\nexport function dayDifference(\n timestamp1: number | Date | Dayjs | string,\n timestamp2: number | Date | Dayjs | string\n): number {\n const timeDifference = Math.abs(dayjs(timestamp1).valueOf() - dayjs(timestamp2).valueOf());\n return Math.floor(timeDifference / (1000 * 60 * 60 * 24));\n}\n\n/**\n * 计算两个日期时间之间的持续时间\n *\n * @param startDateTime 开始日期时间,格式为 时间戳、字符串、Date类型、Dayjs类型\n * @param endDateTime 结束日期时间,格式为 时间戳、字符串、Date类型、Dayjs类型\n * @returns 返回一个包含小时和分钟的对象,表示两个日期时间之间的持续时间\n */\n\nexport function calcDurationDate(\n startDateTime: number | Date | Dayjs | string,\n endDateTime: number | Date | Dayjs | string\n): { hours: number; minutes: number } {\n const MILLISECONDS_PER_HOUR = 1000 * 60 * 60;\n const MILLISECONDS_PER_MINUTE = 1000 * 60;\n\n // 将日期时间字符串转换为 Date 对象\n const startDate = dayjs(startDateTime);\n const endDate = dayjs(endDateTime);\n\n // 非法时间,抛出错误\n if (startDate.isValid() || endDate.isValid()) {\n throw new Error('Invalid date format');\n }\n\n const timeDifference = Math.abs(endDate.valueOf() - startDate.valueOf());\n const hours = Math.floor(timeDifference / MILLISECONDS_PER_HOUR);\n const minutes = Math.floor((timeDifference % MILLISECONDS_PER_HOUR) / MILLISECONDS_PER_MINUTE);\n return { hours, minutes };\n}\n\n// /**\n// * 根据传入的时间间隔,生成从 00:00 到 24:00 的时间数组\n// * @param intervalMinutes\n// * @param {number} [intervalMinutes=15] - 时间间隔(分钟),默认为 15\n// * @returns {string[]} 返回格式为 \"HH:MM\" 的时间字符串数组,包含从 00:00 到 24:00 的间隔时间点\n// * @example\n// * timeRangeForm24Hour(15); // [\"00:00\", \"00:15\", \"00:30\", ..., \"23:45\", \"24:00\"]\n// * timeRangeForm24Hour(30); // [\"00:00\", \"00:30\", \"01:00\", ..., \"23:30\", \"24:00\"]\n// * timeRangeForm24Hour(60); // [\"00:00\", \"01:00\", ..., \"23:00\", \"24:00\"]\n// */\n// export function timeRangeForm24Hour(intervalMinutes: number = 15): string[] {\n// // 参数校验\n// if (intervalMinutes <= 0 || intervalMinutes > 60 || 60 % intervalMinutes !== 0) {\n// throw new Error(\n// 'intervalMinutes must be a positive divisor of 60 (e.g., 1, 5, 10, 15, 20, 30, 60)'\n// );\n// }\n// const timeArray: string[] = [];\n// const HOURS_IN_DAY = 24;\n// const MINUTES_IN_HOUR = 60;\n// for (let hour = 0; hour < HOURS_IN_DAY; hour++) {\n// for (let minute = 0; minute < MINUTES_IN_HOUR; minute += intervalMinutes) {\n// const formattedHour = String(hour).padStart(2, '0');\n// const formattedMinute = String(minute).padStart(2, '0');\n// timeArray.push(`${formattedHour}:${formattedMinute}`);\n// }\n// }\n// // 添加 24:00 作为结束时间\n// timeArray.push('24:00');\n\n// return timeArray;\n// }\n\n// export function testFunction() {\n// return ['testFunction'];\n// }\n","/**\n * 5+原生下载(适用于Android/HarmonyOS)\n */\nexport function nativeDownload(url: string, fileName: string) {\n const dtask =\n plus.downloader &&\n plus.downloader.createDownload(\n url,\n { filename: `download/${fileName}` }, // 保存到downloads目录\n (d: any, status: number) => {\n if (status === 200) {\n plus.nativeUI.toast(`文件已保存到: ${d.filename}`);\n } else {\n plus.nativeUI.alert(`下载失败,错误代码: ${status}`);\n // 失败后尝试使用web下载\n webDownload(url, fileName);\n }\n }\n );\n dtask.start();\n}\n\n/**\n * 普通web下载(a标签方式)\n */\nexport function webDownload(url: string, fileName: string = '') {\n const link = document.createElement('a');\n try {\n link.href = url;\n link.download = fileName;\n link.style.display = 'none';\n document.body.appendChild(link);\n link.click();\n\n setTimeout(() => {\n document.body.removeChild(link);\n if (url.startsWith('blob:')) {\n window.URL.revokeObjectURL(url);\n }\n }, 100);\n } catch (error) {\n // 如果a标签方式也失败,提示用户\n alert('文件下载失败,请检查网络连接或尝试其他方式下载');\n }\n}\n\n/**\n *\n * @param headers 响应头\n * @param fileType 文件后缀名 默认xlsx\n * @returns\n */\nexport function findFileNameByContentDisposition(\n headers: { [x: string]: any; get: (arg0: string) => any },\n fileType: string = 'xlsx'\n) {\n // 从响应头获取文件名\n const contentDisposition = headers['content-disposition'];\n let filename = `${new Date().valueOf()}.${fileType}`; // 默认文件名\n\n if (contentDisposition) {\n const filenameMatch = contentDisposition.match(/filename[^;=\\n]*=((['\"]).*?\\2|[^;\\n]*)/);\n if (filenameMatch && filenameMatch[1]) {\n filename = filenameMatch[1].replace(/['\"]/g, '');\n // 处理UTF-8编码的文件名 (RFC 5987)\n if (filename.startsWith(\"UTF-8''\")) {\n filename = decodeURIComponent(filename.replace(\"UTF-8''\", ''));\n }\n }\n }\n\n return decodeURIComponent(filename);\n}\n","/**\n * 从URL中获取指定参数的值\n * @param url - 要解析的URL字符串\n * @param name - 要获取的参数名\n * @returns 参数值字符串,如果不存在则返回空字符串\n */\nexport const getParam = (url: string, name: string): string => {\n if (!url || !name) return '';\n\n const reg = new RegExp(`(^|\\\\?|&)${name}=([^&]*)(&|$)`);\n const match = url.match(reg);\n\n return match ? decodeURIComponent(match[2]) : '';\n};\n\n/**\n * @description 使用递归扁平化嵌套数据\n * @param {Array} list 列表\n * @param {Array} childrenField 嵌套数据的字段\n * @returns {Array}\n */\nexport function getFlatMenuList(\n list: Record<string, any>[],\n childrenField: string = 'children'\n): Record<string, any>[] {\n let newList: Record<string, any>[] = JSON.parse(JSON.stringify(list));\n return newList.flatMap((item) => [\n item,\n ...(item[childrenField] ? getFlatMenuList(item.children) : []),\n ]);\n}\n\n/**\n * 根据传入的时间间隔,生成从 00:00 到 24:00 的时间数组\n * @param intervalMinutes\n * @param {number} [intervalMinutes=15] - 时间间隔(分钟),默认为 15\n * @returns {string[]} 返回格式为 \"HH:MM\" 的时间字符串数组,包含从 00:00 到 24:00 的间隔时间点\n * @example\n * timeRangeForm24Hour(15); // [\"00:00\", \"00:15\", \"00:30\", ..., \"23:45\", \"24:00\"]\n * timeRangeForm24Hour(30); // [\"00:00\", \"00:30\", \"01:00\", ..., \"23:30\", \"24:00\"]\n * timeRangeForm24Hour(60); // [\"00:00\", \"01:00\", ..., \"23:00\", \"24:00\"]\n */\nexport function timeRangeForm24Hour(intervalMinutes: number = 15): string[] {\n // 参数校验\n if (intervalMinutes <= 0 || intervalMinutes > 60 || 60 % intervalMinutes !== 0) {\n throw new Error(\n 'intervalMinutes must be a positive divisor of 60 (e.g., 1, 5, 10, 15, 20, 30, 60)'\n );\n }\n const timeArray: string[] = [];\n const HOURS_IN_DAY = 24;\n const MINUTES_IN_HOUR = 60;\n for (let hour = 0; hour < HOURS_IN_DAY; hour++) {\n for (let minute = 0; minute < MINUTES_IN_HOUR; minute += intervalMinutes) {\n const formattedHour = String(hour).padStart(2, '0');\n const formattedMinute = String(minute).padStart(2, '0');\n timeArray.push(`${formattedHour}:${formattedMinute}`);\n }\n }\n // 添加 24:00 作为结束时间\n timeArray.push('24:00');\n\n return timeArray;\n}\n\nexport function testFunction() {\n return ['testFunction'];\n}\n"],"names":["createNameSpace","name","prefixName","createBEM","_bem","blockSuffix","element","modifier","state","is","val","type","isFunction","isDef","isUnDef","isObject","isDate","isNumber","isAsyncFunction","isPromise","isString","isBoolean","isArray","isClient","isWindow","isElement","isNull","isNullOrUnDef","isHexColor","str","isUndefined","value","transformKeysAndMerge","sourceData","target","keyTransfor","key","newProperties","objectKeys","obj","objectValues","FULL_DATE_FORMAT","is0000","date","d","dayjs","is2400","mapToNearest15MinInterval","dateTime","interval","time","timestamp","secondsPerInterval","roundedTimestamp","generateHourOptions","count","_","i","generateTimeOptionsWithStep","totalMinutesInDay","step","result","hour","minute","dayDifference","timestamp1","timestamp2","timeDifference","calcDurationDate","startDateTime","endDateTime","startDate","endDate","hours","minutes","nativeDownload","url","fileName","status","webDownload","link","findFileNameByContentDisposition","headers","fileType","contentDisposition","filename","filenameMatch","getParam","reg","match","getFlatMenuList","list","childrenField","item","timeRangeForm24Hour","intervalMinutes","timeArray","HOURS_IN_DAY","MINUTES_IN_HOUR","formattedHour","formattedMinute","testFunction"],"mappings":"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"}