@xxkatt/utils 0.0.0-stage → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +37 -2
- package/dist/index.d.ts +111 -0
- package/dist/index.js +270 -0
- package/dist/index.js.map +1 -0
- package/package.json +32 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 xxkatt
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,38 @@
|
|
|
1
|
-
|
|
1
|
+
<h1 align="center">@xxkatt/utils</h1>
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<p align="center">把常用的小工具,放在一起。</p>
|
|
4
|
+
<p align="center">轻量、类型齐全的 JavaScript / TypeScript 工具函数库</p>
|
|
5
|
+
|
|
6
|
+
<p align="center">
|
|
7
|
+
<a href="https://www.npmjs.com/package/@xxkatt/utils"><img src="https://img.shields.io/npm/v/@xxkatt/utils?color=a1b858&label=version" alt="npm version" /></a>
|
|
8
|
+
<a href="https://www.npmjs.com/package/@xxkatt/utils"><img src="https://img.shields.io/npm/dm/@xxkatt/utils?color=50a36f&label=downloads" alt="npm downloads" /></a>
|
|
9
|
+
<a href="https://github.com/xxkatt/xxkatt-utils/blob/master/packages/js/utils/LICENSE"><img src="https://img.shields.io/npm/l/@xxkatt/utils?color=3178c6" alt="MIT license" /></a>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
## 👀 文档
|
|
13
|
+
|
|
14
|
+
[查看文档](https://xxkatt.github.io/xxkatt-utils/) · [源码仓库](https://github.com/xxkatt/xxkatt-utils) · [问题反馈](https://github.com/xxkatt/xxkatt-utils/issues)
|
|
15
|
+
|
|
16
|
+
## 🚀 特性
|
|
17
|
+
|
|
18
|
+
- 🦾 **类型齐全**:使用 TypeScript 编写,提供类型声明与参数提示。
|
|
19
|
+
- 💫 **零依赖**:无运行时依赖,只安装工具库本身。
|
|
20
|
+
- ⚡️ **按需打包**:提供 ESM 导出,支持 Tree-shaking。
|
|
21
|
+
- 🌎 **框架无关**:支持 Node.js 24+ 和现代浏览器,可搭配不同的前端框架使用。
|
|
22
|
+
|
|
23
|
+
## 📦 安装
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
# npm
|
|
27
|
+
npm install @xxkatt/utils
|
|
28
|
+
|
|
29
|
+
# pnpm
|
|
30
|
+
pnpm add @xxkatt/utils
|
|
31
|
+
|
|
32
|
+
# yarn
|
|
33
|
+
yarn add @xxkatt/utils
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 许可证
|
|
37
|
+
|
|
38
|
+
[MIT © 2026 xxkatt](./LICENSE)
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 生成 UUID v4,默认返回 32 个小写十六进制字符。
|
|
3
|
+
*
|
|
4
|
+
* @param prefix 原样拼接在 UUID 前的前缀,分隔符需自行提供。
|
|
5
|
+
* @param hyphens 是否保留标准 UUID 中的横杠,默认 false。
|
|
6
|
+
* @example
|
|
7
|
+
* uuid()
|
|
8
|
+
* uuid('', true)
|
|
9
|
+
* uuid('user_')
|
|
10
|
+
* uuid('user_', true)
|
|
11
|
+
*/
|
|
12
|
+
export declare function uuid(prefix?: string, hyphens?: boolean): string;
|
|
13
|
+
/**
|
|
14
|
+
* 使用加密安全随机数生成 ID;自定义长度的 ID 不遵循 UUID 格式。
|
|
15
|
+
* 字符表依次为 0–9、a–z、A–Z,使用前 radix 个字符。
|
|
16
|
+
*
|
|
17
|
+
* @param length 字符数量,必须为非负安全整数,默认 32;0 返回空字符串。
|
|
18
|
+
* @param radix 基数,必须为 2–62 的整数,默认 16。
|
|
19
|
+
* @example
|
|
20
|
+
* randomId(8, 10)
|
|
21
|
+
* randomId(21, 62)
|
|
22
|
+
*/
|
|
23
|
+
export declare function randomId(length?: number, radix?: number): string;
|
|
24
|
+
/**
|
|
25
|
+
* 在浏览器中下载 URL、完整 Data URL 或 Blob/File。
|
|
26
|
+
*
|
|
27
|
+
* @param source 文件地址或文件内容;字符串始终作为地址处理。
|
|
28
|
+
* @param filename 建议保存的完整文件名,包含扩展名。
|
|
29
|
+
* @returns 触发下载后完成,不代表文件已保存到磁盘。
|
|
30
|
+
* @example
|
|
31
|
+
* await download('/files/report.pdf', 'report.pdf')
|
|
32
|
+
* await download(new Blob(['hello'], { type: 'text/plain' }), 'hello.txt')
|
|
33
|
+
*/
|
|
34
|
+
export declare function download(source: string | Blob, filename: string): Promise<void>;
|
|
35
|
+
export interface DebouncedFunction<This, Args extends unknown[]> {
|
|
36
|
+
(this: This, ...args: Args): void;
|
|
37
|
+
cancel(): void;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 防抖:停止调用 wait 毫秒后,使用最后一次调用的 this 和参数执行回调。
|
|
41
|
+
*
|
|
42
|
+
* @param fn 要延迟执行的回调。
|
|
43
|
+
* @param wait 等待时间,单位毫秒,遵循原生 setTimeout 的时间规则。
|
|
44
|
+
* @returns 带有 cancel() 方法的防抖函数;cancel() 取消尚未执行的回调。
|
|
45
|
+
* @example
|
|
46
|
+
* const search = debounce((keyword: string) => console.log(keyword), 300)
|
|
47
|
+
* search('hello')
|
|
48
|
+
* search.cancel()
|
|
49
|
+
*/
|
|
50
|
+
export declare function debounce<This, Args extends unknown[]>(fn: (this: This, ...args: Args) => unknown, wait: number): DebouncedFunction<This, Args>;
|
|
51
|
+
export interface ThrottledFunction<This, Args extends unknown[]> {
|
|
52
|
+
(this: This, ...args: Args): void;
|
|
53
|
+
cancel(): void;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* 节流:首次调用立即执行,间隔内的调用在 wait 毫秒后以最后一次的 this 和参数执行。
|
|
57
|
+
* 持续调用时,每隔 wait 毫秒执行一次;仅调用一次时不会重复执行。
|
|
58
|
+
*
|
|
59
|
+
* @param fn 要限制执行频率的回调。
|
|
60
|
+
* @param wait 执行间隔,单位毫秒,遵循原生 setTimeout 的时间规则。
|
|
61
|
+
* @returns 带有 cancel() 方法的节流函数;cancel() 取消待执行回调并重置间隔。
|
|
62
|
+
* @example
|
|
63
|
+
* const update = throttle((position: number) => console.log(position), 100)
|
|
64
|
+
* update(10)
|
|
65
|
+
* update.cancel()
|
|
66
|
+
*/
|
|
67
|
+
export declare function throttle<This, Args extends unknown[]>(fn: (this: This, ...args: Args) => unknown, wait: number): ThrottledFunction<This, Args>;
|
|
68
|
+
/** 按 Object.prototype.toString 的标签判断类型,如 'Date'、'Map';区分大小写。 */
|
|
69
|
+
export declare function is(value: unknown, type: string): boolean;
|
|
70
|
+
/** 仅判断原始字符串,不包含 String 包装对象。 */
|
|
71
|
+
export declare function isString(value: unknown): value is string;
|
|
72
|
+
/** 判断原始 number,包含 NaN 和 Infinity,不进行数值有效性检查。 */
|
|
73
|
+
export declare function isNumber(value: unknown): value is number;
|
|
74
|
+
/** 仅判断原始布尔值。 */
|
|
75
|
+
export declare function isBoolean(value: unknown): value is boolean;
|
|
76
|
+
export declare function isBigInt(value: unknown): value is bigint;
|
|
77
|
+
export declare function isSymbol(value: unknown): value is symbol;
|
|
78
|
+
export declare function isUndefined(value: unknown): value is undefined;
|
|
79
|
+
/** 排除 undefined,保留 null。 */
|
|
80
|
+
export declare function isDefined<T>(value: T): value is Exclude<T, undefined>;
|
|
81
|
+
export declare function isNull(value: unknown): value is null;
|
|
82
|
+
/** 判断 null 或 undefined。 */
|
|
83
|
+
export declare function isNil(value: unknown): value is null | undefined;
|
|
84
|
+
/** 判断非 null 的对象,包含数组、内置对象和类实例,不包含函数。 */
|
|
85
|
+
export declare function isObject(value: unknown): value is object;
|
|
86
|
+
/** 判断普通对象,支持对象字面量、跨 realm 对象和 Object.create(null)。 */
|
|
87
|
+
export declare function isPlainObject(value: unknown): value is Record<PropertyKey, unknown>;
|
|
88
|
+
/** 判断 Date 类型,包含 Invalid Date。 */
|
|
89
|
+
export declare function isDate(value: unknown): value is Date;
|
|
90
|
+
export declare function isRegExp(value: unknown): value is RegExp;
|
|
91
|
+
/** 包含普通函数、异步函数和生成器函数;不检查参数或返回值类型。 */
|
|
92
|
+
export declare function isFunction(value: unknown): value is (...args: never[]) => unknown;
|
|
93
|
+
/** 仅判断数组,不检查元素类型。 */
|
|
94
|
+
export declare function isArray(value: unknown): value is unknown[];
|
|
95
|
+
export declare function isMap(value: unknown): value is Map<unknown, unknown>;
|
|
96
|
+
export declare function isSet(value: unknown): value is Set<unknown>;
|
|
97
|
+
/** 判断 Promise 或具有可调用 then 方法的对象/函数,收窄为 PromiseLike。 */
|
|
98
|
+
export declare function isPromise(value: unknown): value is PromiseLike<unknown>;
|
|
99
|
+
/** 判断可被 JSON.parse 解析的字符串,包含 JSON 原始值。 */
|
|
100
|
+
export declare function isJSON(value: unknown): boolean;
|
|
101
|
+
/** 判断空字符串、数组、Map、Set 或无自有可枚举属性的普通对象。 */
|
|
102
|
+
export declare function isEmpty(value: unknown): boolean;
|
|
103
|
+
/** 在 isEmpty 的基础上,将 null、undefined 也视为空。 */
|
|
104
|
+
export declare function isAllEmpty(value: unknown): boolean;
|
|
105
|
+
/** 判断绝对 HTTP(S) URL,拒绝空白字符、反斜杠和相对地址。 */
|
|
106
|
+
export declare function isUrl(value: unknown): boolean;
|
|
107
|
+
/** 常用邮箱格式校验,不验证邮箱是否存在,不覆盖完整 RFC 邮箱语法。 */
|
|
108
|
+
export declare function isEmail(value: unknown): boolean;
|
|
109
|
+
/** 中国大陆 11 位手机号格式:以 1 开头,第二位为 3–9;不验证号段分配或号码存在性。 */
|
|
110
|
+
export declare function isPhone(value: unknown): boolean;
|
|
111
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
// src/uuid/index.ts
|
|
2
|
+
const ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
3
|
+
/**
|
|
4
|
+
* 生成 UUID v4,默认返回 32 个小写十六进制字符。
|
|
5
|
+
*
|
|
6
|
+
* @param prefix 原样拼接在 UUID 前的前缀,分隔符需自行提供。
|
|
7
|
+
* @param hyphens 是否保留标准 UUID 中的横杠,默认 false。
|
|
8
|
+
* @example
|
|
9
|
+
* uuid()
|
|
10
|
+
* uuid('', true)
|
|
11
|
+
* uuid('user_')
|
|
12
|
+
* uuid('user_', true)
|
|
13
|
+
*/
|
|
14
|
+
function uuid(prefix = "", hyphens = false) {
|
|
15
|
+
const crypto = globalThis.crypto;
|
|
16
|
+
let value;
|
|
17
|
+
if (typeof crypto?.randomUUID === "function") value = crypto.randomUUID();
|
|
18
|
+
else {
|
|
19
|
+
if (typeof crypto?.getRandomValues !== "function") throw new Error("uuid requires crypto.randomUUID or crypto.getRandomValues");
|
|
20
|
+
const bytes = /* @__PURE__ */ new Uint8Array(16);
|
|
21
|
+
crypto.getRandomValues(bytes);
|
|
22
|
+
bytes[6] = bytes[6] & 15 | 64;
|
|
23
|
+
bytes[8] = bytes[8] & 63 | 128;
|
|
24
|
+
const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
25
|
+
value = `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
26
|
+
}
|
|
27
|
+
return prefix + (hyphens ? value : value.replace(/-/g, ""));
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 使用加密安全随机数生成 ID;自定义长度的 ID 不遵循 UUID 格式。
|
|
31
|
+
* 字符表依次为 0–9、a–z、A–Z,使用前 radix 个字符。
|
|
32
|
+
*
|
|
33
|
+
* @param length 字符数量,必须为非负安全整数,默认 32;0 返回空字符串。
|
|
34
|
+
* @param radix 基数,必须为 2–62 的整数,默认 16。
|
|
35
|
+
* @example
|
|
36
|
+
* randomId(8, 10)
|
|
37
|
+
* randomId(21, 62)
|
|
38
|
+
*/
|
|
39
|
+
function randomId(length = 32, radix = 16) {
|
|
40
|
+
if (!Number.isSafeInteger(length) || length < 0) throw new RangeError("length must be a non-negative safe integer");
|
|
41
|
+
if (!Number.isInteger(radix) || radix < 2 || radix > 62) throw new RangeError("radix must be an integer between 2 and 62");
|
|
42
|
+
if (length === 0) return "";
|
|
43
|
+
const bytes = new Uint8Array(Math.min(length, 65536));
|
|
44
|
+
const limit = 256 - 256 % radix;
|
|
45
|
+
let value = "";
|
|
46
|
+
while (value.length < length) {
|
|
47
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
48
|
+
for (const byte of bytes) {
|
|
49
|
+
if (byte >= limit) continue;
|
|
50
|
+
value += ALPHABET.charAt(byte % radix);
|
|
51
|
+
if (value.length === length) break;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return value;
|
|
55
|
+
}
|
|
56
|
+
// src/download/index.ts
|
|
57
|
+
/**
|
|
58
|
+
* 在浏览器中下载 URL、完整 Data URL 或 Blob/File。
|
|
59
|
+
*
|
|
60
|
+
* @param source 文件地址或文件内容;字符串始终作为地址处理。
|
|
61
|
+
* @param filename 建议保存的完整文件名,包含扩展名。
|
|
62
|
+
* @returns 触发下载后完成,不代表文件已保存到磁盘。
|
|
63
|
+
* @example
|
|
64
|
+
* await download('/files/report.pdf', 'report.pdf')
|
|
65
|
+
* await download(new Blob(['hello'], { type: 'text/plain' }), 'hello.txt')
|
|
66
|
+
*/
|
|
67
|
+
async function download(source, filename) {
|
|
68
|
+
if (typeof document === "undefined" || !document.body) throw new Error("download requires a browser environment");
|
|
69
|
+
let blob;
|
|
70
|
+
if (typeof source === "string") {
|
|
71
|
+
const response = await fetch(source);
|
|
72
|
+
if (!response.ok) throw new Error(`Download failed: HTTP ${response.status}`);
|
|
73
|
+
blob = await response.blob();
|
|
74
|
+
} else blob = source;
|
|
75
|
+
const anchor = document.createElement("a");
|
|
76
|
+
const url = URL.createObjectURL(blob);
|
|
77
|
+
try {
|
|
78
|
+
anchor.href = url;
|
|
79
|
+
anchor.download = filename;
|
|
80
|
+
anchor.hidden = true;
|
|
81
|
+
document.body.append(anchor);
|
|
82
|
+
anchor.click();
|
|
83
|
+
} finally {
|
|
84
|
+
anchor.remove();
|
|
85
|
+
setTimeout(() => URL.revokeObjectURL(url), 1e3);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// src/debounce/index.ts
|
|
89
|
+
/**
|
|
90
|
+
* 防抖:停止调用 wait 毫秒后,使用最后一次调用的 this 和参数执行回调。
|
|
91
|
+
*
|
|
92
|
+
* @param fn 要延迟执行的回调。
|
|
93
|
+
* @param wait 等待时间,单位毫秒,遵循原生 setTimeout 的时间规则。
|
|
94
|
+
* @returns 带有 cancel() 方法的防抖函数;cancel() 取消尚未执行的回调。
|
|
95
|
+
* @example
|
|
96
|
+
* const search = debounce((keyword: string) => console.log(keyword), 300)
|
|
97
|
+
* search('hello')
|
|
98
|
+
* search.cancel()
|
|
99
|
+
*/
|
|
100
|
+
function debounce(fn, wait) {
|
|
101
|
+
let timer;
|
|
102
|
+
function debounced(...args) {
|
|
103
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
104
|
+
timer = setTimeout(() => {
|
|
105
|
+
timer = void 0;
|
|
106
|
+
fn.apply(this, args);
|
|
107
|
+
}, wait);
|
|
108
|
+
}
|
|
109
|
+
debounced.cancel = () => {
|
|
110
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
111
|
+
timer = void 0;
|
|
112
|
+
};
|
|
113
|
+
return debounced;
|
|
114
|
+
}
|
|
115
|
+
// src/throttle/index.ts
|
|
116
|
+
/**
|
|
117
|
+
* 节流:首次调用立即执行,间隔内的调用在 wait 毫秒后以最后一次的 this 和参数执行。
|
|
118
|
+
* 持续调用时,每隔 wait 毫秒执行一次;仅调用一次时不会重复执行。
|
|
119
|
+
*
|
|
120
|
+
* @param fn 要限制执行频率的回调。
|
|
121
|
+
* @param wait 执行间隔,单位毫秒,遵循原生 setTimeout 的时间规则。
|
|
122
|
+
* @returns 带有 cancel() 方法的节流函数;cancel() 取消待执行回调并重置间隔。
|
|
123
|
+
* @example
|
|
124
|
+
* const update = throttle((position: number) => console.log(position), 100)
|
|
125
|
+
* update(10)
|
|
126
|
+
* update.cancel()
|
|
127
|
+
*/
|
|
128
|
+
function throttle(fn, wait) {
|
|
129
|
+
let timer;
|
|
130
|
+
let pending;
|
|
131
|
+
function onTimeout() {
|
|
132
|
+
timer = void 0;
|
|
133
|
+
if (!pending) return;
|
|
134
|
+
const { thisArg, args } = pending;
|
|
135
|
+
pending = void 0;
|
|
136
|
+
timer = setTimeout(onTimeout, wait);
|
|
137
|
+
fn.apply(thisArg, args);
|
|
138
|
+
}
|
|
139
|
+
function throttled(...args) {
|
|
140
|
+
if (timer === void 0) {
|
|
141
|
+
timer = setTimeout(onTimeout, wait);
|
|
142
|
+
fn.apply(this, args);
|
|
143
|
+
} else pending = {
|
|
144
|
+
thisArg: this,
|
|
145
|
+
args
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
throttled.cancel = () => {
|
|
149
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
150
|
+
timer = void 0;
|
|
151
|
+
pending = void 0;
|
|
152
|
+
};
|
|
153
|
+
return throttled;
|
|
154
|
+
}
|
|
155
|
+
// src/is/index.ts
|
|
156
|
+
/** 按 Object.prototype.toString 的标签判断类型,如 'Date'、'Map';区分大小写。 */
|
|
157
|
+
function is(value, type) {
|
|
158
|
+
return Object.prototype.toString.call(value) === `[object ${type}]`;
|
|
159
|
+
}
|
|
160
|
+
/** 仅判断原始字符串,不包含 String 包装对象。 */
|
|
161
|
+
function isString(value) {
|
|
162
|
+
return typeof value === "string";
|
|
163
|
+
}
|
|
164
|
+
/** 判断原始 number,包含 NaN 和 Infinity,不进行数值有效性检查。 */
|
|
165
|
+
function isNumber(value) {
|
|
166
|
+
return typeof value === "number";
|
|
167
|
+
}
|
|
168
|
+
/** 仅判断原始布尔值。 */
|
|
169
|
+
function isBoolean(value) {
|
|
170
|
+
return typeof value === "boolean";
|
|
171
|
+
}
|
|
172
|
+
function isBigInt(value) {
|
|
173
|
+
return typeof value === "bigint";
|
|
174
|
+
}
|
|
175
|
+
function isSymbol(value) {
|
|
176
|
+
return typeof value === "symbol";
|
|
177
|
+
}
|
|
178
|
+
function isUndefined(value) {
|
|
179
|
+
return value === void 0;
|
|
180
|
+
}
|
|
181
|
+
/** 排除 undefined,保留 null。 */
|
|
182
|
+
function isDefined(value) {
|
|
183
|
+
return value !== void 0;
|
|
184
|
+
}
|
|
185
|
+
function isNull(value) {
|
|
186
|
+
return value === null;
|
|
187
|
+
}
|
|
188
|
+
/** 判断 null 或 undefined。 */
|
|
189
|
+
function isNil(value) {
|
|
190
|
+
return value === null || value === void 0;
|
|
191
|
+
}
|
|
192
|
+
/** 判断非 null 的对象,包含数组、内置对象和类实例,不包含函数。 */
|
|
193
|
+
function isObject(value) {
|
|
194
|
+
return value !== null && typeof value === "object";
|
|
195
|
+
}
|
|
196
|
+
/** 判断普通对象,支持对象字面量、跨 realm 对象和 Object.create(null)。 */
|
|
197
|
+
function isPlainObject(value) {
|
|
198
|
+
if (!is(value, "Object")) return false;
|
|
199
|
+
const prototype = Object.getPrototypeOf(value);
|
|
200
|
+
if (prototype === null) return true;
|
|
201
|
+
const constructor = Object.hasOwn(prototype, "constructor") && prototype.constructor;
|
|
202
|
+
return typeof constructor === "function" && Function.prototype.toString.call(constructor) === Function.prototype.toString.call(Object);
|
|
203
|
+
}
|
|
204
|
+
/** 判断 Date 类型,包含 Invalid Date。 */
|
|
205
|
+
function isDate(value) {
|
|
206
|
+
return is(value, "Date");
|
|
207
|
+
}
|
|
208
|
+
function isRegExp(value) {
|
|
209
|
+
return is(value, "RegExp");
|
|
210
|
+
}
|
|
211
|
+
/** 包含普通函数、异步函数和生成器函数;不检查参数或返回值类型。 */
|
|
212
|
+
function isFunction(value) {
|
|
213
|
+
return typeof value === "function";
|
|
214
|
+
}
|
|
215
|
+
/** 仅判断数组,不检查元素类型。 */
|
|
216
|
+
function isArray(value) {
|
|
217
|
+
return Array.isArray(value);
|
|
218
|
+
}
|
|
219
|
+
function isMap(value) {
|
|
220
|
+
return is(value, "Map");
|
|
221
|
+
}
|
|
222
|
+
function isSet(value) {
|
|
223
|
+
return is(value, "Set");
|
|
224
|
+
}
|
|
225
|
+
/** 判断 Promise 或具有可调用 then 方法的对象/函数,收窄为 PromiseLike。 */
|
|
226
|
+
function isPromise(value) {
|
|
227
|
+
return (isObject(value) || isFunction(value)) && "then" in value && isFunction(value.then);
|
|
228
|
+
}
|
|
229
|
+
/** 判断可被 JSON.parse 解析的字符串,包含 JSON 原始值。 */
|
|
230
|
+
function isJSON(value) {
|
|
231
|
+
if (!isString(value)) return false;
|
|
232
|
+
try {
|
|
233
|
+
JSON.parse(value);
|
|
234
|
+
return true;
|
|
235
|
+
} catch {
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/** 判断空字符串、数组、Map、Set 或无自有可枚举属性的普通对象。 */
|
|
240
|
+
function isEmpty(value) {
|
|
241
|
+
if (isString(value) || isArray(value)) return value.length === 0;
|
|
242
|
+
if (isMap(value) || isSet(value)) return value.size === 0;
|
|
243
|
+
if (isPlainObject(value)) return !Reflect.ownKeys(value).some((key) => Object.prototype.propertyIsEnumerable.call(value, key));
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
/** 在 isEmpty 的基础上,将 null、undefined 也视为空。 */
|
|
247
|
+
function isAllEmpty(value) {
|
|
248
|
+
return isNil(value) || isEmpty(value);
|
|
249
|
+
}
|
|
250
|
+
/** 判断绝对 HTTP(S) URL,拒绝空白字符、反斜杠和相对地址。 */
|
|
251
|
+
function isUrl(value) {
|
|
252
|
+
if (!isString(value) || !/^https?:\/\//i.test(value) || /[\s\\]/.test(value)) return false;
|
|
253
|
+
try {
|
|
254
|
+
const url = new URL(value);
|
|
255
|
+
return (url.protocol === "http:" || url.protocol === "https:") && url.hostname !== "";
|
|
256
|
+
} catch {
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
/** 常用邮箱格式校验,不验证邮箱是否存在,不覆盖完整 RFC 邮箱语法。 */
|
|
261
|
+
function isEmail(value) {
|
|
262
|
+
return isString(value) && /^[a-z\d!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z\d!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z\d](?:[a-z\d-]*[a-z\d])?\.)+[a-z]{2,}$/i.test(value);
|
|
263
|
+
}
|
|
264
|
+
/** 中国大陆 11 位手机号格式:以 1 开头,第二位为 3–9;不验证号段分配或号码存在性。 */
|
|
265
|
+
function isPhone(value) {
|
|
266
|
+
return isString(value) && /^1[3-9]\d{9}$/.test(value);
|
|
267
|
+
}
|
|
268
|
+
export { debounce, download, is, isAllEmpty, isArray, isBigInt, isBoolean, isDate, isDefined, isEmail, isEmpty, isFunction, isJSON, isMap, isNil, isNull, isNumber, isObject, isPhone, isPlainObject, isPromise, isRegExp, isSet, isString, isSymbol, isUndefined, isUrl, randomId, throttle, uuid };
|
|
269
|
+
|
|
270
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/uuid/index.ts","../src/download/index.ts","../src/debounce/index.ts","../src/throttle/index.ts","../src/is/index.ts"],"sourcesContent":["const ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'\n\n/**\n * 生成 UUID v4,默认返回 32 个小写十六进制字符。\n *\n * @param prefix 原样拼接在 UUID 前的前缀,分隔符需自行提供。\n * @param hyphens 是否保留标准 UUID 中的横杠,默认 false。\n * @example\n * uuid()\n * uuid('', true)\n * uuid('user_')\n * uuid('user_', true)\n */\nexport function uuid(prefix: string = '', hyphens: boolean = false): string {\n const crypto = globalThis.crypto\n let value: string\n\n if (typeof crypto?.randomUUID === 'function') {\n value = crypto.randomUUID()\n } else {\n if (typeof crypto?.getRandomValues !== 'function') {\n throw new Error('uuid requires crypto.randomUUID or crypto.getRandomValues')\n }\n\n const bytes = new Uint8Array(16)\n crypto.getRandomValues(bytes)\n // 设置 UUID v4 的版本位和 RFC 变体位,保留其余随机位。\n bytes[6] = (bytes[6]! & 0x0f) | 0x40\n bytes[8] = (bytes[8]! & 0x3f) | 0x80\n const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join('')\n value = `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`\n }\n\n return prefix + (hyphens ? value : value.replace(/-/g, ''))\n}\n\n/**\n * 使用加密安全随机数生成 ID;自定义长度的 ID 不遵循 UUID 格式。\n * 字符表依次为 0–9、a–z、A–Z,使用前 radix 个字符。\n *\n * @param length 字符数量,必须为非负安全整数,默认 32;0 返回空字符串。\n * @param radix 基数,必须为 2–62 的整数,默认 16。\n * @example\n * randomId(8, 10)\n * randomId(21, 62)\n */\nexport function randomId(length: number = 32, radix: number = 16): string {\n if (!Number.isSafeInteger(length) || length < 0) {\n throw new RangeError('length must be a non-negative safe integer')\n }\n if (!Number.isInteger(radix) || radix < 2 || radix > ALPHABET.length) {\n throw new RangeError('radix must be an integer between 2 and 62')\n }\n if (length === 0) return ''\n\n const bytes = new Uint8Array(Math.min(length, 65_536))\n const limit = 256 - (256 % radix)\n let value = ''\n\n while (value.length < length) {\n globalThis.crypto.getRandomValues(bytes)\n for (const byte of bytes) {\n // 丢弃无法均分到字符表的尾部区间,避免取模导致分布偏差。\n if (byte >= limit) continue\n value += ALPHABET.charAt(byte % radix)\n if (value.length === length) break\n }\n }\n\n return value\n}\n","/**\n * 在浏览器中下载 URL、完整 Data URL 或 Blob/File。\n *\n * @param source 文件地址或文件内容;字符串始终作为地址处理。\n * @param filename 建议保存的完整文件名,包含扩展名。\n * @returns 触发下载后完成,不代表文件已保存到磁盘。\n * @example\n * await download('/files/report.pdf', 'report.pdf')\n * await download(new Blob(['hello'], { type: 'text/plain' }), 'hello.txt')\n */\nexport async function download(source: string | Blob, filename: string): Promise<void> {\n if (typeof document === 'undefined' || !document.body) {\n throw new Error('download requires a browser environment')\n }\n\n let blob: Blob\n if (typeof source === 'string') {\n const response = await fetch(source)\n if (!response.ok) {\n throw new Error(`Download failed: HTTP ${response.status}`)\n }\n blob = await response.blob()\n } else {\n blob = source\n }\n\n const anchor = document.createElement('a')\n const url = URL.createObjectURL(blob)\n try {\n anchor.href = url\n anchor.download = filename\n anchor.hidden = true\n document.body.append(anchor)\n anchor.click()\n } finally {\n anchor.remove()\n // 留出浏览器开始读取文件的时间,避免同步释放导致下载失败。\n setTimeout(() => URL.revokeObjectURL(url), 1000)\n }\n}\n","export interface DebouncedFunction<This, Args extends unknown[]> {\n (this: This, ...args: Args): void\n cancel(): void\n}\n\n/**\n * 防抖:停止调用 wait 毫秒后,使用最后一次调用的 this 和参数执行回调。\n *\n * @param fn 要延迟执行的回调。\n * @param wait 等待时间,单位毫秒,遵循原生 setTimeout 的时间规则。\n * @returns 带有 cancel() 方法的防抖函数;cancel() 取消尚未执行的回调。\n * @example\n * const search = debounce((keyword: string) => console.log(keyword), 300)\n * search('hello')\n * search.cancel()\n */\nexport function debounce<This, Args extends unknown[]>(\n fn: (this: This, ...args: Args) => unknown,\n wait: number,\n): DebouncedFunction<This, Args> {\n let timer: ReturnType<typeof setTimeout> | undefined\n\n function debounced(this: This, ...args: Args): void {\n if (timer !== undefined) clearTimeout(timer)\n timer = setTimeout(() => {\n timer = undefined\n fn.apply(this, args)\n }, wait)\n }\n\n debounced.cancel = (): void => {\n if (timer !== undefined) clearTimeout(timer)\n timer = undefined\n }\n\n return debounced\n}\n","export interface ThrottledFunction<This, Args extends unknown[]> {\n (this: This, ...args: Args): void\n cancel(): void\n}\n\n/**\n * 节流:首次调用立即执行,间隔内的调用在 wait 毫秒后以最后一次的 this 和参数执行。\n * 持续调用时,每隔 wait 毫秒执行一次;仅调用一次时不会重复执行。\n *\n * @param fn 要限制执行频率的回调。\n * @param wait 执行间隔,单位毫秒,遵循原生 setTimeout 的时间规则。\n * @returns 带有 cancel() 方法的节流函数;cancel() 取消待执行回调并重置间隔。\n * @example\n * const update = throttle((position: number) => console.log(position), 100)\n * update(10)\n * update.cancel()\n */\nexport function throttle<This, Args extends unknown[]>(\n fn: (this: This, ...args: Args) => unknown,\n wait: number,\n): ThrottledFunction<This, Args> {\n let timer: ReturnType<typeof setTimeout> | undefined\n let pending: { thisArg: This; args: Args } | undefined\n\n function onTimeout(): void {\n timer = undefined\n if (!pending) return\n\n const { thisArg, args } = pending\n pending = undefined\n // 在执行用户回调前建立下一轮间隔,支持回调内再次调用或取消。\n timer = setTimeout(onTimeout, wait)\n fn.apply(thisArg, args)\n }\n\n function throttled(this: This, ...args: Args): void {\n if (timer === undefined) {\n timer = setTimeout(onTimeout, wait)\n fn.apply(this, args)\n } else {\n pending = { thisArg: this, args }\n }\n }\n\n throttled.cancel = (): void => {\n if (timer !== undefined) clearTimeout(timer)\n timer = undefined\n pending = undefined\n }\n\n return throttled\n}\n","/** 按 Object.prototype.toString 的标签判断类型,如 'Date'、'Map';区分大小写。 */\nexport function is(value: unknown, type: string): boolean {\n return Object.prototype.toString.call(value) === `[object ${type}]`\n}\n\n/** 仅判断原始字符串,不包含 String 包装对象。 */\nexport function isString(value: unknown): value is string {\n return typeof value === 'string'\n}\n\n/** 判断原始 number,包含 NaN 和 Infinity,不进行数值有效性检查。 */\nexport function isNumber(value: unknown): value is number {\n return typeof value === 'number'\n}\n\n/** 仅判断原始布尔值。 */\nexport function isBoolean(value: unknown): value is boolean {\n return typeof value === 'boolean'\n}\n\nexport function isBigInt(value: unknown): value is bigint {\n return typeof value === 'bigint'\n}\n\nexport function isSymbol(value: unknown): value is symbol {\n return typeof value === 'symbol'\n}\n\nexport function isUndefined(value: unknown): value is undefined {\n return value === undefined\n}\n\n/** 排除 undefined,保留 null。 */\nexport function isDefined<T>(value: T): value is Exclude<T, undefined> {\n return value !== undefined\n}\n\nexport function isNull(value: unknown): value is null {\n return value === null\n}\n\n/** 判断 null 或 undefined。 */\nexport function isNil(value: unknown): value is null | undefined {\n return value === null || value === undefined\n}\n\n/** 判断非 null 的对象,包含数组、内置对象和类实例,不包含函数。 */\nexport function isObject(value: unknown): value is object {\n return value !== null && typeof value === 'object'\n}\n\n/** 判断普通对象,支持对象字面量、跨 realm 对象和 Object.create(null)。 */\nexport function isPlainObject(value: unknown): value is Record<PropertyKey, unknown> {\n if (!is(value, 'Object')) return false\n const prototype = Object.getPrototypeOf(value)\n if (prototype === null) return true\n const constructor = Object.hasOwn(prototype, 'constructor') && prototype.constructor\n return (\n typeof constructor === 'function' &&\n Function.prototype.toString.call(constructor) === Function.prototype.toString.call(Object)\n )\n}\n\n/** 判断 Date 类型,包含 Invalid Date。 */\nexport function isDate(value: unknown): value is Date {\n return is(value, 'Date')\n}\n\nexport function isRegExp(value: unknown): value is RegExp {\n return is(value, 'RegExp')\n}\n\n/** 包含普通函数、异步函数和生成器函数;不检查参数或返回值类型。 */\nexport function isFunction(value: unknown): value is (...args: never[]) => unknown {\n return typeof value === 'function'\n}\n\n/** 仅判断数组,不检查元素类型。 */\nexport function isArray(value: unknown): value is unknown[] {\n return Array.isArray(value)\n}\n\nexport function isMap(value: unknown): value is Map<unknown, unknown> {\n return is(value, 'Map')\n}\n\nexport function isSet(value: unknown): value is Set<unknown> {\n return is(value, 'Set')\n}\n\n/** 判断 Promise 或具有可调用 then 方法的对象/函数,收窄为 PromiseLike。 */\nexport function isPromise(value: unknown): value is PromiseLike<unknown> {\n return (isObject(value) || isFunction(value)) && 'then' in value && isFunction(value.then)\n}\n\n/** 判断可被 JSON.parse 解析的字符串,包含 JSON 原始值。 */\nexport function isJSON(value: unknown): boolean {\n if (!isString(value)) return false\n try {\n JSON.parse(value)\n return true\n } catch {\n return false\n }\n}\n\n/** 判断空字符串、数组、Map、Set 或无自有可枚举属性的普通对象。 */\nexport function isEmpty(value: unknown): boolean {\n if (isString(value) || isArray(value)) return value.length === 0\n if (isMap(value) || isSet(value)) return value.size === 0\n if (isPlainObject(value)) {\n return !Reflect.ownKeys(value).some((key) =>\n Object.prototype.propertyIsEnumerable.call(value, key),\n )\n }\n return false\n}\n\n/** 在 isEmpty 的基础上,将 null、undefined 也视为空。 */\nexport function isAllEmpty(value: unknown): boolean {\n return isNil(value) || isEmpty(value)\n}\n\n/** 判断绝对 HTTP(S) URL,拒绝空白字符、反斜杠和相对地址。 */\nexport function isUrl(value: unknown): boolean {\n if (!isString(value) || !/^https?:\\/\\//i.test(value) || /[\\s\\\\]/.test(value)) return false\n try {\n const url = new URL(value)\n return (url.protocol === 'http:' || url.protocol === 'https:') && url.hostname !== ''\n } catch {\n return false\n }\n}\n\n/** 常用邮箱格式校验,不验证邮箱是否存在,不覆盖完整 RFC 邮箱语法。 */\nexport function isEmail(value: unknown): boolean {\n return (\n isString(value) &&\n /^[a-z\\d!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z\\d!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z\\d](?:[a-z\\d-]*[a-z\\d])?\\.)+[a-z]{2,}$/i.test(\n value,\n )\n )\n}\n\n/** 中国大陆 11 位手机号格式:以 1 开头,第二位为 3–9;不验证号段分配或号码存在性。 */\nexport function isPhone(value: unknown): boolean {\n return isString(value) && /^1[3-9]\\d{9}$/.test(value)\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xxkatt/utils",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "常用的 JavaScript / TypeScript 工具函数",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/xxkatt/xxkatt-utils.git",
|
|
9
|
+
"directory": "packages/js/utils"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"type": "module",
|
|
15
|
+
"sideEffects": false,
|
|
16
|
+
"main": "./dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"publishConfig": {
|
|
25
|
+
"access": "public",
|
|
26
|
+
"registry": "https://registry.npmjs.org/"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsdown",
|
|
30
|
+
"typecheck": "tsc -p tsconfig.json",
|
|
31
|
+
"test": "vitest run",
|
|
32
|
+
"test:watch": "vitest",
|
|
33
|
+
"clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\""
|
|
34
|
+
}
|
|
6
35
|
}
|