@snack-kit/lib 0.2.0 → 0.4.0

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.
Files changed (43) hide show
  1. package/README.md +248 -17
  2. package/dist/cjs/chunk-U6KYHCBL.cjs +264 -0
  3. package/dist/cjs/chunk-U6KYHCBL.cjs.map +1 -0
  4. package/dist/cjs/{chunk-N7BJS6LI.cjs → chunk-XEQEQWDB.cjs} +48 -14
  5. package/dist/cjs/chunk-XEQEQWDB.cjs.map +1 -0
  6. package/dist/cjs/{chunk-YOWLTZM5.cjs → chunk-ZJMTV2GJ.cjs} +7 -6
  7. package/dist/cjs/chunk-ZJMTV2GJ.cjs.map +1 -0
  8. package/dist/cjs/debugger.cjs +7 -3
  9. package/dist/cjs/http.cjs +13 -13
  10. package/dist/cjs/index.cjs +157 -16
  11. package/dist/cjs/index.cjs.map +1 -1
  12. package/dist/cjs/utils.cjs +144 -0
  13. package/dist/cjs/utils.cjs.map +1 -0
  14. package/dist/es/{chunk-4DLFIN3C.js → chunk-4SGFAIRT.js} +4 -3
  15. package/dist/es/chunk-4SGFAIRT.js.map +1 -0
  16. package/dist/es/chunk-WJX5Q3WL.js +229 -0
  17. package/dist/es/chunk-WJX5Q3WL.js.map +1 -0
  18. package/dist/es/{chunk-JQYH5FWE.js → chunk-YV6SGXUJ.js} +48 -15
  19. package/dist/es/chunk-YV6SGXUJ.js.map +1 -0
  20. package/dist/es/debugger.js +2 -2
  21. package/dist/es/http.js +1 -1
  22. package/dist/es/index.js +4 -3
  23. package/dist/es/index.js.map +1 -1
  24. package/dist/es/utils.js +3 -0
  25. package/dist/es/utils.js.map +1 -0
  26. package/dist/types/context-C4dFUDbw.d.ts +237 -0
  27. package/dist/types/debugger.d.ts +3 -0
  28. package/dist/types/http.d.ts +61 -236
  29. package/dist/types/index.d.ts +4 -2
  30. package/dist/types/utils.d.ts +410 -0
  31. package/dist/umd/debugger.global.js +28 -5
  32. package/dist/umd/debugger.global.js.map +1 -1
  33. package/dist/umd/http.global.js +45 -12
  34. package/dist/umd/http.global.js.map +1 -1
  35. package/dist/umd/index.global.js +308 -13
  36. package/dist/umd/index.global.js.map +1 -1
  37. package/dist/umd/utils.global.js +269 -0
  38. package/dist/umd/utils.global.js.map +1 -0
  39. package/package.json +6 -1
  40. package/dist/cjs/chunk-N7BJS6LI.cjs.map +0 -1
  41. package/dist/cjs/chunk-YOWLTZM5.cjs.map +0 -1
  42. package/dist/es/chunk-4DLFIN3C.js.map +0 -1
  43. package/dist/es/chunk-JQYH5FWE.js.map +0 -1
@@ -0,0 +1,229 @@
1
+ // src/utils/detect.ts
2
+ var _toString = (val) => Object.prototype.toString.call(val);
3
+ var IsNumber = (val) => !isNaN(parseFloat(val)) && isFinite(val);
4
+ var IsRealNumber = (val) => typeof val === "number" && !isNaN(val);
5
+ var IsString = (val) => _toString(val) === "[object String]";
6
+ var IsBoolean = (val) => _toString(val) === "[object Boolean]";
7
+ var IsArray = (val) => Array.isArray(val);
8
+ var IsFunction = (val) => _toString(val) === "[object Function]";
9
+ var IsObject = (val) => _toString(val) === "[object Object]";
10
+ var IsNull = (val) => val === null || val === void 0 || val === "";
11
+ var IsEqual = (a, b) => {
12
+ if (a === b) return true;
13
+ if (typeof a !== typeof b) return false;
14
+ if (a === null || b === null) return false;
15
+ if (typeof a !== "object") return false;
16
+ if (Array.isArray(a) !== Array.isArray(b)) return false;
17
+ const keysA = Object.keys(a);
18
+ const keysB = Object.keys(b);
19
+ if (keysA.length !== keysB.length) return false;
20
+ for (const key of keysA) {
21
+ if (!IsEqual(a[key], b[key])) {
22
+ return false;
23
+ }
24
+ }
25
+ return true;
26
+ };
27
+
28
+ // src/utils/validate.ts
29
+ var REGEX = {
30
+ /** 手机号(宽松:13-19 开头) */
31
+ phone: /^(?:(?:\+|00)86)?1[3-9]\d{9}$/,
32
+ /** 手机号(严谨,基于工信部 2019 年最新公布号段) */
33
+ strictPhone: /^(?:(?:\+|00)86)?1(?:(?:3\d)|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8\d)|(?:9[189]))\d{8}$/,
34
+ /** 邮箱(符合 RFC 标准) */
35
+ email: /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-_0-9]+\.)+[a-zA-Z]{2,}))$/,
36
+ /** URL(支持 http / https / ftp) */
37
+ url: /^(https?|ftp):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:/~+#]*[\w\-@?^=%&/~+#])?/,
38
+ /** IPv4 地址 */
39
+ ipv4: /^((25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/,
40
+ /** 整数(含负数和零) */
41
+ integer: /^[+-]?\d+$/,
42
+ /** 正整数(不含零) */
43
+ positiveInteger: /^[1-9]\d*$/,
44
+ /** 二代身份证 */
45
+ idcard: /^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]$/,
46
+ /** 日期(宽松,如 2022-9-1) */
47
+ date: /^\d{1,4}-(1[0-2]|0?[1-9])-(0?[1-9]|[1-2]\d|30|31)$/,
48
+ /** 16 进制颜色值 */
49
+ color: /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/
50
+ };
51
+ var IsEmail = (val) => REGEX.email.test(val);
52
+ var IsPhone = (val) => REGEX.phone.test(val);
53
+ var IsUrl = (val) => REGEX.url.test(val);
54
+ var IsIpv4 = (val) => REGEX.ipv4.test(val);
55
+ var IsInteger = (val) => REGEX.integer.test(val);
56
+ var IsPositiveInteger = (val) => REGEX.positiveInteger.test(val);
57
+
58
+ // src/utils/array.ts
59
+ var Unique = (arr) => [...new Set(arr)];
60
+ var UniqueByKey = (arr, key) => {
61
+ const seen = /* @__PURE__ */ new Set();
62
+ const result = [];
63
+ for (const item of arr) {
64
+ const k = item[key];
65
+ if (!seen.has(k)) {
66
+ seen.add(k);
67
+ result.push(item);
68
+ }
69
+ }
70
+ return result;
71
+ };
72
+ var Minus = (arr, other) => {
73
+ const otherSet = new Set(other);
74
+ return arr.filter((item) => !otherSet.has(item));
75
+ };
76
+
77
+ // src/utils/object.ts
78
+ var DeepClone = (obj) => {
79
+ if (typeof structuredClone === "function") {
80
+ return structuredClone(obj);
81
+ }
82
+ return JSON.parse(JSON.stringify(obj));
83
+ };
84
+ var CleanObject = (obj) => {
85
+ const result = {};
86
+ for (const key in obj) {
87
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
88
+ const val = obj[key];
89
+ if (val !== null && val !== void 0) {
90
+ result[key] = val;
91
+ }
92
+ }
93
+ }
94
+ return result;
95
+ };
96
+ var Pick = (obj, keys) => {
97
+ const result = {};
98
+ for (const key of keys) {
99
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
100
+ result[key] = obj[key];
101
+ }
102
+ }
103
+ return result;
104
+ };
105
+ var Omit = (obj, keys) => {
106
+ const excludeSet = new Set(keys);
107
+ const result = {};
108
+ for (const key in obj) {
109
+ if (Object.prototype.hasOwnProperty.call(obj, key) && !excludeSet.has(key)) {
110
+ result[key] = obj[key];
111
+ }
112
+ }
113
+ return result;
114
+ };
115
+
116
+ // src/utils/func.ts
117
+ var Debounce = (fn, delay = 300) => {
118
+ let timer = null;
119
+ return function(...args) {
120
+ if (timer !== null) clearTimeout(timer);
121
+ timer = setTimeout(() => {
122
+ fn.apply(this, args);
123
+ timer = null;
124
+ }, delay);
125
+ };
126
+ };
127
+ var Throttle = (fn, delay = 50) => {
128
+ let lastTime = 0;
129
+ return function(...args) {
130
+ const now = Date.now();
131
+ if (now - lastTime >= delay) {
132
+ lastTime = now;
133
+ fn.apply(this, args);
134
+ }
135
+ };
136
+ };
137
+ var Delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
138
+
139
+ // src/utils/string.ts
140
+ var UUID = () => {
141
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
142
+ return crypto.randomUUID();
143
+ }
144
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
145
+ const arr = new Uint8Array(1);
146
+ crypto.getRandomValues(arr);
147
+ const r = arr[0] & 15;
148
+ const v = c === "x" ? r : r & 3 | 8;
149
+ return v.toString(16);
150
+ });
151
+ };
152
+ var GetURLParam = (name, url = typeof window !== "undefined" ? window.location.href : "") => {
153
+ try {
154
+ return new URL(url).searchParams.get(name) ?? "";
155
+ } catch {
156
+ return "";
157
+ }
158
+ };
159
+ var GetURLParams = (url = typeof window !== "undefined" ? window.location.href : "") => {
160
+ try {
161
+ const result = {};
162
+ new URL(url).searchParams.forEach((val, key) => {
163
+ result[key] = val;
164
+ });
165
+ return result;
166
+ } catch {
167
+ return {};
168
+ }
169
+ };
170
+ var ObjectToQuery = (obj) => {
171
+ const params = new URLSearchParams();
172
+ for (const [key, val] of Object.entries(obj)) {
173
+ if (val !== null && val !== void 0) {
174
+ params.append(key, String(val));
175
+ }
176
+ }
177
+ const str = params.toString();
178
+ return str ? `?${str}` : "";
179
+ };
180
+ var QueryToObject = (query) => {
181
+ const str = query.startsWith("?") ? query.slice(1) : query;
182
+ const result = {};
183
+ new URLSearchParams(str).forEach((val, key) => {
184
+ result[key] = val;
185
+ });
186
+ return result;
187
+ };
188
+
189
+ // src/utils/time.ts
190
+ var FormatDate = (date = /* @__PURE__ */ new Date(), format = "yyyy-MM-dd HH:mm:ss") => {
191
+ const d = date instanceof Date ? date : new Date(date);
192
+ if (isNaN(d.getTime())) return "";
193
+ const map = {
194
+ "M+": d.getMonth() + 1,
195
+ "d+": d.getDate(),
196
+ "H+": d.getHours(),
197
+ "m+": d.getMinutes(),
198
+ "s+": d.getSeconds()
199
+ };
200
+ let result = format.replace(
201
+ /(y+)/,
202
+ (_, p) => String(d.getFullYear()).slice(4 - p.length)
203
+ );
204
+ for (const [pattern, value] of Object.entries(map)) {
205
+ result = result.replace(
206
+ new RegExp(`(${pattern})`),
207
+ (_, p) => String(value).padStart(p.length, "0")
208
+ );
209
+ }
210
+ return result;
211
+ };
212
+ var GetDateOffset = (date = /* @__PURE__ */ new Date(), days = 0, format = "yyyy-MM-dd HH:mm:ss") => {
213
+ const d = new Date(date.getTime());
214
+ d.setDate(d.getDate() + days);
215
+ return FormatDate(d, format);
216
+ };
217
+ var GetDayRange = (date = /* @__PURE__ */ new Date()) => {
218
+ const y = date.getFullYear();
219
+ const m = date.getMonth();
220
+ const d = date.getDate();
221
+ return {
222
+ start: new Date(y, m, d, 0, 0, 0, 0).getTime(),
223
+ end: new Date(y, m, d, 23, 59, 59, 999).getTime()
224
+ };
225
+ };
226
+
227
+ export { CleanObject, Debounce, DeepClone, Delay, FormatDate, GetDateOffset, GetDayRange, GetURLParam, GetURLParams, IsArray, IsBoolean, IsEmail, IsEqual, IsFunction, IsInteger, IsIpv4, IsNull, IsNumber, IsObject, IsPhone, IsPositiveInteger, IsRealNumber, IsString, IsUrl, Minus, ObjectToQuery, Omit, Pick, QueryToObject, REGEX, Throttle, UUID, Unique, UniqueByKey };
228
+ //# sourceMappingURL=chunk-WJX5Q3WL.js.map
229
+ //# sourceMappingURL=chunk-WJX5Q3WL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/detect.ts","../../src/utils/validate.ts","../../src/utils/array.ts","../../src/utils/object.ts","../../src/utils/func.ts","../../src/utils/string.ts","../../src/utils/time.ts"],"names":[],"mappings":"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","file":"chunk-WJX5Q3WL.js","sourcesContent":["/**\n * 类型检测工具\n *\n * 统一使用 Object.prototype.toString 确保跨环境准确性,\n * 规避 typeof null === 'object' 等已知陷阱。\n */\n\nconst _toString = (val: unknown): string => Object.prototype.toString.call(val)\n\n/**\n * 是否为数字(含可转换的字符串数字,如 '42'、'3.14')\n * @example IsNumber(42) // true\n * @example IsNumber('42') // true\n * @example IsNumber('abc') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsNumber = (val: unknown): boolean =>\n !isNaN(parseFloat(val as string)) && isFinite(val as number)\n\n/**\n * 是否为严格数字类型(不含字符串数字)\n * @example IsRealNumber(42) // true\n * @example IsRealNumber('42') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsRealNumber = (val: unknown): val is number =>\n typeof val === 'number' && !isNaN(val)\n\n/**\n * 是否为字符串\n * @example IsString('hello') // true\n * @example IsString(new String('hello')) // true\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsString = (val: unknown): val is string =>\n _toString(val) === '[object String]'\n\n/**\n * 是否为布尔值\n * @example IsBoolean(true) // true\n * @example IsBoolean(1) // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsBoolean = (val: unknown): val is boolean =>\n _toString(val) === '[object Boolean]'\n\n/**\n * 是否为数组\n * @example IsArray([1, 2]) // true\n * @example IsArray({}) // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3.5+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsArray = (val: unknown): val is unknown[] => Array.isArray(val)\n\n/**\n * 是否为函数\n * @example IsFunction(() => {}) // true\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsFunction = (val: unknown): val is (...args: unknown[]) => unknown =>\n _toString(val) === '[object Function]'\n\n/**\n * 是否为普通对象(排除 null 和数组)\n * @example IsObject({}) // true\n * @example IsObject([]) // false\n * @example IsObject(null) // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsObject = (val: unknown): val is Record<string, unknown> =>\n _toString(val) === '[object Object]'\n\n/**\n * 是否为空值(null / undefined / 空字符串)\n * @example IsNull(null) // true\n * @example IsNull(undefined) // true\n * @example IsNull('') // true\n * @example IsNull(0) // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsNull = (val: unknown): boolean =>\n val === null || val === undefined || val === ''\n\n/**\n * 深度相等比较,支持对象和数组的递归比较。\n *\n * 注意:仅比较自身可枚举属性,不比较原型链上的属性。\n * 不支持 Map、Set、Date、RegExp 等特殊对象的深度比较。\n * @example IsEqual({ a: 1 }, { a: 1 }) // true\n * @example IsEqual([1, 2], [1, 2]) // true\n * @example IsEqual({ a: 1 }, { a: 2 }) // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsEqual = (a: unknown, b: unknown): boolean => {\n if (a === b) return true\n if (typeof a !== typeof b) return false\n if (a === null || b === null) return false\n if (typeof a !== 'object') return false\n // 数组与普通对象不相等\n if (Array.isArray(a) !== Array.isArray(b)) return false\n\n const keysA = Object.keys(a as object)\n const keysB = Object.keys(b as object)\n if (keysA.length !== keysB.length) return false\n\n for (const key of keysA) {\n if (!IsEqual((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key])) {\n return false\n }\n }\n return true\n}\n","/**\n * 输入校验工具 + 常用正则常量\n */\n\n/**\n * 常用正则规则常量,来源参考 any-rule(https://github.com/any86/any-rule)\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const REGEX = {\n /** 手机号(宽松:13-19 开头) */\n phone: /^(?:(?:\\+|00)86)?1[3-9]\\d{9}$/,\n /** 手机号(严谨,基于工信部 2019 年最新公布号段) */\n strictPhone: /^(?:(?:\\+|00)86)?1(?:(?:3\\d)|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8\\d)|(?:9[189]))\\d{8}$/,\n /** 邮箱(符合 RFC 标准) */\n email: /^(([^<>()[\\]\\\\.,;:\\s@\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-_0-9]+\\.)+[a-zA-Z]{2,}))$/,\n /** URL(支持 http / https / ftp) */\n url: /^(https?|ftp):\\/\\/[\\w\\-]+(\\.[\\w\\-]+)+([\\w\\-.,@?^=%&:/~+#]*[\\w\\-@?^=%&/~+#])?/,\n /** IPv4 地址 */\n ipv4: /^((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)$/,\n /** 整数(含负数和零) */\n integer: /^[+-]?\\d+$/,\n /** 正整数(不含零) */\n positiveInteger: /^[1-9]\\d*$/,\n /** 二代身份证 */\n idcard: /^[1-9]\\d{5}(?:18|19|20)\\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\\d|30|31)\\d{3}[\\dXx]$/,\n /** 日期(宽松,如 2022-9-1) */\n date: /^\\d{1,4}-(1[0-2]|0?[1-9])-(0?[1-9]|[1-2]\\d|30|31)$/,\n /** 16 进制颜色值 */\n color: /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/,\n} as const\n\n/**\n * 是否为合法邮箱地址\n * @example IsEmail('user@example.com') // true\n * @example IsEmail('invalid') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsEmail = (val: string): boolean => REGEX.email.test(val)\n\n/**\n * 是否为中国大陆手机号(宽松校验)\n * @example IsPhone('13812345678') // true\n * @example IsPhone('12345678901') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsPhone = (val: string): boolean => REGEX.phone.test(val)\n\n/**\n * 是否为合法 URL\n * @example IsUrl('https://example.com') // true\n * @example IsUrl('not-a-url') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsUrl = (val: string): boolean => REGEX.url.test(val)\n\n/**\n * 是否为合法 IPv4 地址\n * @example IsIpv4('192.168.1.1') // true\n * @example IsIpv4('999.0.0.1') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsIpv4 = (val: string): boolean => REGEX.ipv4.test(val)\n\n/**\n * 是否为整数(含负数和零)\n * @example IsInteger('42') // true\n * @example IsInteger('-10') // true\n * @example IsInteger('3.14') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsInteger = (val: string): boolean => REGEX.integer.test(val)\n\n/**\n * 是否为正整数(不含零)\n * @example IsPositiveInteger('1') // true\n * @example IsPositiveInteger('0') // false\n * @example IsPositiveInteger('-1') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsPositiveInteger = (val: string): boolean => REGEX.positiveInteger.test(val)\n","/**\n * 数组工具\n */\n\n/**\n * 数组去重(基于 Set,时间复杂度 O(n))\n * @example Unique([1, 2, 1, 3]) // [1, 2, 3]\n * @remarks\n * 浏览器兼容性:Chrome 38+ · Firefox 13+ · Safari 7.1+ · Node.js 0.12+\n *\n * 依赖 `Set`(ES2015)。\n */\nexport const Unique = <T>(arr: T[]): T[] => [...new Set(arr)]\n\n/**\n * 按对象指定 key 的值去重,保留首次出现的元素\n * @param arr 待去重数组\n * @param key 用于去重的对象属性名\n * @example\n * UniqueByKey([{ id: 1, name: 'a' }, { id: 1, name: 'b' }], 'id')\n * // [{ id: 1, name: 'a' }]\n * @remarks\n * 浏览器兼容性:Chrome 38+ · Firefox 13+ · Safari 7.1+ · Node.js 0.12+\n *\n * 依赖 `Set`(ES2015)。\n */\nexport const UniqueByKey = <T extends object>(arr: T[], key: keyof T): T[] => {\n const seen = new Set<unknown>()\n const result: T[] = []\n for (const item of arr) {\n const k = item[key]\n if (!seen.has(k)) {\n seen.add(k)\n result.push(item)\n }\n }\n return result\n}\n\n/**\n * 差集:返回只在 arr 中存在、不在 other 中存在的元素(基于 Set,时间复杂度 O(n))\n * @param arr 基础数组\n * @param other 比较数组\n * @example Minus([1, 2, 3], [2, 3, 4]) // [1]\n * @remarks\n * 浏览器兼容性:Chrome 38+ · Firefox 13+ · Safari 7.1+ · Node.js 0.12+\n *\n * 依赖 `Set`(ES2015)。\n */\nexport const Minus = <T>(arr: T[], other: T[]): T[] => {\n const otherSet = new Set(other)\n return arr.filter(item => !otherSet.has(item))\n}\n","/**\n * 对象工具\n */\n\n/**\n * 深拷贝对象或数组。\n *\n * 优先使用原生 `structuredClone`(支持 Date、RegExp、Map、Set、循环引用等),\n * 降级为 JSON 序列化(不支持 undefined、函数、循环引用)。\n * @example DeepClone({ a: { b: 1 } }) // { a: { b: 1 } }(新对象)\n * @remarks\n * 浏览器兼容性:\n * - `structuredClone`(优先):Chrome 98+ · Firefox 94+ · Safari 15.4+ · Node.js 17.0+\n * - JSON 降级(自动回退):Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n *\n * 在不支持 `structuredClone` 的环境中自动降级为 `JSON.parse(JSON.stringify(obj))`,\n * 降级时不支持 `undefined`、函数、`Date`、`RegExp`、循环引用。\n */\nexport const DeepClone = <T>(obj: T): T => {\n if (typeof structuredClone === 'function') {\n return structuredClone(obj)\n }\n // 降级:仅适用于纯 JSON 可序列化的数据\n return JSON.parse(JSON.stringify(obj)) as T\n}\n\n/**\n * 删除对象中值为 null 或 undefined 的属性,返回新对象(不修改原对象)。\n *\n * 注意:空字符串、false、0 等假值不会被删除。\n * @example CleanObject({ a: 1, b: null, c: undefined }) // { a: 1 }\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const CleanObject = <T extends object>(obj: T): Partial<T> => {\n const result = {} as Partial<T>\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n const val = obj[key]\n if (val !== null && val !== undefined) {\n result[key] = val\n }\n }\n }\n return result\n}\n\n/**\n * 按 key 列表提取对象子集,返回新对象(类型安全)。\n * @example Pick({ a: 1, b: 2, c: 3 }, ['a', 'c']) // { a: 1, c: 3 }\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const Pick = <T extends object, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> => {\n const result = {} as Pick<T, K>\n for (const key of keys) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n result[key] = obj[key]\n }\n }\n return result\n}\n\n/**\n * 排除指定 key 后返回新对象(类型安全)。\n * @example Omit({ a: 1, b: 2, c: 3 }, ['b']) // { a: 1, c: 3 }\n * @remarks\n * 浏览器兼容性:Chrome 38+ · Firefox 13+ · Safari 7.1+ · Node.js 0.12+\n *\n * 依赖 `Set`(ES2015)。\n */\nexport const Omit = <T extends object, K extends keyof T>(obj: T, keys: K[]): Omit<T, K> => {\n const excludeSet = new Set<keyof T>(keys)\n const result = {} as Omit<T, K>\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key) && !excludeSet.has(key as keyof T)) {\n (result as Record<string, unknown>)[key] = obj[key]\n }\n }\n return result\n}\n","/**\n * 函数工具\n */\n\n/**\n * 防抖:在最后一次调用后等待 delay 毫秒再执行(trailing edge)。\n *\n * 适合搜索输入、窗口 resize、表单提交等场景。\n * @param fn 要防抖的函数\n * @param delay 延迟毫秒数,默认 300ms\n * @example\n * const handleInput = Debounce((val: string) => search(val), 500)\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n *\n * 依赖 `setTimeout` / `clearTimeout`,全平台支持。\n */\nexport const Debounce = <T extends (...args: Parameters<T>) => ReturnType<T>>(\n fn: T,\n delay = 300\n): ((...args: Parameters<T>) => void) => {\n let timer: ReturnType<typeof setTimeout> | null = null\n return function (this: ThisParameterType<T>, ...args: Parameters<T>) {\n if (timer !== null) clearTimeout(timer)\n timer = setTimeout(() => {\n fn.apply(this, args)\n timer = null\n }, delay)\n }\n}\n\n/**\n * 节流:在 delay 毫秒内最多执行一次(leading edge,时间戳实现)。\n *\n * 适合滚动监听、mousemove、高频点击等场景。\n * @param fn 要节流的函数\n * @param delay 节流间隔毫秒数,默认 50ms\n * @example\n * const handleScroll = Throttle(() => updatePosition(), 100)\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n *\n * 依赖 `Date.now()`,无 `setTimeout` 悬空回调风险。\n */\nexport const Throttle = <T extends (...args: Parameters<T>) => ReturnType<T>>(\n fn: T,\n delay = 50\n): ((...args: Parameters<T>) => void) => {\n let lastTime = 0\n return function (this: ThisParameterType<T>, ...args: Parameters<T>) {\n const now = Date.now()\n if (now - lastTime >= delay) {\n lastTime = now\n fn.apply(this, args)\n }\n }\n}\n\n/**\n * Promise 延迟:等待指定毫秒数后 resolve。\n * @param ms 延迟毫秒数\n * @example await Delay(1000) // 等待 1 秒\n * @remarks\n * 浏览器兼容性:Chrome 32+ · Firefox 29+ · Safari 8+ · Node.js 0.12+\n *\n * 依赖 `Promise`(ES2015)和 `setTimeout`。\n */\nexport const Delay = (ms: number): Promise<void> =>\n new Promise(resolve => setTimeout(resolve, ms))\n","/**\n * 字符串 / UUID / URL 工具\n */\n\n/**\n * 生成标准 RFC 4122 v4 UUID。\n *\n * 优先使用 `crypto.randomUUID()`(现代浏览器 / Node.js 19+),\n * 降级为基于 `crypto.getRandomValues` 的手动实现。\n * @example UUID() // 'f47ac10b-58cc-4372-a567-0e02b2c3d479'\n * @remarks\n * 浏览器兼容性:\n * - `crypto.randomUUID()`(优先):Chrome 92+ · Firefox 95+ · Safari 15.4+ · Node.js 19.0+\n * - `crypto.getRandomValues` 降级:Chrome 11+ · Firefox 21+ · Safari 6.1+ · Node.js 15.0+\n *\n * Node.js 14.17+ 可通过 `import { randomUUID } from 'crypto'` 单独使用,\n * 但全局 `crypto` 对象需 Node.js 15.0+ 才可用。\n */\nexport const UUID = (): string => {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID()\n }\n // 降级:RFC 4122 v4,使用 crypto.getRandomValues 保证随机性\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const arr = new Uint8Array(1)\n crypto.getRandomValues(arr)\n const r = arr[0] & 0xf\n const v = c === 'x' ? r : (r & 0x3) | 0x8\n return v.toString(16)\n })\n}\n\n/**\n * 从 URL 中获取指定查询参数的值,不存在则返回空字符串。\n * @param name 参数名\n * @param url 目标 URL,默认取 `window.location.href`\n * @example GetURLParam('page', 'https://example.com?page=2&size=10') // '2'\n * @remarks\n * 浏览器兼容性:Chrome 49+ · Firefox 44+ · Safari 10.1+ · Node.js 10.0+\n *\n * 依赖 `URL` API 和 `URLSearchParams`(WHATWG URL Standard)。\n * 若 URL 格式非法会静默返回空字符串。\n */\nexport const GetURLParam = (\n name: string,\n url: string = typeof window !== 'undefined' ? window.location.href : ''\n): string => {\n try {\n return new URL(url).searchParams.get(name) ?? ''\n } catch {\n return ''\n }\n}\n\n/**\n * 获取 URL 中所有查询参数,以键值对对象返回。\n *\n * 若同名参数出现多次,取最后一个值。\n * @param url 目标 URL,默认取 `window.location.href`\n * @example GetURLParams('https://example.com?a=1&b=2') // { a: '1', b: '2' }\n * @remarks\n * 浏览器兼容性:Chrome 49+ · Firefox 44+ · Safari 10.1+ · Node.js 10.0+\n *\n * 依赖 `URL` API 和 `URLSearchParams`(WHATWG URL Standard)。\n * 若 URL 格式非法会静默返回空对象。\n */\nexport const GetURLParams = (\n url: string = typeof window !== 'undefined' ? window.location.href : ''\n): Record<string, string> => {\n try {\n const result: Record<string, string> = {}\n new URL(url).searchParams.forEach((val, key) => {\n result[key] = val\n })\n return result\n } catch {\n return {}\n }\n}\n\n/**\n * 将对象转换为 URL 查询字符串(以 `?` 开头)。\n *\n * 值为 null / undefined 的属性会被跳过,特殊字符自动编码。\n * @example ObjectToQuery({ page: 1, size: 10 }) // '?page=1&size=10'\n * @example ObjectToQuery({}) // ''\n * @remarks\n * 浏览器兼容性:Chrome 49+ · Firefox 44+ · Safari 10.1+ · Node.js 10.0+\n *\n * 依赖 `URLSearchParams`(WHATWG URL Standard)。\n * 空格编码为 `+`(application/x-www-form-urlencoded 规范),\n * 与 `encodeURIComponent` 的 `%20` 编码略有差异。\n */\nexport const ObjectToQuery = (obj: Record<string, unknown>): string => {\n const params = new URLSearchParams()\n for (const [key, val] of Object.entries(obj)) {\n if (val !== null && val !== undefined) {\n params.append(key, String(val))\n }\n }\n const str = params.toString()\n return str ? `?${str}` : ''\n}\n\n/**\n * 将查询字符串解析为键值对对象。\n *\n * 支持以 `?` 开头或不以 `?` 开头的格式,自动解码编码字符。\n * @example QueryToObject('?a=1&b=hello%20world') // { a: '1', b: 'hello world' }\n * @remarks\n * 浏览器兼容性:Chrome 49+ · Firefox 44+ · Safari 10.1+ · Node.js 10.0+\n *\n * 依赖 `URLSearchParams`(WHATWG URL Standard)。\n */\nexport const QueryToObject = (query: string): Record<string, string> => {\n const str = query.startsWith('?') ? query.slice(1) : query\n const result: Record<string, string> = {}\n new URLSearchParams(str).forEach((val, key) => {\n result[key] = val\n })\n return result\n}\n","/**\n * 时间日期工具\n */\n\n/**\n * 格式化日期时间。\n *\n * 支持占位符:`yyyy`(年)、`MM`(月)、`dd`(日)、`HH`(24 小时制小时)、`mm`(分钟)、`ss`(秒)。\n * @param date 日期,默认当前时间,支持 Date 对象、日期字符串、时间戳\n * @param format 格式字符串,默认 `'yyyy-MM-dd HH:mm:ss'`\n * @example FormatDate(new Date('2024-01-05 09:05:03')) // '2024-01-05 09:05:03'\n * @example FormatDate(new Date('2024-01-05'), 'yyyy/MM/dd') // '2024/01/05'\n * @example FormatDate(new Date('2024-01-05'), 'yy-MM-dd') // '24-01-05'\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n *\n * 依赖原生 `Date` API,全平台支持。\n * 传入非法日期字符串时返回空字符串。\n */\nexport const FormatDate = (\n date: Date | string | number = new Date(),\n format = 'yyyy-MM-dd HH:mm:ss'\n): string => {\n const d = date instanceof Date ? date : new Date(date)\n if (isNaN(d.getTime())) return ''\n\n const map: Record<string, number> = {\n 'M+': d.getMonth() + 1,\n 'd+': d.getDate(),\n 'H+': d.getHours(),\n 'm+': d.getMinutes(),\n 's+': d.getSeconds(),\n }\n\n // 年份单独处理(支持 yy / yyyy)\n let result = format.replace(/(y+)/, (_, p: string) =>\n String(d.getFullYear()).slice(4 - p.length)\n )\n\n for (const [pattern, value] of Object.entries(map)) {\n result = result.replace(new RegExp(`(${pattern})`), (_, p: string) =>\n String(value).padStart(p.length, '0')\n )\n }\n\n return result\n}\n\n/**\n * 获取指定日期偏移 N 天后的日期字符串。\n *\n * 正数表示往后,负数表示往前。不修改传入的 Date 对象。\n * @param date 基准日期,默认当前时间\n * @param days 偏移天数(正数往后,负数往前)\n * @param format 格式字符串,默认 `'yyyy-MM-dd HH:mm:ss'`\n * @example GetDateOffset(new Date('2024-01-10'), 3, 'yyyy-MM-dd') // '2024-01-13'\n * @example GetDateOffset(new Date('2024-01-10'), -3, 'yyyy-MM-dd') // '2024-01-07'\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n *\n * 依赖原生 `Date` API,全平台支持。\n */\nexport const GetDateOffset = (\n date: Date = new Date(),\n days = 0,\n format = 'yyyy-MM-dd HH:mm:ss'\n): string => {\n const d = new Date(date.getTime())\n d.setDate(d.getDate() + days)\n return FormatDate(d, format)\n}\n\n/**\n * 获取指定日期当天的开始时间戳(00:00:00.000)和结束时间戳(23:59:59.999)。\n * @param date 指定日期,默认当前时间\n * @example GetDayRange(new Date('2024-01-05'))\n * // { start: 1704384000000, end: 1704470399999 }\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n *\n * 依赖原生 `Date` API,全平台支持。\n * 时间戳基于本地时区计算。\n */\nexport const GetDayRange = (\n date: Date = new Date()\n): { start: number; end: number } => {\n const y = date.getFullYear()\n const m = date.getMonth()\n const d = date.getDate()\n return {\n start: new Date(y, m, d, 0, 0, 0, 0).getTime(),\n end: new Date(y, m, d, 23, 59, 59, 999).getTime(),\n }\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  import axios, { isAxiosError } from 'axios';
2
2
 
3
3
  // src/http/context.ts
4
+ var DEBUGGER_ACTIVE_KEY = "__snackkit_debugger__active";
4
5
  var HttpContext = class {
5
6
  constructor() {
6
7
  this._store = /* @__PURE__ */ new Map();
@@ -9,12 +10,24 @@ var HttpContext = class {
9
10
  /**
10
11
  * 加载服务地址映射
11
12
  *
13
+ * 支持三种调用方式:
14
+ * - **传入字符串**:作为网关地址,自动请求 `GET /ngw/context` 获取映射表
15
+ * - **传入对象**:直接注入键值映射,不发起网络请求
16
+ * - **不传参数**:
17
+ * - 生产环境(`NODE_ENV === 'production'`):以当前页面 `Origin` 为网关地址自动加载
18
+ * - 开发环境:立即返回,不做任何操作(应由 `Debugger.init()` 接管加载流程)
19
+ *
12
20
  * 远程加载时,响应中的 `$info` 元数据字段会被单独存储,不计入路由映射表。
13
21
  *
14
- * @param source 远程加载传入网关 URL;本地注入传入键值对象
22
+ * @param source 网关 URL / 键值对象 / 省略
15
23
  * @param timeout 远程加载超时(ms),默认 5000
16
24
  *
17
- * @example 远程加载
25
+ * @example 不传参——生产环境自动使用当前页面 Origin
26
+ * ```ts
27
+ * await Context.load()
28
+ * ```
29
+ *
30
+ * @example 传入网关地址
18
31
  * ```ts
19
32
  * await Context.load('http://172.16.32.155:20000', 3000)
20
33
  * ```
@@ -25,6 +38,11 @@ var HttpContext = class {
25
38
  * ```
26
39
  */
27
40
  async load(source, timeout = 5e3) {
41
+ if (source === void 0) {
42
+ if (globalThis[DEBUGGER_ACTIVE_KEY]) return;
43
+ if (!Origin) return;
44
+ source = Origin;
45
+ }
28
46
  if (typeof source === "string") {
29
47
  const url = `${source}/ngw/context`;
30
48
  const res = await axios.get(url, { timeout });
@@ -176,22 +194,37 @@ async function Request(config) {
176
194
  Unregister(cancelId);
177
195
  }
178
196
  }
179
- function Get(url, config) {
180
- return Request({ ...config, method: "GET", url });
197
+ function Get(urlOrConfig, config) {
198
+ if (typeof urlOrConfig === "string") {
199
+ return Request({ ...config, method: "GET", url: urlOrConfig });
200
+ }
201
+ return Request({ ...urlOrConfig, method: "GET" });
181
202
  }
182
- function Post(url, data, config) {
183
- return Request({ ...config, method: "POST", url, data });
203
+ function Post(urlOrConfig, data, config) {
204
+ if (typeof urlOrConfig === "string") {
205
+ return Request({ ...config, method: "POST", url: urlOrConfig, data });
206
+ }
207
+ return Request({ ...urlOrConfig, method: "POST" });
184
208
  }
185
- function Put(url, data, config) {
186
- return Request({ ...config, method: "PUT", url, data });
209
+ function Put(urlOrConfig, data, config) {
210
+ if (typeof urlOrConfig === "string") {
211
+ return Request({ ...config, method: "PUT", url: urlOrConfig, data });
212
+ }
213
+ return Request({ ...urlOrConfig, method: "PUT" });
187
214
  }
188
- function Patch(url, data, config) {
189
- return Request({ ...config, method: "PATCH", url, data });
215
+ function Patch(urlOrConfig, data, config) {
216
+ if (typeof urlOrConfig === "string") {
217
+ return Request({ ...config, method: "PATCH", url: urlOrConfig, data });
218
+ }
219
+ return Request({ ...urlOrConfig, method: "PATCH" });
190
220
  }
191
- function Del(url, config) {
192
- return Request({ ...config, method: "DELETE", url });
221
+ function Del(urlOrConfig, config) {
222
+ if (typeof urlOrConfig === "string") {
223
+ return Request({ ...config, method: "DELETE", url: urlOrConfig });
224
+ }
225
+ return Request({ ...urlOrConfig, method: "DELETE" });
193
226
  }
194
227
 
195
- export { Cancel, CancelAll, Context, Ctx, Del, Get, HttpContext, Origin, Patch, Post, Put, Request };
196
- //# sourceMappingURL=chunk-JQYH5FWE.js.map
197
- //# sourceMappingURL=chunk-JQYH5FWE.js.map
228
+ export { Cancel, CancelAll, Context, Ctx, DEBUGGER_ACTIVE_KEY, Del, Get, HttpContext, Origin, Patch, Post, Put, Request };
229
+ //# sourceMappingURL=chunk-YV6SGXUJ.js.map
230
+ //# sourceMappingURL=chunk-YV6SGXUJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/http/context.ts","../../src/http/cancel.ts","../../src/http/client.ts"],"names":["axios"],"mappings":"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","file":"chunk-YV6SGXUJ.js","sourcesContent":["import axios from 'axios'\nimport type { ContextInfo } from './types'\n\n/**\n * globalThis 上的标志位 key,由 `Debugger.init()` 写入。\n * `Context.load()` 无参数调用时,若检测到此标志则跳过自动加载,\n * 由 Debugger 负责在用户选择服务后调用 `Context.load(origin)`。\n */\nexport const DEBUGGER_ACTIVE_KEY = '__snackkit_debugger__active'\n\n/** 网关 `/ngw/context` 原始响应格式(包含路由映射和 `$info` 元数据) */\ninterface ContextResponse {\n $info?: ContextInfo\n [key: string]: string | ContextInfo | undefined\n}\n\n/**\n * 管理服务地址映射的上下文单例\n *\n * 支持三种加载方式:\n * - **不传参数**:生产环境自动以当前页面 Origin 为网关,开发环境由 `Debugger` 接管\n * - **远程加载**:传入网关 URL,自动请求 `GET /ngw/context` 获取映射表\n * - **本地注入**:直接传入键值对象,不发起网络请求\n *\n * @example 生产环境不传参(推荐)\n * ```ts\n * import { Context } from '@snack-kit/lib/http'\n *\n * await Context.load()\n * Context.get('ngw') // 'https://app.example.com/ngw'\n * ```\n *\n * @example 远程加载(指定网关)\n * ```ts\n * await Context.load('http://172.16.32.155:20000')\n * Context.get('ngw') // 'http://172.16.32.155:20000/ngw'\n * Context.info // { version: '4.6.2-r10', domain: '...', ... }\n * ```\n *\n * @example 本地注入\n * ```ts\n * await Context.load({\n * 'user-svc': 'http://user.api.com',\n * 'order-svc': 'http://order.api.com',\n * })\n * ```\n */\nexport class HttpContext {\n private _store = new Map<string, string>()\n private _loaded = false\n private _info: ContextInfo | undefined\n\n /**\n * 加载服务地址映射\n *\n * 支持三种调用方式:\n * - **传入字符串**:作为网关地址,自动请求 `GET /ngw/context` 获取映射表\n * - **传入对象**:直接注入键值映射,不发起网络请求\n * - **不传参数**:\n * - 生产环境(`NODE_ENV === 'production'`):以当前页面 `Origin` 为网关地址自动加载\n * - 开发环境:立即返回,不做任何操作(应由 `Debugger.init()` 接管加载流程)\n *\n * 远程加载时,响应中的 `$info` 元数据字段会被单独存储,不计入路由映射表。\n *\n * @param source 网关 URL / 键值对象 / 省略\n * @param timeout 远程加载超时(ms),默认 5000\n *\n * @example 不传参——生产环境自动使用当前页面 Origin\n * ```ts\n * await Context.load()\n * ```\n *\n * @example 传入网关地址\n * ```ts\n * await Context.load('http://172.16.32.155:20000', 3000)\n * ```\n *\n * @example 本地注入\n * ```ts\n * await Context.load({ 'user-svc': 'http://user.api.com' })\n * ```\n */\n async load(source?: string | Record<string, string>, timeout = 5000): Promise<void> {\n if (source === undefined) {\n // Debugger 已激活时,由其负责加载,此处跳过\n if ((globalThis as Record<string, unknown>)[DEBUGGER_ACTIVE_KEY]) return\n // 生产环境:以当前页面 Origin 为网关地址\n if (!Origin) return\n source = Origin\n }\n if (typeof source === 'string') {\n const url = `${source}/ngw/context`\n const res = await axios.get<ContextResponse>(url, { timeout })\n const data = res.data\n if (data && typeof data === 'object') {\n this._store.clear()\n for (const [k, v] of Object.entries(data)) {\n if (k === '$info') {\n // 保存元数据,不计入路由映射\n this._info = v as ContextInfo\n } else if (typeof v === 'string') {\n this._store.set(k, v)\n }\n }\n }\n } else {\n this._store.clear()\n for (const [k, v] of Object.entries(source)) {\n this._store.set(k, v)\n }\n }\n this._loaded = true\n }\n\n /**\n * 获取指定 ctx key 对应的服务地址\n * @param key ctx key,例如 `'ngw'`、`'osc'`\n * @returns 服务地址,未找到时返回空字符串\n *\n * @example\n * ```ts\n * await Context.load('http://172.16.32.155:20000')\n * Context.get('osc') // 'http://172.16.32.155:20000/osc'\n * Context.get('none') // ''\n * ```\n */\n get(key: string): string {\n return this._store.get(key) ?? ''\n }\n\n /**\n * 网关元数据(仅远程加载后可用)\n *\n * @example\n * ```ts\n * await Context.load('http://172.16.32.155:20000')\n * Context.info?.version // '4.6.2-r10'\n * Context.info?.domain // 'http://172.16.32.155:20000'\n * ```\n */\n get info(): ContextInfo | undefined {\n return this._info\n }\n\n /**\n * Context 是否已加载\n *\n * @example\n * ```ts\n * Context.loaded // false\n * await Context.load({ 'user-svc': 'http://user.api.com' })\n * Context.loaded // true\n * ```\n */\n get loaded(): boolean {\n return this._loaded\n }\n\n /**\n * 清空所有映射并重置加载状态\n *\n * @example\n * ```ts\n * Context.clear()\n * Context.loaded // false\n * ```\n */\n clear(): void {\n this._store.clear()\n this._loaded = false\n this._info = undefined\n }\n}\n\n/** 模块级单例,避免全局 window 污染 */\nconst _instance = new HttpContext()\n\n/**\n * HttpContext 全局单例\n *\n * @example\n * ```ts\n * import { Context } from '@snack-kit/lib/http'\n *\n * await Context.load('http://172.16.32.155:20000')\n * Context.get('osc') // 'http://172.16.32.155:20000/osc'\n * ```\n */\nexport const Context: HttpContext = _instance\n\n/** 浏览器 location 对象(兼容 Node/SSR 环境) */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst _loc: { protocol?: string; host?: string; pathname?: string } | undefined =\n typeof globalThis !== 'undefined'\n ? ((globalThis as Record<string, unknown>)['location'] as typeof _loc)\n : undefined\n\n/**\n * 当前页面的 origin(`protocol + host`)\n *\n * 在非浏览器环境(如 SSR/Node)返回空字符串。\n *\n * @example\n * ```ts\n * import { Origin } from '@snack-kit/lib/http'\n * // 浏览器中:'https://app.example.com'\n * // Node 环境:''\n * ```\n */\nexport const Origin: string =\n _loc?.protocol && _loc?.host ? `${_loc.protocol}//${_loc.host}` : ''\n\n/**\n * 当前页面路径的首段,可直接用作 `ctx` 参数\n *\n * 例如 `/osc/employee` → `'osc'`,在非浏览器环境返回空字符串。\n *\n * @example\n * ```ts\n * import { Ctx, Get } from '@snack-kit/lib/http'\n *\n * // 当前路径为 /osc/... 时,Ctx === 'osc'\n * const result = await Get('/employee', { ctx: Ctx })\n * ```\n */\nexport const Ctx: string = _loc?.pathname ? (_loc.pathname.split('/')[1] ?? '') : ''\n","/** 模块私有注册表,避免全局 window 污染 */\nconst registry = new Map<string, AbortController>()\n\n/**\n * 注册一个请求取消控制器\n *\n * 若已存在相同 id 的控制器,先取消旧请求再注册新的。\n *\n * @param id 请求唯一标识\n * @returns 新创建的 AbortController\n *\n * @example\n * ```ts\n * import { Register, Cancel } from '@snack-kit/lib/http'\n *\n * const ctrl = Register('my-req')\n * // 请求进行中时手动取消\n * Cancel('my-req')\n * ```\n */\nexport function Register(id: string): AbortController {\n if (registry.has(id)) {\n registry.get(id)!.abort()\n }\n const controller = new AbortController()\n registry.set(id, controller)\n return controller\n}\n\n/**\n * 取消指定 id 的请求并从注册表移除\n *\n * @param id 请求唯一标识\n * @returns 是否找到并取消了请求\n *\n * @example\n * ```ts\n * import { Get, Cancel } from '@snack-kit/lib/http'\n *\n * let cancelId = ''\n * Get('/api/data', { onCancelId: (id) => { cancelId = id } })\n *\n * // 需要时取消\n * Cancel(cancelId)\n * ```\n */\nexport function Cancel(id: string): boolean {\n const controller = registry.get(id)\n if (!controller) return false\n controller.abort()\n registry.delete(id)\n return true\n}\n\n/**\n * 取消所有已注册的请求并清空注册表\n *\n * @example\n * ```ts\n * import { CancelAll } from '@snack-kit/lib/http'\n *\n * // 页面卸载时取消所有进行中的请求\n * window.addEventListener('beforeunload', () => CancelAll())\n * ```\n */\nexport function CancelAll(): void {\n for (const controller of registry.values()) {\n controller.abort()\n }\n registry.clear()\n}\n\n/**\n * 从注册表中移除指定 id(不触发取消,用于请求完成后内部清理)\n *\n * @param id 请求唯一标识\n */\nexport function Unregister(id: string): void {\n registry.delete(id)\n}\n","import axios, { isAxiosError } from 'axios'\nimport { Context } from './context'\nimport { Register, Unregister } from './cancel'\nimport type { HttpRequestConfig, HttpMethodConfig, HttpResult } from './types'\n\n/** 生成请求唯一 ID */\nfunction generateId(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID()\n }\n return `${Date.now()}-${Math.random().toString(36).slice(2)}`\n}\n\n/**\n * 核心请求函数,所有快捷方法基于此实现\n *\n * 自动处理:\n * - `ctx` → 从 HttpContext 查询 baseURL 并注入\n * - `cache: false`(默认)→ URL 附加 `?_=timestamp` 防缓存\n * - 请求取消 → 自动注册 AbortController,完成后自动清理\n * - 错误捕获 → 统一返回 `{ error }` 而非 throw\n *\n * @param config 请求配置\n * @returns 请求结果\n *\n * @example 基础用法\n * ```ts\n * import { Request } from '@snack-kit/lib/http'\n *\n * const result = await Request<{ id: number }>({ url: '/api/user', method: 'GET' })\n * if (result.error) {\n * console.error(result.error.message)\n * } else {\n * console.log(result.data)\n * }\n * ```\n *\n * @example 使用 ctx 自动注入 baseURL\n * ```ts\n * import { context, Request } from '@snack-kit/lib/http'\n *\n * await context.load({ 'user-svc': 'http://user.api.com' })\n * const result = await Request({ url: '/profile', method: 'GET', ctx: 'user-svc' })\n * // 实际请求:GET http://user.api.com/profile\n * ```\n */\nexport async function Request<T>(config: HttpRequestConfig): Promise<HttpResult<T>> {\n const { ctx, cancelId: customCancelId, onCancelId, cache = false, ...axiosConfig } = config\n\n // ctx 自动注入 baseURL\n if (ctx && Context.loaded) {\n const base = Context.get(ctx)\n if (base) {\n axiosConfig.baseURL = base\n }\n }\n\n // 防缓存:默认添加时间戳参数\n if (!cache) {\n const sep = (axiosConfig.url ?? '').includes('?') ? '&' : '?'\n axiosConfig.url = `${axiosConfig.url ?? ''}${sep}_=${Date.now()}`\n }\n\n // 注册取消控制器\n const cancelId = customCancelId ?? generateId()\n const controller = Register(cancelId)\n axiosConfig.signal = controller.signal\n onCancelId?.(cancelId)\n\n try {\n const response = await axios.request<T>({ ...axiosConfig })\n return response\n } catch (err) {\n if (isAxiosError(err)) {\n return {\n error: {\n status: err.response?.status,\n message: err.message,\n data: err.response?.data,\n },\n }\n }\n // AbortError 或其他非 axios 错误\n const message = err instanceof Error ? err.message : String(err)\n return { error: { message } }\n } finally {\n Unregister(cancelId)\n }\n}\n\n/**\n * 发起 GET 请求\n *\n * 支持两种调用方式:\n * - `Get(url, config?)` — 位置参数形式\n * - `Get(config)` — 纯配置对象形式(`method` 已预置,无需传入)\n *\n * @example 位置参数\n * ```ts\n * const { data, error } = await Get<{ name: string }>('/api/user/1')\n * ```\n *\n * @example 配置对象\n * ```ts\n * const { data } = await Get({ url: '/api/user/1', ctx: 'user-svc' })\n * ```\n *\n * @example 获取 cancelId 以便主动取消\n * ```ts\n * let cancelId = ''\n * Get('/api/list', { onCancelId: (id) => { cancelId = id } })\n * Cancel(cancelId)\n * ```\n */\nexport function Get<T>(url: string, config?: HttpMethodConfig): Promise<HttpResult<T>>\nexport function Get<T>(config: HttpMethodConfig): Promise<HttpResult<T>>\nexport function Get<T>(\n urlOrConfig: string | HttpMethodConfig,\n config?: HttpMethodConfig,\n): Promise<HttpResult<T>> {\n if (typeof urlOrConfig === 'string') {\n return Request<T>({ ...config, method: 'GET', url: urlOrConfig })\n }\n return Request<T>({ ...urlOrConfig, method: 'GET' })\n}\n\n/**\n * 发起 POST 请求\n *\n * 支持两种调用方式:\n * - `Post(url, data?, config?)` — 位置参数形式\n * - `Post(config)` — 纯配置对象形式(`data` 通过 `config.data` 传入,`method` 已预置)\n *\n * @example 位置参数\n * ```ts\n * const { data, error } = await Post<{ token: string }>('/api/login', {\n * username: 'admin',\n * password: '123456',\n * })\n * ```\n *\n * @example 配置对象\n * ```ts\n * const { data } = await Post({\n * url: '/api/login',\n * data: { username: 'admin', password: '123456' },\n * ctx: 'user-svc',\n * })\n * ```\n */\nexport function Post<T>(url: string, data?: unknown, config?: HttpMethodConfig): Promise<HttpResult<T>>\nexport function Post<T>(config: HttpMethodConfig): Promise<HttpResult<T>>\nexport function Post<T>(\n urlOrConfig: string | HttpMethodConfig,\n data?: unknown,\n config?: HttpMethodConfig,\n): Promise<HttpResult<T>> {\n if (typeof urlOrConfig === 'string') {\n return Request<T>({ ...config, method: 'POST', url: urlOrConfig, data })\n }\n return Request<T>({ ...urlOrConfig, method: 'POST' })\n}\n\n/**\n * 发起 PUT 请求\n *\n * 支持两种调用方式:\n * - `Put(url, data?, config?)` — 位置参数形式\n * - `Put(config)` — 纯配置对象形式(`data` 通过 `config.data` 传入,`method` 已预置)\n *\n * @example 位置参数\n * ```ts\n * await Put('/api/user/1', { name: 'Alice' })\n * ```\n *\n * @example 配置对象\n * ```ts\n * await Put({ url: '/api/user/1', data: { name: 'Alice' }, ctx: 'user-svc' })\n * ```\n */\nexport function Put<T>(url: string, data?: unknown, config?: HttpMethodConfig): Promise<HttpResult<T>>\nexport function Put<T>(config: HttpMethodConfig): Promise<HttpResult<T>>\nexport function Put<T>(\n urlOrConfig: string | HttpMethodConfig,\n data?: unknown,\n config?: HttpMethodConfig,\n): Promise<HttpResult<T>> {\n if (typeof urlOrConfig === 'string') {\n return Request<T>({ ...config, method: 'PUT', url: urlOrConfig, data })\n }\n return Request<T>({ ...urlOrConfig, method: 'PUT' })\n}\n\n/**\n * 发起 PATCH 请求\n *\n * 支持两种调用方式:\n * - `Patch(url, data?, config?)` — 位置参数形式\n * - `Patch(config)` — 纯配置对象形式(`data` 通过 `config.data` 传入,`method` 已预置)\n *\n * @example 位置参数\n * ```ts\n * await Patch('/api/user/1', { avatar: 'https://...' })\n * ```\n *\n * @example 配置对象\n * ```ts\n * await Patch({ url: '/api/user/1', data: { avatar: 'https://...' }, ctx: 'user-svc' })\n * ```\n */\nexport function Patch<T>(url: string, data?: unknown, config?: HttpMethodConfig): Promise<HttpResult<T>>\nexport function Patch<T>(config: HttpMethodConfig): Promise<HttpResult<T>>\nexport function Patch<T>(\n urlOrConfig: string | HttpMethodConfig,\n data?: unknown,\n config?: HttpMethodConfig,\n): Promise<HttpResult<T>> {\n if (typeof urlOrConfig === 'string') {\n return Request<T>({ ...config, method: 'PATCH', url: urlOrConfig, data })\n }\n return Request<T>({ ...urlOrConfig, method: 'PATCH' })\n}\n\n/**\n * 发起 DELETE 请求\n *\n * 支持两种调用方式:\n * - `Del(url, config?)` — 位置参数形式\n * - `Del(config)` — 纯配置对象形式(`method` 已预置)\n *\n * @example 位置参数\n * ```ts\n * await Del('/api/user/1')\n * ```\n *\n * @example 配置对象\n * ```ts\n * await Del({ url: '/api/user/1', ctx: 'user-svc' })\n * ```\n */\nexport function Del<T>(url: string, config?: HttpMethodConfig): Promise<HttpResult<T>>\nexport function Del<T>(config: HttpMethodConfig): Promise<HttpResult<T>>\nexport function Del<T>(\n urlOrConfig: string | HttpMethodConfig,\n config?: HttpMethodConfig,\n): Promise<HttpResult<T>> {\n if (typeof urlOrConfig === 'string') {\n return Request<T>({ ...config, method: 'DELETE', url: urlOrConfig })\n }\n return Request<T>({ ...urlOrConfig, method: 'DELETE' })\n}\n"]}
@@ -1,4 +1,4 @@
1
- export { Debugger } from './chunk-4DLFIN3C.js';
2
- import './chunk-JQYH5FWE.js';
1
+ export { Debugger } from './chunk-4SGFAIRT.js';
2
+ export { DEBUGGER_ACTIVE_KEY } from './chunk-YV6SGXUJ.js';
3
3
  //# sourceMappingURL=debugger.js.map
4
4
  //# sourceMappingURL=debugger.js.map
package/dist/es/http.js CHANGED
@@ -1,4 +1,4 @@
1
1
  import './chunk-BEL6AFK4.js';
2
- export { Cancel, CancelAll, Context, Ctx, Del, Get, HttpContext, Origin, Patch, Post, Put, Request } from './chunk-JQYH5FWE.js';
2
+ export { Cancel, CancelAll, Context, Ctx, Del, Get, HttpContext, Origin, Patch, Post, Put, Request } from './chunk-YV6SGXUJ.js';
3
3
  //# sourceMappingURL=http.js.map
4
4
  //# sourceMappingURL=http.js.map
package/dist/es/index.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import './chunk-BEL6AFK4.js';
2
- export { Debugger } from './chunk-4DLFIN3C.js';
3
- export { Cancel, CancelAll, Context, Ctx, Del, Get, HttpContext, Origin, Patch, Post, Put, Request } from './chunk-JQYH5FWE.js';
2
+ export { Debugger } from './chunk-4SGFAIRT.js';
3
+ export { Cancel, CancelAll, Context, Ctx, DEBUGGER_ACTIVE_KEY, Del, Get, HttpContext, Origin, Patch, Post, Put, Request } from './chunk-YV6SGXUJ.js';
4
+ export { CleanObject, Debounce, DeepClone, Delay, FormatDate, GetDateOffset, GetDayRange, GetURLParam, GetURLParams, IsArray, IsBoolean, IsEmail, IsEqual, IsFunction, IsInteger, IsIpv4, IsNull, IsNumber, IsObject, IsPhone, IsPositiveInteger, IsRealNumber, IsString, IsUrl, Minus, ObjectToQuery, Omit, Pick, QueryToObject, REGEX, Throttle, UUID, Unique, UniqueByKey } from './chunk-WJX5Q3WL.js';
4
5
 
5
6
  // package.json
6
- var version = "0.2.0";
7
+ var version = "0.4.0";
7
8
 
8
9
  export { version as VERSION };
9
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../package.json"],"names":[],"mappings":";;;;;AAEE,IAAA,OAAA,GAAW","file":"index.js","sourcesContent":["{\n \"name\": \"@snack-kit/lib\",\n \"version\": \"0.2.0\",\n \"description\": \"Enterprise-grade utility library\",\n \"keywords\": [],\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/types/index.d.ts\",\n \"import\": \"./dist/es/index.js\",\n \"require\": \"./dist/cjs/index.cjs\"\n },\n \"./http\": {\n \"types\": \"./dist/types/http.d.ts\",\n \"import\": \"./dist/es/http.js\",\n \"require\": \"./dist/cjs/http.cjs\"\n },\n \"./debugger\": {\n \"types\": \"./dist/types/debugger.d.ts\",\n \"import\": \"./dist/es/debugger.js\",\n \"require\": \"./dist/cjs/debugger.cjs\"\n }\n },\n \"main\": \"./dist/cjs/index.cjs\",\n \"module\": \"./dist/es/index.js\",\n \"types\": \"./dist/types/index.d.ts\",\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"build:watch\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"docs\": \"typedoc && cp -r docs/demo docs/api/demo\",\n \"docs:watch\": \"typedoc --watch\",\n \"lint\": \"tsc --noEmit\",\n \"prepublishOnly\": \"npm run build\",\n \"release\": \"npm run build && npm publish --access public\"\n },\n \"devDependencies\": {\n \"@vitest/coverage-v8\": \"^2.0.0\",\n \"tsup\": \"^8.0.0\",\n \"typedoc\": \"^0.26.0\",\n \"typescript\": \"^5.5.3\",\n \"vitest\": \"^2.0.0\"\n },\n \"dependencies\": {\n \"axios\": \"^1.13.6\"\n }\n}\n"]}
1
+ {"version":3,"sources":["../../package.json"],"names":[],"mappings":";;;;;;AAEE,IAAA,OAAA,GAAW","file":"index.js","sourcesContent":["{\n \"name\": \"@snack-kit/lib\",\n \"version\": \"0.4.0\",\n \"description\": \"Enterprise-grade utility library\",\n \"keywords\": [],\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/types/index.d.ts\",\n \"import\": \"./dist/es/index.js\",\n \"require\": \"./dist/cjs/index.cjs\"\n },\n \"./http\": {\n \"types\": \"./dist/types/http.d.ts\",\n \"import\": \"./dist/es/http.js\",\n \"require\": \"./dist/cjs/http.cjs\"\n },\n \"./debugger\": {\n \"types\": \"./dist/types/debugger.d.ts\",\n \"import\": \"./dist/es/debugger.js\",\n \"require\": \"./dist/cjs/debugger.cjs\"\n },\n \"./utils\": {\n \"types\": \"./dist/types/utils.d.ts\",\n \"import\": \"./dist/es/utils.js\",\n \"require\": \"./dist/cjs/utils.cjs\"\n }\n },\n \"main\": \"./dist/cjs/index.cjs\",\n \"module\": \"./dist/es/index.js\",\n \"types\": \"./dist/types/index.d.ts\",\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"build:watch\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"docs\": \"typedoc && cp -r docs/demo docs/api/demo\",\n \"docs:watch\": \"typedoc --watch\",\n \"lint\": \"tsc --noEmit\",\n \"prepublishOnly\": \"npm run build\",\n \"release\": \"npm run build && npm publish --access public\"\n },\n \"devDependencies\": {\n \"@vitest/coverage-v8\": \"^2.0.0\",\n \"tsup\": \"^8.0.0\",\n \"typedoc\": \"^0.26.0\",\n \"typescript\": \"^5.5.3\",\n \"vitest\": \"^2.0.0\"\n },\n \"dependencies\": {\n \"axios\": \"^1.13.6\"\n }\n}\n"]}
@@ -0,0 +1,3 @@
1
+ export { CleanObject, Debounce, DeepClone, Delay, FormatDate, GetDateOffset, GetDayRange, GetURLParam, GetURLParams, IsArray, IsBoolean, IsEmail, IsEqual, IsFunction, IsInteger, IsIpv4, IsNull, IsNumber, IsObject, IsPhone, IsPositiveInteger, IsRealNumber, IsString, IsUrl, Minus, ObjectToQuery, Omit, Pick, QueryToObject, REGEX, Throttle, UUID, Unique, UniqueByKey } from './chunk-WJX5Q3WL.js';
2
+ //# sourceMappingURL=utils.js.map
3
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"utils.js"}