@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/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
- };