utils-uniapp 1.1.8 → 1.1.10

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.
@@ -5,6 +5,7 @@
5
5
  */
6
6
  type StorageMode = 'session' | 'local';
7
7
 
8
+
8
9
  /**
9
10
  * 底层存储适配器接口,抹平uni‑storage与sessionStorage API差异
10
11
  */
@@ -41,6 +42,7 @@ interface IStorageAdapter {
41
42
  clear(): void;
42
43
  }
43
44
 
45
+
44
46
  /**
45
47
  * StorageCache实例构造配置项
46
48
  */
@@ -51,11 +53,18 @@ interface StorageCacheOptions {
51
53
  version?: string | number;
52
54
  /** 实例隔离前缀,内部自动追加下划线分隔,默认空字符串 */
53
55
  prefix?: string;
56
+ /**
57
+ * 实例默认过期秒数;set不传expire时使用该值
58
+ * <=0代表永不过期,默认0
59
+ */
60
+ defaultExpire?: number;
54
61
  }
55
62
 
63
+
56
64
  /**
57
65
  * 多端缓存工具类
58
66
  * 特性:过期控制、版本校验、实例key隔离前缀;适配uni‑app、H5‑sessionStorage
67
+ * 优先级说明:set传入expire > 实例defaultExpire;仅不传参(undefined)才使用实例默认配置
59
68
  * 注意:
60
69
  * 1. 业务传入key为业务key,内部自动拼接实例prefix
61
70
  * 2. clear仅删除本实例前缀key,无prefix时不执行删除
@@ -72,7 +81,7 @@ export declare class StorageCache {
72
81
  * 设置缓存,支持过期
73
82
  * @param key 业务缓存key
74
83
  * @param data 缓存数据
75
- * @param expire 过期时间,单位秒;<=0永不过期,默认3600
84
+ * @param expire 过期时间,单位秒;不传使用实例defaultExpire;<=0永不过期
76
85
  * @returns true成功,false异常失败
77
86
  */
78
87
  set(key: string, data: any, expire?: number): boolean;
@@ -113,16 +122,19 @@ export declare class StorageCache {
113
122
  removeByPrefix(prefix: string): boolean;
114
123
  }
115
124
 
125
+
116
126
  /**
117
- * 全局默认local缓存实例,无实例隔离前缀,直接操作原始key
127
+ * 全局默认local缓存实例,无实例隔离前缀,直接操作原始key,默认永不过期
118
128
  * @type {StorageCache}
119
129
  */
120
130
  export declare const localCache: StorageCache;
121
131
 
132
+
122
133
  /**
123
- * 全局默认session缓存实例,无实例隔离前缀;小程序/App自动降级为local
134
+ * 全局默认session缓存实例,无实例隔离前缀;小程序/App自动降级为local,默认永不过期
124
135
  * @type {StorageCache}
125
136
  */
126
137
  export declare const sessionCache: StorageCache;
127
138
 
139
+
128
140
  export default StorageCache;
@@ -1 +1 @@
1
- "use strict";var w=(i,t,r)=>{if(!t.has(i))throw TypeError("Cannot "+r)};var n=(i,t,r)=>(w(i,t,"read from private field"),r?r.call(i):t.get(i)),g=(i,t,r)=>{if(t.has(i))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(i):t.set(i,r)},y=(i,t,r,s)=>(w(i,t,"write to private field"),s?s.call(i,r):t.set(i,r),r);var l=(i,t,r)=>(w(i,t,"access private method"),r);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});var o,h,c,d,p,u,m;const v=class v{constructor(){g(this,u);g(this,o,void 0);g(this,h,void 0);g(this,c,void 0);var a;let t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};const{mode:r="local",version:s="v1",prefix:e=""}=t;y(this,o,l(a=v,d,p).call(a,r)),y(this,h,String(s)),y(this,c,e?e+"_":""),Object.seal(this)}set(t,r){let s=arguments.length>2&&arguments[2]!==void 0?arguments[2]:3600;try{let e=Number(s);Number.isFinite(e)||(e=0);const a=e>0?Math.round(e)*1e3:e,S=l(this,u,m).call(this,t);return n(this,o).set(S,{time:Date.now(),expire:a,version:n(this,h),data:r}),!0}catch(e){return console.error(`设置缓存[${t}]失败:`,e),!1}}get(t){let r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:null;try{const s=l(this,u,m).call(this,t),e=n(this,o).get(s);return!e||typeof e!="object"||Array.isArray(e)||!("time"in e)||!("expire"in e)||!("version"in e)?(e&&n(this,o).remove(s),r):e.version!==n(this,h)?(n(this,o).remove(s),r):e.expire>0&&Date.now()-e.time>=e.expire?(n(this,o).remove(s),r):e.data}catch(s){return console.error(`获取缓存[${t}]失败:`,s),r}}renew(t){try{const r=l(this,u,m).call(this,t),s=n(this,o).get(r);if(!s||typeof s!="object"||Array.isArray(s)||!("time"in s)||!("expire"in s)||!("version"in s))return!1;if(s.version!==n(this,h))return n(this,o).remove(r),!1;if(s.expire>0){if(Date.now()-s.time>=s.expire)return n(this,o).remove(r),!1;s.time=Date.now(),n(this,o).set(r,s)}return!0}catch(r){return console.error(`续期缓存[${t}]失败:`,r),!1}}remove(t){try{const r=l(this,u,m).call(this,t);return n(this,o).remove(r),!0}catch(r){return console.error(`删除缓存[${t}]失败:`,r),!1}}clear(){try{return n(this,o).keys().forEach(r=>{n(this,c)&&r.startsWith(n(this,c))&&n(this,o).remove(r)}),!0}catch(t){return console.error("清空实例缓存失败:",t),!1}}removeByPrefix(t){if(!t)return!1;if(!n(this,c))return console.warn("StorageCache: 当前实例无隔离前缀,禁止调用removeByPrefix,避免误删"),!1;try{const r=l(this,u,m).call(this,t);return n(this,o).keys().forEach(e=>{e.startsWith(r)&&n(this,o).remove(e)}),!0}catch(r){return console.error(`按前缀删除缓存[${t}]失败:`,r),!1}}};o=new WeakMap,h=new WeakMap,c=new WeakMap,d=new WeakSet,p=function(){let t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:"local";const r=typeof window<"u"&&window.sessionStorage,s={set(e,a){uni.setStorageSync(e,a)},get(e){return uni.getStorageSync(e)},remove(e){uni.removeStorageSync(e)},keys(){try{return uni.getStorageInfoSync().keys||[]}catch(e){return console.error("uni getStorageInfoSync error",e),[]}},clear(){uni.clearStorageSync()}};return r&&t==="session"?{set(e,a){try{window.sessionStorage.setItem(e,JSON.stringify(a))}catch(S){console.error("sessionStorage set error",S)}},get(e){const a=window.sessionStorage.getItem(e);if(a===null)return null;try{return JSON.parse(a)}catch{return window.sessionStorage.removeItem(e),null}},remove(e){window.sessionStorage.removeItem(e)},keys(){return Object.keys(window.sessionStorage)},clear(){window.sessionStorage.clear()}}:s},u=new WeakSet,m=function(t){return n(this,c)+t},g(v,d);let f=v;const x=new f,I=new f({mode:"session"});exports.StorageCache=f;exports.default=f;exports.localCache=x;exports.sessionCache=I;
1
+ "use strict";var p=(i,r,e)=>{if(!r.has(i))throw TypeError("Cannot "+e)};var n=(i,r,e)=>(p(i,r,"read from private field"),e?e.call(i):r.get(i)),l=(i,r,e)=>{if(r.has(i))throw TypeError("Cannot add the same private member more than once");r instanceof WeakSet?r.add(i):r.set(i,e)},y=(i,r,e,s)=>(p(i,r,"write to private field"),s?s.call(i,e):r.set(i,e),e);var h=(i,r,e)=>(p(i,r,"access private method"),e);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});var o,f,c,v,S,x,u,m;const w=class w{constructor(){l(this,u);l(this,o,void 0);l(this,f,void 0);l(this,c,void 0);l(this,v,void 0);var g;let r=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};const{mode:e="local",version:s="v1",prefix:t="",defaultExpire:a=0}=r;y(this,o,h(g=w,S,x).call(g,e)),y(this,f,String(s)),y(this,c,t?t+"_":""),y(this,v,Number(a)),Object.seal(this)}set(r,e,s){try{const t=s!==void 0?s:n(this,v);let a=Number(t);Number.isFinite(a)||(a=0);const g=a>0?Math.round(a)*1e3:a,I=h(this,u,m).call(this,r);return n(this,o).set(I,{time:Date.now(),expire:g,version:n(this,f),data:e}),!0}catch(t){return console.error(`设置缓存[${r}]失败:`,t),!1}}get(r){let e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:null;try{const s=h(this,u,m).call(this,r),t=n(this,o).get(s);return!t||typeof t!="object"||Array.isArray(t)||!("time"in t)||!("expire"in t)||!("version"in t)?(t&&n(this,o).remove(s),e):t.version!==n(this,f)?(n(this,o).remove(s),e):t.expire>0&&Date.now()-t.time>=t.expire?(n(this,o).remove(s),e):t.data}catch(s){return console.error(`获取缓存[${r}]失败:`,s),e}}renew(r){try{const e=h(this,u,m).call(this,r),s=n(this,o).get(e);if(!s||typeof s!="object"||Array.isArray(s)||!("time"in s)||!("expire"in s)||!("version"in s))return!1;if(s.version!==n(this,f))return n(this,o).remove(e),!1;if(s.expire>0){if(Date.now()-s.time>=s.expire)return n(this,o).remove(e),!1;s.time=Date.now(),n(this,o).set(e,s)}return!0}catch(e){return console.error(`续期缓存[${r}]失败:`,e),!1}}remove(r){try{const e=h(this,u,m).call(this,r);return n(this,o).remove(e),!0}catch(e){return console.error(`删除缓存[${r}]失败:`,e),!1}}clear(){try{return n(this,o).keys().forEach(e=>{n(this,c)&&e.startsWith(n(this,c))&&n(this,o).remove(e)}),!0}catch(r){return console.error("清空实例缓存失败:",r),!1}}removeByPrefix(r){if(!r)return!1;if(!n(this,c))return console.warn("StorageCache: 当前实例无隔离前缀,禁止调用removeByPrefix,避免误删"),!1;try{const e=h(this,u,m).call(this,r);return n(this,o).keys().forEach(t=>{t.startsWith(e)&&n(this,o).remove(t)}),!0}catch(e){return console.error(`按前缀删除缓存[${r}]失败:`,e),!1}}};o=new WeakMap,f=new WeakMap,c=new WeakMap,v=new WeakMap,S=new WeakSet,x=function(){let r=arguments.length>0&&arguments[0]!==void 0?arguments[0]:"local";const e=typeof window<"u"&&window.sessionStorage,s={set(t,a){uni.setStorageSync(t,a)},get(t){return uni.getStorageSync(t)},remove(t){uni.removeStorageSync(t)},keys(){try{return uni.getStorageInfoSync().keys||[]}catch(t){return console.error("uni getStorageInfoSync error",t),[]}},clear(){uni.clearStorageSync()}};return e&&r==="session"?{set(t,a){try{window.sessionStorage.setItem(t,JSON.stringify(a))}catch(g){console.error("sessionStorage set error",g)}},get(t){const a=window.sessionStorage.getItem(t);if(a===null)return null;try{return JSON.parse(a)}catch{return window.sessionStorage.removeItem(t),null}},remove(t){window.sessionStorage.removeItem(t)},keys(){return Object.keys(window.sessionStorage)},clear(){window.sessionStorage.clear()}}:s},u=new WeakSet,m=function(r){return n(this,c)+r},l(w,S);let d=w;const b=new d,K=new d({mode:"session"});exports.StorageCache=d;exports.default=d;exports.localCache=b;exports.sessionCache=K;
@@ -1,19 +1,28 @@
1
1
  /**
2
- * 依赖说明:需要安装 @types/uni‑app,提供 UniApp.* 命名空间类型
3
2
  * 请求Content‑Type常量
4
3
  */
5
4
  export declare const CONTENT_TYPES: Readonly<{
6
- /** json格式 application/json;charset=UTF-8 */
5
+ /**
6
+ * json格式 application/json;charset=UTF-8
7
+ */
7
8
  JSON: string;
8
- /** 纯文本 text/plain;charset=UTF-8 */
9
+ /**
10
+ * 纯文本 text/plain;charset=UTF-8
11
+ */
9
12
  TEXT: string;
10
- /** url编码表单 application/x-www-form-urlencoded;charset=UTF-8 */
13
+ /**
14
+ * url编码表单 application/x-www-form-urlencoded;charset=UTF-8
15
+ */
11
16
  FORM_URLENCODED: string;
12
- /** 文件上传表单 multipart/form‑data */
17
+ /**
18
+ * 文件上传表单 multipart/form‑data
19
+ */
13
20
  FORM_DATA: string;
14
21
  }>;
15
22
 
16
- /** uni请求任务对象,依赖uni‑app全局UniApp命名空间 */
23
+ /**
24
+ * uni请求任务对象,依赖uni‑app全局UniApp命名空间
25
+ */
17
26
  type UniTask = UniApp.RequestTask | UniApp.UploadTask | UniApp.DownloadTask;
18
27
 
19
28
  type UniRequestResult = UniApp.RequestSuccessCallbackResult;
@@ -21,46 +30,77 @@ type UniUploadResult = UniApp.UploadFileSuccessCallbackResult;
21
30
  type UniDownloadResult = UniApp.DownloadFileSuccessCallbackResult;
22
31
  type UniAnyResult = UniRequestResult | UniUploadResult | UniDownloadResult;
23
32
 
24
- export type RequestFailPayload = {
33
+ /**
34
+ * 请求失败载荷【内部类型,不对外导出】
35
+ */
36
+ type RequestFailPayload = {
25
37
  type: 'fail';
26
38
  res: UniApp.GeneralCallbackResult;
27
39
  };
28
40
 
41
+ /**
42
+ * 缓存适配器抽象接口,对接外部缓存实现
43
+ */
29
44
  export interface CacheAdapter {
45
+ /**
46
+ * 获取缓存
47
+ * @param key 缓存key
48
+ * @returns 缓存值,不存在返回undefined
49
+ */
30
50
  get(key: string): unknown;
51
+
52
+ /**
53
+ * 设置缓存
54
+ * @param key 缓存key
55
+ * @param value 缓存存储内容
56
+ * @param expire 过期秒数;语义由适配器实现,约定 <=0 代表永不过期;request库仅透传数值,不做过期逻辑
57
+ */
31
58
  set(key: string, value: unknown, expire: number): void;
32
59
  }
33
60
 
34
61
  /**
35
- * 外部传入缓存配置入参(仅调用方使用)
62
+ * 外部传入缓存配置入参(仅调用方使用,业务传入)
63
+ * @description 开启请求缓存 isCache=true 时,必须传入对应 mode 的适配器 localAdapter / sessionAdapter
36
64
  */
37
65
  export interface CacheConfigInput {
66
+ /**
67
+ * 自定义缓存业务key;不填默认由url生成,**不包含请求参数**,同URL不同参数务必手动指定key
68
+ */
38
69
  key?: string;
70
+ /**
71
+ * 缓存key前缀,用于业务隔离,会拼接在业务key前面
72
+ */
39
73
  prefix?: string;
74
+ /**
75
+ * 缓存存储模式
76
+ * - local:持久存储
77
+ * - session:会话存储(H5会话销毁;小程序降级持久)
78
+ */
40
79
  mode?: 'local' | 'session';
80
+ /**
81
+ * 缓存过期时间,单位秒;语义由外部CacheAdapter实现,约定 <=0代表永不过期;库默认兜底1小时(3600s)
82
+ */
41
83
  expire?: number;
84
+ /**
85
+ * local模式对应的缓存适配器实例;mode=local且开启缓存时必填
86
+ */
42
87
  localAdapter?: CacheAdapter | null;
88
+ /**
89
+ * session模式对应的缓存适配器实例;mode=session且开启缓存时必填
90
+ */
43
91
  sessionAdapter?: CacheAdapter | null;
44
92
  }
45
93
 
46
94
  /**
47
- * normalizeOpts 之后内部运行时缓存配置对象
95
+ * normalizeOpts 之后内部运行时缓存配置对象【内部类型,不对外导出】
96
+ * @description adapter 字段由内部派生生成,外部禁止传入、禁止读取使用
48
97
  */
49
- export interface CacheConfig {
50
- /** 缓存key;默认仅由url生成,**不包含请求参数**,同URL不同参数需手动指定key */
98
+ interface CacheConfig {
51
99
  key: string;
52
- /** 缓存key前缀 */
53
100
  prefix: string;
54
- /** 缓存模式 */
55
101
  mode: 'local' | 'session';
56
- /** 过期时间,单位秒 */
57
102
  expire: number;
58
- /**
59
- * ⚠️ adapter 为内部运行时派生字段,**外部禁止传入、禁止访问**;
60
- * 开启 isCache:true,必须传入 CacheConfigInput 对应模式的适配器,否则运行时抛出异常
61
- */
62
- adapter: CacheAdapter | null;
63
- [key: string]: unknown;
103
+ readonly adapter: CacheAdapter | null;
64
104
  }
65
105
 
66
106
  /**
@@ -69,7 +109,7 @@ export interface CacheConfig {
69
109
  * @param opts normalizeOpts合并后的完整配置
70
110
  * @returns 处理后的请求参数
71
111
  */
72
- export type ReqInterceptor = (invokeArgs: Record<string, unknown>, opts: RequestOptions) => Promise<Record<string, unknown>> | Record<string, unknown>;
112
+ type ReqInterceptor = (invokeArgs: Record<string, any>, opts: RequestOptions) => Promise<Record<string, any>> | Record<string, any>;
73
113
 
74
114
  /**
75
115
  * 响应拦截器【标准化后】
@@ -78,15 +118,15 @@ export type ReqInterceptor = (invokeArgs: Record<string, unknown>, opts: Request
78
118
  * @param reloadFn 重发当前请求函数,可为null
79
119
  * @returns 处理后业务数据
80
120
  */
81
- export type ResInterceptor = (res: unknown, opts: RequestOptions, reloadFn: (() => Promise<unknown>) | null) => Promise<unknown> | unknown;
121
+ type ResInterceptor = (res: any, opts: RequestOptions, reloadFn: (() => Promise<any>) | null) => Promise<any> | any;
82
122
 
83
123
  /**
84
124
  * 错误拦截器【标准化后】
85
- * @param err 捕获到的异常对象
125
+ * @param err 捕获到的异常对象,可能为接口回调失败载荷 RequestFailPayload 或 JS运行异常 Error
86
126
  * @param opts normalizeOpts合并后的完整配置
87
127
  * @returns 返回非undefined代表错误已接管;返回undefined会继续抛出异常
88
128
  */
89
- export type ErrInterceptor = (err: RequestFailPayload | Error, opts: RequestOptions) => Promise<unknown> | unknown;
129
+ type ErrInterceptor = (err: RequestFailPayload | Error, opts: RequestOptions) => Promise<any> | any;
90
130
 
91
131
  /**
92
132
  * 用户传入拦截器:支持单个函数 / 函数数组,交由 normalizeInterceptor + composeAsync合并
@@ -98,27 +138,47 @@ export type UserErrInterceptor = ErrInterceptor | ErrInterceptor[];
98
138
  /**
99
139
  * normalizeOpts标准化之后的请求额外配置对象【内部运行时】
100
140
  */
101
- export interface RequestOptions {
102
- /** 是否使用表单编码 */
141
+ interface RequestOptions {
142
+ /**
143
+ * 是否使用url‑encoded表单编码
144
+ */
103
145
  qs: boolean;
104
- /** 是否展示错误提示 */
146
+ /**
147
+ * 是否展示错误toast提示
148
+ */
105
149
  showError: boolean;
106
- /** 是否开启缓存;开启时cacheConfig必须提供对应mode的适配器 */
150
+ /**
151
+ * 是否开启请求缓存;开启时cacheConfig必须提供对应mode的适配器
152
+ */
107
153
  isCache: boolean;
108
- /** 缓存配置;adapter为内部运行时派生字段,外部请勿传入、请勿访问;开启isCache:true,必须传入对应模式的适配器,否则运行时抛出异常 */
154
+ /**
155
+ * 缓存配置;adapter为内部运行时派生字段,外部请勿传入、请勿访问;开启isCache:true,必须传入对应模式的适配器,否则运行时抛出异常
156
+ */
109
157
  cacheConfig: CacheConfig;
110
- /** loading提示文字 */
158
+ /**
159
+ * loading提示文字
160
+ */
111
161
  loadingText: string;
112
- /** 是否开启loading */
162
+ /**
163
+ * 是否开启全局loading弹窗
164
+ */
113
165
  loading: boolean;
114
- /** 请求拦截器 */
166
+ /**
167
+ * 请求前置拦截器(已合并为单个函数)
168
+ */
115
169
  reqInterceptor: ReqInterceptor;
116
- /** 响应拦截器 */
170
+ /**
171
+ * 响应拦截器(已合并为单个函数)
172
+ */
117
173
  resInterceptor: ResInterceptor;
118
- /** 错误拦截器 */
174
+ /**
175
+ * 错误拦截器(已合并为单个函数)
176
+ */
119
177
  errInterceptor: ErrInterceptor;
120
- /** 允许扩展自定义字段 */
121
- [key: string]: unknown;
178
+ /**
179
+ * 允许扩展自定义字段
180
+ */
181
+ [key: string]: any;
122
182
  }
123
183
 
124
184
  /**
@@ -127,33 +187,71 @@ export interface RequestOptions {
127
187
  * @description isCache 设置为 true 时,cacheConfig 需要传入对应 mode 的适配器 localAdapter / sessionAdapter,否则运行时抛出异常
128
188
  */
129
189
  export interface UserRequestOpts {
130
- /** 是否使用表单编码 */
190
+ /**
191
+ * 是否使用url‑encoded表单编码
192
+ */
131
193
  qs?: boolean;
132
- /** 是否展示错误提示 */
194
+ /**
195
+ * 是否展示错误toast提示
196
+ */
133
197
  showError?: boolean;
134
- /** 是否开启缓存;开启时cacheConfig必须提供对应mode的适配器(localAdapter/sessionAdapter) */
198
+ /**
199
+ * 是否开启请求缓存;开启时cacheConfig必须提供对应mode的适配器(localAdapter/sessionAdapter)
200
+ */
135
201
  isCache?: boolean;
136
- /** 缓存配置,用户传入部分字段即可;isCache=true必须传入对应mode适配器 */
202
+ /**
203
+ * 缓存配置,用户传入部分字段即可;isCache=true必须传入对应mode适配器
204
+ */
137
205
  cacheConfig?: Partial<CacheConfigInput>;
138
- /** loading提示文字 */
206
+ /**
207
+ * loading提示文字
208
+ */
139
209
  loadingText?: string;
140
- /** 是否开启loading */
210
+ /**
211
+ * 是否开启全局loading弹窗
212
+ */
141
213
  loading?: boolean;
142
- /** 请求前置拦截器,支持单个函数或函数数组 */
214
+ /**
215
+ * 请求前置拦截器,支持单个函数或函数数组
216
+ */
143
217
  reqInterceptor?: UserReqInterceptor;
144
- /** 响应拦截器,支持单个函数或函数数组 */
218
+ /**
219
+ * 响应拦截器,支持单个函数或函数数组
220
+ */
145
221
  resInterceptor?: UserResInterceptor;
146
- /** 错误拦截器,支持单个函数或函数数组 */
222
+ /**
223
+ * 错误拦截器,支持单个函数或函数数组
224
+ */
147
225
  errInterceptor?: UserErrInterceptor;
148
- /** 允许扩展自定义字段 */
149
- [key: string]: unknown;
226
+ /**
227
+ * 允许扩展自定义字段
228
+ */
229
+ [key: string]: any;
150
230
  }
151
231
 
232
+ /**
233
+ * 请求config:uni.request配置,排除内部强制覆盖字段,允许业务扩展
234
+ */
235
+ export type HttpRequestConfig = Omit<UniApp.RequestOptions, 'url'|'header'|'method'|'data'|'cancelToken'> & {[key:string]:any};
236
+
237
+ /**
238
+ * 上传config:uni.uploadFile配置,排除内部强制覆盖字段
239
+ */
240
+ export type UploadConfig = Omit<UniApp.UploadFileOptions, 'url'|'header'|'filePath'|'name'|'formData'|'cancelToken'> & {[key:string]:any};
241
+
242
+ /**
243
+ * 下载config:uni.downloadFile配置,排除内部强制覆盖字段
244
+ */
245
+ export type DownloadConfig = Omit<UniApp.DownloadFileOptions, 'url'|'header'|'cancelToken'> & {[key:string]:any};
246
+
152
247
  /**
153
248
  * 请求取消控制器(仿axios CancelToken)
154
- * 注意:当前实现token由请求内部source生成,**不支持外部传入自定义cancelToken**
249
+ * @description 注意:当前实现token由请求内部source生成,**不支持外部传入自定义cancelToken**
155
250
  */
156
251
  export declare const CancelToken: {
252
+ /**
253
+ * 保存token与uni任务映射
254
+ */
157
255
  caches: Record<string, UniTask>;
158
256
 
159
257
  /**
@@ -187,51 +285,51 @@ export declare const CancelToken: {
187
285
  source(): { token: string; cancel: () => void };
188
286
  };
189
287
 
190
-
191
288
  /**
192
289
  * 包装uni异步API为Promise
193
290
  * @param type uni接口名称 request | uploadFile | downloadFile
194
291
  * @param opts 请求参数,可以传入 cancelToken 用于请求取消
195
- * @description 泛型仅为类型断言,运行时不会做类型转换
292
+ * @description TS 无法表达 Promise reject 类型;本泛型T仅代表resolve成功返回类型;catch捕获为 RequestFailPayload | Error
196
293
  * @returns uni接口回调结果Promise
197
294
  */
198
- export declare function promisifyRequest<T = UniAnyResult>(type: 'request' | 'uploadFile' | 'downloadFile', opts: Record<string, unknown>): Promise<T>;
295
+ export declare function promisifyRequest<T = UniAnyResult>(type: 'request' | 'uploadFile' | 'downloadFile', opts: Record<string, any>): Promise<T>;
199
296
 
200
297
  /**
201
- * 底层展示loading
202
- * @param {string} title loading提示文字
298
+ * 底层直接展示loading,不做计数
299
+ * @param title loading提示文字
203
300
  */
204
301
  export declare function showLoading(title: string): void;
205
302
 
206
303
  /**
207
- * 底层隐藏loading
304
+ * 底层直接隐藏loading,不做计数
208
305
  */
209
306
  export declare function hideLoading(): void;
210
307
 
211
308
  /**
212
- * 开启loading计数,计数>0时展示loading
309
+ * 开启loading计数,计数>0时展示loading;多次调用会叠加计数
213
310
  * @param [title='加载中...'] loading提示文案
214
311
  */
215
312
  export declare function startLoading(title?: string): void;
216
313
 
217
314
  /**
218
- * 关闭loading计数,计数归0则隐藏loading
315
+ * 关闭loading计数,计数归0则真正隐藏loading弹窗
219
316
  */
220
317
  export declare function endLoading(): void;
221
318
 
222
319
  /**
223
- * createRequest返回的请求实例对象
320
+ * createRequest返回的请求实例对象,支持泛型T指定响应类型
224
321
  */
225
322
  export interface RequestInstance {
226
323
  /**
324
+ * 基础请求调用
227
325
  * @param url 请求地址
228
- * @param method get/post等http方法
326
+ * @param method http方法 get/post/put/delete等
229
327
  * @param params 请求参数
230
- * @param [config] 当前请求配置,覆盖defaultConfig
231
- * @param [options] 当前请求扩展选项,覆盖defaultOpts
232
- * @returns {Promise<unknown>}
328
+ * @param [config] 当前请求配置,覆盖实例defaultConfig(baseURL、headers等)
329
+ * @param [options] 当前请求扩展选项,覆盖实例defaultOpts(loading、缓存、拦截器)
330
+ * @returns Promise业务响应数据
233
331
  */
234
- (url: string, method: string, params?: unknown, config?: Record<string, unknown>, options?: UserRequestOpts): Promise<unknown>;
332
+ <T = any>(url: string, method: string, params: any, config?: HttpRequestConfig, options?: UserRequestOpts): Promise<T>;
235
333
 
236
334
  /**
237
335
  * get快捷方法
@@ -239,8 +337,9 @@ export interface RequestInstance {
239
337
  * @param params 请求参数
240
338
  * @param [config] 当前请求配置
241
339
  * @param [options] 当前请求扩展选项
340
+ * @returns Promise业务响应数据
242
341
  */
243
- get(url: string, params?: unknown, config?: Record<string, unknown>, options?: UserRequestOpts): Promise<unknown>;
342
+ get<T = any>(url: string, params: any, config?: HttpRequestConfig, options?: UserRequestOpts): Promise<T>;
244
343
 
245
344
  /**
246
345
  * post快捷方法
@@ -248,53 +347,60 @@ export interface RequestInstance {
248
347
  * @param params 请求参数
249
348
  * @param [config] 当前请求配置
250
349
  * @param [options] 当前请求扩展选项
350
+ * @returns Promise业务响应数据
251
351
  */
252
- post(url: string, params?: unknown, config?: Record<string, unknown>, options?: UserRequestOpts): Promise<unknown>;
352
+ post<T = any>(url: string, params: any, config?: HttpRequestConfig, options?: UserRequestOpts): Promise<T>;
253
353
  }
254
354
 
255
355
  /**
256
356
  * 创建常规http请求实例(get/post)
257
357
  * @param defaultConfig 实例默认配置(baseURL、headers等)
258
358
  * @param defaultOpts 实例默认扩展选项(loading、缓存、拦截器)
259
- * @returns {RequestInstance}
359
+ * @returns RequestInstance 请求实例
260
360
  */
261
- export declare function createRequest(defaultConfig: Record<string, unknown>, defaultOpts?: UserRequestOpts): RequestInstance;
361
+ export declare function createRequest(defaultConfig: HttpRequestConfig, defaultOpts?: UserRequestOpts): RequestInstance;
262
362
 
263
363
  /**
264
364
  * 创建上传文件实例
265
365
  * @param defaultConfig 实例默认配置(baseURL、headers等)
266
366
  * @param defaultOpts 实例默认扩展选项
267
- * @returns 上传函数
367
+ * @returns 上传调用函数
268
368
  */
269
369
  export declare function createUploadFile(
270
- defaultConfig: Record<string, unknown>,
370
+ defaultConfig: UploadConfig,
271
371
  defaultOpts?: UserRequestOpts
272
- ): (url: string, params: { filePath: string; keyName?: string; [key: string]: unknown }, config?: Record<string, unknown>, options?: UserRequestOpts) => Promise<unknown>;
372
+ ): <T = any>(
373
+ url: string,
374
+ params: { filePath: string; keyName?: string; [key: string]: any },
375
+ config?: UploadConfig,
376
+ options?: UserRequestOpts
377
+ ) => Promise<T>;
273
378
 
274
379
  /**
275
380
  * 创建下载文件实例
276
381
  * @param defaultConfig 实例默认配置(baseURL、headers等)
277
382
  * @param defaultOpts 实例默认扩展选项
278
- * @returns 下载函数
383
+ * @returns 下载调用函数
279
384
  */
280
385
  export declare function createDownloadFile(
281
- defaultConfig: Record<string, unknown>,
386
+ defaultConfig: DownloadConfig,
282
387
  defaultOpts?: UserRequestOpts
283
- ): (url: string, params?: Record<string, unknown>, config?: Record<string, unknown>, options?: UserRequestOpts) => Promise<unknown>;
388
+ ): <T = any>(
389
+ url: string,
390
+ params?: Record<string, any>,
391
+ config?: DownloadConfig,
392
+ options?: UserRequestOpts
393
+ ) => Promise<T>;
284
394
 
285
- // 导出全部业务可用类型
286
395
  export type {
287
- ReqInterceptor,
288
- ResInterceptor,
289
- ErrInterceptor,
396
+ CacheAdapter,
397
+ CacheConfigInput,
290
398
  UserReqInterceptor,
291
399
  UserResInterceptor,
292
400
  UserErrInterceptor,
293
- CacheAdapter,
294
- CacheConfigInput,
295
- CacheConfig,
296
- RequestFailPayload,
297
- RequestOptions,
298
401
  UserRequestOpts,
299
- RequestInstance
402
+ RequestInstance,
403
+ HttpRequestConfig,
404
+ UploadConfig,
405
+ DownloadConfig
300
406
  };
package/lib/http/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const w=require("../index-1b48ae95.js"),P=require("../object/index.js"),k=Object.freeze({JSON:"application/json;charset=UTF-8",TEXT:"text/plain;charset=UTF-8",FORM_URLENCODED:"application/x-www-form-urlencoded;charset=UTF-8",FORM_DATA:"multipart/form-data"}),y={caches:Object.create(null),add(e,t){this.caches[e]=t},delete(e){Reflect.deleteProperty(this.caches,e)},_cancel(e){const t=this.caches[e];typeof(t==null?void 0:t.abort)=="function"&&t.abort()},cancelAll(){Object.values(this.caches).forEach(e=>{typeof(e==null?void 0:e.abort)=="function"&&e.abort()}),this.caches=Object.create(null)},source(){const e=`${Date.now()}-${w.getRandomStr(16)}`;return{token:e,cancel:()=>this._cancel(e)}}};function O(e,t){return new Promise((r,n)=>{const i=uni[e]({...t,success(o){if(o.statusCode>=200&&o.statusCode<300)return r(o);n({type:"fail",res:o})},fail(o){n({type:"fail",res:o})},complete(){t.cancelToken&&y.delete(t.cancelToken)}});t.cancelToken&&y.add(t.cancelToken,i)})}let R=0,x=!1;function U(e){x||(x=!0,uni.showLoading({title:e,mask:!0}))}function D(){x&&(x=!1,uni.hideLoading())}function L(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:"加载中...";R++,R===1&&U(e)}function N(){R>0&&R--,R===0&&D()}function j(e,t){return function(r,n,i,o){return e(r,t,n,i,o)}}function A(e){return typeof e=="function"?e:()=>e||{}}function F(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};const n=A(t.headers)(),i=A(r.headers)(),o={...t,...r,headers:{...n,...i}},{headers:s,...u}=o;return{urlRes:e.startsWith("http")?e:o.baseURL?o.baseURL+e:e,headers:s,configRes:u}}function I(e){return typeof e=="function"?[e]:Array.isArray(e)?e.filter(t=>typeof t=="function"):[]}function q(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};const n={qs:!0,showError:!0,isCache:!1,cacheConfig:{},loadingText:e.loadingText,loading:!0,reqInterceptor:a=>a,resInterceptor:a=>a,errInterceptor:()=>{},...t,...r},i={...t.cacheConfig,...r.cacheConfig},{localAdapter:o,sessionAdapter:s,...u}=i,c={key:"",prefix:"api",mode:"local",expire:60*60,...u};if(!c.key){const a=(c.prefix||"api").replace(/:$/,"");c.key=`${a}:${e.url}`}if(c.adapter=c.mode==="session"?s:o,Object.defineProperty(c,"adapter",{writable:!1,configurable:!1}),n.cacheConfig=c,n.isCache){const a=c.adapter;if(!(a&&typeof a.get=="function"&&typeof a.set=="function"))throw new Error("开启缓存(isCache=true)时,请在cacheConfig传入对应mode的适配器,适配器必须实现 get(key)、set(key,value,expire) 方法")}return["reqInterceptor","resInterceptor","errInterceptor"].forEach(a=>{const l=[...I(t[a]),...I(r[a])];n[a]=l.length?w.composeAsync(...l):g=>g}),n}function E(e,t){const r=Array.from(t);return()=>e(...P.cloneDeepWithDescriptors(r))}function _(e,t,r,n,i){return v.apply(this,arguments)}function v(){return v=w._asyncToGenerator(function*(e,t,r,n,i){let o;n.loading&&(L(n.loadingText),o=()=>{N(),o=null});try{var s;const c=yield n.reqInterceptor(r,n),a=yield e(t,c);return(s=o)===null||s===void 0||s(),yield n.resInterceptor(a,n,i)}catch(c){var u;(u=o)===null||u===void 0||u();const a=yield n.errInterceptor(c,n);return a!==void 0?a:Promise.reject(c)}}),v.apply(this,arguments)}function S(e,t){function r(n,i,o,s,u){const c=y.source(),a=E(r,arguments),l=q({url:n,loadingText:"加载中..."},t,u),{urlRes:g,headers:C,configRes:h}=F(n,e,s),f=l.isCache,d=l.cacheConfig;if(f){const T=d.adapter.get(d.key);if(T)return Promise.resolve(T)}const m=i.toUpperCase()==="GET"?k.JSON:l.qs?k.FORM_URLENCODED:k.JSON,b={cancelToken:c.token,method:i,url:g,data:o,header:{"Content-Type":m,...C},...h};return _(O,"request",b,l,a).then(T=>(f&&d.adapter.set(d.key,T,d.expire),T))}return r.get=j(r,"get"),r.post=j(r,"post"),r}function $(e,t){return function r(n,i,o,s){const u=y.source(),c=E(r,arguments),a=q({loadingText:"上传中..."},t,s),{urlRes:l,headers:g,configRes:C}=F(n,e,o),{keyName:h="file",filePath:f,...d}={keyName:"file",...i};if(!f||!f.startsWith("http://tmp")&&!f.startsWith("wxfile://tmp"))return Promise.resolve({data:f});const p={cancelToken:u.token,url:l,filePath:f,name:h,formData:d,header:{...g},...C};return _(O,"uploadFile",p,a,c)}}function z(e,t){return function r(n,i,o,s){const u=y.source(),c=E(r,arguments),a=q({loadingText:"下载中..."},t,s),{urlRes:l,headers:g,configRes:C}=F(n,e,o);let h=l;if(i&&typeof i=="object"){const d=Object.entries(i).filter(p=>{let[,m]=p;return m!=null&&m!==""}).map(p=>{let[m,b]=p;return`${encodeURIComponent(m)}=${encodeURIComponent(b)}`}).join("&");d&&(h+=(h.includes("?")?"&":"?")+d)}const f={cancelToken:u.token,url:h,header:{...g},...C};return _(O,"downloadFile",f,a,c)}}exports.CONTENT_TYPES=k;exports.CancelToken=y;exports.createDownloadFile=z;exports.createRequest=S;exports.createUploadFile=$;exports.endLoading=N;exports.hideLoading=D;exports.promisifyRequest=O;exports.showLoading=U;exports.startLoading=L;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const v=require("../index-1b48ae95.js"),P=require("../object/index.js"),k=Object.freeze({JSON:"application/json;charset=UTF-8",TEXT:"text/plain;charset=UTF-8",FORM_URLENCODED:"application/x-www-form-urlencoded;charset=UTF-8",FORM_DATA:"multipart/form-data"}),y={caches:Object.create(null),add(e,t){this.caches[e]=t},delete(e){Reflect.deleteProperty(this.caches,e)},_cancel(e){const t=this.caches[e];typeof(t==null?void 0:t.abort)=="function"&&t.abort()},cancelAll(){Object.values(this.caches).forEach(e=>{typeof(e==null?void 0:e.abort)=="function"&&e.abort()}),this.caches=Object.create(null)},source(){const e=`${Date.now()}-${v.getRandomStr(16)}`;return{token:e,cancel:()=>this._cancel(e)}}};function O(e,t){return new Promise((r,n)=>{const i=uni[e]({...t,success(o){if(o.statusCode>=200&&o.statusCode<300)return r(o);n({type:"fail",res:o})},fail(o){n({type:"fail",res:o})},complete(){t.cancelToken&&y.delete(t.cancelToken)}});t.cancelToken&&y.add(t.cancelToken,i)})}let R=0,x=!1;function L(e){x||(x=!0,uni.showLoading({title:e,mask:!0}))}function U(){x&&(x=!1,uni.hideLoading())}function D(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:"加载中...";R++,R===1&&L(e)}function N(){R>0&&R--,R===0&&U()}function j(e,t){return function(r,n,i,o){return e(r,t,n,i,o)}}function A(e){return typeof e=="function"?e:()=>e||{}}function F(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};const n=A(t.headers)(),i=A(r.headers)(),o={...t,...r,headers:{...n,...i}},{headers:l,...s}=o;return{urlRes:e.startsWith("http")?e:o.baseURL?o.baseURL+e:e,headers:l,configRes:s}}function I(e){return typeof e=="function"?[e]:Array.isArray(e)?e.filter(t=>typeof t=="function"):[]}function _(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};const n={qs:!0,showError:!0,isCache:!1,cacheConfig:{},loadingText:e.loadingText,loading:!0,reqInterceptor:c=>c,resInterceptor:c=>c,errInterceptor:()=>{},...t,...r},i={...t.cacheConfig,...r.cacheConfig},{localAdapter:o,sessionAdapter:l,...s}=i,a={key:"",prefix:"api",mode:"local",expire:60*60,...s};if(!a.key){const c=(a.prefix||"api").replace(/:$/,"");a.key=`${c}:${e.url}`}if(a.adapter=a.mode==="session"?l:o,Object.defineProperty(a,"adapter",{writable:!1,configurable:!1}),n.cacheConfig=a,n.isCache){const c=a.adapter;if(!(c&&typeof c.get=="function"&&typeof c.set=="function"))throw new Error("开启缓存(isCache=true)时,请在cacheConfig传入对应mode的适配器,适配器必须实现 get(key)、set(key,value,expire) 方法")}return["reqInterceptor","resInterceptor","errInterceptor"].forEach(c=>{const u=[...I(t[c]),...I(r[c])];n[c]=u.length?v.composeAsync(...u):g=>g}),n}function q(e,t){const r=Array.from(t);return()=>e(...P.cloneDeepWithDescriptors(r))}function E(e,t,r,n,i){return w.apply(this,arguments)}function w(){return w=v._asyncToGenerator(function*(e,t,r,n,i){let o;n.loading&&(D(n.loadingText),o=()=>{N(),o=null});try{const s=yield n.reqInterceptor(r,n),a=yield e(t,s);return yield n.resInterceptor(a,n,i)}catch(s){const a=yield n.errInterceptor(s,n);return a!==void 0?a:Promise.reject(s)}finally{var l;(l=o)===null||l===void 0||l()}}),w.apply(this,arguments)}function S(e,t){function r(n,i,o,l,s){const a=y.source(),c=q(r,arguments),u=_({url:n,loadingText:"加载中..."},t,s),{urlRes:g,headers:C,configRes:h}=F(n,e,l),f=u.isCache,d=u.cacheConfig;if(f){const T=d.adapter.get(d.key);if(T)return Promise.resolve(T)}const m=i.toUpperCase()==="GET"?k.JSON:u.qs?k.FORM_URLENCODED:k.JSON,b={cancelToken:a.token,method:i,url:g,data:o,header:{"Content-Type":m,...C},...h};return E(O,"request",b,u,c).then(T=>(f&&d.adapter.set(d.key,T,d.expire),T))}return r.get=j(r,"get"),r.post=j(r,"post"),r}function $(e,t){return function r(n,i,o,l){const s=y.source(),a=q(r,arguments),c=_({loadingText:"上传中..."},t,l),{urlRes:u,headers:g,configRes:C}=F(n,e,o),{keyName:h="file",filePath:f,...d}={keyName:"file",...i};if(!f||!f.startsWith("http://tmp")&&!f.startsWith("wxfile://tmp"))return Promise.resolve({data:f});const p={cancelToken:s.token,url:u,filePath:f,name:h,formData:d,header:{...g},...C};return E(O,"uploadFile",p,c,a)}}function z(e,t){return function r(n,i,o,l){const s=y.source(),a=q(r,arguments),c=_({loadingText:"下载中..."},t,l),{urlRes:u,headers:g,configRes:C}=F(n,e,o);let h=u;if(i&&typeof i=="object"){const d=Object.entries(i).filter(p=>{let[,m]=p;return m!=null&&m!==""}).map(p=>{let[m,b]=p;return`${encodeURIComponent(m)}=${encodeURIComponent(b)}`}).join("&");d&&(h+=(h.includes("?")?"&":"?")+d)}const f={cancelToken:s.token,url:h,header:{...g},...C};return E(O,"downloadFile",f,c,a)}}exports.CONTENT_TYPES=k;exports.CancelToken=y;exports.createDownloadFile=z;exports.createRequest=S;exports.createUploadFile=$;exports.endLoading=N;exports.hideLoading=U;exports.promisifyRequest=O;exports.showLoading=L;exports.startLoading=D;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "utils-uniapp",
3
- "version": "1.1.8",
3
+ "version": "1.1.10",
4
4
  "description": "aubyn's utils for uniapp",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",