npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@infly/ts-libs

v0.1.12

Published

跨技术栈复用的 TypeScript 工具函数库,零框架依赖,纯运行时能力。 从 `@infly/libs` 的巨型 `Uts.js`(7271行)拆分而来,原有 200+ 方法的 JS 工具类迁移为类型安全的 TS 模块。

Readme

@infly/ts-libs — TypeScript 工具库

跨技术栈复用的 TypeScript 工具函数库,零框架依赖,纯运行时能力。
@infly/libs 的巨型 Uts.js(7271行)拆分而来,原有 200+ 方法的 JS 工具类迁移为类型安全的 TS 模块。

npm install @infly/ts-libs
import {
  isFunction,
  pluck,
  filterMoney,
  formatDate,
  validateIDCard,
  exportFile
} from "@infly/ts-libs";
// 浏览器依赖函数通过 sub-path 导入
import { getCookie, storage } from "@infly/ts-libs/browser/storage";

check/is — 类型检查

| 函数 | 说明 | 示例 | |------|------|------| | isTrue(value) | 判断是否为真 | isTrue('a') → true | | isFunction(value) | 是否为函数 | isFunction(()=>{}) → true | | isDefined(value) | 是否已定义(非 undefined) | isDefined(null) → true | | isUndefined(value) | 是否为 undefined | isUndefined(void 0) → true | | isBoolean(value) | 是否为布尔类型 | isBoolean(true) → true | | isObject(value) | 是否为对象(含数组/Date/RegExp) | isObject({}) → true | | isArray(value) | 是否为数组 | isArray([]) → true | | isPureObject(value) | 是否为纯对象(排除数组/Date等) | isPureObject({a:1}) → true | | isRegExp(value) | 是否为正则表达式 | isRegExp(/a/) → true | | isNumber(value) | 是否为 Number(排除 NaN) | isNumber(123) → true | | isNull(value) | 是否为 null | isNull(null) → true | | isString(value) | 是否为字符串 | isString('abc') → true | | isDate(value) | 是否为 Date 对象 | isDate(new Date()) → true | | isError(value) | 是否为 Error 对象 | isError(new Error()) → true | | isPresentValue(value) | 是否有实际值(排除 undefined/null/空串) | isPresentValue(0) → true | | isNaNValue(value) | 是否为 NaN | isNaNValue(NaN) → true | | notEmptyString(value) | 是否为非空字符串 | notEmptyString('a') → true | | notEmptyArray(value) | 是否为非空数组 | notEmptyArray([1]) → true | | notEmptyObject(value) | 是否为非空纯对象 | notEmptyObject({a:1}) → true |

string — 字符串处理

| 函数 | 说明 | 示例 | |------|------|------| | safeRegString(value) | 转义正则特殊字符 | safeRegString('a.b?') → 'a\\.b\\?' | | changeDangerousString(value) | 转义危险正则字符 | 用于构建 RegExp | | startWith(str, value) | 判断字符串是否以指定值开头 | startWith('帮助中心','帮助') → true | | endWith(str, value) | 判断字符串是否以指定值结尾 | endWith('帮助中心','中心') → true | | toLowerCase(str) | 转小写 | toLowerCase('VALUE') → 'value' | | toUpperCase(str) | 转大写 | toUpperCase('value') → 'VALUE' | | parse(value) | 安全 JSON 解析,失败返回 {$isError} | parse('{"a":1}') → {a:1} | | toJSON(value) | 字符串转 JSON(兼容非字符串) | toJSON('{"a":1}') → {a:1} | | match(rawString, regExp, resultPs?) | 正则匹配字符串 | match('test123',/\d+/) → '123' | | notContainReg(value, mode?) | 生成"不包含"的正则 | notContainReg('<div>') → /^((?!<div>).)+$/ | | getPartStringBySymbolIndex(str, sym, start?, end?) | 按分隔符截取字符串片段 | getPartStringBySymbolIndex('a/b/c','/',1,2) → 'b' | | safeDateString(str) | 统一日期分隔符为 / | safeDateString('2022-07-22') → '2022/07/22' | | hadEncode(str) | 检查字符串是否已 URL 编码 | hadEncode('%20abc') → true | | ifHadEncode(str) | 检测双重编码 | 先将 % 替换为 %25 后再检测 | | hadWord(str, keyword, symbol?) | 检查按分隔符分割后是否完整包含某值 | hadWord('a,b,c','b',',') → true | | encryptString(str, start, len) | 加密字符串中间部分 | encryptString('13800138000',3,4) → '138****8000' | | reorderString(str) | 反转字符串 | reorderString('abc') → 'cba' |

math — 数学计算

| 函数 | 说明 | 示例 | |------|------|------| | min(x, y) | 取两值中的最小值 | min(10,38) → 10 | | float(value, length, returnNumber?) | 浮点数指定小数位(不四舍五入) | float(23,2) → '23.00' | | parseFloatValue(value) | 从字符串解析浮点数 | parseFloatValue('59.2') → 59.2 | | filterMoney(value, size?) | 金额千分位格式化 | filterMoney(123222123,2) → '123,222,123.00' | | formatMoney(s, type?) | 格式化金额(兼容旧版) | formatMoney('1234.5') → '1,234.50' | | digitUppercase(n) | 阿拉伯数字转中文大写 | digitUppercase(938.13) → '玖佰叁拾捌元壹角叁分' | | exchangeMoneyByUnit(value, unit?, floatCount?) | 金额单位转换 | exchangeMoneyByUnit(100000) → '10.00万' | | getNumberValueByUnit(value, unit) | 获取数值指定位的值 | getNumberValueByUnit(928212,'千') → '8' | | splitMoney(money, intOrFloat?) | 分割整数和小数 | splitMoney(239238.23,1) → '23' | | formatNumUnit(num, dividend?, limit?, text?) | 格式化数值单位 | formatNumUnit(109700,10000,1,'w') → '10.9w' | | generateEmptyArray(len) | 生成空值数组 | generateEmptyArray(5) → [empty×5] |

date — 日期处理

| 函数 | 说明 | 示例 | |------|------|------| | now(dateStr?) | 获取当前时间戳 | now() → 1658389259324 | | daysInMonth(dateStr, symbol?) | 获取月份天数 | daysInMonth('2022-07-22') → 31 | | getWeek(dateStr) | 获取星期值(1-7,周一=1) | getWeek('2022-07-18') → 1 | | getDayStamp(dateStr?, type?) | 获取当天开始/结束时间戳(0=开始 1=结束) | getDayStamp('2022-07-22',1) → 23:59:59.999 | | getNumDayBefore(num?, dateStr?) | N天前零时时间戳 | getNumDayBefore(30,'2022-07-22') → 2022-06-21 00:00 | | getTimeFromSymbol(str) | 占位符时间计算(1y2m3d4h5i6s) | getTimeFromSymbol('1d') → 明天此时 | | getTimeFromMillisecond(ms, labels?, addZero?) | 毫秒转天时分秒 | getTimeFromMillisecond(5400000) → {value:'1小时30分00秒'} | | formatDate(date, format?) | 格式化日期 | formatDate(new Date(),'Y-m-d H:i:s') → '2022-07-19 11:34:15' |

validation — 校验

| 函数 | 说明 | 示例 | |------|------|------| | validateIDCard(id, isStrict?) | 身份证校验(兼容15/18位) | validateIDCard('11010119900307663X') → true | | validatePhoneNumber(phone) | 中国大陆手机号校验 | validatePhoneNumber('13800138000') → true | | isIntPrice(price) | 限制只能输入整数价格 | isIntPrice('12a3') → '123' |

condition — 条件判断

| 函数 | 说明 | 示例 | |------|------|------| | TR(isTrue, trueResult, falseResult) | 三元表达式替代 | TR(true,'a','b') → 'a' | | checkCondition(list, type?) | 检测多条件('or'/'and') | checkCondition([true,false],'or') → true | | or(list) | OR 模式快捷方式 | or([false,true]) → true | | and(list) | AND 模式快捷方式 | and([true,true]) → true |

array — 数组处理

| 函数 | 说明 | 示例 | |------|------|------| | pluck(source, fieldName, acceptRepeat?) | 提取对象数组指定字段值(默认去重) | pluck([{name:'a'},{name:'b'}],'name') → ['a','b'] | | pluckMap(array, keyField, valueField?) | 对象数组转 key-value 映射 | pluckMap([{name:'zs',age:18}],'name','age') → {zs:18} | | uniqueArray(array, processValue?) | 字符串/数字数组去重 | uniqueArray(['a','b','a']) → ['a','b'] | | uniqueObjArray(array) | 对象数组去重(JSON 深度比较) | uniqueObjArray([{a:1},{a:2},{a:1}]) → [{a:1},{a:2}] | | mergeArrayWithoutDuplicate(raw, append, config?) | 合并去重(支持对象数组按 key 去重) | mergeArrayWithoutDuplicate([1,2],[2,3]) → [1,2,3] | | sum(array) | 数字数组求和 | sum([1,2,3]) → 6 | | countTotalFromArray(array, fieldName?) | 对象数组按字段求和 | countTotalFromArray([{a:100},{a:200}],'a') → 300 | | findIndex(source, obj, validate?) | 查找对象在数组中的索引 | 仅搜索对象类型 | | index(source, value, isContainMode?) | 查找字符串/数字在数组中的索引(支持正则) | index([0,1,2,3],2) → 2 | | contain(source, value, isContainMode?, isIgnoreCase?) | 数组或字符串是否包含某值(支持正则) | contain(['a','b'],'b') → true | | findObjByCondition(arr, cond, strict?, returnIndex?, returnBoth?) | 按条件查找对象数组 | 支持严格/非严格模式 | | filterObjByCondition(arr, cond, strict?) | 按条件过滤对象数组 | findObjByCondition 别名 | | filterObjByRegexpCondition(arr, cond, cb?, single?, ignoreCase?) | 正则条件过滤对象数组 | 支持单条件/多条件模式 | | sort(rawArray, options, customCallback?) | 数组排序(修改原数组) | sort(arr, {pty:'a', orderBy:1}) | | reorderByArrayIndex(arr, index, change) | 调整数组中某项位置 | reorderByArrayIndex([0,1,2],1,2) → [0,2,1] | | getSameBetweenArray(checkList, propName?) | 获取多个数组交集 | getSameBetweenArray([[1,2],[2,3],[2,4]]) → [2] | | removeItemFromArray(list, item, isContainMode?) | 从数组删除某项 | 支持值匹配/引用匹配 | | arrayUpdateEachValue(list, config, cb?) | 批量更新数组项的字段 | arrayUpdateEachValue(arr, {key:'sel', value:true}) | | fetchStringArrayToObject(source, defaultValue?) | 字符串数组转对象映射(性能优化用) | fetchStringArrayToObject(['a','b']) → {a:true, b:true} | | generateArray(length, withIndex?) | 生成指定长度数组 | generateArray(3,true) → [0,1,2] | | join(arr, symbol?) | 数组转字符串(默认逗号) | join(['a','b']) → 'a,b' | | convertToArray(value) | 字符串/数组统一转数组(逗号/中文逗号分隔) | convertToArray('a,b,c') → ['a','b','c'] | | loop(arr, cb, currentLoop?) | 简单遍历(通过 currentLoop.break/continue 控制) | | | generatePathByParent(item, idx, parent?, field?) | 为树节点生成索引路径 | item.__path = parent.__path.concat([index]) | | pushArray(rawArr, pushArr, position?) | 数组指定位置插入(改变原数组) | pushArray([1,2],[59],0) → [59,1,2] | | mergeArray(rawArr, valueArray) | 合并到数组末尾(改变原数组) | mergeArray([1,2],[8,9]) → [1,2,8,9] | | unshiftArray(rawArr, valueArray) | 合并到数组开头(改变原数组) | unshiftArray([1,2],[8,9]) → [8,9,1,2] | | concat(rawArr, valueArray) | 合并返回新数组(不改变原数组) | concat([1,2],[3]) → [1,2,3] |

object — 对象处理

| 函数 | 说明 | 示例 | |------|------|------| | getObjectKeys(obj) | 获取对象的键名列表 | getObjectKeys({a:1,b:2}) → ['a','b'] | | DAO(obj, path, value?) | 深度获取/设置嵌套属性(a.b.c) | DAO({a:{b:{c:1}}},'a.b.c') → 1 | | getNestedValue(obj, path) | 通过点号路径获取嵌套值 | getNestedValue({a:{b:'x'}},'a.b') → 'x' | | objectIsEqual(a, b) | 深度相等比较(支持嵌套对象) | objectIsEqual({a:1},{a:1}) → true | | arrayIsEqual(arr1, arr2) | 判断数组是否相等 | arrayIsEqual([1,2],[1,2]) → true | | mergeObjectWithReference(target, source, isOverride?) | 合并对象(修改原对象) | mergeObjectWithReference({a:1},{b:2}) | | extend(target, props) | 扩展对象属性 | extend({a:1},{b:2}) → {a:1,b:2} | | toStr(obj) | 对象转 JSON 字符串 | toStr({a:1}) → '{"a":1}' | | getAutoMatchFromConfig(config) | 数组转为 Filter.autoMatch 对象 | {key:'id', value:'name', list:[...]} | | setListToMap(list, propName) | 数组转 Boolean 映射 | setListToMap([{code:'a'}],'code') → {a:true} | | filterCommaFields(obj, replaceOrigin?) | 深度过滤对象中包含逗号的字段 | 默认修改原对象 | | updateObjectByConfig(obj, config, callback?) | 根据配置更新对象属性 | updateObjectByConfig(obj, {name:'a'}) |


browser/ — 浏览器依赖模块

通过 sub-path 导入:import { xxx } from "@infly/ts-libs/browser/yyy"
这些模块依赖 DOM/Cookie/localStorage/location 等浏览器 API

browser/fileExport — 文件导出流程

downloadFile(blob, filename) 只负责浏览器下载;exportFile(config) 负责确认、请求文件流、下载和状态通知。请求客户端与交互能力均由调用方注入,因此不依赖 Vue 或 Element UI。

await exportFile({
  url: "/admin/orders/export/",
  fileName: "订单明细",
  request,
  reqMethod: "get",
  message,
  messageBox,
  loading
});

Vue2 项目需要实例级 $exportFile 时,应使用 @infly/libs/adapters/vue2/module/file-export.js,不要在 UI 组件包中注册全局 mixin。

browser/dom — DOM 操作

| 函数 | 说明 | |------|------| | E(exp, parentElement?) | querySelector 选择器 | | createDom(html) | 创建 DOM 元素(HTML字符串/标签名) | | addDom(type, parent, element, new?) | DOM 插入:before/after/prepend/append/replace | | removeDom(element) | 删除元素 | | addClass(elem, className) | 添加类名 | | removeClass(elem, className) | 移除类名 | | toggleClass(elem, className) | 切换类名 | | hasClass(elem, className, notStrict?) | 检查是否包含类名 | | closest(dom, selector, limit?) | 向上查找匹配选择器的祖先 | | hasParentWithPartClass(dom, part, limit?) | 向上查找含部分类名的祖先 | | html(elem, value?) | 获取/设置 innerHTML | | getTagName(html) | 获取 HTML 字符串的标签名 | | getTagValue(html) | 获取 HTML 字符串的标签内容 | | setStyle(element, obj, isRemove?) | 设置元素样式 | | getStyle(elem, ppt, pseudoElt?) | 获取计算后的样式 | | getPS(elem, withoutScroll?) | 获取元素位置 {top,right,bottom,left} | | getElementOffset(element, event?) | 获取元素相对文档的 offset | | getPointAtElement(element, e) | 获取坐标在元素内的相对位置 | | getTextWidth(text, warpClass?) | 获取文本的 px 宽度 | | setAttr(dom, attr, value) | 设置元素属性 | | setAttrs(dom, config) | 批量设置元素属性 | | removeAttr(dom, attr) | 移除元素属性 | | addScript(src, cb, config?) | 异步加载外部 JS 脚本 | | loadStyleSheet(url, cb, config?) | 异步加载外部 CSS | | loadIframe(url, cb, shouldRemove?) | 异步加载 iframe | | stripTag(html, removeSymbol?) | 去除 HTML 标签 | | setFavicon(url) | 设置网页 favicon | | isDom(obj) | 判断是否为 DOM 元素 |

browser/storage — Cookie/Storage

| 函数 | 说明 | |------|------| | getCookie(name) | 获取 cookie | | setCookie(name, value, options?) | 设置 cookie | | removeCookie(name, options?) | 移除 cookie | | setCookieMt(options) | 批量设置 cookie | | cookiesMap() | 获取所有 cookie 映射 | | storage.get(name) | 读取 localStorage(自动过期处理) | | storage.set(name, value, expires?) | 写入 localStorage(支持 '2h3m' 时间表达式) | | storage.remove(name) | 删除 localStorage | | storage.clear() | 清空 localStorage | | storage.getProjectCache(name) | 获取项目级缓存(自动加项目前缀) | | storage.setProjectCache(name, value) | 设置项目级缓存 | | ssStorage.get(name) | 读取 sessionStorage | | ssStorage.set(name, value) | 写入 sessionStorage | | ssStorage.remove(name) | 删除 sessionStorage | | ssStorage.clear() | 清空 sessionStorage |

browser/route — 路由/导航

| 函数 | 说明 | |------|------| | $stateTo(path) | 应用内跳转 | | $stateGo(options) | 路由跳转(相对/绝对/新窗口/重载) | | href(url, type?, notAuto?) | 页面跳转 | | getRouterSearch(ifReturnParams?) | 获取 URL 查询部分 | | getParamsFormSearch(search) | 解析查询字符串为对象 | | paramsToSearch(param, key?, encode?, deep?, first?) | 对象转 URL 查询字符串 | | pushState(options, title, newUrl) | history.pushState | | repleaceState(options, title, newUrl) | history.replaceState | | initHashCache() | 初始化 hash 路由缓存 | | cleanState(stateList?) | 清理 URL 中的状态参数 |

browser/env — 环境/域名/浏览器

| 函数 | 说明 | |------|------| | getEnv(url?) | 获取当前环境信息(test/publish/localhost/gray/demo/external) | | getOrigin() | 获取协议+域名 | | isDevMode() | 判断是否本地开发模式 | | isDebugMode(check?) | 判断是否可调试模式 | | isIe(version?) | 检查是否为 IE | | isWeiXin() | 检查是否微信内置浏览器 | | initUA() | 初始化 UA 检测 | | isTablet() | 检查是否平板设备 | | isUA(type) | 检查特定 UA 类型 | | toggleMobileViewport(vp?) | 切换移动端 viewport | | getClientPX() | 获取屏幕像素 {height, width} | | hasPhysicalHomeKey() | 判断是否有物理 Home 键 | | getWwwFile(fileUrl, isOld?) | 获取 www 域名静态文件地址 | | normalizeEnvUrl(url?) | 规范化环境变量 URL | | getWapDomain() | 获取移动端域名 | | getUrlParam(name) | 获取当前页面 URL 参数 | | removeParamByRegex(name) | 按正则移除 URL 参数 |

browser/permission — 权限/Token

| 函数 | 说明 | |------|------| | getCurrentProject() | 获取当前项目名 | | getProjectTokenName(project?) | 获取项目对应的 Token 名称 | | getTokenForProject() | 获取项目登录 Token 值 | | isLogin(type?) | 判断是否已登录 | | setPM(permissions, orgId?, token?, project?) | 设置项目级权限缓存 | | getPM(code, settings?) | 读取项目级权限(自动隔离项目/多账号) | | getPMBySettings(code, settings) | 按自定义配置读取权限 | | filterPM(route) | 按权限过滤路由 | | routeToDomain(site, url, type?) | 跨项目/跨站点跳转 | | clearCacheForLogout() | 退出登录时的缓存清理 | | clearAllCookiesAndStorage(options?) | 清除所有 Cookie/Storage(可配置保留项) |

browser/extra — 扩展功能

| 函数 | 说明 | |------|------| | highlightKeyWord(str, keywords, config?) | 高亮关键词(支持嵌套 HTML 标签) | | autoMatch(text, obj, config?) | 状态/类型自动匹配文本 | | textConfig(status, matchObj, type, custom?) | 个性化文案配置 | | checkConfig(name, orgCode?, config?) | 检查功能配置是否启用 | | checkOrgCode(value) | 检查机构代码(支持 ZD/ZDHC/ZDBG/isWYD/isNFY) | | changeLanguage(type, site) | 切换语言(cn/en) | | compressStr(code) | 加密字符串 | | unCompressStr(code) | 解密字符串 | | setAutoState(name, value) | 设置当前页面自动状态(跨组件通讯) | | getAutoState(name) | 获取当前页面自动状态 | | cleanStateScope() | 清除自动状态作用域 | | changeDomainWhenExternal(url) | 外部部署时代域名转换 | | getGatewayDomain(url) | 获取 Gateway 完整域名 | | transArrayBufferToObj(data) | ArrayBuffer 转 JSON 对象 | | removeState(name, value, notChange?) | 移除 URL 中的状态参数 | | copyText(text, noti?, cb?) | 复制文本到剪贴板 | | copyHtml(html, noti?, cb?) | 复制 HTML(粘贴到 Excel/Word 保持格式) | | copyImage(blob) | 复制图片到剪贴板 | | blobToDataURI(blob, cb) | Blob 转为 Data URI | | ce(text) | 控制台打印错误信息 | | te(text) | 抛出 JS 错误(带源追溯) | | runCode(code) | 执行字符串代码 | | regHook(env, cb) | 注册 hook 保持状态更新 | | back(value?) | 浏览器返回 | | noHref() | 返回 javascript:void(0) | | generateFlag() | 生成标记对象(用于去重) | | saveTempStoreList(list) | 保存临时 Storage 列表 |

browser/expression — 条件表达式引擎

| 函数 | 说明 | |------|------| | checkValueByExpression(config, matchAny?, options?, execConfig?, parentRef?) | 检测多组表达式的布尔值(支持嵌套 andOne) | | useConfigExpression(configObj, options) | 检测多组表达式并返回多结果 | | conditionFunctionRender(checkFn, orFn, params?) | 条件式渲染(优先自定义渲染器) | | paramsToSearch(param, key?, encode?, deep?, first?) | 对象递归转 URL 查询字符串 |

browser/clone — 深拷贝

| 函数 | 说明 | |------|------| | copyObj(obj, cb1?, cb2?, cb3?, cb4?, path?, config?, exec?, diff?) | 深度拷贝(完整版,带回调链路和 diff 能力) |

browser/iterate — 迭代器

| 函数 | 说明 | |------|------| | each(arr, cb) | 数组迭代(带 stop 控制,通过 Uts.pauseEach 中断) | | objEach(obj, cb) | 对象遍历(不带 cb 时返回 keys) |

browser/tree — 树形数据

| 函数 | 说明 | |------|------| | loopTree(arr, childProp?, cb, eachConfig?, globalConfig?) | 遍历树形数据(支持深度控制/路径生成/中断) | | generatePathForTree(tree, childProp?, pathField?, parent?) | 给树形数据的每个子项添加索引路径 | | randomOrder(arr) | 数组随机排序(返回新数组) |


使用方式

Monorepo 开发(直引源文件,Webpack/Vite 实时转译)

import { isFunction, pluck, filterMoney } from "@infly/ts-libs";
import { getCookie, storage } from "@infly/ts-libs/browser/storage";

npm 外部项目

npm install @infly/ts-libs
import { isFunction, filterMoney } from "@infly/ts-libs";