@vtj/utils 0.0.9 → 0.0.11
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/lib/cdn/index.cjs.js +1 -1
- package/lib/cdn/index.es.js +1 -1
- package/lib/cdn/index.umd.js +1 -1
- package/lib/index.cjs.js +5 -5
- package/lib/index.es.js +1081 -1078
- package/lib/index.umd.js +6 -6
- package/package.json +2 -3
- package/types/index.d.ts +9 -4
- package/lib/cdn/mock/test_jsonp.js +0 -3
- package/lib/mock/test_jsonp.js +0 -3
- package/src/axios.ts +0 -3
- package/src/cookie.ts +0 -22
- package/src/crypto.ts +0 -6
- package/src/dayjs.ts +0 -4
- package/src/index.ts +0 -9
- package/src/jsonp.ts +0 -74
- package/src/request.ts +0 -347
- package/src/storage.ts +0 -143
- package/src/url.ts +0 -102
- package/src/util.ts +0 -77
- package/types/dev/vite-env.d.ts +0 -7
- package/types/src/axios.d.ts +0 -2
- package/types/src/cookie.d.ts +0 -10
- package/types/src/crypto.d.ts +0 -1
- package/types/src/dayjs.d.ts +0 -2
- package/types/src/index.d.ts +0 -9
- package/types/src/jsonp.d.ts +0 -8
- package/types/src/request.d.ts +0 -41
- package/types/src/storage.d.ts +0 -46
- package/types/src/url.d.ts +0 -44
- package/types/src/util.d.ts +0 -24
- package/types/src/utils.d.ts +0 -3
package/src/jsonp.ts
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { append } from './url';
|
|
2
|
-
import { template } from './util';
|
|
3
|
-
|
|
4
|
-
let __count__ = 0;
|
|
5
|
-
|
|
6
|
-
function noop() {}
|
|
7
|
-
|
|
8
|
-
const defaultOptions: JSONPOptions = {
|
|
9
|
-
cache: false,
|
|
10
|
-
timeout: 60 * 1000,
|
|
11
|
-
param: 'callback',
|
|
12
|
-
prefix: '__jp',
|
|
13
|
-
name: ''
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export interface JSONPOptions {
|
|
17
|
-
cache?: boolean;
|
|
18
|
-
timeout?: number;
|
|
19
|
-
prefix?: string;
|
|
20
|
-
param?: string;
|
|
21
|
-
name?: string;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function jsonp(
|
|
25
|
-
url: string,
|
|
26
|
-
params: Record<string, any> = {},
|
|
27
|
-
options?: JSONPOptions
|
|
28
|
-
) {
|
|
29
|
-
const opts = Object.assign({}, defaultOptions, options || {});
|
|
30
|
-
const id: string = opts.name || `${opts.prefix}${++__count__}`;
|
|
31
|
-
const target = document.getElementsByTagName('script')[0] || document.head;
|
|
32
|
-
let script: HTMLScriptElement;
|
|
33
|
-
let timer: any;
|
|
34
|
-
|
|
35
|
-
return new Promise((resolve, reject) => {
|
|
36
|
-
const cleanup = () => {
|
|
37
|
-
if (script?.parentNode) {
|
|
38
|
-
script.parentNode.removeChild(script);
|
|
39
|
-
(window as any)[id] = noop;
|
|
40
|
-
if (timer) {
|
|
41
|
-
clearTimeout(timer);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
(window as any)[id] = (data: any) => {
|
|
47
|
-
cleanup();
|
|
48
|
-
resolve(data);
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
const query = {
|
|
52
|
-
...params,
|
|
53
|
-
[opts.param as string]: id
|
|
54
|
-
};
|
|
55
|
-
if (!opts.cache) {
|
|
56
|
-
query.__t__ = Date.now();
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (url.includes('${')) {
|
|
60
|
-
const compiled = template(url);
|
|
61
|
-
url = compiled(query || {});
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const _url = append(url, query);
|
|
65
|
-
script = document.createElement('script');
|
|
66
|
-
script.src = _url;
|
|
67
|
-
target.parentNode?.insertBefore(script, target);
|
|
68
|
-
|
|
69
|
-
timer = setTimeout(() => {
|
|
70
|
-
cleanup();
|
|
71
|
-
reject(new Error('Timeout'));
|
|
72
|
-
}, opts.timeout);
|
|
73
|
-
});
|
|
74
|
-
}
|
package/src/request.ts
DELETED
|
@@ -1,347 +0,0 @@
|
|
|
1
|
-
import { pick, trim, uid, merge, template } from './util';
|
|
2
|
-
import { axios } from './axios';
|
|
3
|
-
|
|
4
|
-
const TYPES = {
|
|
5
|
-
form: 'application/x-www-form-urlencoded',
|
|
6
|
-
json: 'application/json',
|
|
7
|
-
data: 'multipart/form-data'
|
|
8
|
-
};
|
|
9
|
-
const DATA_METHODS = ['put', 'post', 'patch'];
|
|
10
|
-
const LOCAL_REQUEST_ID = 'Local-Request-Id';
|
|
11
|
-
const RequestCache: Record<string, any> = {};
|
|
12
|
-
const __loadingArray__: Array<any> = [];
|
|
13
|
-
let __loadingTimer__: any = null;
|
|
14
|
-
let __isLoading__: boolean = false;
|
|
15
|
-
let __requestId__: any, __responseId__: any;
|
|
16
|
-
|
|
17
|
-
const instance = axios.create({
|
|
18
|
-
headers: {
|
|
19
|
-
'Content-Type': 'application/x-www-form-urlencoded'
|
|
20
|
-
},
|
|
21
|
-
timeout: 60 * 1000
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
export interface ISettings {
|
|
25
|
-
loading?: boolean;
|
|
26
|
-
showLoading?: () => void;
|
|
27
|
-
hideLoading?: () => void;
|
|
28
|
-
loadingTime?: number;
|
|
29
|
-
type?: 'form' | 'json' | 'data';
|
|
30
|
-
originResponse?: boolean;
|
|
31
|
-
validSuccess?: boolean;
|
|
32
|
-
validate?: (res: any) => boolean;
|
|
33
|
-
failMessage?: boolean;
|
|
34
|
-
showError?: (msg: any) => void;
|
|
35
|
-
injectHeaders?: (options: IOptions) => Record<string, string>;
|
|
36
|
-
defaults?: Record<string, any>;
|
|
37
|
-
trim?: boolean;
|
|
38
|
-
picked?: boolean;
|
|
39
|
-
pickFilter?: (v: any) => boolean;
|
|
40
|
-
skipWarnResponseCode?: number;
|
|
41
|
-
skipWarnExecutor?: () => void;
|
|
42
|
-
skipWarnCallback?: () => void;
|
|
43
|
-
skipWarnFinally?: () => void;
|
|
44
|
-
skipWarn?: boolean;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const __settings__: ISettings = {
|
|
48
|
-
loading: true,
|
|
49
|
-
// 在此时间内,请求还没回来的话,就显示加载中动画,单位ms
|
|
50
|
-
loadingTime: 50,
|
|
51
|
-
// 发送数据类型,支持:form、json、data
|
|
52
|
-
type: 'form',
|
|
53
|
-
// 响应原始 Response 对象
|
|
54
|
-
originResponse: false,
|
|
55
|
-
// 校验成功
|
|
56
|
-
validSuccess: true,
|
|
57
|
-
// 显示失败信息
|
|
58
|
-
failMessage: true,
|
|
59
|
-
// 覆盖 axios 实例的 defaults 属性
|
|
60
|
-
defaults: Object.create(null),
|
|
61
|
-
// 清除字段值两旁的空格
|
|
62
|
-
trim: true,
|
|
63
|
-
// 剔除null、undefined 空字符串的参数
|
|
64
|
-
picked: true,
|
|
65
|
-
// 自定义剔除函数
|
|
66
|
-
pickFilter: (v: any) => v !== null && v !== undefined && v !== '',
|
|
67
|
-
// 警告响应code编码值
|
|
68
|
-
skipWarnResponseCode: 7,
|
|
69
|
-
skipWarn: false
|
|
70
|
-
// skipWarnExecutor: null,
|
|
71
|
-
// skipWarnCallback: null,
|
|
72
|
-
// skipWarnFinally: null,
|
|
73
|
-
// skipWarn: false
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
export function setConfig(config: ISettings) {
|
|
77
|
-
merge(__settings__, config);
|
|
78
|
-
const defaults = __settings__.defaults || {};
|
|
79
|
-
Object.entries(defaults).forEach(([name, value]) => {
|
|
80
|
-
(instance.defaults as any)[name] = value;
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export interface IOptions {
|
|
85
|
-
url: string;
|
|
86
|
-
method?:
|
|
87
|
-
| 'get'
|
|
88
|
-
| 'GET'
|
|
89
|
-
| 'delete'
|
|
90
|
-
| 'DELETE'
|
|
91
|
-
| 'head'
|
|
92
|
-
| 'HEAD'
|
|
93
|
-
| 'options'
|
|
94
|
-
| 'OPTIONS'
|
|
95
|
-
| 'post'
|
|
96
|
-
| 'POST'
|
|
97
|
-
| 'put'
|
|
98
|
-
| 'PUT'
|
|
99
|
-
| 'patch'
|
|
100
|
-
| 'PATCH';
|
|
101
|
-
baseURL?: string;
|
|
102
|
-
headers?: Record<string, string>;
|
|
103
|
-
params?: any;
|
|
104
|
-
data?: any;
|
|
105
|
-
timeout?: number;
|
|
106
|
-
settings?: ISettings;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export type IApiOptions = string | IOptions;
|
|
110
|
-
|
|
111
|
-
function createHeaders(
|
|
112
|
-
options: IOptions,
|
|
113
|
-
settings: ISettings
|
|
114
|
-
): Record<string, any> {
|
|
115
|
-
const headers = options.headers || Object.create(null);
|
|
116
|
-
const requestHeaders = Object.create(null);
|
|
117
|
-
const contentType = TYPES[settings.type || 'form'];
|
|
118
|
-
if (contentType) {
|
|
119
|
-
requestHeaders['Content-Type'] = contentType;
|
|
120
|
-
}
|
|
121
|
-
const { injectHeaders, skipWarnExecutor } = settings;
|
|
122
|
-
if (injectHeaders) {
|
|
123
|
-
Object.assign(requestHeaders, injectHeaders(options));
|
|
124
|
-
}
|
|
125
|
-
if (skipWarnExecutor) {
|
|
126
|
-
const id = uid();
|
|
127
|
-
requestHeaders[LOCAL_REQUEST_ID] = id;
|
|
128
|
-
RequestCache[id] = {
|
|
129
|
-
options,
|
|
130
|
-
settings
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
return Object.assign(requestHeaders, headers);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
function pickData(data: any, pickFilter?: (v: any) => boolean) {
|
|
137
|
-
// 只对对象进行过滤
|
|
138
|
-
if (!data || Array.isArray(data)) return data;
|
|
139
|
-
return pick(data, pickFilter);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
function toFormData(data: Record<string, any> = {}) {
|
|
143
|
-
if (data instanceof FormData) return data;
|
|
144
|
-
const formData = new FormData();
|
|
145
|
-
Object.entries(data).forEach(([key, value]) => {
|
|
146
|
-
formData.append(key, value);
|
|
147
|
-
});
|
|
148
|
-
return formData;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function openLoading(settings: ISettings) {
|
|
152
|
-
const { loading, loadingTime, showLoading } = settings;
|
|
153
|
-
if (!loading || !showLoading) return;
|
|
154
|
-
__loadingArray__.push(true);
|
|
155
|
-
clearTimeout(__loadingTimer__);
|
|
156
|
-
__loadingTimer__ = setTimeout(() => {
|
|
157
|
-
if (__isLoading__) return;
|
|
158
|
-
__isLoading__ = true;
|
|
159
|
-
showLoading();
|
|
160
|
-
}, loadingTime);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
function closeLoading(settings: ISettings) {
|
|
164
|
-
const { loading, hideLoading } = settings;
|
|
165
|
-
if (!loading || !hideLoading) return;
|
|
166
|
-
clearTimeout(__loadingTimer__);
|
|
167
|
-
__loadingArray__.pop();
|
|
168
|
-
if (__loadingArray__.length === 0 && __isLoading__) {
|
|
169
|
-
hideLoading();
|
|
170
|
-
__isLoading__ = false;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
function showErrorMessage(settings: ISettings, content: string) {
|
|
175
|
-
const { showError, failMessage } = settings;
|
|
176
|
-
if (!failMessage || !showError) return;
|
|
177
|
-
showError(content);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
function processSuccess(
|
|
181
|
-
settings: ISettings,
|
|
182
|
-
res: any,
|
|
183
|
-
resolve: (val: any) => void,
|
|
184
|
-
reject: (reason: any) => void
|
|
185
|
-
) {
|
|
186
|
-
const { originResponse, validSuccess, validate } = settings;
|
|
187
|
-
const { data } = res;
|
|
188
|
-
if (data.promise) {
|
|
189
|
-
return resolve(data.promise);
|
|
190
|
-
}
|
|
191
|
-
if (validSuccess && validate) {
|
|
192
|
-
const success = !!validate(data);
|
|
193
|
-
if (success) {
|
|
194
|
-
resolve(originResponse ? res : data.data);
|
|
195
|
-
} else {
|
|
196
|
-
const { message, msg } = data || {};
|
|
197
|
-
showErrorMessage(settings, message || msg || '未知错误');
|
|
198
|
-
reject(res);
|
|
199
|
-
}
|
|
200
|
-
} else {
|
|
201
|
-
resolve(originResponse ? res : data);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
function processError(
|
|
206
|
-
settings: ISettings,
|
|
207
|
-
e: any,
|
|
208
|
-
reject: (reason: any) => void
|
|
209
|
-
) {
|
|
210
|
-
reject(e);
|
|
211
|
-
if (e && e.message) {
|
|
212
|
-
showErrorMessage(settings, e.message);
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
const data = e?.response?.data;
|
|
216
|
-
if (data) {
|
|
217
|
-
let message = (data.message || data.msg || '').replace(
|
|
218
|
-
/^\[4:ReqFailure]/,
|
|
219
|
-
''
|
|
220
|
-
);
|
|
221
|
-
if (data && data.code === 500) {
|
|
222
|
-
message = '系统繁忙,请稍后重试!';
|
|
223
|
-
}
|
|
224
|
-
showErrorMessage(settings, message);
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
function request(options: IOptions, currentSettings?: ISettings) {
|
|
229
|
-
const { url, method = 'get' } = options;
|
|
230
|
-
const settings = {
|
|
231
|
-
...__settings__,
|
|
232
|
-
...(options.settings || {}),
|
|
233
|
-
...currentSettings
|
|
234
|
-
};
|
|
235
|
-
const headers = createHeaders(options, settings);
|
|
236
|
-
let { data, params } = options;
|
|
237
|
-
if (settings.picked) {
|
|
238
|
-
const { pickFilter } = settings;
|
|
239
|
-
data = data ? pickData(data, pickFilter) : data;
|
|
240
|
-
params = params ? pickData(params, pickFilter) : params;
|
|
241
|
-
}
|
|
242
|
-
if (settings.trim) {
|
|
243
|
-
data = data ? trim(data) : data;
|
|
244
|
-
params = params ? trim(params) : params;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
const { skipWarnExecutor, skipWarn } = settings;
|
|
248
|
-
if (DATA_METHODS.includes(method)) {
|
|
249
|
-
data = skipWarnExecutor ? Object.assign(data || {}, { skipWarn }) : data;
|
|
250
|
-
data = settings.type !== 'json' ? toFormData(data) : data;
|
|
251
|
-
} else {
|
|
252
|
-
params = skipWarnExecutor
|
|
253
|
-
? Object.assign(params || {}, { skipWarn })
|
|
254
|
-
: params;
|
|
255
|
-
params = {
|
|
256
|
-
...params,
|
|
257
|
-
...data
|
|
258
|
-
};
|
|
259
|
-
}
|
|
260
|
-
return new Promise((resolve, reject) => {
|
|
261
|
-
openLoading(settings);
|
|
262
|
-
instance({
|
|
263
|
-
...options,
|
|
264
|
-
url,
|
|
265
|
-
method,
|
|
266
|
-
params,
|
|
267
|
-
data,
|
|
268
|
-
headers
|
|
269
|
-
})
|
|
270
|
-
.then((res) => processSuccess(settings, res, resolve, reject))
|
|
271
|
-
.catch((e) => processError(settings, e, reject))
|
|
272
|
-
.finally(() => {
|
|
273
|
-
closeLoading(settings);
|
|
274
|
-
});
|
|
275
|
-
});
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
instance.interceptors.response.use((res) => {
|
|
279
|
-
const requestId = res?.config?.headers?.[LOCAL_REQUEST_ID] as string;
|
|
280
|
-
const requestCache = RequestCache[requestId];
|
|
281
|
-
delete RequestCache[requestId];
|
|
282
|
-
if (!requestCache) return res;
|
|
283
|
-
const { settings = {}, options } = requestCache;
|
|
284
|
-
const {
|
|
285
|
-
skipWarnExecutor,
|
|
286
|
-
skipWarnResponseCode,
|
|
287
|
-
skipWarnCallback,
|
|
288
|
-
skipWarnFinally
|
|
289
|
-
} = settings;
|
|
290
|
-
if (!skipWarnExecutor) return res;
|
|
291
|
-
if (Number.parseInt(res.data?.code, 10) === skipWarnResponseCode) {
|
|
292
|
-
skipWarnCallback && skipWarnCallback(res.data);
|
|
293
|
-
const promise = new Promise(skipWarnExecutor).then(() => {
|
|
294
|
-
settings.skipWarn = true;
|
|
295
|
-
return request(options, settings);
|
|
296
|
-
});
|
|
297
|
-
promise
|
|
298
|
-
.catch((e) => e)
|
|
299
|
-
.finally(() => {
|
|
300
|
-
skipWarnFinally && skipWarnFinally();
|
|
301
|
-
});
|
|
302
|
-
res.data.promise = promise;
|
|
303
|
-
}
|
|
304
|
-
return res;
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
export function createApi(options: IApiOptions) {
|
|
308
|
-
const dataType = typeof options;
|
|
309
|
-
const opts: IOptions =
|
|
310
|
-
dataType === 'string'
|
|
311
|
-
? ({ url: options as string } as IOptions)
|
|
312
|
-
: (options as IOptions);
|
|
313
|
-
if (!opts.url) throw new Error('missing request url');
|
|
314
|
-
return (data: any, currentOptions = {}) => {
|
|
315
|
-
let url = opts.url;
|
|
316
|
-
if (url.includes('${')) {
|
|
317
|
-
const compiled = template(url);
|
|
318
|
-
url = compiled(data || {});
|
|
319
|
-
}
|
|
320
|
-
request({
|
|
321
|
-
...opts,
|
|
322
|
-
url,
|
|
323
|
-
data,
|
|
324
|
-
...currentOptions
|
|
325
|
-
});
|
|
326
|
-
};
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
export function setRequest(success: any, fail?: any) {
|
|
330
|
-
const request = instance.interceptors.request;
|
|
331
|
-
if (__requestId__) {
|
|
332
|
-
request.eject(__requestId__);
|
|
333
|
-
}
|
|
334
|
-
__requestId__ = request.use(success, fail);
|
|
335
|
-
return __requestId__;
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
export function setResponse(success: any, fail?: any) {
|
|
339
|
-
const response = instance.interceptors.response;
|
|
340
|
-
if (__responseId__) {
|
|
341
|
-
response.eject(__responseId__);
|
|
342
|
-
}
|
|
343
|
-
__responseId__ = response.use(success, fail);
|
|
344
|
-
return __responseId__;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
export { request, instance as axiosInstance, __settings__ as RequestSettings };
|
package/src/storage.ts
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 缓存操作模块,提供sessionStorage和localStorage操作
|
|
3
|
-
* @module storage
|
|
4
|
-
* @author 陈华春
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* sessionStorage
|
|
9
|
-
* @const
|
|
10
|
-
* @type {Storage}
|
|
11
|
-
*/
|
|
12
|
-
const SESSION = window.sessionStorage || {};
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* localStorage
|
|
16
|
-
* @type {Storage}
|
|
17
|
-
*/
|
|
18
|
-
const LOCAL = window.localStorage || {};
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* 内存缓存
|
|
22
|
-
* @type {{}}
|
|
23
|
-
*/
|
|
24
|
-
let CACHES: Record<string, any> = {};
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* 存储方式映射
|
|
28
|
-
*/
|
|
29
|
-
const TYPES: Record<string, any> = {
|
|
30
|
-
local: LOCAL,
|
|
31
|
-
session: SESSION,
|
|
32
|
-
cache: CACHES
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
const defaultOptions = {
|
|
36
|
-
type: 'cache',
|
|
37
|
-
expired: 0,
|
|
38
|
-
prefix: '__NewPearl__'
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* 保存缓存
|
|
43
|
-
* @param {string} key 缓存key
|
|
44
|
-
* @param {String|Object|Array} value 缓存值,对象、数组类型自动JSON.stringify成字符串
|
|
45
|
-
* @param {object} [opts] 选项
|
|
46
|
-
* @param {Object} [opts.type=cache] 存储方式 local、 session、cache
|
|
47
|
-
* @param {number} [opts.expired=0] 过期时间,单位毫秒
|
|
48
|
-
* @param {string} [opts.prefix=__NewPearl__] key 前缀
|
|
49
|
-
*/
|
|
50
|
-
export function save(key: string, value: any = '', opts = {}) {
|
|
51
|
-
if (!key) return;
|
|
52
|
-
const { type, expired, prefix } = { ...defaultOptions, ...opts };
|
|
53
|
-
const timestamp = Date.now();
|
|
54
|
-
const realKey = prefix + key;
|
|
55
|
-
const storage = TYPES[type] || CACHES;
|
|
56
|
-
const info = {
|
|
57
|
-
value,
|
|
58
|
-
timestamp,
|
|
59
|
-
expired
|
|
60
|
-
};
|
|
61
|
-
if (storage === CACHES) {
|
|
62
|
-
storage[realKey] = info;
|
|
63
|
-
} else {
|
|
64
|
-
storage.setItem(realKey, JSON.stringify(info));
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* 获取缓存
|
|
70
|
-
* @param {string} key 缓存key
|
|
71
|
-
* @param {object} [opts] 选项
|
|
72
|
-
* @param {Object} [opts.type=cache] 存储方式 local、 session、cache
|
|
73
|
-
* @param {number} [opts.expired=0] 过期时间,单位毫秒
|
|
74
|
-
* @param {string} [opts.prefix=__NewPearl__] key 前缀
|
|
75
|
-
* @returns {String|Object|Array}
|
|
76
|
-
*/
|
|
77
|
-
export function get(key: string, opts = {}) {
|
|
78
|
-
if (!key) return;
|
|
79
|
-
const { type, prefix } = { ...defaultOptions, ...opts };
|
|
80
|
-
const realKey = prefix + key;
|
|
81
|
-
const storage = TYPES[type] || CACHES;
|
|
82
|
-
let info;
|
|
83
|
-
if (storage === CACHES) {
|
|
84
|
-
info = storage[realKey];
|
|
85
|
-
} else {
|
|
86
|
-
const content = storage.getItem(realKey);
|
|
87
|
-
if (content) {
|
|
88
|
-
info = JSON.parse(content);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
// 不存在缓存
|
|
92
|
-
if (!info) return null;
|
|
93
|
-
const { value, timestamp, expired } = info;
|
|
94
|
-
// 缓存是否过期
|
|
95
|
-
const isExpired = expired > 0 && timestamp + expired < Date.now();
|
|
96
|
-
// 过期清空缓存,返回null
|
|
97
|
-
if (isExpired) {
|
|
98
|
-
remove(key, opts);
|
|
99
|
-
return null;
|
|
100
|
-
}
|
|
101
|
-
return value;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* 删除缓存
|
|
106
|
-
* @param {string} key 缓存key
|
|
107
|
-
* @param {object} [opts] 选项
|
|
108
|
-
* @param {Object} [opts.type=cache] 存储方式 local、 session、cache
|
|
109
|
-
* @param {string} [opts.prefix=__NewPearl__] key 前缀
|
|
110
|
-
*/
|
|
111
|
-
export function remove(key: string, opts = {}) {
|
|
112
|
-
if (!key) return;
|
|
113
|
-
const { type, prefix } = { ...defaultOptions, ...opts };
|
|
114
|
-
const storage = TYPES[type] || CACHES;
|
|
115
|
-
const realKey = prefix + key;
|
|
116
|
-
if (storage === CACHES) {
|
|
117
|
-
delete storage[realKey];
|
|
118
|
-
} else {
|
|
119
|
-
storage.removeItem(realKey);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* 删除全部缓存
|
|
125
|
-
* @param {object} [opts] 选项
|
|
126
|
-
* @param {Object} [opts.type=cache] 存储方式 local、 session、cache
|
|
127
|
-
*/
|
|
128
|
-
export function clear(opts = {}) {
|
|
129
|
-
const { type } = { ...defaultOptions, ...opts };
|
|
130
|
-
const storage = TYPES[type] || CACHES;
|
|
131
|
-
if (storage === CACHES) {
|
|
132
|
-
CACHES = {};
|
|
133
|
-
} else {
|
|
134
|
-
storage.clear();
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
export default {
|
|
139
|
-
save,
|
|
140
|
-
get,
|
|
141
|
-
remove,
|
|
142
|
-
clear
|
|
143
|
-
};
|
package/src/url.ts
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
export const UrlRegex = /^(http|https):\/\/[\w.:\-@]*/;
|
|
2
|
-
|
|
3
|
-
export function isUrl(txt: string) {
|
|
4
|
-
return UrlRegex.test(txt);
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* 获取当前页面的 host
|
|
9
|
-
* @param {boolean} includePath 带上 pathname
|
|
10
|
-
* @return {string}
|
|
11
|
-
*/
|
|
12
|
-
export function getCurrentHost(includePath: boolean) {
|
|
13
|
-
const { protocol, host, pathname } = location;
|
|
14
|
-
return `${protocol}//${host}${includePath ? pathname : ''}`;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* 获取指定url的host
|
|
19
|
-
* @param {string} url
|
|
20
|
-
* @return {string} host
|
|
21
|
-
*/
|
|
22
|
-
export function getHost(url: string = '') {
|
|
23
|
-
const matches = url.match(UrlRegex);
|
|
24
|
-
if (matches) {
|
|
25
|
-
return matches[0];
|
|
26
|
-
}
|
|
27
|
-
return '';
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* 键值对转换成查询字符串
|
|
32
|
-
* @param {object} query 键值对,对象
|
|
33
|
-
* @returns {string} 查询参数字符串
|
|
34
|
-
*/
|
|
35
|
-
export function stringify(query: Record<string, any>) {
|
|
36
|
-
const array = [];
|
|
37
|
-
for (const key in query) {
|
|
38
|
-
if (Object.prototype.hasOwnProperty.call(query, key)) {
|
|
39
|
-
array.push([key, encodeURIComponent(query[key])].join('='));
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return array.join('&');
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* 参数字符串转换成对象形式,如:a=1&b=2 转换成 {a:1, b:2}
|
|
47
|
-
* @param {String} str 需要转换的字符串
|
|
48
|
-
* @param {String} [sep=&] 连接符,可选,默认 &
|
|
49
|
-
* @param {String} [eq==] 键值间隔符,可选,默认 =
|
|
50
|
-
* @returns {Object}
|
|
51
|
-
*/
|
|
52
|
-
export function parse(str: string, sep?: string, eq?: string) {
|
|
53
|
-
const obj: Record<string, any> = {};
|
|
54
|
-
str = (str || location.search).replace(/^[^]*\?/, '');
|
|
55
|
-
sep = sep || '&';
|
|
56
|
-
eq = eq || '=';
|
|
57
|
-
let arr;
|
|
58
|
-
const reg = new RegExp(
|
|
59
|
-
'(?:^|\\' +
|
|
60
|
-
sep +
|
|
61
|
-
')([^\\' +
|
|
62
|
-
eq +
|
|
63
|
-
'\\' +
|
|
64
|
-
sep +
|
|
65
|
-
']+)(?:\\' +
|
|
66
|
-
eq +
|
|
67
|
-
'([^\\' +
|
|
68
|
-
sep +
|
|
69
|
-
']*))?',
|
|
70
|
-
'g'
|
|
71
|
-
);
|
|
72
|
-
while ((arr = reg.exec(str)) !== null) {
|
|
73
|
-
if (arr[1] !== str) {
|
|
74
|
-
obj[decodeURIComponent(arr[1])] = decodeURIComponent(arr[2] || '');
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return obj;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* 在url追加参数
|
|
82
|
-
* @param {string} url 原本的url
|
|
83
|
-
* @param {string|object} query 需要追加的参数,Object|String
|
|
84
|
-
* @returns {string} 追加参数后的url
|
|
85
|
-
*/
|
|
86
|
-
export function append(url: string, query: string | Record<string, any>) {
|
|
87
|
-
query = typeof query === 'string' ? parse(query) : query;
|
|
88
|
-
const path = url.split('?')[0];
|
|
89
|
-
const originalQuery = parse(url);
|
|
90
|
-
const joinQuery = Object.assign({}, originalQuery, query);
|
|
91
|
-
const queryStr = stringify(joinQuery);
|
|
92
|
-
return queryStr ? [path, queryStr].join('?') : url;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export default {
|
|
96
|
-
isUrl,
|
|
97
|
-
getCurrentHost,
|
|
98
|
-
getHost,
|
|
99
|
-
stringify,
|
|
100
|
-
parse,
|
|
101
|
-
append
|
|
102
|
-
};
|