@cloudcome/utils-core 1.1.1 → 1.2.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.
- package/dist/array.cjs +129 -0
- package/dist/array.cjs.map +1 -0
- package/dist/array.d.ts +171 -0
- package/dist/array.mjs +129 -0
- package/dist/array.mjs.map +1 -0
- package/dist/async.cjs +219 -0
- package/dist/async.cjs.map +1 -0
- package/dist/async.d.ts +137 -0
- package/dist/async.mjs +219 -0
- package/dist/async.mjs.map +1 -0
- package/dist/base64.cjs +16 -0
- package/dist/base64.cjs.map +1 -0
- package/dist/base64.d.ts +7 -0
- package/dist/base64.mjs +16 -0
- package/dist/base64.mjs.map +1 -0
- package/dist/cache.cjs +79 -0
- package/dist/cache.cjs.map +1 -0
- package/dist/cache.d.ts +90 -0
- package/dist/cache.mjs +79 -0
- package/dist/cache.mjs.map +1 -0
- package/{src/color/contrast.ts → dist/color/contrast.d.ts} +2 -12
- package/dist/color/distance.d.ts +8 -0
- package/dist/color/helpers.d.ts +2 -0
- package/dist/color/hex-hsl.d.ts +3 -0
- package/{src/color/hex-hsv.ts → dist/color/hex-hsv.d.ts} +3 -11
- package/{src/color/hex-hwb.ts → dist/color/hex-hwb.d.ts} +3 -11
- package/dist/color/hex-rgb.d.ts +18 -0
- package/{src/color/hsl-lighten.ts → dist/color/hsl-lighten.d.ts} +2 -7
- package/{src/color/hsv-brighten.ts → dist/color/hsv-brighten.d.ts} +2 -7
- package/{src/color/luminance.ts → dist/color/luminance.d.ts} +2 -9
- package/{src/color/mix.ts → dist/color/mix.d.ts} +2 -10
- package/dist/color/rgb-hsl.d.ts +23 -0
- package/{src/color/rgb-hsv.ts → dist/color/rgb-hsv.d.ts} +3 -30
- package/dist/color/rgb-hwb.d.ts +29 -0
- package/{src/color/rgb-lab.ts → dist/color/rgb-lab.d.ts} +3 -11
- package/dist/color/rgb-whiter.d.ts +12 -0
- package/dist/color/rgb-xyz.d.ts +22 -0
- package/{src/color/types.ts → dist/color/types.d.ts} +30 -12
- package/{src/color/xyz-lab.ts → dist/color/xyz-lab.d.ts} +3 -32
- package/dist/color.cjs +250 -0
- package/dist/color.cjs.map +1 -0
- package/dist/color.mjs +250 -0
- package/dist/color.mjs.map +1 -0
- package/dist/const.cjs +14 -0
- package/dist/const.cjs.map +1 -0
- package/dist/const.mjs +15 -0
- package/dist/const.mjs.map +1 -0
- package/dist/core.cjs +250 -0
- package/dist/core.cjs.map +1 -0
- package/dist/core.mjs +251 -0
- package/dist/core.mjs.map +1 -0
- package/dist/crypto/md5.d.mts +1 -0
- package/dist/crypto/sha1.d.mts +1 -0
- package/dist/crypto/sha256.d.mts +1 -0
- package/dist/crypto/sha512.d.mts +1 -0
- package/dist/crypto.cjs +812 -0
- package/dist/crypto.cjs.map +1 -0
- package/{src/crypto.ts → dist/crypto.d.ts} +4 -20
- package/dist/crypto.mjs +812 -0
- package/dist/crypto.mjs.map +1 -0
- package/dist/date/const.d.ts +6 -0
- package/dist/date/core.d.ts +52 -0
- package/dist/date/days.d.ts +23 -0
- package/{src/date/is.ts → dist/date/is.d.ts} +8 -102
- package/dist/date/relative.d.ts +44 -0
- package/dist/date/start-end.d.ts +73 -0
- package/dist/date/timezone.d.ts +67 -0
- package/dist/date/weeks.d.ts +72 -0
- package/dist/date.cjs +239 -0
- package/dist/date.cjs.map +1 -0
- package/dist/date.mjs +241 -0
- package/dist/date.mjs.map +1 -0
- package/dist/dict.cjs +2 -0
- package/dist/dict.cjs.map +1 -0
- package/dist/dict.mjs +2 -0
- package/dist/dict.mjs.map +1 -0
- package/dist/each.cjs +18 -0
- package/dist/each.cjs.map +1 -0
- package/dist/each.mjs +19 -0
- package/dist/each.mjs.map +1 -0
- package/dist/easing.cjs +151 -0
- package/dist/easing.cjs.map +1 -0
- package/dist/easing.d.ts +46 -0
- package/dist/easing.mjs +151 -0
- package/dist/easing.mjs.map +1 -0
- package/dist/emitter.cjs +94 -0
- package/dist/emitter.cjs.map +1 -0
- package/dist/emitter.d.ts +68 -0
- package/dist/emitter.mjs +94 -0
- package/dist/emitter.mjs.map +1 -0
- package/dist/enum.cjs +58 -0
- package/dist/enum.cjs.map +1 -0
- package/dist/enum.d.ts +68 -0
- package/dist/enum.mjs +58 -0
- package/dist/enum.mjs.map +1 -0
- package/dist/env.cjs +28 -0
- package/dist/env.cjs.map +1 -0
- package/{src/env.ts → dist/env.d.ts} +6 -30
- package/dist/env.mjs +28 -0
- package/dist/env.mjs.map +1 -0
- package/dist/error.cjs +12 -0
- package/dist/error.cjs.map +1 -0
- package/{src/error.ts → dist/error.d.ts} +3 -12
- package/dist/error.mjs +12 -0
- package/dist/error.mjs.map +1 -0
- package/dist/exception.cjs +22 -0
- package/dist/exception.cjs.map +1 -0
- package/dist/exception.d.ts +31 -0
- package/dist/exception.mjs +22 -0
- package/dist/exception.mjs.map +1 -0
- package/dist/fn.cjs +76 -0
- package/dist/fn.cjs.map +1 -0
- package/dist/fn.d.ts +102 -0
- package/dist/fn.mjs +76 -0
- package/dist/fn.mjs.map +1 -0
- package/dist/index.cjs +5 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +5 -0
- package/dist/index.mjs.map +1 -0
- package/dist/merge.cjs +87 -0
- package/dist/merge.cjs.map +1 -0
- package/dist/merge.mjs +88 -0
- package/dist/merge.mjs.map +1 -0
- package/dist/number.cjs +14 -0
- package/dist/number.cjs.map +1 -0
- package/dist/number.d.ts +153 -0
- package/dist/number.mjs +14 -0
- package/dist/number.mjs.map +1 -0
- package/{src/object/each.ts → dist/object/each.d.ts} +3 -23
- package/dist/object/get-set.d.ts +111 -0
- package/dist/object/is.d.ts +32 -0
- package/dist/object/merge.d.ts +72 -0
- package/{src/object/process.ts → dist/object/process.d.ts} +4 -38
- package/dist/object.cjs +130 -0
- package/dist/object.cjs.map +1 -0
- package/dist/object.mjs +130 -0
- package/dist/object.mjs.map +1 -0
- package/dist/path.cjs +77 -0
- package/dist/path.cjs.map +1 -0
- package/dist/path.d.ts +82 -0
- package/dist/path.mjs +77 -0
- package/dist/path.mjs.map +1 -0
- package/dist/promise.cjs +62 -0
- package/dist/promise.cjs.map +1 -0
- package/{src/promise.ts → dist/promise.d.ts} +6 -67
- package/dist/promise.mjs +62 -0
- package/dist/promise.mjs.map +1 -0
- package/dist/qs.cjs +47 -0
- package/dist/qs.cjs.map +1 -0
- package/{src/qs.ts → dist/qs.d.ts} +3 -60
- package/dist/qs.mjs +47 -0
- package/dist/qs.mjs.map +1 -0
- package/dist/regexp.cjs +66 -0
- package/dist/regexp.cjs.map +1 -0
- package/dist/regexp.d.ts +65 -0
- package/dist/regexp.mjs +66 -0
- package/dist/regexp.mjs.map +1 -0
- package/dist/string.cjs +16 -0
- package/dist/string.cjs.map +1 -0
- package/dist/string.d.ts +80 -0
- package/dist/string.mjs +16 -0
- package/dist/string.mjs.map +1 -0
- package/dist/string2.cjs +157 -0
- package/dist/string2.cjs.map +1 -0
- package/dist/string2.mjs +158 -0
- package/dist/string2.mjs.map +1 -0
- package/dist/time/from.d.ts +14 -0
- package/dist/time/to.d.ts +38 -0
- package/dist/time.cjs +82 -0
- package/dist/time.cjs.map +1 -0
- package/dist/time.mjs +82 -0
- package/dist/time.mjs.map +1 -0
- package/dist/timer.cjs +119 -0
- package/dist/timer.cjs.map +1 -0
- package/dist/timer.d.ts +96 -0
- package/{src/timer.ts → dist/timer.mjs} +17 -124
- package/dist/timer.mjs.map +1 -0
- package/dist/tree.cjs +125 -0
- package/dist/tree.cjs.map +1 -0
- package/{src/tree.ts → dist/tree.d.ts} +41 -225
- package/dist/tree.mjs +125 -0
- package/dist/tree.mjs.map +1 -0
- package/dist/type.cjs +78 -0
- package/dist/type.cjs.map +1 -0
- package/{src/type.ts → dist/type.d.ts} +20 -96
- package/dist/type.mjs +78 -0
- package/dist/type.mjs.map +1 -0
- package/dist/types.cjs +2 -0
- package/dist/types.cjs.map +1 -0
- package/{src/types.ts → dist/types.d.ts} +12 -33
- package/dist/types.mjs +2 -0
- package/dist/types.mjs.map +1 -0
- package/dist/unique.cjs +46 -0
- package/dist/unique.cjs.map +1 -0
- package/dist/unique.d.ts +22 -0
- package/dist/unique.mjs +46 -0
- package/dist/unique.mjs.map +1 -0
- package/dist/url.cjs +37 -0
- package/dist/url.cjs.map +1 -0
- package/dist/url.d.ts +53 -0
- package/dist/url.mjs +37 -0
- package/dist/url.mjs.map +1 -0
- package/dist/version.cjs +33 -0
- package/dist/version.cjs.map +1 -0
- package/dist/version.d.ts +32 -0
- package/dist/version.mjs +33 -0
- package/dist/version.mjs.map +1 -0
- package/package.json +8 -2
- package/CHANGELOG.md +0 -52
- package/src/array.ts +0 -312
- package/src/async.ts +0 -379
- package/src/base64.ts +0 -20
- package/src/cache.ts +0 -146
- package/src/color/distance.ts +0 -28
- package/src/color/helpers.ts +0 -23
- package/src/color/hex-hsl.ts +0 -11
- package/src/color/hex-rgb.ts +0 -39
- package/src/color/rgb-hsl.ts +0 -53
- package/src/color/rgb-hwb.ts +0 -56
- package/src/color/rgb-whiter.ts +0 -22
- package/src/color/rgb-xyz.ts +0 -62
- package/src/crypto/md5.mjs +0 -357
- package/src/crypto/sha1.mjs +0 -300
- package/src/crypto/sha256.mjs +0 -310
- package/src/crypto/sha512.mjs +0 -459
- package/src/date/const.ts +0 -6
- package/src/date/core.ts +0 -162
- package/src/date/days.ts +0 -51
- package/src/date/relative.ts +0 -92
- package/src/date/start-end.ts +0 -246
- package/src/date/timezone.ts +0 -220
- package/src/date/weeks.ts +0 -100
- package/src/dts/global.d.ts +0 -27
- package/src/easing.ts +0 -166
- package/src/emitter.ts +0 -117
- package/src/enum.ts +0 -171
- package/src/exception.ts +0 -68
- package/src/fn.ts +0 -197
- package/src/index.ts +0 -1
- package/src/number.ts +0 -236
- package/src/object/get-set.ts +0 -273
- package/src/object/is.ts +0 -128
- package/src/object/merge.ts +0 -180
- package/src/path.ts +0 -188
- package/src/regexp.ts +0 -156
- package/src/string.ts +0 -146
- package/src/time/from.ts +0 -57
- package/src/time/to.ts +0 -106
- package/src/unique.ts +0 -77
- package/src/url.ts +0 -93
- package/src/version.ts +0 -71
- package/test/array.test.ts +0 -332
- package/test/async-real.test.ts +0 -39
- package/test/async.test.ts +0 -375
- package/test/base64.test.ts +0 -32
- package/test/cache.test.ts +0 -83
- package/test/color.test.ts +0 -163
- package/test/crypto.test.ts +0 -34
- package/test/date-tz.test.ts +0 -206
- package/test/date.test.ts +0 -353
- package/test/easing.test.ts +0 -33
- package/test/emitter.test.ts +0 -71
- package/test/enum.test.ts +0 -113
- package/test/env.test.ts +0 -69
- package/test/error.test.ts +0 -58
- package/test/exception.test.ts +0 -43
- package/test/fn.test.ts +0 -263
- package/test/helpers.ts +0 -23
- package/test/index.test.ts +0 -6
- package/test/number.test.ts +0 -213
- package/test/object.test.ts +0 -309
- package/test/path.test.ts +0 -156
- package/test/promise.test.ts +0 -199
- package/test/qs.test.ts +0 -79
- package/test/regexp.test.ts +0 -97
- package/test/string.test.ts +0 -150
- package/test/time.test.ts +0 -214
- package/test/timer.test.ts +0 -114
- package/test/tree.test.ts +0 -348
- package/test/type.test.ts +0 -226
- package/test/unique.test.ts +0 -71
- package/test/url.test.ts +0 -136
- package/test/version.test.ts +0 -52
- package/tsconfig.json +0 -31
- package/vite.config.mts +0 -114
- /package/{src/color.ts → dist/color.d.ts} +0 -0
- /package/{src/date.ts → dist/date.d.ts} +0 -0
- /package/{src/dict.ts → dist/dict.d.ts} +0 -0
- /package/{src/object.ts → dist/object.d.ts} +0 -0
- /package/{src/time.ts → dist/time.d.ts} +0 -0
package/dist/object.mjs
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { o, a } from "./each.mjs";
|
|
2
|
+
import { isUndefined, isArray, isObject } from "./type.mjs";
|
|
3
|
+
import { o as o2, a as a2 } from "./merge.mjs";
|
|
4
|
+
function pathToKeys(path) {
|
|
5
|
+
if (isArray(path)) return [...path];
|
|
6
|
+
let pathFinal = path.replace(/\[(\w+)\]/g, ".$1");
|
|
7
|
+
pathFinal = pathFinal.replace(/^\./, "");
|
|
8
|
+
return pathFinal.split(".");
|
|
9
|
+
}
|
|
10
|
+
function isObjectOrArray(v) {
|
|
11
|
+
return isObject(v) || isArray(v);
|
|
12
|
+
}
|
|
13
|
+
function objectGet(obj, path) {
|
|
14
|
+
const keys = pathToKeys(path);
|
|
15
|
+
const lastKey = keys.pop();
|
|
16
|
+
let parent = obj;
|
|
17
|
+
const keysFinal = [];
|
|
18
|
+
for (let i = 0; i < keys.length; i++) {
|
|
19
|
+
const key = keys[i];
|
|
20
|
+
keysFinal.push(key);
|
|
21
|
+
if (!isObjectOrArray(parent)) break;
|
|
22
|
+
parent = parent[key];
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
parent,
|
|
26
|
+
keys: keysFinal,
|
|
27
|
+
key: lastKey,
|
|
28
|
+
// @ts-ignore
|
|
29
|
+
value: isObjectOrArray(parent) && lastKey ? parent[lastKey] : void 0
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const defaultObjectSetOptions = {
|
|
33
|
+
beforeSet: () => true,
|
|
34
|
+
undefinedSet: () => ({})
|
|
35
|
+
};
|
|
36
|
+
function objectSet(obj, path, val, options) {
|
|
37
|
+
const { beforeSet, undefinedSet } = Object.assign({}, defaultObjectSetOptions, options);
|
|
38
|
+
const keys = pathToKeys(path);
|
|
39
|
+
const lastKey = keys.pop();
|
|
40
|
+
let parent = obj;
|
|
41
|
+
let stopped = false;
|
|
42
|
+
const keysFinal = [];
|
|
43
|
+
for (const key of keys) {
|
|
44
|
+
let val2 = parent[key];
|
|
45
|
+
keysFinal.push(key);
|
|
46
|
+
if (isUndefined(val2)) {
|
|
47
|
+
const seted = undefinedSet({
|
|
48
|
+
parent,
|
|
49
|
+
keys: keysFinal,
|
|
50
|
+
key,
|
|
51
|
+
value: val2
|
|
52
|
+
});
|
|
53
|
+
if (!seted) {
|
|
54
|
+
stopped = true;
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
val2 = parent[key] = seted;
|
|
58
|
+
}
|
|
59
|
+
parent = val2;
|
|
60
|
+
}
|
|
61
|
+
if (!stopped && !isUndefined(lastKey)) {
|
|
62
|
+
keysFinal.push(lastKey);
|
|
63
|
+
if (beforeSet({
|
|
64
|
+
parent,
|
|
65
|
+
keys: keysFinal,
|
|
66
|
+
key: lastKey,
|
|
67
|
+
value: parent[lastKey]
|
|
68
|
+
})) {
|
|
69
|
+
parent[lastKey] = val;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
keys: keysFinal,
|
|
74
|
+
parent,
|
|
75
|
+
key: lastKey,
|
|
76
|
+
value: val
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function isEmptyObject(obj) {
|
|
80
|
+
return Object.getOwnPropertyNames(obj).length === 0 && Object.getOwnPropertySymbols(obj).length === 0;
|
|
81
|
+
}
|
|
82
|
+
function isPlainObject(obj) {
|
|
83
|
+
const proto = Object.getPrototypeOf(obj);
|
|
84
|
+
if (!proto) return true;
|
|
85
|
+
return proto === Object.prototype;
|
|
86
|
+
}
|
|
87
|
+
function objectPick(object, keys) {
|
|
88
|
+
const result = {};
|
|
89
|
+
for (const key of keys) {
|
|
90
|
+
if (key in object) {
|
|
91
|
+
result[key] = object[key];
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
function objectOmit(object, keys) {
|
|
97
|
+
const result = {};
|
|
98
|
+
for (const key in object) {
|
|
99
|
+
if (!keys.includes(key)) {
|
|
100
|
+
result[key] = object[key];
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
105
|
+
function objectMap(object, mapper) {
|
|
106
|
+
return Object.fromEntries(
|
|
107
|
+
Object.entries(object).map(([key, value]) => [
|
|
108
|
+
key,
|
|
109
|
+
mapper(
|
|
110
|
+
// @ts-expect-error
|
|
111
|
+
value,
|
|
112
|
+
key
|
|
113
|
+
)
|
|
114
|
+
])
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
export {
|
|
118
|
+
isEmptyObject,
|
|
119
|
+
isPlainObject,
|
|
120
|
+
o2 as objectDefaults,
|
|
121
|
+
o as objectEach,
|
|
122
|
+
a as objectEachAsync,
|
|
123
|
+
objectGet,
|
|
124
|
+
objectMap,
|
|
125
|
+
a2 as objectMerge,
|
|
126
|
+
objectOmit,
|
|
127
|
+
objectPick,
|
|
128
|
+
objectSet
|
|
129
|
+
};
|
|
130
|
+
//# sourceMappingURL=object.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"object.mjs","sources":["../src/object/get-set.ts","../src/object/is.ts","../src/object/process.ts"],"sourcesContent":["import { isArray, isObject, isUndefined } from '@/type';\nimport type { AnyArray, AnyObject } from '@/types';\n\n// @ref https://stackoverflow.com/a/67609485\n\ntype Idx<T, K> = K extends keyof T\n ? T[K]\n : number extends keyof T\n ? K extends `${number}`\n ? T[number]\n : never\n : never;\n\ntype Join<K, P> = K extends string | number\n ? P extends string | number\n ? `${K}${'' extends P ? '' : '.'}${P}`\n : never\n : never;\n\ntype Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...0[]];\n\nexport type ObjectPath<O, D extends number = 4> = [D] extends [never]\n ? never\n : O extends object\n ? {\n [K in keyof O]-?: K extends string | number ? `${K}` | Join<K, ObjectPath<O[K], Prev[D]>> : never;\n }[keyof O]\n : '';\n\nexport type ObjectLeafPath<O, D extends number = 4> = [D] extends [never]\n ? never\n : O extends object\n ? {\n [K in keyof O]-?: K extends string | number\n ? O[K] extends string | number\n ? `${K}` | Join<K, ObjectLeafPath<O[K], Prev[D]>>\n : Join<K, ObjectLeafPath<O[K], Prev[D]>>\n : never;\n }[keyof O]\n : '';\n\nexport type ObjectPathValue<O, P extends ObjectPath<O, 4>> = P extends `${infer Key}.${infer Rest}`\n ? Rest extends ObjectPath<Idx<O, Key>, 4>\n ? ObjectPathValue<Idx<O, Key>, Rest>\n : never\n : Idx<O, P>;\n\nfunction pathToKeys(path: string | string[]) {\n // 下文用到该数组时会进行修改操作,因此复制一份\n if (isArray(path)) return [...path];\n\n let pathFinal = path.replace(/\\[(\\w+)\\]/g, '.$1');\n pathFinal = pathFinal.replace(/^\\./, '');\n return pathFinal.split('.');\n}\n\nfunction isObjectOrArray(v: unknown) {\n return isObject(v) || isArray(v);\n}\n\n/**\n * 表示对象节点的信息。\n *\n * @template V - 键值的类型。\n */\nexport type TObjectNode<V = unknown | undefined> = {\n /**\n * 当前节点的父级对象。\n */\n parent: unknown | undefined;\n\n /**\n * 当前节点的键名路径。\n */\n keys: string[];\n\n /**\n * 当前节点的键名。\n */\n key: string | undefined;\n\n /**\n * 当前节点的键值。\n */\n value: V;\n};\n\n/**\n * 根据属性路径获取属性值\n * @param {O} obj\n * @param {string | string[] | P} path\n * @returns {TObjectNode<O>}\n * 根据属性路径获取属性值。\n *\n * @template O - 目标对象的类型。\n * @template P - 属性路径的类型。\n * @param {O} obj - 要操作的目标对象。\n * @param {P | string | string[]} path - 属性路径,可以是字符串或字符串数组。支持点分隔符(如 \"a.b.c\")或数组形式(如 [\"a\", \"b\", \"c\"])。\n * @returns {TObjectNode<O>} 返回一个包含父级、键名路径、键名和键值的对象节点。\n *\n * @example\n * ```typescript\n * const obj = { a: { b: { c: 42 } } };\n * const result = objectGet(obj, 'a.b.c');\n * console.log(result.value); // 输出 42\n * ```\n */\nexport function objectGet<O extends AnyObject, P extends ObjectPath<O>>(\n obj: O,\n path: P | string | string[],\n): TObjectNode<O> {\n const keys = pathToKeys(path);\n const lastKey = keys.pop();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n let parent: any = obj;\n const keysFinal: string[] = [];\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n\n keysFinal.push(key);\n if (!isObjectOrArray(parent)) break;\n\n // @ts-ignore\n parent = parent[key];\n }\n\n return {\n parent: parent,\n keys: keysFinal,\n key: lastKey,\n // @ts-ignore\n value: isObjectOrArray(parent) && lastKey ? parent[lastKey] : undefined,\n };\n}\n\n// /**\n// * 根据路径获取对象叶子节点值\n// * @param {O} obj\n// * @param {P} path\n// * @returns {ObjectNode<O>}\n// */\n// export function objectLeaf<O extends AnyObject, P extends ObjectLeafPath<O>>(obj: O, path: P) {\n// return objectGet(obj, path);\n// }\n\n/**\n * 配置选项,用于控制 `objectSet` 的行为。\n *\n * @template O - 目标对象的类型。\n */\nexport type TObjectSetOptions<O extends AnyObject> = {\n /**\n * 在设置值之前调用的钩子函数。\n * 如果返回 `false`,则阻止设置值。\n *\n * @param {TObjectNode<O> & { key: string }} node - 当前节点信息。\n * @returns {boolean | undefined | void} 返回 `false` 时阻止设置值。\n */\n // biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\n beforeSet(node: TObjectNode<O> & { key: string }): boolean | undefined | void;\n\n /**\n * 当遇到未定义的中间节点时调用的钩子函数。\n * 返回值将用于创建中间节点。\n *\n * @param {TObjectNode<O>} node - 当前节点信息。\n * @returns {AnyObject | AnyArray | undefined | void} 返回值将用于创建中间节点。\n */\n // biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\n undefinedSet(node: TObjectNode<O>): AnyObject | AnyArray | undefined | void;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\nconst defaultObjectSetOptions: TObjectSetOptions<any> = {\n beforeSet: () => true,\n undefinedSet: () => ({}),\n};\n\n/**\n * 根据属性路径设置属性值\n * @param {AnyObject} obj\n * @param {string} path\n * @param {V} val\n * @param {Partial<TObjectSetOptions<O>>} options\n * @returns {TObjectNode<O, V>}\n * 根据属性路径设置属性值。\n *\n * @template O - 目标对象的类型。\n * @template V - 要设置的值的类型。\n * @param {O} obj - 要操作的目标对象。\n * @param {string | string[]} path - 属性路径,可以是字符串或字符串数组。支持点分隔符(如 \"a.b.c\")或数组形式(如 [\"a\", \"b\", \"c\"])。\n * @param {V} val - 要设置的值。\n * @param {Partial<TObjectSetOptions<O>>} [options] - 可选配置项,用于控制设置行为。\n * @returns {TObjectNode<V>} 返回一个包含父级、键名路径、键名和键值的对象节点。\n *\n * @example\n * ```typescript\n * const obj = {};\n * objectSet(obj, 'a.b.c', 42);\n * console.log(obj); // 输出 { a: { b: { c: 42 } } }\n *\n * objectSet(obj, 'a.b.c', 100, {\n * beforeSet: (node) => node.key === 'c',\n * });\n * console.log(obj); // 输出 { a: { b: { c: 100 } } }\n * ```\n */\nexport function objectSet<O extends AnyObject, V>(\n obj: O,\n path: string | string[],\n val: V,\n options?: Partial<TObjectSetOptions<O>>,\n): TObjectNode<V> {\n const { beforeSet, undefinedSet } = Object.assign({}, defaultObjectSetOptions, options);\n const keys = pathToKeys(path);\n const lastKey = keys.pop();\n let parent = obj;\n let stopped = false;\n const keysFinal: string[] = [];\n\n for (const key of keys) {\n let val = parent[key];\n keysFinal.push(key);\n\n if (isUndefined(val)) {\n const seted = undefinedSet({\n parent: parent,\n keys: keysFinal,\n key: key,\n value: val,\n });\n\n if (!seted) {\n stopped = true;\n break;\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n val = parent[key] = seted;\n }\n\n // @ts-ignore\n parent = val;\n }\n\n if (!stopped && !isUndefined(lastKey)) {\n keysFinal.push(lastKey);\n\n if (\n beforeSet({\n parent: parent,\n keys: keysFinal,\n key: lastKey,\n value: parent[lastKey],\n })\n ) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n parent[lastKey] = val;\n }\n }\n\n return {\n keys: keysFinal,\n parent: parent,\n key: lastKey,\n value: val,\n };\n}\n","import { isArray, isObject, isString, typeIs } from '@/type';\nimport type { AnyArray, AnyFunction, AnyObject } from '@/types';\n\n/**\n * 检查一个对象是否为空对象(不包含任何自有属性,包括符号属性)。\n *\n * @param obj - 要检查的对象\n * @returns 如果对象没有自有属性(包括符号属性)则返回 true,否则返回 false\n *\n * @example\n * ```typescript\n * isEmptyObject({}); // true\n * isEmptyObject({ a: 1 }); // false\n * isEmptyObject(Object.create(null)); // true\n * isEmptyObject({ [Symbol('key')]: 'value' }); // false\n * ```\n */\nexport function isEmptyObject(obj: AnyObject): boolean {\n return Object.getOwnPropertyNames(obj).length === 0 && Object.getOwnPropertySymbols(obj).length === 0;\n}\n\n/**\n * 检查一个对象是否为纯对象(通过对象字面量或Object构造函数创建,而非其他构造函数的实例)。\n *\n * @param obj - 要检查的对象\n * @returns 如果是纯对象则返回 true,否则返回 false\n *\n * @example\n * ```typescript\n * isPlainObject({}); // true\n * isPlainObject(Object.create(null)); // true\n * isPlainObject(new Date()); // false\n * isPlainObject([]); // false\n * isPlainObject(() => {}); // false\n * ```\n */\nexport function isPlainObject(obj: AnyObject): boolean {\n const proto: unknown = Object.getPrototypeOf(obj);\n\n // 对象无原型\n if (!proto) return true;\n\n // 是否对象直接实例\n return proto === Object.prototype;\n}\n\n// 移除,原因是,定义对象尽可能的使用 type 关键字即可避开此问题\n// /**\n// * 精确对象,常用于联合类型判断\n// * 相关 bug:https://l.ydr.me/Zp88vFKc\n// */\n// // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n// export type ExactObject<T = any> = T extends AnyFunction\n// ? never\n// : T extends AnyArray\n// ? never\n// : T extends object\n// ? T\n// : never;\n//\n// /**\n// * 检查值是否为精确接口对象\n// * @param object - 传入对象,必须是一个对象与其他类型的联合\n// * @returns 如果值为对象则返回 true,否则返回 false\n// * @example\n// * ```typescript\n// * type Id = string | string[] | (() => string);\n// *\n// * interface Cache {\n// * id?: Id;\n// * }\n// *\n// * type Share = {\n// * id?: Id;\n// * }\n// *\n// * interface Options {\n// * cache?: Id | Cache;\n// * share?: Id | Share;\n// * }\n// *\n// * function test(options: Options) {\n// * // string | string[] | (() => string) | Cache | undefined\n// * const cache = options.cache;\n// *\n// * // Cache\n// * // 需要使用\n// * if (isExactObject(cache)) {\n// * cache.id;\n// * }\n// * // string[]\n// * else if (isArray(cache)) {\n// * cache.push();\n// * }\n// * // string\n// * else if (isString(cache)) {\n// * cache.charCodeAt(0);\n// * }\n// * // (() => string) | undefined\n// * else {\n// * cache?.();\n// * }\n// *\n// * // string | string[] | (() => string) | Share | undefined\n// * const share = options.share;\n// *\n// * // Share\n// * if (isObject(share)) {\n// * share.id;\n// * }\n// * // string[]\n// * else if (isArray(share)) {\n// * share.push();\n// * }\n// * // string\n// * else if (isString(share)) {\n// * share.charCodeAt(0);\n// * }\n// * // (() => string) | undefined\n// * else {\n// * share?.();\n// * }\n// * }\n// * ```\n// */\n// export function isExactObject<T>(object: T): object is ExactObject<T> {\n// return typeIs(object) === 'object';\n// }\n","import type { AnyObject } from '@/types';\n\n/**\n * 从对象中选择指定键的属性,返回一个新的对象。\n *\n * @param object - 要从中选择属性的对象。\n * @param keys - 要选择的键数组。\n * @returns 包含指定键属性的新对象。\n *\n * @example\n * ```typescript\n * const obj = { a: 1, b: 2, c: 3 };\n * const result = objectPick(obj, ['a', 'c']);\n * console.log(result); // { a: 1, c: 3 }\n * ```\n */\nexport function objectPick<T extends AnyObject, K extends keyof T>(object: T, keys: K[]): Pick<T, K> {\n const result = {} as Pick<T, K>;\n for (const key of keys) {\n if (key in object) {\n result[key] = object[key];\n }\n }\n return result;\n}\n\n/**\n * 从对象中排除指定键的属性,返回一个新的对象。\n *\n * @param object - 要从中排除属性的对象。\n * @param keys - 要排除的键数组。\n * @returns 排除指定键属性后的新对象。\n *\n * @example\n * ```typescript\n * const obj = { a: 1, b: 2, c: 3, d: 4 };\n * const result = objectOmit(obj, ['a', 'd']);\n * console.log(result); // { b: 2, c: 3 }\n * ```\n */\nexport function objectOmit<T extends AnyObject, K extends keyof T>(object: T, keys: K[]): Omit<T, K> {\n const result = {} as Omit<T, K>;\n for (const key in object) {\n if (!keys.includes(key as unknown as K)) {\n // @ts-expect-error\n result[key] = object[key];\n }\n }\n return result;\n}\n\n/**\n * 遍历对象的每个键值对,并对每个键值对执行提供的映射函数,返回一个新的对象。\n *\n * @param object - 要遍历的对象。\n * @param mapper - 对每个键值对执行的映射函数。\n * @returns 返回一个新的对象,其中每个值都是通过映射函数处理后的结果。\n *\n * @example\n * ```typescript\n * const obj = { a: 1, b: 2, c: 3 };\n * const result = objectMap(obj, (val, key) => String(val * 2));\n * console.log(result); // { a: '2', b: '4', c: '6' }\n * ```\n */\nexport function objectMap<T extends AnyObject, V>(\n object: T,\n mapper: (value: T[keyof T], key: keyof T) => V,\n): Record<keyof T, V> {\n return Object.fromEntries(\n Object.entries(object).map(([key, value]) => [\n key,\n mapper(\n // @ts-expect-error\n value,\n key as keyof T,\n ),\n ]),\n ) as Record<keyof T, V>;\n}\n"],"names":["val"],"mappings":";;;AA+CA,SAAS,WAAW,MAAyB;AAE3C,MAAI,QAAQ,IAAI,EAAU,QAAA,CAAC,GAAG,IAAI;AAElC,MAAI,YAAY,KAAK,QAAQ,cAAc,KAAK;AACpC,cAAA,UAAU,QAAQ,OAAO,EAAE;AAChC,SAAA,UAAU,MAAM,GAAG;AAC5B;AAEA,SAAS,gBAAgB,GAAY;AACnC,SAAO,SAAS,CAAC,KAAK,QAAQ,CAAC;AACjC;AAiDgB,SAAA,UACd,KACA,MACgB;AACV,QAAA,OAAO,WAAW,IAAI;AACtB,QAAA,UAAU,KAAK,IAAI;AAGzB,MAAI,SAAc;AAClB,QAAM,YAAsB,CAAC;AAE7B,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AAC9B,UAAA,MAAM,KAAK,CAAC;AAElB,cAAU,KAAK,GAAG;AACd,QAAA,CAAC,gBAAgB,MAAM,EAAG;AAG9B,aAAS,OAAO,GAAG;AAAA,EAAA;AAGd,SAAA;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,KAAK;AAAA;AAAA,IAEL,OAAO,gBAAgB,MAAM,KAAK,UAAU,OAAO,OAAO,IAAI;AAAA,EAChE;AACF;AAyCA,MAAM,0BAAkD;AAAA,EACtD,WAAW,MAAM;AAAA,EACjB,cAAc,OAAO,CAAC;AACxB;AA+BO,SAAS,UACd,KACA,MACA,KACA,SACgB;AACV,QAAA,EAAE,WAAW,iBAAiB,OAAO,OAAO,CAAI,GAAA,yBAAyB,OAAO;AAChF,QAAA,OAAO,WAAW,IAAI;AACtB,QAAA,UAAU,KAAK,IAAI;AACzB,MAAI,SAAS;AACb,MAAI,UAAU;AACd,QAAM,YAAsB,CAAC;AAE7B,aAAW,OAAO,MAAM;AAClBA,QAAAA,OAAM,OAAO,GAAG;AACpB,cAAU,KAAK,GAAG;AAEd,QAAA,YAAYA,IAAG,GAAG;AACpB,YAAM,QAAQ,aAAa;AAAA,QACzB;AAAA,QACA,MAAM;AAAA,QACN;AAAA,QACA,OAAOA;AAAAA,MAAA,CACR;AAED,UAAI,CAAC,OAAO;AACA,kBAAA;AACV;AAAA,MAAA;AAKFA,aAAM,OAAO,GAAG,IAAI;AAAA,IAAA;AAIbA,aAAAA;AAAAA,EAAA;AAGX,MAAI,CAAC,WAAW,CAAC,YAAY,OAAO,GAAG;AACrC,cAAU,KAAK,OAAO;AAEtB,QACE,UAAU;AAAA,MACR;AAAA,MACA,MAAM;AAAA,MACN,KAAK;AAAA,MACL,OAAO,OAAO,OAAO;AAAA,IAAA,CACtB,GACD;AAGA,aAAO,OAAO,IAAI;AAAA,IAAA;AAAA,EACpB;AAGK,SAAA;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA,KAAK;AAAA,IACL,OAAO;AAAA,EACT;AACF;AC/PO,SAAS,cAAc,KAAyB;AAC9C,SAAA,OAAO,oBAAoB,GAAG,EAAE,WAAW,KAAK,OAAO,sBAAsB,GAAG,EAAE,WAAW;AACtG;AAiBO,SAAS,cAAc,KAAyB;AAC/C,QAAA,QAAiB,OAAO,eAAe,GAAG;AAG5C,MAAA,CAAC,MAAc,QAAA;AAGnB,SAAO,UAAU,OAAO;AAC1B;AC5BgB,SAAA,WAAmD,QAAW,MAAuB;AACnG,QAAM,SAAS,CAAC;AAChB,aAAW,OAAO,MAAM;AACtB,QAAI,OAAO,QAAQ;AACV,aAAA,GAAG,IAAI,OAAO,GAAG;AAAA,IAAA;AAAA,EAC1B;AAEK,SAAA;AACT;AAgBgB,SAAA,WAAmD,QAAW,MAAuB;AACnG,QAAM,SAAS,CAAC;AAChB,aAAW,OAAO,QAAQ;AACxB,QAAI,CAAC,KAAK,SAAS,GAAmB,GAAG;AAEhC,aAAA,GAAG,IAAI,OAAO,GAAG;AAAA,IAAA;AAAA,EAC1B;AAEK,SAAA;AACT;AAgBgB,SAAA,UACd,QACA,QACoB;AACpB,SAAO,OAAO;AAAA,IACZ,OAAO,QAAQ,MAAM,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;AAAA,MAC3C;AAAA,MACA;AAAA;AAAA,QAEE;AAAA,QACA;AAAA,MAAA;AAAA,IAEH,CAAA;AAAA,EACH;AACF;"}
|
package/dist/path.cjs
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const array = require("./array.cjs");
|
|
4
|
+
function _isCurrentSlice(slice) {
|
|
5
|
+
return slice === ".";
|
|
6
|
+
}
|
|
7
|
+
function _isParentSlice(slice) {
|
|
8
|
+
return slice === "..";
|
|
9
|
+
}
|
|
10
|
+
function isAbsolutePath(path) {
|
|
11
|
+
return path.startsWith("/");
|
|
12
|
+
}
|
|
13
|
+
function isRelativePath(path) {
|
|
14
|
+
return !isAbsolutePath(path);
|
|
15
|
+
}
|
|
16
|
+
function pathNormalize(path) {
|
|
17
|
+
const slices = path.replace(/\\/g, "/").replace(/\/{2,}/g, "/").replace(/\.{3,}/g, "..").replace(/\/\.\//g, "/").split("/").map((point) => point.trim());
|
|
18
|
+
const points = [];
|
|
19
|
+
const isAbs = slices[0] === "";
|
|
20
|
+
const push = (point) => {
|
|
21
|
+
points.push(point);
|
|
22
|
+
};
|
|
23
|
+
const back = () => {
|
|
24
|
+
if (points.length === 1 && isAbs) return;
|
|
25
|
+
if (points.length === 0 || points.at(-1) === "..") {
|
|
26
|
+
points.push("..");
|
|
27
|
+
} else {
|
|
28
|
+
points.pop();
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
for (const slice of slices) {
|
|
32
|
+
const isCurrent = _isCurrentSlice(slice);
|
|
33
|
+
const isParent = _isParentSlice(slice);
|
|
34
|
+
if (isCurrent) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (isParent) {
|
|
38
|
+
back();
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
push(slice);
|
|
42
|
+
}
|
|
43
|
+
return points.join("/");
|
|
44
|
+
}
|
|
45
|
+
function pathJoin(from, ...to) {
|
|
46
|
+
return pathNormalize([from, ...to].join("/"));
|
|
47
|
+
}
|
|
48
|
+
function pathResolve(from, ...to) {
|
|
49
|
+
const paths = [from, ...to].map(pathNormalize);
|
|
50
|
+
let lastStartPath = from;
|
|
51
|
+
let lastStartIndex = 0;
|
|
52
|
+
array.arrayEach(
|
|
53
|
+
paths,
|
|
54
|
+
(path, index) => {
|
|
55
|
+
if (isAbsolutePath(path)) {
|
|
56
|
+
lastStartPath = path;
|
|
57
|
+
lastStartIndex = index;
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
true
|
|
62
|
+
);
|
|
63
|
+
return pathJoin(lastStartPath, ...paths.slice(lastStartIndex + 1));
|
|
64
|
+
}
|
|
65
|
+
function pathRelativize(path) {
|
|
66
|
+
if (isAbsolutePath(path)) return path;
|
|
67
|
+
if (path.startsWith("./")) return path;
|
|
68
|
+
if (path.startsWith("../")) return path;
|
|
69
|
+
return `./${path}`;
|
|
70
|
+
}
|
|
71
|
+
exports.isAbsolutePath = isAbsolutePath;
|
|
72
|
+
exports.isRelativePath = isRelativePath;
|
|
73
|
+
exports.pathJoin = pathJoin;
|
|
74
|
+
exports.pathNormalize = pathNormalize;
|
|
75
|
+
exports.pathRelativize = pathRelativize;
|
|
76
|
+
exports.pathResolve = pathResolve;
|
|
77
|
+
//# sourceMappingURL=path.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path.cjs","sources":["../src/path.ts"],"sourcesContent":["import { arrayEach } from './array';\n\n/**\n * 判断是否是当前目录标记\n * @param {string} slice - 路径片段\n * @returns {boolean} - 如果是当前目录标记'.'则返回true,否则返回false\n */\nfunction _isCurrentSlice(slice: string): boolean {\n return slice === '.';\n}\n\n/**\n * 判断是否是上级目录标记\n * @param {string} slice - 路径片段\n * @returns {boolean} - 如果是上级目录标记'..'则返回true,否则返回false\n */\nfunction _isParentSlice(slice: string): boolean {\n return slice === '..';\n}\n\n/**\n * 判断是否是绝对路径\n * @param {string} path - 路径字符串\n * @returns {boolean} - 如果是绝对路径则返回true,否则返回false\n * @example\n * ```typescript\n * const isAbs = isAbsolutePath('/path/to/file');\n * console.log(isAbs); // 输出: true\n * ```\n */\nexport function isAbsolutePath(path: string): boolean {\n return path.startsWith('/');\n}\n\n/**\n * 判断是否是相对路径\n * @param {string} path - 路径字符串\n * @returns {boolean} - 如果是相对路径则返回true,否则返回false\n * @example\n * ```typescript\n * const isRel = isRelativePath('path/to/file');\n * console.log(isRel); // 输出: true\n * ```\n */\nexport function isRelativePath(path: string): boolean {\n return !isAbsolutePath(path);\n}\n\n/**\n * 标准化路径\n * @param {string} path - 要标准化的路径字符串。\n * @returns {string} - 标准化后的路径字符串。\n * @example\n * ```typescript\n * const normalizedPath = pathNormalize('/path///to///file');\n * console.log(normalizedPath); // 输出: '/path/to/file'\n * ```\n */\nexport function pathNormalize(path: string): string {\n const slices = path\n .replace(/\\\\/g, '/')\n .replace(/\\/{2,}/g, '/')\n .replace(/\\.{3,}/g, '..')\n .replace(/\\/\\.\\//g, '/')\n .split('/')\n .map((point) => point.trim());\n const points: string[] = [];\n const isAbs = slices[0] === '';\n\n const push = (point: string) => {\n points.push(point);\n };\n\n const back = () => {\n // 绝对路径不能退到根目录\n if (points.length === 1 && isAbs) return;\n\n //\n if (points.length === 0 || points.at(-1) === '..') {\n points.push('..');\n } else {\n points.pop();\n }\n };\n\n for (const slice of slices) {\n const isCurrent = _isCurrentSlice(slice);\n const isParent = _isParentSlice(slice);\n\n // // 未进入实际路径\n // if (!inPoints) {\n // push(slice);\n // inPoints = !isCurrent && !isParent;\n // continue;\n // }\n\n if (isCurrent) {\n continue;\n }\n\n if (isParent) {\n back();\n continue;\n }\n\n push(slice);\n }\n\n return points.join('/');\n}\n\n/**\n * 路径合并\n * @param {string} from - 起始路径。\n * @param {...string[]} to - 要合并的路径片段。\n * @returns {string} - 合并后的路径字符串。\n * @example\n * ```typescript\n * const fullPath = pathJoin('/path', '/to', 'file');\n * console.log(fullPath); // 输出: '/path/to/file'\n * ```\n */\nexport function pathJoin(from: string, ...to: string[]): string {\n return pathNormalize([from, ...to].join('/'));\n}\n\n/**\n * 解析路径\n * @param {string} from - 起始路径\n * @param {...string[]} to - 要解析的路径片段\n * @returns {string} - 解析后的绝对路径\n * @example\n * ```typescript\n * const resolvedPath = pathResolve('/path', '/to', 'file');\n * console.log(resolvedPath); // 输出: '/to/file'\n * ```\n */\nexport function pathResolve(from: string, ...to: string[]): string {\n const paths = [from, ...to].map(pathNormalize);\n\n let lastStartPath = from;\n let lastStartIndex = 0;\n\n arrayEach(\n paths,\n (path, index) => {\n if (isAbsolutePath(path)) {\n lastStartPath = path;\n lastStartIndex = index;\n return false;\n }\n },\n true,\n );\n\n return pathJoin(lastStartPath, ...paths.slice(lastStartIndex + 1));\n}\n\n/**\n * 将相对路径转换为标准的相对路径格式(添加'./'前缀)\n *\n * @param {string} path - 要处理的路径字符串\n * @returns {string} 处理后的路径字符串\n *\n * @example <caption>处理绝对路径</caption>\n * ```typescript\n * const result = pathRelativize('/path/to/file');\n * console.log(result); // 输出: '/path/to/file'\n * ```\n *\n * @example <caption>处理已带'./'前缀的相对路径</caption>\n * ```typescript\n * const result = pathRelativize('./path/to/file');\n * console.log(result); // 输出: './path/to/file'\n * ```\n *\n * @example <caption>处理不带'./'前缀的相对路径</caption>\n * ```typescript\n * const result = pathRelativize('path/to/file');\n * console.log(result); // 输出: './path/to/file'\n * ```\n */\nexport function pathRelativize(path: string): string {\n if (isAbsolutePath(path)) return path;\n if (path.startsWith('./')) return path;\n if (path.startsWith('../')) return path;\n return `./${path}`;\n}\n"],"names":["arrayEach"],"mappings":";;;AAOA,SAAS,gBAAgB,OAAwB;AAC/C,SAAO,UAAU;AACnB;AAOA,SAAS,eAAe,OAAwB;AAC9C,SAAO,UAAU;AACnB;AAYO,SAAS,eAAe,MAAuB;AAC7C,SAAA,KAAK,WAAW,GAAG;AAC5B;AAYO,SAAS,eAAe,MAAuB;AAC7C,SAAA,CAAC,eAAe,IAAI;AAC7B;AAYO,SAAS,cAAc,MAAsB;AAC5C,QAAA,SAAS,KACZ,QAAQ,OAAO,GAAG,EAClB,QAAQ,WAAW,GAAG,EACtB,QAAQ,WAAW,IAAI,EACvB,QAAQ,WAAW,GAAG,EACtB,MAAM,GAAG,EACT,IAAI,CAAC,UAAU,MAAM,KAAA,CAAM;AAC9B,QAAM,SAAmB,CAAC;AACpB,QAAA,QAAQ,OAAO,CAAC,MAAM;AAEtB,QAAA,OAAO,CAAC,UAAkB;AAC9B,WAAO,KAAK,KAAK;AAAA,EACnB;AAEA,QAAM,OAAO,MAAM;AAEb,QAAA,OAAO,WAAW,KAAK,MAAO;AAGlC,QAAI,OAAO,WAAW,KAAK,OAAO,GAAG,EAAE,MAAM,MAAM;AACjD,aAAO,KAAK,IAAI;AAAA,IAAA,OACX;AACL,aAAO,IAAI;AAAA,IAAA;AAAA,EAEf;AAEA,aAAW,SAAS,QAAQ;AACpB,UAAA,YAAY,gBAAgB,KAAK;AACjC,UAAA,WAAW,eAAe,KAAK;AASrC,QAAI,WAAW;AACb;AAAA,IAAA;AAGF,QAAI,UAAU;AACP,WAAA;AACL;AAAA,IAAA;AAGF,SAAK,KAAK;AAAA,EAAA;AAGL,SAAA,OAAO,KAAK,GAAG;AACxB;AAagB,SAAA,SAAS,SAAiB,IAAsB;AACvD,SAAA,cAAc,CAAC,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG,CAAC;AAC9C;AAagB,SAAA,YAAY,SAAiB,IAAsB;AACjE,QAAM,QAAQ,CAAC,MAAM,GAAG,EAAE,EAAE,IAAI,aAAa;AAE7C,MAAI,gBAAgB;AACpB,MAAI,iBAAiB;AAErBA,QAAA;AAAA,IACE;AAAA,IACA,CAAC,MAAM,UAAU;AACX,UAAA,eAAe,IAAI,GAAG;AACR,wBAAA;AACC,yBAAA;AACV,eAAA;AAAA,MAAA;AAAA,IAEX;AAAA,IACA;AAAA,EACF;AAEA,SAAO,SAAS,eAAe,GAAG,MAAM,MAAM,iBAAiB,CAAC,CAAC;AACnE;AA0BO,SAAS,eAAe,MAAsB;AAC/C,MAAA,eAAe,IAAI,EAAU,QAAA;AACjC,MAAI,KAAK,WAAW,IAAI,EAAU,QAAA;AAClC,MAAI,KAAK,WAAW,KAAK,EAAU,QAAA;AACnC,SAAO,KAAK,IAAI;AAClB;;;;;;;"}
|
package/dist/path.d.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 判断是否是绝对路径
|
|
3
|
+
* @param {string} path - 路径字符串
|
|
4
|
+
* @returns {boolean} - 如果是绝对路径则返回true,否则返回false
|
|
5
|
+
* @example
|
|
6
|
+
* ```typescript
|
|
7
|
+
* const isAbs = isAbsolutePath('/path/to/file');
|
|
8
|
+
* console.log(isAbs); // 输出: true
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
export declare function isAbsolutePath(path: string): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* 判断是否是相对路径
|
|
14
|
+
* @param {string} path - 路径字符串
|
|
15
|
+
* @returns {boolean} - 如果是相对路径则返回true,否则返回false
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const isRel = isRelativePath('path/to/file');
|
|
19
|
+
* console.log(isRel); // 输出: true
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare function isRelativePath(path: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* 标准化路径
|
|
25
|
+
* @param {string} path - 要标准化的路径字符串。
|
|
26
|
+
* @returns {string} - 标准化后的路径字符串。
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const normalizedPath = pathNormalize('/path///to///file');
|
|
30
|
+
* console.log(normalizedPath); // 输出: '/path/to/file'
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare function pathNormalize(path: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* 路径合并
|
|
36
|
+
* @param {string} from - 起始路径。
|
|
37
|
+
* @param {...string[]} to - 要合并的路径片段。
|
|
38
|
+
* @returns {string} - 合并后的路径字符串。
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* const fullPath = pathJoin('/path', '/to', 'file');
|
|
42
|
+
* console.log(fullPath); // 输出: '/path/to/file'
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export declare function pathJoin(from: string, ...to: string[]): string;
|
|
46
|
+
/**
|
|
47
|
+
* 解析路径
|
|
48
|
+
* @param {string} from - 起始路径
|
|
49
|
+
* @param {...string[]} to - 要解析的路径片段
|
|
50
|
+
* @returns {string} - 解析后的绝对路径
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* const resolvedPath = pathResolve('/path', '/to', 'file');
|
|
54
|
+
* console.log(resolvedPath); // 输出: '/to/file'
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export declare function pathResolve(from: string, ...to: string[]): string;
|
|
58
|
+
/**
|
|
59
|
+
* 将相对路径转换为标准的相对路径格式(添加'./'前缀)
|
|
60
|
+
*
|
|
61
|
+
* @param {string} path - 要处理的路径字符串
|
|
62
|
+
* @returns {string} 处理后的路径字符串
|
|
63
|
+
*
|
|
64
|
+
* @example <caption>处理绝对路径</caption>
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const result = pathRelativize('/path/to/file');
|
|
67
|
+
* console.log(result); // 输出: '/path/to/file'
|
|
68
|
+
* ```
|
|
69
|
+
*
|
|
70
|
+
* @example <caption>处理已带'./'前缀的相对路径</caption>
|
|
71
|
+
* ```typescript
|
|
72
|
+
* const result = pathRelativize('./path/to/file');
|
|
73
|
+
* console.log(result); // 输出: './path/to/file'
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* @example <caption>处理不带'./'前缀的相对路径</caption>
|
|
77
|
+
* ```typescript
|
|
78
|
+
* const result = pathRelativize('path/to/file');
|
|
79
|
+
* console.log(result); // 输出: './path/to/file'
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export declare function pathRelativize(path: string): string;
|
package/dist/path.mjs
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { arrayEach } from "./array.mjs";
|
|
2
|
+
function _isCurrentSlice(slice) {
|
|
3
|
+
return slice === ".";
|
|
4
|
+
}
|
|
5
|
+
function _isParentSlice(slice) {
|
|
6
|
+
return slice === "..";
|
|
7
|
+
}
|
|
8
|
+
function isAbsolutePath(path) {
|
|
9
|
+
return path.startsWith("/");
|
|
10
|
+
}
|
|
11
|
+
function isRelativePath(path) {
|
|
12
|
+
return !isAbsolutePath(path);
|
|
13
|
+
}
|
|
14
|
+
function pathNormalize(path) {
|
|
15
|
+
const slices = path.replace(/\\/g, "/").replace(/\/{2,}/g, "/").replace(/\.{3,}/g, "..").replace(/\/\.\//g, "/").split("/").map((point) => point.trim());
|
|
16
|
+
const points = [];
|
|
17
|
+
const isAbs = slices[0] === "";
|
|
18
|
+
const push = (point) => {
|
|
19
|
+
points.push(point);
|
|
20
|
+
};
|
|
21
|
+
const back = () => {
|
|
22
|
+
if (points.length === 1 && isAbs) return;
|
|
23
|
+
if (points.length === 0 || points.at(-1) === "..") {
|
|
24
|
+
points.push("..");
|
|
25
|
+
} else {
|
|
26
|
+
points.pop();
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
for (const slice of slices) {
|
|
30
|
+
const isCurrent = _isCurrentSlice(slice);
|
|
31
|
+
const isParent = _isParentSlice(slice);
|
|
32
|
+
if (isCurrent) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (isParent) {
|
|
36
|
+
back();
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
push(slice);
|
|
40
|
+
}
|
|
41
|
+
return points.join("/");
|
|
42
|
+
}
|
|
43
|
+
function pathJoin(from, ...to) {
|
|
44
|
+
return pathNormalize([from, ...to].join("/"));
|
|
45
|
+
}
|
|
46
|
+
function pathResolve(from, ...to) {
|
|
47
|
+
const paths = [from, ...to].map(pathNormalize);
|
|
48
|
+
let lastStartPath = from;
|
|
49
|
+
let lastStartIndex = 0;
|
|
50
|
+
arrayEach(
|
|
51
|
+
paths,
|
|
52
|
+
(path, index) => {
|
|
53
|
+
if (isAbsolutePath(path)) {
|
|
54
|
+
lastStartPath = path;
|
|
55
|
+
lastStartIndex = index;
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
true
|
|
60
|
+
);
|
|
61
|
+
return pathJoin(lastStartPath, ...paths.slice(lastStartIndex + 1));
|
|
62
|
+
}
|
|
63
|
+
function pathRelativize(path) {
|
|
64
|
+
if (isAbsolutePath(path)) return path;
|
|
65
|
+
if (path.startsWith("./")) return path;
|
|
66
|
+
if (path.startsWith("../")) return path;
|
|
67
|
+
return `./${path}`;
|
|
68
|
+
}
|
|
69
|
+
export {
|
|
70
|
+
isAbsolutePath,
|
|
71
|
+
isRelativePath,
|
|
72
|
+
pathJoin,
|
|
73
|
+
pathNormalize,
|
|
74
|
+
pathRelativize,
|
|
75
|
+
pathResolve
|
|
76
|
+
};
|
|
77
|
+
//# sourceMappingURL=path.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path.mjs","sources":["../src/path.ts"],"sourcesContent":["import { arrayEach } from './array';\n\n/**\n * 判断是否是当前目录标记\n * @param {string} slice - 路径片段\n * @returns {boolean} - 如果是当前目录标记'.'则返回true,否则返回false\n */\nfunction _isCurrentSlice(slice: string): boolean {\n return slice === '.';\n}\n\n/**\n * 判断是否是上级目录标记\n * @param {string} slice - 路径片段\n * @returns {boolean} - 如果是上级目录标记'..'则返回true,否则返回false\n */\nfunction _isParentSlice(slice: string): boolean {\n return slice === '..';\n}\n\n/**\n * 判断是否是绝对路径\n * @param {string} path - 路径字符串\n * @returns {boolean} - 如果是绝对路径则返回true,否则返回false\n * @example\n * ```typescript\n * const isAbs = isAbsolutePath('/path/to/file');\n * console.log(isAbs); // 输出: true\n * ```\n */\nexport function isAbsolutePath(path: string): boolean {\n return path.startsWith('/');\n}\n\n/**\n * 判断是否是相对路径\n * @param {string} path - 路径字符串\n * @returns {boolean} - 如果是相对路径则返回true,否则返回false\n * @example\n * ```typescript\n * const isRel = isRelativePath('path/to/file');\n * console.log(isRel); // 输出: true\n * ```\n */\nexport function isRelativePath(path: string): boolean {\n return !isAbsolutePath(path);\n}\n\n/**\n * 标准化路径\n * @param {string} path - 要标准化的路径字符串。\n * @returns {string} - 标准化后的路径字符串。\n * @example\n * ```typescript\n * const normalizedPath = pathNormalize('/path///to///file');\n * console.log(normalizedPath); // 输出: '/path/to/file'\n * ```\n */\nexport function pathNormalize(path: string): string {\n const slices = path\n .replace(/\\\\/g, '/')\n .replace(/\\/{2,}/g, '/')\n .replace(/\\.{3,}/g, '..')\n .replace(/\\/\\.\\//g, '/')\n .split('/')\n .map((point) => point.trim());\n const points: string[] = [];\n const isAbs = slices[0] === '';\n\n const push = (point: string) => {\n points.push(point);\n };\n\n const back = () => {\n // 绝对路径不能退到根目录\n if (points.length === 1 && isAbs) return;\n\n //\n if (points.length === 0 || points.at(-1) === '..') {\n points.push('..');\n } else {\n points.pop();\n }\n };\n\n for (const slice of slices) {\n const isCurrent = _isCurrentSlice(slice);\n const isParent = _isParentSlice(slice);\n\n // // 未进入实际路径\n // if (!inPoints) {\n // push(slice);\n // inPoints = !isCurrent && !isParent;\n // continue;\n // }\n\n if (isCurrent) {\n continue;\n }\n\n if (isParent) {\n back();\n continue;\n }\n\n push(slice);\n }\n\n return points.join('/');\n}\n\n/**\n * 路径合并\n * @param {string} from - 起始路径。\n * @param {...string[]} to - 要合并的路径片段。\n * @returns {string} - 合并后的路径字符串。\n * @example\n * ```typescript\n * const fullPath = pathJoin('/path', '/to', 'file');\n * console.log(fullPath); // 输出: '/path/to/file'\n * ```\n */\nexport function pathJoin(from: string, ...to: string[]): string {\n return pathNormalize([from, ...to].join('/'));\n}\n\n/**\n * 解析路径\n * @param {string} from - 起始路径\n * @param {...string[]} to - 要解析的路径片段\n * @returns {string} - 解析后的绝对路径\n * @example\n * ```typescript\n * const resolvedPath = pathResolve('/path', '/to', 'file');\n * console.log(resolvedPath); // 输出: '/to/file'\n * ```\n */\nexport function pathResolve(from: string, ...to: string[]): string {\n const paths = [from, ...to].map(pathNormalize);\n\n let lastStartPath = from;\n let lastStartIndex = 0;\n\n arrayEach(\n paths,\n (path, index) => {\n if (isAbsolutePath(path)) {\n lastStartPath = path;\n lastStartIndex = index;\n return false;\n }\n },\n true,\n );\n\n return pathJoin(lastStartPath, ...paths.slice(lastStartIndex + 1));\n}\n\n/**\n * 将相对路径转换为标准的相对路径格式(添加'./'前缀)\n *\n * @param {string} path - 要处理的路径字符串\n * @returns {string} 处理后的路径字符串\n *\n * @example <caption>处理绝对路径</caption>\n * ```typescript\n * const result = pathRelativize('/path/to/file');\n * console.log(result); // 输出: '/path/to/file'\n * ```\n *\n * @example <caption>处理已带'./'前缀的相对路径</caption>\n * ```typescript\n * const result = pathRelativize('./path/to/file');\n * console.log(result); // 输出: './path/to/file'\n * ```\n *\n * @example <caption>处理不带'./'前缀的相对路径</caption>\n * ```typescript\n * const result = pathRelativize('path/to/file');\n * console.log(result); // 输出: './path/to/file'\n * ```\n */\nexport function pathRelativize(path: string): string {\n if (isAbsolutePath(path)) return path;\n if (path.startsWith('./')) return path;\n if (path.startsWith('../')) return path;\n return `./${path}`;\n}\n"],"names":[],"mappings":";AAOA,SAAS,gBAAgB,OAAwB;AAC/C,SAAO,UAAU;AACnB;AAOA,SAAS,eAAe,OAAwB;AAC9C,SAAO,UAAU;AACnB;AAYO,SAAS,eAAe,MAAuB;AAC7C,SAAA,KAAK,WAAW,GAAG;AAC5B;AAYO,SAAS,eAAe,MAAuB;AAC7C,SAAA,CAAC,eAAe,IAAI;AAC7B;AAYO,SAAS,cAAc,MAAsB;AAC5C,QAAA,SAAS,KACZ,QAAQ,OAAO,GAAG,EAClB,QAAQ,WAAW,GAAG,EACtB,QAAQ,WAAW,IAAI,EACvB,QAAQ,WAAW,GAAG,EACtB,MAAM,GAAG,EACT,IAAI,CAAC,UAAU,MAAM,KAAA,CAAM;AAC9B,QAAM,SAAmB,CAAC;AACpB,QAAA,QAAQ,OAAO,CAAC,MAAM;AAEtB,QAAA,OAAO,CAAC,UAAkB;AAC9B,WAAO,KAAK,KAAK;AAAA,EACnB;AAEA,QAAM,OAAO,MAAM;AAEb,QAAA,OAAO,WAAW,KAAK,MAAO;AAGlC,QAAI,OAAO,WAAW,KAAK,OAAO,GAAG,EAAE,MAAM,MAAM;AACjD,aAAO,KAAK,IAAI;AAAA,IAAA,OACX;AACL,aAAO,IAAI;AAAA,IAAA;AAAA,EAEf;AAEA,aAAW,SAAS,QAAQ;AACpB,UAAA,YAAY,gBAAgB,KAAK;AACjC,UAAA,WAAW,eAAe,KAAK;AASrC,QAAI,WAAW;AACb;AAAA,IAAA;AAGF,QAAI,UAAU;AACP,WAAA;AACL;AAAA,IAAA;AAGF,SAAK,KAAK;AAAA,EAAA;AAGL,SAAA,OAAO,KAAK,GAAG;AACxB;AAagB,SAAA,SAAS,SAAiB,IAAsB;AACvD,SAAA,cAAc,CAAC,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG,CAAC;AAC9C;AAagB,SAAA,YAAY,SAAiB,IAAsB;AACjE,QAAM,QAAQ,CAAC,MAAM,GAAG,EAAE,EAAE,IAAI,aAAa;AAE7C,MAAI,gBAAgB;AACpB,MAAI,iBAAiB;AAErB;AAAA,IACE;AAAA,IACA,CAAC,MAAM,UAAU;AACX,UAAA,eAAe,IAAI,GAAG;AACR,wBAAA;AACC,yBAAA;AACV,eAAA;AAAA,MAAA;AAAA,IAEX;AAAA,IACA;AAAA,EACF;AAEA,SAAO,SAAS,eAAe,GAAG,MAAM,MAAM,iBAAiB,CAAC,CAAC;AACnE;AA0BO,SAAS,eAAe,MAAsB;AAC/C,MAAA,eAAe,IAAI,EAAU,QAAA;AACjC,MAAI,KAAK,WAAW,IAAI,EAAU,QAAA;AAClC,MAAI,KAAK,WAAW,KAAK,EAAU,QAAA;AACnC,SAAO,KAAK,IAAI;AAClB;"}
|
package/dist/promise.cjs
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const type = require("./type.cjs");
|
|
4
|
+
function isPromiseLike(unknown) {
|
|
5
|
+
return type.isPromise(unknown) || type.isObject(unknown) && typeof unknown.then === "function";
|
|
6
|
+
}
|
|
7
|
+
async function promiseDelay(ms = 0, ctrl) {
|
|
8
|
+
return new Promise((resolve) => {
|
|
9
|
+
const t = setTimeout(resolve, ms);
|
|
10
|
+
if (ctrl) {
|
|
11
|
+
ctrl.signal.addEventListener("abort", () => {
|
|
12
|
+
clearTimeout(t);
|
|
13
|
+
resolve();
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
async function promiseTimeout(promise, ms) {
|
|
19
|
+
const ctrl = new AbortController();
|
|
20
|
+
const result = await Promise.race([
|
|
21
|
+
promise,
|
|
22
|
+
promiseDelay(ms, ctrl).then(() => {
|
|
23
|
+
throw new Error("timeout");
|
|
24
|
+
})
|
|
25
|
+
]);
|
|
26
|
+
ctrl.abort();
|
|
27
|
+
return result;
|
|
28
|
+
}
|
|
29
|
+
function promiseWhen(condition, ms = 10) {
|
|
30
|
+
return new Promise((resolve, reject) => {
|
|
31
|
+
const check = () => {
|
|
32
|
+
if (condition()) {
|
|
33
|
+
resolve();
|
|
34
|
+
} else {
|
|
35
|
+
setTimeout(check, ms);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
check();
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function promiseShared(promise) {
|
|
42
|
+
return new Promise((resolve, reject) => {
|
|
43
|
+
promise.then(resolve, reject);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
function createMinDelayPromise(ms) {
|
|
47
|
+
const startTime = Date.now();
|
|
48
|
+
return async function end() {
|
|
49
|
+
const endTime = Date.now();
|
|
50
|
+
const waitTime = ms - (endTime - startTime);
|
|
51
|
+
if (waitTime > 0) {
|
|
52
|
+
await promiseDelay(waitTime);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
exports.createMinDelayPromise = createMinDelayPromise;
|
|
57
|
+
exports.isPromiseLike = isPromiseLike;
|
|
58
|
+
exports.promiseDelay = promiseDelay;
|
|
59
|
+
exports.promiseShared = promiseShared;
|
|
60
|
+
exports.promiseTimeout = promiseTimeout;
|
|
61
|
+
exports.promiseWhen = promiseWhen;
|
|
62
|
+
//# sourceMappingURL=promise.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promise.cjs","sources":["../src/promise.ts"],"sourcesContent":["import { isObject, isPromise } from './type';\n\n/**\n * 检查给定的值是否为 Promise 类似对象。\n * @param unknown - 要检查的值。\n * @returns 如果值是 Promise 类似对象,则返回 `true`,否则返回 `false`。\n */\nexport function isPromiseLike<T>(unknown: unknown): unknown is Promise<T> {\n return isPromise(unknown) || (isObject(unknown) && typeof (unknown as unknown as Promise<T>).then === 'function');\n}\n\n/**\n * 等待一定时间后解决 Promise\n * @param ms - 等待的毫秒数,默认为 0\n * @param ctrl - 可选的 AbortController,用于提前终止等待\n * @returns 一个 Promise,等待指定时间后解决\n */\nexport async function promiseDelay(ms = 0, ctrl?: AbortController) {\n return new Promise<void>((resolve) => {\n const t = setTimeout(resolve, ms);\n\n if (ctrl) {\n ctrl.signal.addEventListener('abort', () => {\n clearTimeout(t);\n resolve();\n });\n }\n });\n}\n\n/**\n * 使 Promise 在指定时间内执行,超时则拒绝\n * @param promise - 要执行的 Promise\n * @param ms - 超时的毫秒数\n * @returns 如果 Promise 在指定时间内解决,则返回其结果;否则抛出 \"timeout\" 错误\n * @throws {Error} 如果 Promise 超时,抛出 \"timeout\" 错误\n */\nexport async function promiseTimeout<T>(promise: Promise<T>, ms: number) {\n const ctrl = new AbortController();\n const result = await Promise.race([\n promise,\n promiseDelay(ms, ctrl).then(() => {\n throw new Error('timeout');\n }),\n ]);\n ctrl.abort();\n return result;\n}\n\n/**\n * 在指定条件满足时解决 Promise\n * @param condition - 一个返回布尔值的函数,用于检查条件是否满足\n * @param ms - 检查条件的时间间隔(毫秒),默认为 10\n * @returns 一个 Promise,在条件满足时解决\n */\nexport function promiseWhen(condition: () => boolean, ms = 10) {\n return new Promise<void>((resolve, reject) => {\n const check = () => {\n if (condition()) {\n resolve();\n } else {\n setTimeout(check, ms);\n }\n };\n\n check();\n });\n}\n\n/**\n * 创建一个与给定 Promise 共享状态的新 Promise。\n * 新的 Promise 不具备 resolve 或 reject 的能力,它仅反映原始 Promise 的状态。\n * @param promise - 要共享状态的原始 Promise。\n * @returns 一个新的 Promise,其状态与给定的 Promise 完全相同。\n * @example\n * const { promise: p1 } = Promise.withResolvers();\n * const sp1 = sharedPromise(p1);\n * const sp2 = sharedPromise(p1);\n * // 此时 sp1、sp2 完全共享 p1 的状态,自身并不具备 resolve 或 reject 的能力\n */\nexport function promiseShared<T>(promise: Promise<T>) {\n return new Promise<T>((resolve, reject) => {\n promise.then(resolve, reject);\n });\n}\n\n/**\n * 创建一个最小等待时间的函数\n * @param {number} ms - 最小等待时间(毫秒)\n * @returns {function} 返回一个异步函数,该函数会确保从 createMinDelayPromise 调用到其执行的时间至少为 ms 毫秒\n * @example\n * const end = createMinDelayPromise(1000);\n * // 执行一些操作\n * await end(); // 确保从 createMinDelayPromise 调用到这里的总时间至少为 1000 毫秒\n */\nexport function createMinDelayPromise(ms: number) {\n const startTime = Date.now();\n /**\n * 确保最小等待时间的结束函数\n * @async\n * @function end\n * @returns {Promise<void>} 在达到最小等待时间后解决\n */\n return async function end() {\n const endTime = Date.now();\n const waitTime = ms - (endTime - startTime);\n if (waitTime > 0) {\n await promiseDelay(waitTime);\n }\n };\n}\n"],"names":["isPromise","isObject"],"mappings":";;;AAOO,SAAS,cAAiB,SAAyC;AACjE,SAAAA,KAAA,UAAU,OAAO,KAAMC,KAAA,SAAS,OAAO,KAAK,OAAQ,QAAkC,SAAS;AACxG;AAQsB,eAAA,aAAa,KAAK,GAAG,MAAwB;AAC1D,SAAA,IAAI,QAAc,CAAC,YAAY;AAC9B,UAAA,IAAI,WAAW,SAAS,EAAE;AAEhC,QAAI,MAAM;AACH,WAAA,OAAO,iBAAiB,SAAS,MAAM;AAC1C,qBAAa,CAAC;AACN,gBAAA;AAAA,MAAA,CACT;AAAA,IAAA;AAAA,EACH,CACD;AACH;AASsB,eAAA,eAAkB,SAAqB,IAAY;AACjE,QAAA,OAAO,IAAI,gBAAgB;AAC3B,QAAA,SAAS,MAAM,QAAQ,KAAK;AAAA,IAChC;AAAA,IACA,aAAa,IAAI,IAAI,EAAE,KAAK,MAAM;AAC1B,YAAA,IAAI,MAAM,SAAS;AAAA,IAC1B,CAAA;AAAA,EAAA,CACF;AACD,OAAK,MAAM;AACJ,SAAA;AACT;AAQgB,SAAA,YAAY,WAA0B,KAAK,IAAI;AAC7D,SAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,UAAM,QAAQ,MAAM;AAClB,UAAI,aAAa;AACP,gBAAA;AAAA,MAAA,OACH;AACL,mBAAW,OAAO,EAAE;AAAA,MAAA;AAAA,IAExB;AAEM,UAAA;AAAA,EAAA,CACP;AACH;AAaO,SAAS,cAAiB,SAAqB;AACpD,SAAO,IAAI,QAAW,CAAC,SAAS,WAAW;AACjC,YAAA,KAAK,SAAS,MAAM;AAAA,EAAA,CAC7B;AACH;AAWO,SAAS,sBAAsB,IAAY;AAC1C,QAAA,YAAY,KAAK,IAAI;AAO3B,SAAO,eAAe,MAAM;AACpB,UAAA,UAAU,KAAK,IAAI;AACnB,UAAA,WAAW,MAAM,UAAU;AACjC,QAAI,WAAW,GAAG;AAChB,YAAM,aAAa,QAAQ;AAAA,IAAA;AAAA,EAE/B;AACF;;;;;;;"}
|
|
@@ -1,33 +1,16 @@
|
|
|
1
|
-
import { isObject, isPromise } from './type';
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* 检查给定的值是否为 Promise 类似对象。
|
|
5
3
|
* @param unknown - 要检查的值。
|
|
6
4
|
* @returns 如果值是 Promise 类似对象,则返回 `true`,否则返回 `false`。
|
|
7
5
|
*/
|
|
8
|
-
export function isPromiseLike<T>(unknown: unknown): unknown is Promise<T
|
|
9
|
-
return isPromise(unknown) || (isObject(unknown) && typeof (unknown as unknown as Promise<T>).then === 'function');
|
|
10
|
-
}
|
|
11
|
-
|
|
6
|
+
export declare function isPromiseLike<T>(unknown: unknown): unknown is Promise<T>;
|
|
12
7
|
/**
|
|
13
8
|
* 等待一定时间后解决 Promise
|
|
14
9
|
* @param ms - 等待的毫秒数,默认为 0
|
|
15
10
|
* @param ctrl - 可选的 AbortController,用于提前终止等待
|
|
16
11
|
* @returns 一个 Promise,等待指定时间后解决
|
|
17
12
|
*/
|
|
18
|
-
export
|
|
19
|
-
return new Promise<void>((resolve) => {
|
|
20
|
-
const t = setTimeout(resolve, ms);
|
|
21
|
-
|
|
22
|
-
if (ctrl) {
|
|
23
|
-
ctrl.signal.addEventListener('abort', () => {
|
|
24
|
-
clearTimeout(t);
|
|
25
|
-
resolve();
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
|
|
13
|
+
export declare function promiseDelay(ms?: number, ctrl?: AbortController): Promise<void>;
|
|
31
14
|
/**
|
|
32
15
|
* 使 Promise 在指定时间内执行,超时则拒绝
|
|
33
16
|
* @param promise - 要执行的 Promise
|
|
@@ -35,38 +18,14 @@ export async function promiseDelay(ms = 0, ctrl?: AbortController) {
|
|
|
35
18
|
* @returns 如果 Promise 在指定时间内解决,则返回其结果;否则抛出 "timeout" 错误
|
|
36
19
|
* @throws {Error} 如果 Promise 超时,抛出 "timeout" 错误
|
|
37
20
|
*/
|
|
38
|
-
export
|
|
39
|
-
const ctrl = new AbortController();
|
|
40
|
-
const result = await Promise.race([
|
|
41
|
-
promise,
|
|
42
|
-
promiseDelay(ms, ctrl).then(() => {
|
|
43
|
-
throw new Error('timeout');
|
|
44
|
-
}),
|
|
45
|
-
]);
|
|
46
|
-
ctrl.abort();
|
|
47
|
-
return result;
|
|
48
|
-
}
|
|
49
|
-
|
|
21
|
+
export declare function promiseTimeout<T>(promise: Promise<T>, ms: number): Promise<T>;
|
|
50
22
|
/**
|
|
51
23
|
* 在指定条件满足时解决 Promise
|
|
52
24
|
* @param condition - 一个返回布尔值的函数,用于检查条件是否满足
|
|
53
25
|
* @param ms - 检查条件的时间间隔(毫秒),默认为 10
|
|
54
26
|
* @returns 一个 Promise,在条件满足时解决
|
|
55
27
|
*/
|
|
56
|
-
export function promiseWhen(condition: () => boolean, ms
|
|
57
|
-
return new Promise<void>((resolve, reject) => {
|
|
58
|
-
const check = () => {
|
|
59
|
-
if (condition()) {
|
|
60
|
-
resolve();
|
|
61
|
-
} else {
|
|
62
|
-
setTimeout(check, ms);
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
check();
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
|
|
28
|
+
export declare function promiseWhen(condition: () => boolean, ms?: number): Promise<void>;
|
|
70
29
|
/**
|
|
71
30
|
* 创建一个与给定 Promise 共享状态的新 Promise。
|
|
72
31
|
* 新的 Promise 不具备 resolve 或 reject 的能力,它仅反映原始 Promise 的状态。
|
|
@@ -78,12 +37,7 @@ export function promiseWhen(condition: () => boolean, ms = 10) {
|
|
|
78
37
|
* const sp2 = sharedPromise(p1);
|
|
79
38
|
* // 此时 sp1、sp2 完全共享 p1 的状态,自身并不具备 resolve 或 reject 的能力
|
|
80
39
|
*/
|
|
81
|
-
export function promiseShared<T>(promise: Promise<T>)
|
|
82
|
-
return new Promise<T>((resolve, reject) => {
|
|
83
|
-
promise.then(resolve, reject);
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
|
|
40
|
+
export declare function promiseShared<T>(promise: Promise<T>): Promise<T>;
|
|
87
41
|
/**
|
|
88
42
|
* 创建一个最小等待时间的函数
|
|
89
43
|
* @param {number} ms - 最小等待时间(毫秒)
|
|
@@ -93,19 +47,4 @@ export function promiseShared<T>(promise: Promise<T>) {
|
|
|
93
47
|
* // 执行一些操作
|
|
94
48
|
* await end(); // 确保从 createMinDelayPromise 调用到这里的总时间至少为 1000 毫秒
|
|
95
49
|
*/
|
|
96
|
-
export function createMinDelayPromise(ms: number)
|
|
97
|
-
const startTime = Date.now();
|
|
98
|
-
/**
|
|
99
|
-
* 确保最小等待时间的结束函数
|
|
100
|
-
* @async
|
|
101
|
-
* @function end
|
|
102
|
-
* @returns {Promise<void>} 在达到最小等待时间后解决
|
|
103
|
-
*/
|
|
104
|
-
return async function end() {
|
|
105
|
-
const endTime = Date.now();
|
|
106
|
-
const waitTime = ms - (endTime - startTime);
|
|
107
|
-
if (waitTime > 0) {
|
|
108
|
-
await promiseDelay(waitTime);
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
}
|
|
50
|
+
export declare function createMinDelayPromise(ms: number): () => Promise<void>;
|