snoby-utils
Version:
A javascrpt utils.
1 lines • 24 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","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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"}