@jetlinks-web/core 2.2.16 → 2.2.18
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/index.d.ts +40 -21
- package/dist/index.mjs +3 -3
- package/index.ts +6 -6
- package/package.json +3 -3
- package/src/axios.ts +64 -101
- package/src/fetch.ts +241 -233
- package/src/locales.ts +7 -7
- package/src/router.ts +7 -7
- package/src/stores.ts +10 -10
- package/src/type.ts +63 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AxiosError, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
|
|
1
|
+
import { AxiosError, AxiosResponse, InternalAxiosRequestConfig, AxiosInstance } from 'axios';
|
|
2
2
|
import { AxiosResponseRewrite } from '@jetlinks-web/types';
|
|
3
3
|
import { Observable } from 'rxjs';
|
|
4
4
|
|
|
@@ -29,6 +29,17 @@ interface Options {
|
|
|
29
29
|
requestOptions?: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig | Record<string, any>;
|
|
30
30
|
isCreateTokenRefresh?: boolean;
|
|
31
31
|
}
|
|
32
|
+
interface PageResult<T> {
|
|
33
|
+
data: T[];
|
|
34
|
+
total: number;
|
|
35
|
+
pageIndex: number;
|
|
36
|
+
pageSize: number;
|
|
37
|
+
}
|
|
38
|
+
interface UpdateResult {
|
|
39
|
+
added: number;
|
|
40
|
+
total: number;
|
|
41
|
+
updated: number;
|
|
42
|
+
}
|
|
32
43
|
interface RequestOptions {
|
|
33
44
|
url?: string;
|
|
34
45
|
method?: string;
|
|
@@ -36,6 +47,8 @@ interface RequestOptions {
|
|
|
36
47
|
data?: any;
|
|
37
48
|
[key: string]: any;
|
|
38
49
|
}
|
|
50
|
+
|
|
51
|
+
declare let instance: AxiosInstance;
|
|
39
52
|
declare const abortAllRequests: () => void;
|
|
40
53
|
declare const crateAxios: (options: Options) => void;
|
|
41
54
|
declare const post: <T = any>(url: string, data?: any, ext?: any) => Promise<AxiosResponseRewrite<T>>;
|
|
@@ -55,56 +68,62 @@ declare const request: {
|
|
|
55
68
|
postStream: (url: string, data: any, ext?: any) => Promise<AxiosResponseRewrite<any>>;
|
|
56
69
|
};
|
|
57
70
|
declare class Request {
|
|
58
|
-
|
|
59
|
-
constructor(
|
|
71
|
+
basePath: string;
|
|
72
|
+
constructor(basePath: string);
|
|
73
|
+
private requestWrapper;
|
|
60
74
|
/**
|
|
61
75
|
* 分页查询
|
|
62
76
|
* @param {object} data 查询参数
|
|
63
77
|
* @param {object} options 请求配置
|
|
64
|
-
* @returns {Promise<AxiosResponse<any>>} 分页查询结果
|
|
65
78
|
*/
|
|
66
|
-
page(data?: any, options?: RequestOptions):
|
|
79
|
+
page<T = any>(data?: any, options?: RequestOptions): Promise<AxiosResponseRewrite<PageResult<T>>>;
|
|
67
80
|
/**
|
|
68
81
|
* 不分页查询
|
|
69
82
|
* @param {object} data 查询参数
|
|
70
83
|
* @param {object} options 请求配置
|
|
71
|
-
* @returns {Promise<AxiosResponse<any>>} 不分页查询结果
|
|
72
84
|
*/
|
|
73
|
-
noPage(data?: any, options?: RequestOptions):
|
|
85
|
+
noPage<T = any>(data?: any, options?: RequestOptions): Promise<AxiosResponseRewrite<T[]>>;
|
|
74
86
|
/**
|
|
75
87
|
* 详情查询
|
|
76
88
|
* @param {string} id 详情ID
|
|
77
89
|
* @param {object} params 查询参数
|
|
78
90
|
* @param {object} options 请求配置
|
|
79
|
-
* @returns {Promise<AxiosResponse<any>>} 详情查询结果
|
|
80
91
|
*/
|
|
81
|
-
detail(id: string, params?: any, options?: RequestOptions):
|
|
92
|
+
detail<T = any>(id: string, params?: any, options?: RequestOptions): Promise<AxiosResponseRewrite<T>>;
|
|
82
93
|
/**
|
|
83
94
|
* 保存
|
|
84
95
|
* @param {object} data 保存参数
|
|
85
96
|
* @param {object} options 请求配置
|
|
86
|
-
* @returns {Promise<AxiosResponse<any>>} 保存结果
|
|
87
97
|
*/
|
|
88
|
-
save(data?: any, options?: RequestOptions):
|
|
98
|
+
save<T = any>(data?: any, options?: RequestOptions): Promise<AxiosResponseRewrite<T>>;
|
|
89
99
|
/**
|
|
90
100
|
* 更新
|
|
91
101
|
* @param {object} data 更新参数
|
|
92
102
|
* @param {object} options 请求配置
|
|
93
|
-
* @returns {Promise<AxiosResponse<any>>} 更新结果
|
|
94
103
|
*/
|
|
95
|
-
update(data?: any, options?: RequestOptions): Promise<AxiosResponseRewrite<
|
|
104
|
+
update<T extends UpdateResult>(data?: any, options?: RequestOptions): Promise<AxiosResponseRewrite<T>>;
|
|
96
105
|
/**
|
|
97
106
|
* 删除
|
|
98
107
|
* @param {string} id 删除ID
|
|
108
|
+
* @param {object} params 请求参数
|
|
99
109
|
* @param {object} options 请求配置
|
|
100
|
-
* @
|
|
110
|
+
* @example ${basePath}/${id}
|
|
111
|
+
*/
|
|
112
|
+
delete<T = any>(id: string, params?: any, options?: RequestOptions): Promise<AxiosResponseRewrite<T>>;
|
|
113
|
+
/**
|
|
114
|
+
* 批量操作
|
|
115
|
+
* @param data
|
|
116
|
+
* @param type
|
|
117
|
+
* @param options
|
|
101
118
|
*/
|
|
102
|
-
|
|
103
|
-
post(
|
|
104
|
-
get(
|
|
105
|
-
put(
|
|
106
|
-
patch(
|
|
107
|
-
remove(
|
|
119
|
+
batch<T = any>(data?: {}, type?: string, options?: RequestOptions): Promise<AxiosResponseRewrite<T>>;
|
|
120
|
+
post<T = any>(url: string, data?: any, options?: any): Promise<AxiosResponseRewrite<T>>;
|
|
121
|
+
get<T = any>(url: string, params?: any, options?: any): Promise<AxiosResponseRewrite<T>>;
|
|
122
|
+
put<T = any>(url: string, data?: any, options?: any): Promise<AxiosResponseRewrite<T>>;
|
|
123
|
+
patch<T = any>(url: string, data?: any, options?: any): Promise<AxiosResponseRewrite<T>>;
|
|
124
|
+
remove<T = any>(url: string, params?: any, options?: any): Promise<AxiosResponseRewrite<T>>;
|
|
125
|
+
getStream(url: string, params?: any, options?: any): Promise<AxiosResponseRewrite<any>>;
|
|
126
|
+
postStream(url: string, data?: any, options?: any): Promise<AxiosResponseRewrite<any>>;
|
|
108
127
|
}
|
|
109
128
|
|
|
110
129
|
declare class NdJson {
|
|
@@ -189,4 +208,4 @@ declare const installStores: (_s?: {}) => void;
|
|
|
189
208
|
declare let locales: any;
|
|
190
209
|
declare const installLocales: (l: any) => void;
|
|
191
210
|
|
|
192
|
-
export { NdJson, Request, WebSocketClient, abortAllRequests, crateAxios, get, getStream, installLocales, installRouter, installStores, locales, ndJson, patch, post, postStream, put, remove, request, router, stores, wsClient };
|
|
211
|
+
export { NdJson, Request, WebSocketClient, abortAllRequests, crateAxios, get, getStream, installLocales, installRouter, installStores, instance, locales, ndJson, patch, post, postStream, put, remove, request, router, stores, wsClient };
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{TOKEN_KEY as S,BASE_API as
|
|
2
|
-
`);for(let
|
|
3
|
-
`);for(let
|
|
1
|
+
import{TOKEN_KEY as S,BASE_API as U,LOCAL_BASE_API as D}from"@jetlinks-web/constants";import{getToken as P,randomString as B}from"@jetlinks-web/utils";import J from"axios";import{isFunction as A,isObject as G}from"lodash-es";var l=window.JetlinksCore?.instance||null,o={filter_url:[],code:200,codeKey:"status",timeout:1e3*15,handleRequest:void 0,handleResponse:void 0,handleError:void 0,langKey:"lang",requestOptions:s=>({}),tokenExpiration:()=>{},handleReconnect:()=>Promise.resolve(),isCreateTokenRefresh:!1},R=[],q=!1,me=window.__MICRO_APP_ENVIRONMENT__,g=new Map,Y=s=>{let e=s.__requestKey;g.has(e)&&g.get(e)?.abort();let t=new AbortController;s.signal=t.signal,s.__requestKey=B(32),g.set(e,t)},F=s=>{Y(s);let e=P(),t=localStorage.getItem(o.langKey),n=localStorage.getItem(D);if(t&&(s.headers[o.langKey]=t),n&&!s.baseURL){let r=s.url.startsWith("/")?s.url:`/${s.url}`;s.url=n+r}if(!e&&!o.filter_url?.some(r=>s.url?.includes(r)))return o.tokenExpiration?.(),s;if(s.headers[S]||(s.headers[S]=e),o.requestOptions&&A(o.requestOptions)){let r=o.requestOptions(s);if(r&&G(r))for(let a in r)s[a]=r[a]}return s},V=s=>{if(o.handleResponse&&A(o.handleResponse))return o.handleResponse(s);let e=s.config?.__requestKey;if(e&&g.delete(e),s.data instanceof ArrayBuffer)return s;let t=s.data[o.codeKey||"status"];return typeof s.data=="object"&&typeof s.data.success>"u"&&(s.data.success=t===o.code),s.data},z=async s=>{let e=s.config;if(q)return new Promise((t,n)=>{R.push({resolve:t,reject:n})}).then(t=>(e.headers[S]=t,l(e))).catch(t=>Promise.reject(t));e._retry=!0,q=!0;try{if(await o.handleReconnect?.()){let n=P();return e.headers[S]=n,R.forEach(r=>r.resolve(n)),l(e)}}catch(t){throw R.forEach(n=>n.reject(t)),t}finally{R=[],q=!1}},M=async s=>{let e=s.response?.message||"Error",t=0;if(s.response){let{data:n,status:r}=s.response;switch(t=r,r){case 400:case 403:case 500:e=`${n?.message}`.substring(0,90);break;case 401:if(e=s.response.data.result?.text||"\u7528\u6237\u672A\u767B\u5F55",o.tokenExpiration?.(s),o.isCreateTokenRefresh)return z(s);break;case 404:e=s?.response?.data?.message||`${n?.error} ${n?.path}`;break;default:break}}else s.response===void 0&&(e=s.message.includes("timeout")?"\u63A5\u53E3\u54CD\u5E94\u8D85\u65F6":s.message,t="timeout");return o.handleError&&A(o.handleError)&&o.handleError(e,t,s),Promise.reject(s)},ge=()=>{g.forEach(s=>s.abort()),g.clear()},we=s=>{s&&(o=Object.assign(o,s)),l=J.create({withCredentials:!1,timeout:o.timeout,baseURL:U}),l.interceptors.request.use(F,M),l.interceptors.response.use(V,M)},x=(s,e={},t)=>l({method:"POST",url:s,data:e,...t}),T=(s,e=void 0,t)=>l({method:"GET",url:s,params:e,...t}),$=(s,e={},t)=>l({method:"PUT",url:s,data:e,...t}),j=(s,e={},t)=>l({method:"patch",url:s,data:e,...t}),I=(s,e=void 0,t)=>l({method:"DELETE",url:s,params:e,...t}),X=(s,e,t)=>T(s,e,{responseType:"arraybuffer",...t}),Z=(s,e,t)=>x(s,e,{responseType:"arraybuffer",...t}),ee={post:x,get:T,put:$,patch:j,remove:I,getStream:X,postStream:Z},v=class{constructor(e){this.basePath=e;this.basePath=e.startsWith("/")?e:`/${e}`}requestWrapper(e,t,n={},r={}){let{url:a=e,method:y=t,...i}=r;return ee[y](`${this.basePath}${a}`,n,i)}page(e={},t={url:void 0,method:void 0}){return this.requestWrapper("/_query","post",e,t)}noPage(e={},t={url:void 0,method:void 0}){return this.requestWrapper("/_query/no-paging","post",{paging:!1,...e},t)}detail(e,t,n={url:void 0,method:void 0}){return this.requestWrapper(`/${e}/detail`,"get",t,n)}save(e={},t={url:void 0,method:void 0}){return this.requestWrapper("","post",e,t)}update(e={},t={url:void 0,method:void 0}){return this.requestWrapper("","patch",e,t)}delete(e,t,n={url:void 0,method:void 0}){return this.requestWrapper(`/${e}`,"post",t,n)}batch(e={},t,n){let r=`/_batch${t?"/"+t:""}`;return this.requestWrapper(r,"post",e,n)}post(e,t,n){return x(`${this.basePath}${e}`,t,n)}get(e,t,n){return T(`${this.basePath}${e}`,t,n)}put(e,t,n){return $(`${this.basePath}${e}`,t,n)}patch(e,t,n){return j(`${this.basePath}${e}`,t,n)}remove(e,t,n){return I(`${this.basePath}${e}`,t,n)}getStream(e,t,n){return T(`${this.basePath}${e}`,t,{responseType:"arraybuffer",...n})}postStream(e,t,n){return x(`${this.basePath}${e}`,t,{responseType:"arraybuffer",...n})}};import{getToken as te}from"@jetlinks-web/utils";import{BASE_API as se,TOKEN_KEY as N}from"@jetlinks-web/constants";import{isFunction as K,isObject as L}from"lodash-es";import{Observable as H}from"rxjs";var _=class{options={code:200,codeKey:"status"};isRead=!1;controller=null;constructor(){}create(e){this.options=Object.assign(this.options,e)}getUrl(e){return se+e}get(e,t="{}",n={}){let r=this.getUrl(e),a=this,y=this.controller=new AbortController;return new H(i=>{let h;return fetch(r,{method:"GET",signal:y.signal,keepalive:!0,...n,...this.handleRequest(r)}).then(m=>{h=m.body?.getReader();let k=new TextDecoder,p="";if(!h){i.error(new Error("No readable stream available"));return}let w=()=>{if(!a.isRead){h.cancel(),i.complete();return}h.read().then(({done:d,value:E})=>{if(d){if(p.trim().length>0)try{i.next(JSON.parse(p.trim()))}catch(u){i.error(u)}i.complete();return}let C=k.decode(E,{stream:!0});p+=C;let f=p.split(`
|
|
2
|
+
`);for(let u=0;u<f.length-1;++u){let b=f[u].trim();if(b.length>0)try{i.next(JSON.parse(b.startsWith("data:")?b.slice(5):b))}catch(O){i.error(O);return}}p=f[f.length-1],w()}).catch(d=>{d.name!=="AbortError"&&i.error(d)})};a.isRead=!0,w()}).catch(m=>{i.error(m)}),()=>{a.cancel()}})}post(e,t={},n={}){let r=this.getUrl(e),a=this,y=this.controller=new AbortController;return new H(i=>{let h;return fetch(r,{method:"POST",signal:y.signal,keepalive:!0,body:L(t)?JSON.stringify(t):t,...n,...this.handleRequest(r)}).then(async m=>{h=m.body?.getReader();let k=new TextDecoder,p="";if(!h){i.error(new Error("No readable stream available"));return}let w=()=>{if(!a.isRead){h.cancel(),i.complete();return}h.read().then(({done:d,value:E})=>{if(d){if(p.trim().length>0)try{i.next(JSON.parse(p.trim()))}catch(u){i.error(u)}i.complete();return}let C=k.decode(E,{stream:!0});p+=C;let f=p.split(`
|
|
3
|
+
`);for(let u=0;u<f.length-1;++u){let b=f[u].trim();if(b.length>0)try{i.next(JSON.parse(b.startsWith("data:")?b.slice(5):b))}catch(O){i.error(O);return}}p=f[f.length-1],w()}).catch(d=>{d.name!=="AbortError"&&i.error(d)})};a.isRead=!0,w()}).catch(m=>{i.error(m)}),()=>{a.cancel()}})}handleRequest(e){let t={headers:{"Content-Type":"application/x-ndjson"}},n=te();if(!n&&this.options.filter_url?.some(r=>r.includes(e)))return this.options.tokenExpiration?.(),t;if(t.headers[N]||(t.headers[N]=n),this.options.requestOptions&&K(this.options.requestOptions)){let r=this.options.requestOptions(t);if(r&&L(r))for(let a in r)t[a]=r[a]}return t}handleResponse(e){return this.options.handleResponse&&K(this.options.handleResponse)?this.options.handleResponse(e):e}cancel(){this.isRead&&(this.isRead=!1),this.controller&&this.controller.abort()}},Ee=new _;import{webSocket as ne}from"rxjs/webSocket";import{Observable as re,Subject as ie,timer as Q,EMPTY as oe}from"rxjs";import{retry as ae,catchError as ce}from"rxjs/operators";import{notification as pe}from"ant-design-vue";var c=window.__MICRO_APP_ENVIRONMENT__,W=class{ws=null;subscriptions=new Map;pendingSubscriptions=new Map;heartbeatSubscription=null;reconnectAttempts=0;maxReconnectAttempts=2;isConnected=!1;tempQueue=[];url="";options={};wsClient;constructor(e){this.setOptions(e),this.setupConnectionMonitor(),c&&window.microApp.addGlobalDataListener(t=>{this.wsClient=t.wsClient})}setOptions(e){this.options=e||{}}initWebSocket(e){this.url=e}setupConnectionMonitor(){c||(window.addEventListener("online",()=>{console.log("Network is online, attempting to reconnect..."),this.reconnect()}),window.addEventListener("offline",()=>{console.log("Network is offline, caching subscriptions..."),this.cacheSubscriptions()}),window.addEventListener("beforeunload",()=>{this.disconnect()}))}getReconnectDelay(){return this.reconnectAttempts<=10?5e3:this.reconnectAttempts<=20?15e3:6e4}setupWebSocket(){if(c&&this.wsClient){this.wsClient.setupWebSocket();return}this.ws||!this.url||(this.ws=ne({url:this.url,openObserver:{next:()=>{console.log("WebSocket connected"),this.isConnected=!0,this.reconnectAttempts=0,this.startHeartbeat(),this.restoreSubscriptions(),this.processTempQueue()}},closeObserver:{next:()=>{console.log("WebSocket disconnected"),this.isConnected=!1;let e=this.getReconnectDelay();setTimeout(()=>{this.reconnectAttempts+=1,!(this.reconnectAttempts>this.maxReconnectAttempts)&&(this.cacheSubscriptions(),this.stopHeartbeat(),this.reconnect())},e)}}}),this.ws.pipe(ce(e=>(console.error("WebSocket error:",e),oe)),ae({delay:(e,t)=>{if(this.reconnectAttempts=t,t>this.maxReconnectAttempts)throw new Error("Max reconnection attempts reached");return Q(this.getReconnectDelay())}})).subscribe(e=>this.handleMessage(e),e=>console.error("WebSocket error:",e)))}startHeartbeat(){if(c&&this.wsClient){this.wsClient.startHeartbeat();return}this.stopHeartbeat(),this.heartbeatSubscription=Q(0,2e3).subscribe(()=>{this.send({type:"ping"})})}stopHeartbeat(){if(c&&this.wsClient){this.wsClient.stopHeartbeat();return}this.heartbeatSubscription&&(this.heartbeatSubscription.unsubscribe(),this.heartbeatSubscription=null)}handleMessage(e){if(c&&this.wsClient){this.wsClient.handleMessage(e);return}if(e.type==="pong")return;if(e.type==="error"){this.options.onError?this.options.onError(e):pe.error({key:"error",message:e.message});return}let t=this.subscriptions.get(e.requestId||"");t&&(e.type==="complete"?(t.complete(),this.subscriptions.delete(e.requestId||"")):e.type==="result"&&t.next(e))}processTempQueue(){if(c&&this.wsClient){this.wsClient.processTempQueue();return}for(;this.tempQueue.length>0;){let e=this.tempQueue.shift();e&&this.send(e)}}cacheSubscriptions(){if(c&&this.wsClient){this.wsClient.cacheSubscriptions();return}this.pendingSubscriptions=new Map(this.subscriptions),this.subscriptions.clear()}restoreSubscriptions(){if(c&&this.wsClient){this.wsClient.restoreSubscriptions();return}this.pendingSubscriptions.forEach((e,t)=>{this.subscriptions.set(t,e)}),this.pendingSubscriptions.clear()}reconnect(){if(c&&this.wsClient){this.wsClient.reconnect();return}!this.isConnected&&navigator.onLine&&(this.ws=null,this.setupWebSocket())}connect(){if(c&&this.wsClient){this.wsClient.connect();return}this.setupWebSocket()}disconnect(){if(c&&this.wsClient){this.wsClient.disconnect();return}this.ws&&(this.ws.complete(),this.ws=null),this.stopHeartbeat(),this.subscriptions.clear(),this.pendingSubscriptions.clear(),this.tempQueue=[]}send(e){if(c&&this.wsClient){this.wsClient.send(e);return}this.ws&&this.isConnected?this.ws.next(e):this.tempQueue.push(e)}getWebSocket(e,t,n={}){if(console.log("getWebSocket",this.wsClient,e),c&&this.wsClient)return this.wsClient.getWebSocket(e,t,n);let r=new ie;this.subscriptions.set(e,r);let a={id:e,topic:t,parameter:n,type:"sub"};return this.send(a),new re(y=>{let i=r.subscribe(y);return()=>{i.unsubscribe(),this.send({id:e,type:"unsub"}),this.subscriptions.delete(e)}})}},Me=new W;var ue,Pe=s=>{ue=s};var le={},je=(s={})=>{le=s};var he,Ne=s=>{he=s};export{_ as NdJson,v as Request,W as WebSocketClient,ge as abortAllRequests,we as crateAxios,T as get,X as getStream,Ne as installLocales,Pe as installRouter,je as installStores,l as instance,he as locales,Ee as ndJson,j as patch,x as post,Z as postStream,$ as put,I as remove,ee as request,ue as router,le as stores,Me as wsClient};
|
package/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export * from './src/axios'
|
|
2
|
-
export * from './src/fetch'
|
|
3
|
-
export * from './src/websocket'
|
|
4
|
-
export * from './src/router'
|
|
5
|
-
export * from './src/stores'
|
|
6
|
-
export * from './src/locales'
|
|
1
|
+
export * from './src/axios'
|
|
2
|
+
export * from './src/fetch'
|
|
3
|
+
export * from './src/websocket'
|
|
4
|
+
export * from './src/router'
|
|
5
|
+
export * from './src/stores'
|
|
6
|
+
export * from './src/locales'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jetlinks-web/core",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.18",
|
|
4
4
|
"main": "dist/index.mjs",
|
|
5
5
|
"module": "dist/index.mjs",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"axios": "^1.7.4",
|
|
30
30
|
"rxjs": "^7.8.1",
|
|
31
31
|
"@jetlinks-web/constants": "^1.0.9",
|
|
32
|
-
"@jetlinks-web/
|
|
33
|
-
"@jetlinks-web/
|
|
32
|
+
"@jetlinks-web/types": "^1.0.2",
|
|
33
|
+
"@jetlinks-web/utils": "^1.2.12"
|
|
34
34
|
},
|
|
35
35
|
"publishConfig": {
|
|
36
36
|
"registry": "https://registry.npmjs.org/",
|
package/src/axios.ts
CHANGED
|
@@ -3,64 +3,13 @@ import {getToken, randomString} from '@jetlinks-web/utils'
|
|
|
3
3
|
import axios from 'axios'
|
|
4
4
|
import type {
|
|
5
5
|
AxiosInstance,
|
|
6
|
-
AxiosResponse,
|
|
7
|
-
AxiosError,
|
|
8
|
-
InternalAxiosRequestConfig,
|
|
9
6
|
} from 'axios'
|
|
10
7
|
import type { AxiosResponseRewrite } from '@jetlinks-web/types'
|
|
11
8
|
import {isFunction, isObject} from 'lodash-es'
|
|
9
|
+
import type { Options, ExpandRequestConfig, ExpandAxiosResponse, ExpandAxiosError, RequestOptions, PageResult, UpdateResult } from './type'
|
|
12
10
|
|
|
13
|
-
|
|
11
|
+
export let instance: AxiosInstance = (window as any).JetlinksCore?.instance || null
|
|
14
12
|
|
|
15
|
-
tokenExpiration: (err?: AxiosError<any>, response?: AxiosResponse) => void
|
|
16
|
-
handleReconnect: () => Promise<any>
|
|
17
|
-
filter_url?: Array<string>
|
|
18
|
-
code?: number
|
|
19
|
-
codeKey?: string
|
|
20
|
-
timeout?: number
|
|
21
|
-
handleRequest?: () => void
|
|
22
|
-
/**
|
|
23
|
-
* 用以获取localstorage中的lang
|
|
24
|
-
*/
|
|
25
|
-
langKey?: string
|
|
26
|
-
/**
|
|
27
|
-
* response处理函数
|
|
28
|
-
* @param response AxiosResponse实例
|
|
29
|
-
*/
|
|
30
|
-
handleResponse?: (response: AxiosResponse) => void
|
|
31
|
-
/**
|
|
32
|
-
* 错误处理函数
|
|
33
|
-
* @param msg 错误消息
|
|
34
|
-
* @param status 错误code
|
|
35
|
-
* @param error 错误实例
|
|
36
|
-
*/
|
|
37
|
-
handleError?: (msg: string, status: string | number, error: AxiosError<any>) => void
|
|
38
|
-
requestOptions?: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig | Record<string, any>
|
|
39
|
-
isCreateTokenRefresh?: boolean
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
interface typeRequestConfig extends InternalAxiosRequestConfig {
|
|
43
|
-
__requestKey?: string
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
interface typeAxiosResponse extends AxiosResponse {
|
|
47
|
-
config: typeRequestConfig
|
|
48
|
-
message: string
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
interface typeAxiosError<T> extends AxiosError<T> {
|
|
52
|
-
response: typeAxiosResponse
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
interface RequestOptions {
|
|
56
|
-
url?: string
|
|
57
|
-
method?: string
|
|
58
|
-
params?: any
|
|
59
|
-
data?: any
|
|
60
|
-
[key: string]: any
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
let instance: AxiosInstance
|
|
64
13
|
let _options: Options = {
|
|
65
14
|
filter_url: [],
|
|
66
15
|
code: 200,
|
|
@@ -82,8 +31,8 @@ let isRefreshing = false;
|
|
|
82
31
|
const isApp = (window as any).__MICRO_APP_ENVIRONMENT__
|
|
83
32
|
|
|
84
33
|
const pendingRequests = new Map<string, AbortController>();
|
|
85
|
-
const requestRecords = (config:
|
|
86
|
-
const key =
|
|
34
|
+
const requestRecords = (config: ExpandRequestConfig) => {
|
|
35
|
+
const key = config.__requestKey
|
|
87
36
|
|
|
88
37
|
// 取消重复请求
|
|
89
38
|
if (pendingRequests.has(key)) {
|
|
@@ -92,11 +41,12 @@ const requestRecords = (config: typeRequestConfig) => {
|
|
|
92
41
|
|
|
93
42
|
const controller = new AbortController()
|
|
94
43
|
config.signal = controller.signal;
|
|
95
|
-
config.__requestKey =
|
|
44
|
+
config.__requestKey = randomString(32);
|
|
96
45
|
|
|
97
46
|
pendingRequests.set(key, controller)
|
|
98
47
|
}
|
|
99
|
-
|
|
48
|
+
|
|
49
|
+
const handleRequest = (config: ExpandRequestConfig) => {
|
|
100
50
|
requestRecords(config)
|
|
101
51
|
const token = getToken();
|
|
102
52
|
const lang = localStorage.getItem(_options.langKey)
|
|
@@ -134,7 +84,7 @@ const handleRequest = (config: typeRequestConfig) => {
|
|
|
134
84
|
return config
|
|
135
85
|
}
|
|
136
86
|
|
|
137
|
-
const handleResponse = (response:
|
|
87
|
+
const handleResponse = (response: ExpandAxiosResponse) => {
|
|
138
88
|
if (_options.handleResponse && isFunction(_options.handleResponse)) {
|
|
139
89
|
return _options.handleResponse(response)
|
|
140
90
|
}
|
|
@@ -189,7 +139,7 @@ const createTokenRefreshHandler = async (err) => {
|
|
|
189
139
|
isRefreshing = false;
|
|
190
140
|
}
|
|
191
141
|
}
|
|
192
|
-
const errorHandler = async (err:
|
|
142
|
+
const errorHandler = async (err: ExpandAxiosError<any>) => {
|
|
193
143
|
let description = err.response?.message || 'Error'
|
|
194
144
|
let _status: string | number = 0
|
|
195
145
|
if (err.response) {
|
|
@@ -311,38 +261,43 @@ export const request = {
|
|
|
311
261
|
}
|
|
312
262
|
|
|
313
263
|
export class Request {
|
|
314
|
-
modulePath: string
|
|
315
264
|
|
|
316
|
-
constructor(
|
|
317
|
-
this.
|
|
265
|
+
constructor(public basePath: string) {
|
|
266
|
+
this.basePath = basePath.startsWith('/') ? basePath : `/${basePath}`
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
private requestWrapper<T = any>(
|
|
270
|
+
defaultUrl: string,
|
|
271
|
+
defaultMethod: 'post'| 'get'| 'put'| 'patch'| 'remove'| 'getStream'| 'postStream',
|
|
272
|
+
dataOrParams: any = {},
|
|
273
|
+
options: RequestOptions = {}
|
|
274
|
+
): Promise<AxiosResponseRewrite<T>> {
|
|
275
|
+
const { url = defaultUrl, method = defaultMethod, ...rest } = options
|
|
276
|
+
return request[method]<T>(`${this.basePath}${url}`, dataOrParams, rest)
|
|
318
277
|
}
|
|
319
278
|
|
|
320
279
|
/**
|
|
321
280
|
* 分页查询
|
|
322
281
|
* @param {object} data 查询参数
|
|
323
282
|
* @param {object} options 请求配置
|
|
324
|
-
* @returns {Promise<AxiosResponse<any>>} 分页查询结果
|
|
325
283
|
*/
|
|
326
|
-
page(data: any={}, options: RequestOptions= {
|
|
284
|
+
page<T = any>(data: any={}, options: RequestOptions= {
|
|
327
285
|
url: undefined,
|
|
328
286
|
method: undefined,
|
|
329
287
|
}) {
|
|
330
|
-
|
|
331
|
-
return request[method](`${this.modulePath}${url}`, data, rest)
|
|
288
|
+
return this.requestWrapper<PageResult<T>>('/_query', 'post', data, options)
|
|
332
289
|
}
|
|
333
290
|
|
|
334
291
|
/**
|
|
335
292
|
* 不分页查询
|
|
336
293
|
* @param {object} data 查询参数
|
|
337
294
|
* @param {object} options 请求配置
|
|
338
|
-
* @returns {Promise<AxiosResponse<any>>} 不分页查询结果
|
|
339
295
|
*/
|
|
340
|
-
noPage(data: any={}, options: RequestOptions = {
|
|
296
|
+
noPage<T = any>(data: any={}, options: RequestOptions = {
|
|
341
297
|
url: undefined,
|
|
342
298
|
method: undefined,
|
|
343
299
|
}) {
|
|
344
|
-
|
|
345
|
-
return request[method](`${this.modulePath}${url}`, { paging: false, ...data}, rest)
|
|
300
|
+
return this.requestWrapper<T[]>('/_query/no-paging', 'post', { paging: false, ...data }, options)
|
|
346
301
|
}
|
|
347
302
|
|
|
348
303
|
/**
|
|
@@ -350,81 +305,89 @@ export class Request {
|
|
|
350
305
|
* @param {string} id 详情ID
|
|
351
306
|
* @param {object} params 查询参数
|
|
352
307
|
* @param {object} options 请求配置
|
|
353
|
-
* @returns {Promise<AxiosResponse<any>>} 详情查询结果
|
|
354
308
|
*/
|
|
355
|
-
detail(id: string, params?: any, options: RequestOptions= {
|
|
309
|
+
detail<T = any>(id: string, params?: any, options: RequestOptions= {
|
|
356
310
|
url: undefined,
|
|
357
311
|
method: undefined,
|
|
358
312
|
}) {
|
|
359
|
-
|
|
360
|
-
return request[method](`${this.modulePath}${url}`, params, rest)
|
|
313
|
+
return this.requestWrapper<T>(`/${id}/detail`, 'get', params, options)
|
|
361
314
|
}
|
|
362
315
|
|
|
363
316
|
/**
|
|
364
317
|
* 保存
|
|
365
318
|
* @param {object} data 保存参数
|
|
366
319
|
* @param {object} options 请求配置
|
|
367
|
-
* @returns {Promise<AxiosResponse<any>>} 保存结果
|
|
368
320
|
*/
|
|
369
|
-
save(data: any={}, options: RequestOptions = {
|
|
321
|
+
save<T = any>(data: any={}, options: RequestOptions = {
|
|
370
322
|
url: undefined,
|
|
371
323
|
method: undefined,
|
|
372
324
|
}) {
|
|
373
|
-
|
|
374
|
-
return request[method](`${this.modulePath}${url}`, data, rest)
|
|
325
|
+
return this.requestWrapper<T>('', 'post', data, options)
|
|
375
326
|
}
|
|
376
327
|
|
|
377
328
|
/**
|
|
378
329
|
* 更新
|
|
379
330
|
* @param {object} data 更新参数
|
|
380
331
|
* @param {object} options 请求配置
|
|
381
|
-
* @returns {Promise<AxiosResponse<any>>} 更新结果
|
|
382
332
|
*/
|
|
383
|
-
update(data: any={}, options: RequestOptions = {
|
|
333
|
+
update<T extends UpdateResult>(data: any={}, options: RequestOptions = {
|
|
384
334
|
url: undefined,
|
|
385
335
|
method: undefined,
|
|
386
336
|
}) {
|
|
387
|
-
|
|
388
|
-
return patch(`${this.modulePath}${url}`, data, rest)
|
|
337
|
+
return this.requestWrapper<T>('', 'patch', data, options)
|
|
389
338
|
}
|
|
390
339
|
|
|
391
340
|
/**
|
|
392
341
|
* 删除
|
|
393
342
|
* @param {string} id 删除ID
|
|
343
|
+
* @param {object} params 请求参数
|
|
394
344
|
* @param {object} options 请求配置
|
|
395
|
-
* @
|
|
345
|
+
* @example ${basePath}/${id}
|
|
396
346
|
*/
|
|
397
|
-
delete(id: string, params?: any, options: RequestOptions = {
|
|
347
|
+
delete<T = any>(id: string, params?: any, options: RequestOptions = {
|
|
398
348
|
url: undefined,
|
|
399
349
|
method: undefined,
|
|
400
350
|
}) {
|
|
401
|
-
|
|
402
|
-
|
|
351
|
+
return this.requestWrapper<T>(`/${id}`, 'post', params, options)
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* 批量操作
|
|
356
|
+
* @param data
|
|
357
|
+
* @param type
|
|
358
|
+
* @param options
|
|
359
|
+
*/
|
|
360
|
+
batch<T = any>(data = {}, type?: string, options?: RequestOptions) {
|
|
361
|
+
const url = `/_batch${type ? '/' + type : ''}`
|
|
362
|
+
return this.requestWrapper<T>(url, 'post', data, options)
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
post<T = any>(url: string, data?: any, options?: any) {
|
|
366
|
+
return post<T>(`${this.basePath}${url}`, data, options)
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
get<T = any>(url: string, params?: any, options?: any) {
|
|
370
|
+
return get<T>(`${this.basePath}${url}`, params, options)
|
|
403
371
|
}
|
|
404
372
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
return post(`${this.modulePath}${url}`, data, options)
|
|
373
|
+
put<T = any>(url: string, data?: any, options?: any) {
|
|
374
|
+
return put<T>(`${this.basePath}${url}`, data, options)
|
|
408
375
|
}
|
|
409
376
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
return get(`${this.modulePath}${url}`, params, options)
|
|
377
|
+
patch<T = any>(url: string, data?: any, options?: any) {
|
|
378
|
+
return patch<T>(`${this.basePath}${url}`, data, options)
|
|
413
379
|
}
|
|
414
380
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
return put(`${this.modulePath}${url}`, data, options)
|
|
381
|
+
remove<T = any>(url: string, params?: any, options?: any) {
|
|
382
|
+
return remove<T>(`${this.basePath}${url}`, params, options)
|
|
418
383
|
}
|
|
419
384
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
return patch(`${this.modulePath}${url}`, data, options)
|
|
385
|
+
getStream(url: string, params?: any, options?: any) {
|
|
386
|
+
return get(`${this.basePath}${url}`, params, { responseType: 'arraybuffer', ...options })
|
|
423
387
|
}
|
|
424
388
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
return remove(`${this.modulePath}${url}`, params, options)
|
|
389
|
+
postStream(url: string, data?: any, options?: any) {
|
|
390
|
+
return post(`${this.basePath}${url}`, data, { responseType: 'arraybuffer', ...options })
|
|
428
391
|
}
|
|
429
392
|
}
|
|
430
393
|
|
package/src/fetch.ts
CHANGED
|
@@ -1,233 +1,241 @@
|
|
|
1
|
-
import {getToken} from "@jetlinks-web/utils";
|
|
2
|
-
import {BASE_API, TOKEN_KEY} from "@jetlinks-web/constants";
|
|
3
|
-
import {isFunction, isObject} from "lodash-es";
|
|
4
|
-
import { Observable, } from 'rxjs'
|
|
5
|
-
|
|
6
|
-
export class NdJson {
|
|
7
|
-
options: any = {
|
|
8
|
-
code: 200,
|
|
9
|
-
codeKey: 'status'
|
|
10
|
-
}
|
|
11
|
-
isRead = false
|
|
12
|
-
controller = null
|
|
13
|
-
constructor() {}
|
|
14
|
-
|
|
15
|
-
create(options) {
|
|
16
|
-
this.options = Object.assign(this.options, options)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
getUrl(url) {
|
|
20
|
-
return BASE_API + url
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
get(url, data = '{}', extra = {}) {
|
|
24
|
-
const _url = this.getUrl(url)
|
|
25
|
-
const that = this
|
|
26
|
-
const controller = this.controller = new AbortController();
|
|
27
|
-
|
|
28
|
-
return new Observable(observer => {
|
|
29
|
-
let reader
|
|
30
|
-
fetch(
|
|
31
|
-
_url,
|
|
32
|
-
{
|
|
33
|
-
method: 'GET',
|
|
34
|
-
signal: controller.signal,
|
|
35
|
-
keepalive: true,
|
|
36
|
-
...extra,
|
|
37
|
-
...this.handleRequest(_url)
|
|
38
|
-
}
|
|
39
|
-
).then(resp => {
|
|
40
|
-
reader = resp.body?.getReader();
|
|
41
|
-
const decoder = new TextDecoder();
|
|
42
|
-
let data_buf = "";
|
|
43
|
-
|
|
44
|
-
if (!reader) {
|
|
45
|
-
observer.error(new Error('No readable stream available'));
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const read = () => {
|
|
50
|
-
|
|
51
|
-
if (!that.isRead) {
|
|
52
|
-
reader.cancel()
|
|
53
|
-
observer.complete();
|
|
54
|
-
return
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
reader.read().then(({ done, value }) => {
|
|
58
|
-
if (done) {
|
|
59
|
-
if (data_buf.trim().length > 0) {
|
|
60
|
-
try {
|
|
61
|
-
observer.next(JSON.parse(data_buf.trim()));
|
|
62
|
-
} catch (e) {
|
|
63
|
-
observer.error(e);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
observer.complete();
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const data = decoder.decode(value, { stream: true });
|
|
71
|
-
data_buf += data;
|
|
72
|
-
|
|
73
|
-
let lines = data_buf.split('\n');
|
|
74
|
-
for (let i = 0; i < lines.length - 1; ++i) {
|
|
75
|
-
const line = lines[i].trim();
|
|
76
|
-
if (line.length > 0) {
|
|
77
|
-
try {
|
|
78
|
-
observer.next(JSON.parse(line));
|
|
79
|
-
} catch (e) {
|
|
80
|
-
observer.error(e);
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
1
|
+
import {getToken} from "@jetlinks-web/utils";
|
|
2
|
+
import {BASE_API, TOKEN_KEY} from "@jetlinks-web/constants";
|
|
3
|
+
import {isFunction, isObject} from "lodash-es";
|
|
4
|
+
import { Observable, } from 'rxjs'
|
|
5
|
+
|
|
6
|
+
export class NdJson {
|
|
7
|
+
options: any = {
|
|
8
|
+
code: 200,
|
|
9
|
+
codeKey: 'status'
|
|
10
|
+
}
|
|
11
|
+
isRead = false
|
|
12
|
+
controller = null
|
|
13
|
+
constructor() {}
|
|
14
|
+
|
|
15
|
+
create(options) {
|
|
16
|
+
this.options = Object.assign(this.options, options)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
getUrl(url) {
|
|
20
|
+
return BASE_API + url
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
get(url, data = '{}', extra = {}) {
|
|
24
|
+
const _url = this.getUrl(url)
|
|
25
|
+
const that = this
|
|
26
|
+
const controller = this.controller = new AbortController();
|
|
27
|
+
|
|
28
|
+
return new Observable(observer => {
|
|
29
|
+
let reader
|
|
30
|
+
fetch(
|
|
31
|
+
_url,
|
|
32
|
+
{
|
|
33
|
+
method: 'GET',
|
|
34
|
+
signal: controller.signal,
|
|
35
|
+
keepalive: true,
|
|
36
|
+
...extra,
|
|
37
|
+
...this.handleRequest(_url)
|
|
38
|
+
}
|
|
39
|
+
).then(resp => {
|
|
40
|
+
reader = resp.body?.getReader();
|
|
41
|
+
const decoder = new TextDecoder();
|
|
42
|
+
let data_buf = "";
|
|
43
|
+
|
|
44
|
+
if (!reader) {
|
|
45
|
+
observer.error(new Error('No readable stream available'));
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const read = () => {
|
|
50
|
+
|
|
51
|
+
if (!that.isRead) {
|
|
52
|
+
reader.cancel()
|
|
53
|
+
observer.complete();
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
reader.read().then(({ done, value }) => {
|
|
58
|
+
if (done) {
|
|
59
|
+
if (data_buf.trim().length > 0) {
|
|
60
|
+
try {
|
|
61
|
+
observer.next(JSON.parse(data_buf.trim()));
|
|
62
|
+
} catch (e) {
|
|
63
|
+
observer.error(e);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
observer.complete();
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const data = decoder.decode(value, { stream: true });
|
|
71
|
+
data_buf += data;
|
|
72
|
+
|
|
73
|
+
let lines = data_buf.split('\n');
|
|
74
|
+
for (let i = 0; i < lines.length - 1; ++i) {
|
|
75
|
+
const line = lines[i].trim();
|
|
76
|
+
if (line.length > 0) {
|
|
77
|
+
try {
|
|
78
|
+
observer.next(JSON.parse(line.startsWith('data:') ? line.slice(5) : line));
|
|
79
|
+
} catch (e) {
|
|
80
|
+
observer.error(e);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
data_buf = lines[lines.length - 1];
|
|
86
|
+
read();
|
|
87
|
+
}).catch(err => {
|
|
88
|
+
if (err.name !== 'AbortError') {
|
|
89
|
+
observer.error(err);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
that.isRead = true
|
|
94
|
+
read();
|
|
95
|
+
}).catch(e => {
|
|
96
|
+
observer.error(e)
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
return () => {
|
|
100
|
+
that.cancel()
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
post(url, data: BodyInit | any ={}, extra = {}) {
|
|
106
|
+
const _url = this.getUrl(url)
|
|
107
|
+
const that = this
|
|
108
|
+
const controller = this.controller = new AbortController();
|
|
109
|
+
|
|
110
|
+
return new Observable(observer => {
|
|
111
|
+
let reader
|
|
112
|
+
fetch(
|
|
113
|
+
_url,
|
|
114
|
+
{
|
|
115
|
+
method: 'POST',
|
|
116
|
+
signal: controller.signal,
|
|
117
|
+
keepalive: true,
|
|
118
|
+
body: isObject(data) ? JSON.stringify(data) : data,
|
|
119
|
+
...extra,
|
|
120
|
+
...this.handleRequest(_url)
|
|
121
|
+
}
|
|
122
|
+
).then(async resp => {
|
|
123
|
+
reader = resp.body?.getReader();
|
|
124
|
+
const decoder = new TextDecoder();
|
|
125
|
+
let data_buf = "";
|
|
126
|
+
|
|
127
|
+
if (!reader) {
|
|
128
|
+
observer.error(new Error('No readable stream available'));
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const read = () => {
|
|
133
|
+
|
|
134
|
+
if (!that.isRead) {
|
|
135
|
+
reader.cancel()
|
|
136
|
+
observer.complete();
|
|
137
|
+
return
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
reader.read().then(({ done, value }) => {
|
|
141
|
+
if (done) {
|
|
142
|
+
if (data_buf.trim().length > 0) {
|
|
143
|
+
try {
|
|
144
|
+
observer.next(JSON.parse(data_buf.trim()));
|
|
145
|
+
} catch (e) {
|
|
146
|
+
observer.error(e);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
observer.complete();
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const data = decoder.decode(value, { stream: true });
|
|
154
|
+
data_buf += data;
|
|
155
|
+
|
|
156
|
+
let lines = data_buf.split('\n');
|
|
157
|
+
for (let i = 0; i < lines.length - 1; ++i) {
|
|
158
|
+
const line = lines[i].trim();
|
|
159
|
+
if (line.length > 0) {
|
|
160
|
+
try {
|
|
161
|
+
observer.next(JSON.parse(line.startsWith('data:') ? line.slice(5) : line));
|
|
162
|
+
} catch (e) {
|
|
163
|
+
observer.error(e);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
data_buf = lines[lines.length - 1];
|
|
169
|
+
read();
|
|
170
|
+
}).catch(err => {
|
|
171
|
+
if (err.name !== 'AbortError') {
|
|
172
|
+
observer.error(err);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
};
|
|
176
|
+
that.isRead = true
|
|
177
|
+
read();
|
|
178
|
+
}).catch(e => {
|
|
179
|
+
observer.error(e)
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
return () => {
|
|
183
|
+
that.cancel()
|
|
184
|
+
}
|
|
185
|
+
})
|
|
186
|
+
}
|
|
187
|
+
handleRequest(url): RequestInit {
|
|
188
|
+
const config: RequestInit = {
|
|
189
|
+
headers: {
|
|
190
|
+
'Content-Type': 'application/x-ndjson',
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const token = getToken()
|
|
195
|
+
|
|
196
|
+
if (!token && this.options.filter_url?.some(_url => _url.includes(url))) {
|
|
197
|
+
this.options.tokenExpiration?.()
|
|
198
|
+
return config
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (!config.headers[TOKEN_KEY]) {
|
|
202
|
+
config.headers[TOKEN_KEY] = token
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (this.options.requestOptions && isFunction(this.options.requestOptions)) {
|
|
206
|
+
const extraOptions = this.options.requestOptions(config)
|
|
207
|
+
if (extraOptions && isObject(extraOptions)) {
|
|
208
|
+
for (const key in extraOptions) {
|
|
209
|
+
config[key] = extraOptions[key]
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return config
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
handleResponse(response) {
|
|
218
|
+
|
|
219
|
+
if (this.options.handleResponse && isFunction(this.options.handleResponse)) {
|
|
220
|
+
return this.options.handleResponse(response)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// const status = response[this.options.codeKey || 'status']
|
|
224
|
+
// response.success = status === this.options.code
|
|
225
|
+
|
|
226
|
+
return response
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
cancel() {
|
|
230
|
+
if (this.isRead) {
|
|
231
|
+
this.isRead = false
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (this.controller) {
|
|
235
|
+
this.controller.abort()
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
export const ndJson = new NdJson()
|
package/src/locales.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
let locales
|
|
2
|
-
|
|
3
|
-
const installLocales = (l) => {
|
|
4
|
-
locales = l
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export { locales, installLocales }
|
|
1
|
+
let locales
|
|
2
|
+
|
|
3
|
+
const installLocales = (l) => {
|
|
4
|
+
locales = l
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export { locales, installLocales }
|
package/src/router.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
let router
|
|
2
|
-
|
|
3
|
-
const installRouter = (r) => {
|
|
4
|
-
router = r
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export { router, installRouter }
|
|
1
|
+
let router
|
|
2
|
+
|
|
3
|
+
const installRouter = (r) => {
|
|
4
|
+
router = r
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export { router, installRouter }
|
package/src/stores.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
let stores = {}
|
|
2
|
-
|
|
3
|
-
const installStores = (_s = {}) => {
|
|
4
|
-
stores = _s
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export {
|
|
8
|
-
stores,
|
|
9
|
-
installStores
|
|
10
|
-
}
|
|
1
|
+
let stores = {}
|
|
2
|
+
|
|
3
|
+
const installStores = (_s = {}) => {
|
|
4
|
+
stores = _s
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
stores,
|
|
9
|
+
installStores
|
|
10
|
+
}
|
package/src/type.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type {AxiosError, AxiosResponse, InternalAxiosRequestConfig} from "axios";
|
|
2
|
+
|
|
3
|
+
export interface Options {
|
|
4
|
+
tokenExpiration: (err?: AxiosError<any>, response?: AxiosResponse) => void
|
|
5
|
+
handleReconnect: () => Promise<any>
|
|
6
|
+
filter_url?: Array<string>
|
|
7
|
+
code?: number
|
|
8
|
+
codeKey?: string
|
|
9
|
+
timeout?: number
|
|
10
|
+
handleRequest?: () => void
|
|
11
|
+
/**
|
|
12
|
+
* 用以获取localstorage中的lang
|
|
13
|
+
*/
|
|
14
|
+
langKey?: string
|
|
15
|
+
/**
|
|
16
|
+
* response处理函数
|
|
17
|
+
* @param response AxiosResponse实例
|
|
18
|
+
*/
|
|
19
|
+
handleResponse?: (response: AxiosResponse) => void
|
|
20
|
+
/**
|
|
21
|
+
* 错误处理函数
|
|
22
|
+
* @param msg 错误消息
|
|
23
|
+
* @param status 错误code
|
|
24
|
+
* @param error 错误实例
|
|
25
|
+
*/
|
|
26
|
+
handleError?: (msg: string, status: string | number, error: AxiosError<any>) => void
|
|
27
|
+
requestOptions?: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig | Record<string, any>
|
|
28
|
+
isCreateTokenRefresh?: boolean
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface ExpandRequestConfig extends InternalAxiosRequestConfig {
|
|
32
|
+
__requestKey?: string
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface ExpandAxiosResponse extends AxiosResponse {
|
|
36
|
+
config: ExpandRequestConfig
|
|
37
|
+
message: string
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface ExpandAxiosError<T> extends AxiosError<T> {
|
|
41
|
+
response: ExpandAxiosResponse
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface PageResult<T> {
|
|
45
|
+
data: T[],
|
|
46
|
+
total: number
|
|
47
|
+
pageIndex: number
|
|
48
|
+
pageSize: number
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface UpdateResult {
|
|
52
|
+
added: number
|
|
53
|
+
total: number
|
|
54
|
+
updated: number
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface RequestOptions {
|
|
58
|
+
url?: string
|
|
59
|
+
method?: string
|
|
60
|
+
params?: any
|
|
61
|
+
data?: any
|
|
62
|
+
[key: string]: any
|
|
63
|
+
}
|