@nanawan/axle 1.0.3 → 1.0.4
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/api.d.mts +27 -0
- package/dist/api.mjs +46 -0
- package/dist/index.d.mts +91 -0
- package/dist/index.mjs +324 -0
- package/dist/instance-9YUALwMk.d.mts +64 -0
- package/dist/use.d.mts +85 -0
- package/dist/use.mjs +229 -0
- package/package.json +2 -2
package/dist/api.d.mts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { c as AxleRequestConfig, s as AxleInstance, y as RunnerMethod } from "./instance-9YUALwMk.mjs";
|
|
2
|
+
import { UseAxle, UseAxleInstance, UseAxleOptions, UseAxleOptionsWithRunnable, WatchOptions } from "./use.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/api.d.ts
|
|
5
|
+
type ApiPathParams = Record<string, any> | (() => Record<string, any>);
|
|
6
|
+
type ApiWatchOptions = WatchOptions & {
|
|
7
|
+
pathParams?: boolean;
|
|
8
|
+
};
|
|
9
|
+
type ApiUseOptions<V, R, P, D> = Partial<UseAxleOptions<V, R, P, D>> & {
|
|
10
|
+
pathParams?: ApiPathParams;
|
|
11
|
+
watch?: ApiWatchOptions;
|
|
12
|
+
};
|
|
13
|
+
type ApiUseOptionsWithRunnable<V, R, P, D> = Partial<Omit<UseAxleOptionsWithRunnable<V, R, P, D>, 'runnable'>> & Pick<UseAxleOptionsWithRunnable<V, R, P, D>, 'runnable'> & {
|
|
14
|
+
pathParams?: ApiPathParams;
|
|
15
|
+
watch?: ApiWatchOptions;
|
|
16
|
+
};
|
|
17
|
+
declare function createApi(axle: AxleInstance, useAxle: UseAxle): <R = any, P = Record<string, any>, D = Record<string, any>>(url: string, method: RunnerMethod) => {
|
|
18
|
+
url: string;
|
|
19
|
+
load: (params?: P | undefined, pathParams?: ApiPathParams, config?: AxleRequestConfig<D, Record<string, any>> | undefined) => Promise<R>;
|
|
20
|
+
use: {
|
|
21
|
+
<V = R>(options?: ApiUseOptionsWithRunnable<V, R, P, D> | undefined): UseAxleInstance<V, R | undefined, P, D>;
|
|
22
|
+
<V_1 = R>(options?: ApiUseOptions<V_1, R, P, D> | undefined): UseAxleInstance<V_1, R, P, D>;
|
|
23
|
+
};
|
|
24
|
+
patchUrl: (url: string, pathParams: ApiPathParams) => string;
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
export { ApiPathParams, ApiUseOptions, ApiUseOptionsWithRunnable, ApiWatchOptions, createApi };
|
package/dist/api.mjs
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { isFunction } from "parattail";
|
|
2
|
+
//#region src/api.ts
|
|
3
|
+
function createApi(axle, useAxle) {
|
|
4
|
+
return function api(url, method) {
|
|
5
|
+
function load(params, pathParams, config) {
|
|
6
|
+
return axle[method](patchUrl(url, pathParams ?? {}), params, config);
|
|
7
|
+
}
|
|
8
|
+
function use(options = {}) {
|
|
9
|
+
const { pathParams = {}, watch: watchOptions, ...rest } = options;
|
|
10
|
+
const enableWatchPathParams = isFunction(pathParams) && (watchOptions?.pathParams || watchOptions === true);
|
|
11
|
+
return useAxle({
|
|
12
|
+
url: () => patchUrl(url, pathParams),
|
|
13
|
+
method,
|
|
14
|
+
watch: watchOptions === true ? {
|
|
15
|
+
params: true,
|
|
16
|
+
config: true,
|
|
17
|
+
_custom: enableWatchPathParams ? pathParams : void 0
|
|
18
|
+
} : watchOptions === false ? {
|
|
19
|
+
params: false,
|
|
20
|
+
config: false
|
|
21
|
+
} : {
|
|
22
|
+
params: false,
|
|
23
|
+
config: false,
|
|
24
|
+
...watchOptions,
|
|
25
|
+
_custom: enableWatchPathParams ? pathParams : void 0
|
|
26
|
+
},
|
|
27
|
+
...rest
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
function patchUrl(url, pathParams) {
|
|
31
|
+
const params = isFunction(pathParams) ? pathParams() : pathParams;
|
|
32
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
33
|
+
url = url.replace(`:${key}`, value);
|
|
34
|
+
});
|
|
35
|
+
return url;
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
url,
|
|
39
|
+
load,
|
|
40
|
+
use,
|
|
41
|
+
patchUrl
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
export { createApi };
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { C as isAxiosError, S as createModifyRunner, _ as ResponseInterceptor, a as AxiosRequestHeaders, b as createAxle, c as AxleRequestConfig, d as HeadersDefaults, f as Interceptor, g as RequestInterceptor, h as ModifyRunner, i as AxiosRequestConfig, l as FetchMethod, m as ModifyMethod, n as AxiosInstance, o as AxiosResponse, p as InternalAxiosRequestConfig, r as AxiosInterceptorOptions, s as AxleInstance, t as AxiosError, u as FetchRunner, v as ResponseType, x as createFetchRunner, y as RunnerMethod } from "./instance-9YUALwMk.mjs";
|
|
2
|
+
import { AxiosInterceptorOptions as AxiosInterceptorOptions$1, AxiosRequestConfig as AxiosRequestConfig$1, AxiosResponse as AxiosResponse$1 } from "axios";
|
|
3
|
+
|
|
4
|
+
//#region src/matcher.d.ts
|
|
5
|
+
type MatchPattern = string | ((options: {
|
|
6
|
+
url: string;
|
|
7
|
+
method: string;
|
|
8
|
+
status?: number;
|
|
9
|
+
}) => boolean);
|
|
10
|
+
declare function matchPattern(pattern: MatchPattern, method: string, url: string, status?: number): boolean;
|
|
11
|
+
declare function createMatcher(include?: MatchPattern[], exclude?: MatchPattern[]): (method: string, url: string, status?: number) => boolean;
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/helper.d.ts
|
|
14
|
+
interface WithResponseReturn<R> {
|
|
15
|
+
response: R | undefined;
|
|
16
|
+
errorResponse: AxiosResponse$1 | undefined;
|
|
17
|
+
}
|
|
18
|
+
declare function withResponse<R>(promise: Promise<R>): Promise<WithResponseReturn<R>>;
|
|
19
|
+
declare function download(url: string | Blob, filename: string): void;
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/interceptors/requestHeadersInterceptor.d.ts
|
|
22
|
+
interface RequestHeadersInterceptorOptions {
|
|
23
|
+
headers?: Record<string, string> | (() => Record<string, string>);
|
|
24
|
+
include?: MatchPattern[];
|
|
25
|
+
exclude?: MatchPattern[];
|
|
26
|
+
axiosInterceptorOptions?: AxiosInterceptorOptions$1;
|
|
27
|
+
}
|
|
28
|
+
declare function requestHeadersInterceptor(options?: RequestHeadersInterceptorOptions): RequestInterceptor;
|
|
29
|
+
//#endregion
|
|
30
|
+
//#region src/interceptors/requestMockInterceptor.d.ts
|
|
31
|
+
type RequestMockInterceptorMapping = {
|
|
32
|
+
url: string | ((url: string) => boolean);
|
|
33
|
+
handler: (config: AxiosRequestConfig$1) => {
|
|
34
|
+
data: any;
|
|
35
|
+
status?: number;
|
|
36
|
+
statusText?: string;
|
|
37
|
+
};
|
|
38
|
+
method?: string;
|
|
39
|
+
delay?: number;
|
|
40
|
+
};
|
|
41
|
+
interface RequestMockInterceptorOptions {
|
|
42
|
+
mappings?: RequestMockInterceptorMapping[];
|
|
43
|
+
include?: MatchPattern[];
|
|
44
|
+
exclude?: MatchPattern[];
|
|
45
|
+
axiosInterceptorOptions?: AxiosInterceptorOptions$1;
|
|
46
|
+
}
|
|
47
|
+
declare function requestMockInterceptor(options?: RequestMockInterceptorOptions): RequestInterceptor;
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region src/interceptors/responseBlobInterceptor.d.ts
|
|
50
|
+
interface ResponseBlobInterceptorOptions {
|
|
51
|
+
onResponse?: (response: AxiosResponse$1<any, any>) => any;
|
|
52
|
+
include?: MatchPattern[];
|
|
53
|
+
exclude?: MatchPattern[];
|
|
54
|
+
axiosInterceptorOptions?: AxiosInterceptorOptions$1;
|
|
55
|
+
}
|
|
56
|
+
declare function responseBlobInterceptor(options?: ResponseBlobInterceptorOptions): ResponseInterceptor;
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/interceptors/responseRetryInterceptor.d.ts
|
|
59
|
+
interface ResponseRetryInterceptorOptions {
|
|
60
|
+
count?: number;
|
|
61
|
+
include?: MatchPattern[];
|
|
62
|
+
exclude?: MatchPattern[];
|
|
63
|
+
axiosInterceptorOptions?: AxiosInterceptorOptions$1;
|
|
64
|
+
}
|
|
65
|
+
declare function responseRetryInterceptor(options: ResponseRetryInterceptorOptions): ResponseInterceptor;
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region src/interceptors/responseStatusInterceptor.d.ts
|
|
68
|
+
interface ResponseStatusInterceptorOptions {
|
|
69
|
+
validStatusHandler?: Record<number | string, (response: AxiosResponse$1<any, any>) => any>;
|
|
70
|
+
invalidStatusHandler?: Record<number | string, (error: any) => any>;
|
|
71
|
+
include?: MatchPattern[];
|
|
72
|
+
exclude?: MatchPattern[];
|
|
73
|
+
axiosInterceptorOptions?: AxiosInterceptorOptions$1;
|
|
74
|
+
}
|
|
75
|
+
declare function responseStatusInterceptor(options: ResponseStatusInterceptorOptions): ResponseInterceptor;
|
|
76
|
+
//#endregion
|
|
77
|
+
//#region src/interceptors/requestMd5Interceptor.d.ts
|
|
78
|
+
type RequestMd5InterceptorMapping = {
|
|
79
|
+
url: string | ((url: string) => boolean);
|
|
80
|
+
path: string[];
|
|
81
|
+
method?: string;
|
|
82
|
+
};
|
|
83
|
+
interface RequestMd5InterceptorOptions {
|
|
84
|
+
mappings?: RequestMd5InterceptorMapping[];
|
|
85
|
+
include?: MatchPattern[];
|
|
86
|
+
exclude?: MatchPattern[];
|
|
87
|
+
axiosInterceptorOptions?: AxiosInterceptorOptions$1;
|
|
88
|
+
}
|
|
89
|
+
declare function requestMd5Interceptor(options?: RequestMd5InterceptorOptions): RequestInterceptor;
|
|
90
|
+
//#endregion
|
|
91
|
+
export { AxiosError, AxiosInstance, AxiosInterceptorOptions, AxiosRequestConfig, AxiosRequestHeaders, AxiosResponse, AxleInstance, AxleRequestConfig, FetchMethod, FetchRunner, HeadersDefaults, Interceptor, InternalAxiosRequestConfig, MatchPattern, ModifyMethod, ModifyRunner, RequestHeadersInterceptorOptions, RequestInterceptor, RequestMd5InterceptorMapping, RequestMd5InterceptorOptions, RequestMockInterceptorMapping, RequestMockInterceptorOptions, ResponseBlobInterceptorOptions, ResponseInterceptor, ResponseRetryInterceptorOptions, ResponseStatusInterceptorOptions, ResponseType, RunnerMethod, WithResponseReturn, createAxle, createFetchRunner, createMatcher, createModifyRunner, download, isAxiosError, matchPattern, requestHeadersInterceptor, requestMd5Interceptor, requestMockInterceptor, responseBlobInterceptor, responseRetryInterceptor, responseStatusInterceptor, withResponse };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
import axios, { AxiosError, AxiosError as AxiosError$1, isAxiosError, isAxiosError as isAxiosError$1, isCancel } from "axios";
|
|
2
|
+
import qs from "qs";
|
|
3
|
+
import { inBrowser, isFunction, isString } from "parattail";
|
|
4
|
+
import md5 from "crypto-js/md5.js";
|
|
5
|
+
import get from "lodash/get.js";
|
|
6
|
+
import set from "lodash/set.js";
|
|
7
|
+
//#region src/utils/index.ts
|
|
8
|
+
function isFormData(value) {
|
|
9
|
+
return typeof FormData !== "undefined" && value instanceof FormData;
|
|
10
|
+
}
|
|
11
|
+
function formDataToObject(formData) {
|
|
12
|
+
const normalizedData = {};
|
|
13
|
+
formData.forEach((value, key) => {
|
|
14
|
+
normalizedData[key] = value;
|
|
15
|
+
});
|
|
16
|
+
return normalizedData;
|
|
17
|
+
}
|
|
18
|
+
function objectToFormData(object) {
|
|
19
|
+
const formData = new FormData();
|
|
20
|
+
Object.keys(object).forEach((key) => formData.append(key, object[key]));
|
|
21
|
+
return formData;
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/instance.ts
|
|
25
|
+
function createFetchRunner(service, method, responseType) {
|
|
26
|
+
return function(url, params, config) {
|
|
27
|
+
return service[method](url, {
|
|
28
|
+
params,
|
|
29
|
+
responseType,
|
|
30
|
+
...config
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function createModifyRunner(service, method, contentType) {
|
|
35
|
+
return function(url, params, config) {
|
|
36
|
+
let normalizedParams = params ?? {};
|
|
37
|
+
if (contentType === "application/x-www-form-urlencoded") normalizedParams = qs.stringify(normalizedParams);
|
|
38
|
+
if (contentType === "multipart/form-data") normalizedParams = objectToFormData(normalizedParams);
|
|
39
|
+
return service[method](url, normalizedParams, {
|
|
40
|
+
headers: { "Content-Type": contentType },
|
|
41
|
+
...config
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function createAxle(config = {}) {
|
|
46
|
+
const service = axios.create(config);
|
|
47
|
+
function getHeaders() {
|
|
48
|
+
return service.defaults.headers.common;
|
|
49
|
+
}
|
|
50
|
+
function setHeader(key, value) {
|
|
51
|
+
service.defaults.headers.common[key] = value;
|
|
52
|
+
}
|
|
53
|
+
function removeHeader(key) {
|
|
54
|
+
if (typeof key === "string") {
|
|
55
|
+
Reflect.deleteProperty(service.defaults.headers.common, key);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
key.forEach((k) => Reflect.deleteProperty(service.defaults.headers.common, k));
|
|
59
|
+
}
|
|
60
|
+
function useRequestInterceptor(...interceptors) {
|
|
61
|
+
interceptors.forEach((interceptor) => {
|
|
62
|
+
service.interceptors.request.use(interceptor.onFulfilled, interceptor.onRejected, interceptor.options);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
function useResponseInterceptor(...interceptors) {
|
|
66
|
+
interceptors.forEach((interceptor) => {
|
|
67
|
+
service.interceptors.response.use(interceptor.onFulfilled, interceptor.onRejected, interceptor.options);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
get: createFetchRunner(service, "get", "json"),
|
|
72
|
+
getBlob: createFetchRunner(service, "get", "blob"),
|
|
73
|
+
getDocument: createFetchRunner(service, "get", "document"),
|
|
74
|
+
getArrayBuffer: createFetchRunner(service, "get", "arraybuffer"),
|
|
75
|
+
getText: createFetchRunner(service, "get", "text"),
|
|
76
|
+
getStream: createFetchRunner(service, "get", "stream"),
|
|
77
|
+
head: createFetchRunner(service, "head", "json"),
|
|
78
|
+
headBlob: createFetchRunner(service, "head", "blob"),
|
|
79
|
+
headDocument: createFetchRunner(service, "head", "document"),
|
|
80
|
+
headArrayBuffer: createFetchRunner(service, "head", "arraybuffer"),
|
|
81
|
+
headText: createFetchRunner(service, "head", "text"),
|
|
82
|
+
headStream: createFetchRunner(service, "head", "stream"),
|
|
83
|
+
options: createFetchRunner(service, "options", "json"),
|
|
84
|
+
optionsBlob: createFetchRunner(service, "options", "blob"),
|
|
85
|
+
optionsDocument: createFetchRunner(service, "options", "document"),
|
|
86
|
+
optionsArrayBuffer: createFetchRunner(service, "options", "arraybuffer"),
|
|
87
|
+
optionsText: createFetchRunner(service, "options", "text"),
|
|
88
|
+
optionsStream: createFetchRunner(service, "options", "stream"),
|
|
89
|
+
delete: createFetchRunner(service, "delete", "json"),
|
|
90
|
+
deleteBlob: createFetchRunner(service, "delete", "blob"),
|
|
91
|
+
deleteDocument: createFetchRunner(service, "delete", "document"),
|
|
92
|
+
deleteArrayBuffer: createFetchRunner(service, "delete", "arraybuffer"),
|
|
93
|
+
deleteText: createFetchRunner(service, "delete", "text"),
|
|
94
|
+
deleteStream: createFetchRunner(service, "delete", "stream"),
|
|
95
|
+
post: createModifyRunner(service, "post", "application/json"),
|
|
96
|
+
postUrlEncode: createModifyRunner(service, "post", "application/x-www-form-urlencoded"),
|
|
97
|
+
postMultipart: createModifyRunner(service, "post", "multipart/form-data"),
|
|
98
|
+
put: createModifyRunner(service, "put", "application/json"),
|
|
99
|
+
putUrlEncode: createModifyRunner(service, "put", "application/x-www-form-urlencoded"),
|
|
100
|
+
putMultipart: createModifyRunner(service, "put", "multipart/form-data"),
|
|
101
|
+
patch: createModifyRunner(service, "patch", "application/json"),
|
|
102
|
+
patchUrlEncode: createModifyRunner(service, "patch", "application/x-www-form-urlencoded"),
|
|
103
|
+
patchMultipart: createModifyRunner(service, "patch", "multipart/form-data"),
|
|
104
|
+
getHeaders,
|
|
105
|
+
setHeader,
|
|
106
|
+
removeHeader,
|
|
107
|
+
useRequestInterceptor,
|
|
108
|
+
useResponseInterceptor,
|
|
109
|
+
axios: service
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
//#endregion
|
|
113
|
+
//#region src/matcher.ts
|
|
114
|
+
function matchPattern(pattern, method, url, status) {
|
|
115
|
+
if (isFunction(pattern)) return pattern({
|
|
116
|
+
url,
|
|
117
|
+
method,
|
|
118
|
+
status
|
|
119
|
+
});
|
|
120
|
+
if (pattern.startsWith("status:")) return pattern.replace("status:", "").trim() === String(status);
|
|
121
|
+
return pattern.startsWith("method:") ? pattern.replace("method:", "").trim() === method : url === pattern;
|
|
122
|
+
}
|
|
123
|
+
function createMatcher(include, exclude) {
|
|
124
|
+
function matcher(method, url, status) {
|
|
125
|
+
if (!include && !exclude) return true;
|
|
126
|
+
if ((exclude ?? []).some((pattern) => matchPattern(pattern, method, url, status))) return false;
|
|
127
|
+
if (!include) return true;
|
|
128
|
+
return (include ?? []).some((pattern) => matchPattern(pattern, method, url, status));
|
|
129
|
+
}
|
|
130
|
+
return matcher;
|
|
131
|
+
}
|
|
132
|
+
//#endregion
|
|
133
|
+
//#region src/helper.ts
|
|
134
|
+
function withResponse(promise) {
|
|
135
|
+
return new Promise((resolve, reject) => {
|
|
136
|
+
promise.then((response) => {
|
|
137
|
+
resolve({
|
|
138
|
+
response,
|
|
139
|
+
errorResponse: void 0
|
|
140
|
+
});
|
|
141
|
+
}).catch((error) => {
|
|
142
|
+
if (isAxiosError$1(error)) resolve({
|
|
143
|
+
response: void 0,
|
|
144
|
+
errorResponse: error.response
|
|
145
|
+
});
|
|
146
|
+
else reject(error);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
function download(url, filename) {
|
|
151
|
+
if (!inBrowser()) return;
|
|
152
|
+
const a = document.createElement("a");
|
|
153
|
+
a.download = filename;
|
|
154
|
+
a.style.display = "none";
|
|
155
|
+
a.href = typeof url === "string" ? url : URL.createObjectURL(url);
|
|
156
|
+
document.body.appendChild(a);
|
|
157
|
+
a.click();
|
|
158
|
+
URL.revokeObjectURL(a.href);
|
|
159
|
+
document.body.removeChild(a);
|
|
160
|
+
}
|
|
161
|
+
//#endregion
|
|
162
|
+
//#region src/interceptors/requestHeadersInterceptor.ts
|
|
163
|
+
function requestHeadersInterceptor(options = {}) {
|
|
164
|
+
const { headers: headersOrGetter } = options;
|
|
165
|
+
return {
|
|
166
|
+
onFulfilled(config) {
|
|
167
|
+
if (!createMatcher(options.include, options.exclude)(config.method ?? "", config.url ?? "")) return config;
|
|
168
|
+
const headers = (isFunction(headersOrGetter) ? headersOrGetter() : headersOrGetter) ?? {};
|
|
169
|
+
Object.entries(headers).forEach(([key, value]) => {
|
|
170
|
+
config.headers[key] = value;
|
|
171
|
+
});
|
|
172
|
+
return config;
|
|
173
|
+
},
|
|
174
|
+
onRejected: (error) => Promise.reject(error),
|
|
175
|
+
options: options.axiosInterceptorOptions
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
//#endregion
|
|
179
|
+
//#region src/interceptors/requestMockInterceptor.ts
|
|
180
|
+
function settle(response, resolve, reject, delay = 0) {
|
|
181
|
+
if (delay > 0) {
|
|
182
|
+
setTimeout(() => {
|
|
183
|
+
settle(response, resolve, reject);
|
|
184
|
+
}, delay);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
if (!response.config.validateStatus || response.config.validateStatus(response.status)) resolve(response);
|
|
188
|
+
else reject(new AxiosError$1(`Request failed with status code ${response.status}`, void 0, response.config, response));
|
|
189
|
+
}
|
|
190
|
+
function requestMockInterceptor(options = {}) {
|
|
191
|
+
return {
|
|
192
|
+
onFulfilled(config) {
|
|
193
|
+
if (!createMatcher(options.include, options.exclude)(config.method ?? "", config.url ?? "")) return config;
|
|
194
|
+
const findMapping = () => (options.mappings ?? []).find((mapping) => {
|
|
195
|
+
const isMatchUrl = isFunction(mapping.url) ? mapping.url(config.url ?? "") : mapping.url === (config.url ?? "");
|
|
196
|
+
const isMatchMethod = mapping.method != null ? config.method === mapping.method : true;
|
|
197
|
+
return isMatchUrl && isMatchMethod;
|
|
198
|
+
});
|
|
199
|
+
const mapping = findMapping();
|
|
200
|
+
if (!mapping) return config;
|
|
201
|
+
config.adapter = () => {
|
|
202
|
+
const partialResponse = mapping.handler(config);
|
|
203
|
+
const response = {
|
|
204
|
+
...partialResponse,
|
|
205
|
+
headers: config.headers,
|
|
206
|
+
config,
|
|
207
|
+
request: {},
|
|
208
|
+
data: partialResponse.data,
|
|
209
|
+
status: partialResponse.status ?? 200,
|
|
210
|
+
statusText: partialResponse.statusText ?? "OK"
|
|
211
|
+
};
|
|
212
|
+
return new Promise((resolve, reject) => {
|
|
213
|
+
settle(response, resolve, reject, mapping.delay);
|
|
214
|
+
});
|
|
215
|
+
};
|
|
216
|
+
return config;
|
|
217
|
+
},
|
|
218
|
+
onRejected: (error) => Promise.reject(error),
|
|
219
|
+
options: options.axiosInterceptorOptions
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
//#endregion
|
|
223
|
+
//#region src/interceptors/responseBlobInterceptor.ts
|
|
224
|
+
function responseBlobInterceptor(options = {}) {
|
|
225
|
+
return {
|
|
226
|
+
onFulfilled(response) {
|
|
227
|
+
if (!createMatcher(options.include, options.exclude)(response.config.method ?? "", response.config.url ?? "", response.status)) return response;
|
|
228
|
+
if (response.request.responseType === "blob") return options.onResponse?.(response) ?? response;
|
|
229
|
+
return response;
|
|
230
|
+
},
|
|
231
|
+
onRejected: (error) => Promise.reject(error),
|
|
232
|
+
options: options.axiosInterceptorOptions
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
//#endregion
|
|
236
|
+
//#region src/interceptors/responseRetryInterceptor.ts
|
|
237
|
+
function responseRetryInterceptor(options) {
|
|
238
|
+
return {
|
|
239
|
+
onFulfilled: (response) => response,
|
|
240
|
+
onRejected(error) {
|
|
241
|
+
if (!createMatcher(options.include, options.exclude)(error.config.method ?? "", error.config.url ?? "", error?.response?.status) || isCancel(error)) return Promise.reject(error);
|
|
242
|
+
const { count = 1 } = options;
|
|
243
|
+
let retryCount = 0;
|
|
244
|
+
async function retry() {
|
|
245
|
+
try {
|
|
246
|
+
retryCount++;
|
|
247
|
+
return await axios.create()(error.config);
|
|
248
|
+
} catch (error) {
|
|
249
|
+
if (retryCount === count) return Promise.reject(error);
|
|
250
|
+
return retry();
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return retry();
|
|
254
|
+
},
|
|
255
|
+
options: options.axiosInterceptorOptions
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
//#endregion
|
|
259
|
+
//#region src/interceptors/responseStatusInterceptor.ts
|
|
260
|
+
function responseStatusInterceptor(options) {
|
|
261
|
+
return {
|
|
262
|
+
onFulfilled: (response) => {
|
|
263
|
+
if (!createMatcher(options.include, options.exclude)(response.config.method ?? "", response.config.url ?? "", response.status)) return response;
|
|
264
|
+
const handler = (options.validStatusHandler ?? {})[response.status];
|
|
265
|
+
if (!handler) return response;
|
|
266
|
+
return handler(response) ?? response;
|
|
267
|
+
},
|
|
268
|
+
onRejected: (error) => {
|
|
269
|
+
if (!createMatcher(options.include, options.exclude)(error.config.method ?? "", error.config.url ?? "", error?.response?.status)) return Promise.reject(error);
|
|
270
|
+
const handler = (options.invalidStatusHandler ?? {})[error.response.status];
|
|
271
|
+
if (!handler) return Promise.reject(error);
|
|
272
|
+
return handler(error) ?? Promise.reject(error);
|
|
273
|
+
},
|
|
274
|
+
options: options.axiosInterceptorOptions
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
//#endregion
|
|
278
|
+
//#region src/interceptors/requestMd5Interceptor.ts
|
|
279
|
+
function withCtxMd5(ctx, mapping) {
|
|
280
|
+
mapping.path.forEach((path) => {
|
|
281
|
+
const targetValue = get(ctx, path);
|
|
282
|
+
if (targetValue != null) set(ctx, path, md5(String(targetValue)).toString());
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
function withMd5(config, mapping) {
|
|
286
|
+
const { data = {}, params = {}, headers = {} } = config;
|
|
287
|
+
const ctx = {
|
|
288
|
+
data: isFormData(data) ? data : JSON.parse(JSON.stringify(data)),
|
|
289
|
+
params: JSON.parse(JSON.stringify(params)),
|
|
290
|
+
headers: JSON.parse(JSON.stringify(headers))
|
|
291
|
+
};
|
|
292
|
+
if (isString(ctx.data) && ctx.data.length > 0 && ctx.headers["Content-Type"] === "application/x-www-form-urlencoded") {
|
|
293
|
+
ctx.data = qs.parse(ctx.data);
|
|
294
|
+
withCtxMd5(ctx, mapping);
|
|
295
|
+
ctx.data = qs.stringify(ctx.data);
|
|
296
|
+
} else if (isFormData(ctx.data)) {
|
|
297
|
+
ctx.data = formDataToObject(ctx.data);
|
|
298
|
+
withCtxMd5(ctx, mapping);
|
|
299
|
+
ctx.data = objectToFormData(ctx.data);
|
|
300
|
+
} else withCtxMd5(ctx, mapping);
|
|
301
|
+
return {
|
|
302
|
+
...config,
|
|
303
|
+
...ctx
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
function requestMd5Interceptor(options = {}) {
|
|
307
|
+
return {
|
|
308
|
+
onFulfilled(config) {
|
|
309
|
+
if (!createMatcher(options.include, options.exclude)(config.method ?? "", config.url ?? "")) return config;
|
|
310
|
+
const findMapping = () => (options.mappings ?? []).find((mapping) => {
|
|
311
|
+
const isMatchUrl = isFunction(mapping.url) ? mapping.url(config.url ?? "") : mapping.url === (config.url ?? "");
|
|
312
|
+
const isMatchMethod = mapping.method != null ? config.method === mapping.method : true;
|
|
313
|
+
return isMatchUrl && isMatchMethod;
|
|
314
|
+
});
|
|
315
|
+
const mapping = findMapping();
|
|
316
|
+
if (!mapping) return config;
|
|
317
|
+
return withMd5(config, mapping);
|
|
318
|
+
},
|
|
319
|
+
onRejected: (error) => Promise.reject(error),
|
|
320
|
+
options: options.axiosInterceptorOptions
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
//#endregion
|
|
324
|
+
export { AxiosError, createAxle, createFetchRunner, createMatcher, createModifyRunner, download, isAxiosError, matchPattern, requestHeadersInterceptor, requestMd5Interceptor, requestMockInterceptor, responseBlobInterceptor, responseRetryInterceptor, responseStatusInterceptor, withResponse };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { AxiosError as AxiosError$1, AxiosInstance, AxiosInterceptorOptions as AxiosInterceptorOptions$1, AxiosRequestConfig as AxiosRequestConfig$1, AxiosRequestHeaders, AxiosResponse as AxiosResponse$1, HeadersDefaults, InternalAxiosRequestConfig, ResponseType, isAxiosError as isAxiosError$1 } from "axios";
|
|
2
|
+
|
|
3
|
+
//#region src/instance.d.ts
|
|
4
|
+
interface AxleRequestConfig<D = any, E = Record<string, any>> extends AxiosRequestConfig$1<D> {
|
|
5
|
+
extra?: E;
|
|
6
|
+
}
|
|
7
|
+
type FetchRunner = <R = AxiosResponse$1, P = Record<string, any>, D = Record<string, any>>(url: string, params?: P, config?: AxleRequestConfig<D>) => Promise<R>;
|
|
8
|
+
type ModifyRunner = <R = AxiosResponse$1, P = Record<string, any>, D = Record<string, any>>(url: string, params?: P, config?: AxleRequestConfig<D>) => Promise<R>;
|
|
9
|
+
type FetchMethod = 'get' | 'delete' | 'options' | 'head';
|
|
10
|
+
type ModifyMethod = 'post' | 'put' | 'patch';
|
|
11
|
+
type RunnerMethod = keyof Omit<AxleInstance, 'axios' | 'getHeaders' | 'setHeader' | 'removeHeader' | 'useRequestInterceptor' | 'useResponseInterceptor'>;
|
|
12
|
+
interface Interceptor<V> {
|
|
13
|
+
onFulfilled?: ((value: V) => any) | null;
|
|
14
|
+
onRejected?: ((error: any) => any) | null;
|
|
15
|
+
options?: AxiosInterceptorOptions$1;
|
|
16
|
+
}
|
|
17
|
+
type RequestInterceptor = Interceptor<InternalAxiosRequestConfig>;
|
|
18
|
+
type ResponseInterceptor<V = AxiosResponse$1<any, any>> = Interceptor<V>;
|
|
19
|
+
type AxleInstance = {
|
|
20
|
+
get: FetchRunner;
|
|
21
|
+
getBlob: FetchRunner;
|
|
22
|
+
getDocument: FetchRunner;
|
|
23
|
+
getText: FetchRunner;
|
|
24
|
+
getArrayBuffer: FetchRunner;
|
|
25
|
+
getStream: FetchRunner;
|
|
26
|
+
head: FetchRunner;
|
|
27
|
+
headBlob: FetchRunner;
|
|
28
|
+
headDocument: FetchRunner;
|
|
29
|
+
headText: FetchRunner;
|
|
30
|
+
headArrayBuffer: FetchRunner;
|
|
31
|
+
headStream: FetchRunner;
|
|
32
|
+
options: FetchRunner;
|
|
33
|
+
optionsBlob: FetchRunner;
|
|
34
|
+
optionsDocument: FetchRunner;
|
|
35
|
+
optionsText: FetchRunner;
|
|
36
|
+
optionsArrayBuffer: FetchRunner;
|
|
37
|
+
optionsStream: FetchRunner;
|
|
38
|
+
delete: FetchRunner;
|
|
39
|
+
deleteBlob: FetchRunner;
|
|
40
|
+
deleteDocument: FetchRunner;
|
|
41
|
+
deleteText: FetchRunner;
|
|
42
|
+
deleteArrayBuffer: FetchRunner;
|
|
43
|
+
deleteStream: FetchRunner;
|
|
44
|
+
post: ModifyRunner;
|
|
45
|
+
postUrlEncode: ModifyRunner;
|
|
46
|
+
postMultipart: ModifyRunner;
|
|
47
|
+
put: ModifyRunner;
|
|
48
|
+
putUrlEncode: ModifyRunner;
|
|
49
|
+
putMultipart: ModifyRunner;
|
|
50
|
+
patch: ModifyRunner;
|
|
51
|
+
patchUrlEncode: ModifyRunner;
|
|
52
|
+
patchMultipart: ModifyRunner;
|
|
53
|
+
getHeaders(): HeadersDefaults['common'];
|
|
54
|
+
setHeader(key: string, value: string): void;
|
|
55
|
+
removeHeader(key: string | string[]): void;
|
|
56
|
+
useRequestInterceptor(...interceptors: RequestInterceptor[]): void;
|
|
57
|
+
useResponseInterceptor(...interceptors: ResponseInterceptor[]): void;
|
|
58
|
+
axios: AxiosInstance;
|
|
59
|
+
};
|
|
60
|
+
declare function createFetchRunner(service: AxiosInstance, method: FetchMethod, responseType: ResponseType): <R = AxiosResponse$1<any, any, {}>, P = Record<string, any>, D = Record<string, any>>(url: string, params?: P | undefined, config?: AxleRequestConfig<D, Record<string, any>> | undefined) => Promise<R>;
|
|
61
|
+
declare function createModifyRunner(service: AxiosInstance, method: ModifyMethod, contentType: 'application/json' | 'multipart/form-data' | 'application/x-www-form-urlencoded'): <R = AxiosResponse$1<any, any, {}>, P = Record<string, any>, D = Record<string, any>>(url: string, params?: P | undefined, config?: AxleRequestConfig<D, Record<string, any>> | undefined) => Promise<R>;
|
|
62
|
+
declare function createAxle(config?: AxleRequestConfig): AxleInstance;
|
|
63
|
+
//#endregion
|
|
64
|
+
export { isAxiosError$1 as C, createModifyRunner as S, ResponseInterceptor as _, AxiosRequestHeaders as a, createAxle as b, AxleRequestConfig as c, HeadersDefaults as d, Interceptor as f, RequestInterceptor as g, ModifyRunner as h, AxiosRequestConfig$1 as i, FetchMethod as l, ModifyMethod as m, AxiosInstance as n, AxiosResponse$1 as o, InternalAxiosRequestConfig as p, AxiosInterceptorOptions$1 as r, AxleInstance as s, AxiosError$1 as t, FetchRunner as u, ResponseType as v, createFetchRunner as x, RunnerMethod as y };
|
package/dist/use.d.mts
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { c as AxleRequestConfig, s as AxleInstance, y as RunnerMethod } from "./instance-9YUALwMk.mjs";
|
|
2
|
+
import { Ref } from "vue";
|
|
3
|
+
|
|
4
|
+
//#region src/use.d.ts
|
|
5
|
+
type Runnable = () => boolean;
|
|
6
|
+
interface RunOptions<V, P, D> {
|
|
7
|
+
url?: string;
|
|
8
|
+
params?: P;
|
|
9
|
+
config?: AxleRequestConfig<D>;
|
|
10
|
+
resetValue?: boolean;
|
|
11
|
+
cloneResetValue?: boolean | ((value: V) => V);
|
|
12
|
+
}
|
|
13
|
+
type UseAxleExtra<V> = {
|
|
14
|
+
loading: Ref<boolean>;
|
|
15
|
+
error: Ref<Error | undefined>;
|
|
16
|
+
uploadProgress: Ref<number>;
|
|
17
|
+
downloadProgress: Ref<number>;
|
|
18
|
+
pollingCanceled: Ref<boolean>;
|
|
19
|
+
abort(): void;
|
|
20
|
+
resetValue(options?: ResetValueOptions<V>): void;
|
|
21
|
+
invalidateCache(): void;
|
|
22
|
+
cancelPolling(): void;
|
|
23
|
+
};
|
|
24
|
+
interface UseAxleRefs<V> {
|
|
25
|
+
value: Ref<V>;
|
|
26
|
+
loading: Ref<boolean>;
|
|
27
|
+
error: Ref<Error | undefined>;
|
|
28
|
+
uploadProgress: Ref<number>;
|
|
29
|
+
downloadProgress: Ref<number>;
|
|
30
|
+
pollingCanceled: Ref<boolean>;
|
|
31
|
+
}
|
|
32
|
+
type Run<V, R, P, D> = {
|
|
33
|
+
(options?: RunOptions<V, P, D>): Promise<R>;
|
|
34
|
+
} & UseAxleExtra<V>;
|
|
35
|
+
type WatchOptions = boolean | {
|
|
36
|
+
params?: boolean;
|
|
37
|
+
config?: boolean;
|
|
38
|
+
_custom?: () => any;
|
|
39
|
+
};
|
|
40
|
+
interface UseAxleOptions<V = any, R = any, P = Record<string, any>, D = Record<string, any>> {
|
|
41
|
+
url: string | (() => string);
|
|
42
|
+
method: RunnerMethod;
|
|
43
|
+
value?: V;
|
|
44
|
+
immediate?: boolean;
|
|
45
|
+
resetValue?: boolean;
|
|
46
|
+
cloneResetValue?: boolean | ((value: V) => V);
|
|
47
|
+
abortOnUnmount?: boolean;
|
|
48
|
+
cacheKey?: string | (() => string);
|
|
49
|
+
cacheTime?: number;
|
|
50
|
+
config?: AxleRequestConfig<D> | (() => AxleRequestConfig<D>);
|
|
51
|
+
watch?: WatchOptions;
|
|
52
|
+
pollingInterval?: number;
|
|
53
|
+
pollingOnHidden?: boolean;
|
|
54
|
+
pollingOnDeactivated?: boolean;
|
|
55
|
+
refreshOnWindowFocus?: boolean;
|
|
56
|
+
params?: P | (() => P);
|
|
57
|
+
onBefore?(refs: UseAxleRefs<V>): void;
|
|
58
|
+
onAfter?(refs: UseAxleRefs<V>): void;
|
|
59
|
+
onTransform?(response: R, refs: UseAxleRefs<V>): V | Promise<V>;
|
|
60
|
+
onSuccess?(response: R, refs: UseAxleRefs<V>): void;
|
|
61
|
+
onError?(error: Error, refs: UseAxleRefs<V>): void;
|
|
62
|
+
}
|
|
63
|
+
interface ResetValueOptions<V> {
|
|
64
|
+
cloneResetValue?: boolean | ((value: V) => V);
|
|
65
|
+
}
|
|
66
|
+
type UseAxleInstance<V, R, P, D> = [value: Ref<V>, run: Run<V, R, P, D>, extra: UseAxleExtra<V>];
|
|
67
|
+
interface CreateUseAxleOptions {
|
|
68
|
+
axle: AxleInstance;
|
|
69
|
+
immediate?: boolean;
|
|
70
|
+
abortOnUnmount?: boolean;
|
|
71
|
+
cacheTime?: number;
|
|
72
|
+
onTransform?(response: any, refs: any): any;
|
|
73
|
+
}
|
|
74
|
+
type UseAxleOptionsWithRunnable<V = any, R = any, P = Record<string, any>, D = Record<string, any>> = UseAxleOptions<V, R, P, D> & {
|
|
75
|
+
runnable: Runnable;
|
|
76
|
+
};
|
|
77
|
+
interface UseAxle {
|
|
78
|
+
<V = any, R = any, P = Record<string, any>, D = Record<string, any>>(options: UseAxleOptionsWithRunnable<V, R, P, D>): UseAxleInstance<V, R | undefined, P, D>;
|
|
79
|
+
<V = any, R = any, P = Record<string, any>, D = Record<string, any>>(options: UseAxleOptions<V, R, P, D>): UseAxleInstance<V, R, P, D>;
|
|
80
|
+
}
|
|
81
|
+
declare function normalizeValueGetter<T>(valueGetter: T | (() => T)): T;
|
|
82
|
+
declare function cleanupCacheBuffer(): void;
|
|
83
|
+
declare function createUseAxle(options: CreateUseAxleOptions): UseAxle;
|
|
84
|
+
//#endregion
|
|
85
|
+
export { CreateUseAxleOptions, ResetValueOptions, Run, RunOptions, Runnable, UseAxle, UseAxleExtra, UseAxleInstance, UseAxleOptions, UseAxleOptionsWithRunnable, UseAxleRefs, WatchOptions, cleanupCacheBuffer, createUseAxle, normalizeValueGetter };
|
package/dist/use.mjs
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { isFunction } from "parattail";
|
|
2
|
+
import { getCurrentInstance, onActivated, onDeactivated, onMounted, onUnmounted, ref, watch } from "vue";
|
|
3
|
+
//#region src/use.ts
|
|
4
|
+
function normalizeValueGetter(valueGetter) {
|
|
5
|
+
return isFunction(valueGetter) ? valueGetter() : valueGetter;
|
|
6
|
+
}
|
|
7
|
+
const cacheBuffer = /* @__PURE__ */ new Map();
|
|
8
|
+
function cleanupCacheBuffer() {
|
|
9
|
+
cacheBuffer.forEach((value, key) => {
|
|
10
|
+
if (value.expiredTime && Date.now() >= value.expiredTime) cacheBuffer.delete(key);
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
function createUseAxle(options) {
|
|
14
|
+
const { axle, onTransform: defaultOnTransform, immediate: defaultImmediate = true, abortOnUnmount: defaultAbortOnUnmount = true, cacheTime: defaultCacheTime = Infinity } = options;
|
|
15
|
+
const useAxle = (options) => {
|
|
16
|
+
const { url: initialUrlOrGetter, method, immediate = defaultImmediate, abortOnUnmount = defaultAbortOnUnmount, cacheTime = defaultCacheTime, cacheKey, pollingInterval, pollingOnHidden = true, pollingOnDeactivated = false, refreshOnWindowFocus = false, value: initialValue, resetValue: initialResetValue, cloneResetValue: initialCloneResetValue, params: initialParamsOrGetter, config: initialConfigOrGetter, watch: watchOptions, runnable = () => true, onBefore = () => {}, onAfter = () => {}, onTransform = defaultOnTransform ?? ((response) => response), onSuccess = () => {}, onError = () => {} } = options;
|
|
17
|
+
const value = ref(initialValue);
|
|
18
|
+
const loading = ref(false);
|
|
19
|
+
const error = ref();
|
|
20
|
+
const downloadProgress = ref(0);
|
|
21
|
+
const uploadProgress = ref(0);
|
|
22
|
+
const pollingCanceled = ref(false);
|
|
23
|
+
const refs = {
|
|
24
|
+
value,
|
|
25
|
+
loading,
|
|
26
|
+
error,
|
|
27
|
+
downloadProgress,
|
|
28
|
+
uploadProgress,
|
|
29
|
+
pollingCanceled
|
|
30
|
+
};
|
|
31
|
+
const extra = {
|
|
32
|
+
uploadProgress,
|
|
33
|
+
downloadProgress,
|
|
34
|
+
loading,
|
|
35
|
+
error,
|
|
36
|
+
pollingCanceled,
|
|
37
|
+
abort,
|
|
38
|
+
resetValue,
|
|
39
|
+
invalidateCache,
|
|
40
|
+
cancelPolling
|
|
41
|
+
};
|
|
42
|
+
let controller = new AbortController();
|
|
43
|
+
let pollingTimer = null;
|
|
44
|
+
let deactivated = false;
|
|
45
|
+
let hidden = false;
|
|
46
|
+
let unmounted = false;
|
|
47
|
+
const run = Object.assign(async (options = {}) => {
|
|
48
|
+
if (!runnable() || abortOnUnmount && unmounted) return;
|
|
49
|
+
pollingCanceled.value = false;
|
|
50
|
+
if (controller.signal.aborted) controller = new AbortController();
|
|
51
|
+
if ((options.resetValue ?? initialResetValue ?? false) === true) resetValue(options);
|
|
52
|
+
uploadProgress.value = 0;
|
|
53
|
+
downloadProgress.value = 0;
|
|
54
|
+
const url = options.url ?? normalizeValueGetter(initialUrlOrGetter);
|
|
55
|
+
const params = options.params ?? normalizeValueGetter(initialParamsOrGetter);
|
|
56
|
+
const config = options.config ?? normalizeValueGetter(initialConfigOrGetter);
|
|
57
|
+
const normalizedCacheKey = cacheKey ? normalizeValueGetter(cacheKey) : void 0;
|
|
58
|
+
onBefore(refs);
|
|
59
|
+
loading.value = true;
|
|
60
|
+
try {
|
|
61
|
+
cleanupCacheBuffer();
|
|
62
|
+
const response = await getResponse();
|
|
63
|
+
if (shouldSetCacheResponse(normalizedCacheKey)) {
|
|
64
|
+
const cache = cacheBuffer.get(normalizedCacheKey);
|
|
65
|
+
cache.response = response;
|
|
66
|
+
cache.expiredTime = Date.now() + cacheTime;
|
|
67
|
+
}
|
|
68
|
+
value.value = await onTransform(response, refs);
|
|
69
|
+
error.value = void 0;
|
|
70
|
+
onSuccess(response, refs);
|
|
71
|
+
loading.value = false;
|
|
72
|
+
onAfter(refs);
|
|
73
|
+
return response;
|
|
74
|
+
} catch (responseError) {
|
|
75
|
+
error.value = responseError;
|
|
76
|
+
onError(responseError, refs);
|
|
77
|
+
loading.value = false;
|
|
78
|
+
onAfter(refs);
|
|
79
|
+
throw responseError;
|
|
80
|
+
} finally {
|
|
81
|
+
clearPolling();
|
|
82
|
+
startPolling();
|
|
83
|
+
}
|
|
84
|
+
function getResponse() {
|
|
85
|
+
if (shouldUseCache(normalizedCacheKey)) return JSON.parse(JSON.stringify(cacheBuffer.get(normalizedCacheKey).response));
|
|
86
|
+
if (shouldAwaitCachePromise(normalizedCacheKey)) return cacheBuffer.get(normalizedCacheKey).promise;
|
|
87
|
+
const promise = fetchResponse();
|
|
88
|
+
if (shouldSetCachePromise(normalizedCacheKey)) cacheBuffer.set(normalizedCacheKey, { promise });
|
|
89
|
+
return promise;
|
|
90
|
+
}
|
|
91
|
+
function fetchResponse() {
|
|
92
|
+
return axle[method](url, params, {
|
|
93
|
+
signal: controller.signal,
|
|
94
|
+
onUploadProgress(event) {
|
|
95
|
+
uploadProgress.value = event.progress ?? 0;
|
|
96
|
+
},
|
|
97
|
+
onDownloadProgress(event) {
|
|
98
|
+
downloadProgress.value = event.progress ?? 0;
|
|
99
|
+
},
|
|
100
|
+
...config
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
function shouldUseCache(key) {
|
|
104
|
+
if (!key || !cacheBuffer.has(key)) return false;
|
|
105
|
+
return cacheBuffer.get(key).response != null;
|
|
106
|
+
}
|
|
107
|
+
function shouldAwaitCachePromise(key) {
|
|
108
|
+
if (!key || !cacheBuffer.has(key)) return false;
|
|
109
|
+
return cacheBuffer.get(key).promise;
|
|
110
|
+
}
|
|
111
|
+
function shouldSetCachePromise(key) {
|
|
112
|
+
if (!key || cacheBuffer.has(key)) return false;
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
function shouldSetCacheResponse(key) {
|
|
116
|
+
if (!key || !cacheBuffer.has(key)) return false;
|
|
117
|
+
return cacheBuffer.get(key).response == null;
|
|
118
|
+
}
|
|
119
|
+
}, extra);
|
|
120
|
+
if (immediate) runWithInitialConfig();
|
|
121
|
+
if (getCurrentInstance()) {
|
|
122
|
+
onActivated(() => {
|
|
123
|
+
deactivated = false;
|
|
124
|
+
addVisibilityChangeListener();
|
|
125
|
+
addWindowFocusListener();
|
|
126
|
+
startPolling();
|
|
127
|
+
});
|
|
128
|
+
onMounted(() => {
|
|
129
|
+
addVisibilityChangeListener();
|
|
130
|
+
addWindowFocusListener();
|
|
131
|
+
});
|
|
132
|
+
onDeactivated(() => {
|
|
133
|
+
deactivated = true;
|
|
134
|
+
removeVisibilityChangeListener();
|
|
135
|
+
removeWindowFocusListener();
|
|
136
|
+
clearPolling();
|
|
137
|
+
});
|
|
138
|
+
onUnmounted(() => {
|
|
139
|
+
removeVisibilityChangeListener();
|
|
140
|
+
removeWindowFocusListener();
|
|
141
|
+
cancelPolling();
|
|
142
|
+
});
|
|
143
|
+
onUnmounted(() => {
|
|
144
|
+
unmounted = true;
|
|
145
|
+
if (abortOnUnmount) abort();
|
|
146
|
+
});
|
|
147
|
+
if (watchOptions) {
|
|
148
|
+
const normalizedWatchOptions = watchOptions === true ? {
|
|
149
|
+
params: true,
|
|
150
|
+
config: true
|
|
151
|
+
} : {
|
|
152
|
+
params: false,
|
|
153
|
+
config: false,
|
|
154
|
+
...watchOptions
|
|
155
|
+
};
|
|
156
|
+
const enableWatchParams = isFunction(initialParamsOrGetter) && normalizedWatchOptions.params;
|
|
157
|
+
const enableWatchConfig = isFunction(initialConfigOrGetter) && normalizedWatchOptions.config;
|
|
158
|
+
watch(() => [
|
|
159
|
+
enableWatchParams ? normalizeValueGetter(initialParamsOrGetter) : void 0,
|
|
160
|
+
enableWatchConfig ? normalizeValueGetter(initialConfigOrGetter) : void 0,
|
|
161
|
+
normalizedWatchOptions._custom ? normalizedWatchOptions._custom() : void 0
|
|
162
|
+
], () => {
|
|
163
|
+
runWithInitialConfig();
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function runWithInitialConfig() {
|
|
168
|
+
return run({
|
|
169
|
+
url: normalizeValueGetter(initialUrlOrGetter),
|
|
170
|
+
params: normalizeValueGetter(initialParamsOrGetter),
|
|
171
|
+
config: normalizeValueGetter(initialConfigOrGetter)
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
function resetValue(options = {}) {
|
|
175
|
+
value.value = ((options.cloneResetValue ?? initialCloneResetValue ?? false) === true ? (v) => v == null ? null : JSON.parse(JSON.stringify(v)) : isFunction(initialCloneResetValue) ? initialCloneResetValue : (v) => v)(initialValue);
|
|
176
|
+
}
|
|
177
|
+
function abort() {
|
|
178
|
+
controller.abort();
|
|
179
|
+
}
|
|
180
|
+
function addWindowFocusListener() {
|
|
181
|
+
if (typeof window !== "undefined") window.addEventListener("focus", handleWindowFocus);
|
|
182
|
+
}
|
|
183
|
+
function removeWindowFocusListener() {
|
|
184
|
+
if (typeof window !== "undefined") window.removeEventListener("focus", handleWindowFocus);
|
|
185
|
+
}
|
|
186
|
+
function handleWindowFocus() {
|
|
187
|
+
if (refreshOnWindowFocus) runWithInitialConfig();
|
|
188
|
+
}
|
|
189
|
+
function addVisibilityChangeListener() {
|
|
190
|
+
if (typeof document !== "undefined") document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
191
|
+
}
|
|
192
|
+
function removeVisibilityChangeListener() {
|
|
193
|
+
if (typeof document !== "undefined") document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
194
|
+
}
|
|
195
|
+
function handleVisibilityChange() {
|
|
196
|
+
hidden = document.visibilityState === "hidden";
|
|
197
|
+
if (pollingOnHidden) return;
|
|
198
|
+
hidden ? clearPolling() : startPolling();
|
|
199
|
+
}
|
|
200
|
+
function startPolling() {
|
|
201
|
+
if (pollingInterval == null || pollingCanceled.value || pollingTimer != null || deactivated && !pollingOnDeactivated || hidden && !pollingOnHidden) return;
|
|
202
|
+
pollingTimer = setTimeout(() => {
|
|
203
|
+
runWithInitialConfig();
|
|
204
|
+
}, pollingInterval);
|
|
205
|
+
}
|
|
206
|
+
function clearPolling() {
|
|
207
|
+
if (pollingTimer == null) return;
|
|
208
|
+
clearTimeout(pollingTimer);
|
|
209
|
+
pollingTimer = null;
|
|
210
|
+
}
|
|
211
|
+
function cancelPolling() {
|
|
212
|
+
clearPolling();
|
|
213
|
+
pollingCanceled.value = true;
|
|
214
|
+
}
|
|
215
|
+
function invalidateCache() {
|
|
216
|
+
const normalizedCacheKey = cacheKey ? normalizeValueGetter(cacheKey) : void 0;
|
|
217
|
+
if (!normalizedCacheKey || !cacheBuffer.has(normalizedCacheKey)) return;
|
|
218
|
+
cacheBuffer.delete(normalizedCacheKey);
|
|
219
|
+
}
|
|
220
|
+
return [
|
|
221
|
+
value,
|
|
222
|
+
run,
|
|
223
|
+
extra
|
|
224
|
+
];
|
|
225
|
+
};
|
|
226
|
+
return useAxle;
|
|
227
|
+
}
|
|
228
|
+
//#endregion
|
|
229
|
+
export { cleanupCacheBuffer, createUseAxle, normalizeValueGetter };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nanawan/axle",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "Progressive request tool based on axios",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"axios",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"crypto-js": "^4.2.0",
|
|
68
68
|
"lodash": "4.17.21",
|
|
69
69
|
"qs": "^6.11.0",
|
|
70
|
-
"parattail": "^2.0.
|
|
70
|
+
"parattail": "^2.0.10"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
73
|
"@types/crypto-js": "^4.2.1",
|