@solar-taro/http 1.0.0 → 1.0.1
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/api.interceptor.d.ts +9 -0
- package/api.interceptor.js +35 -0
- package/api.interceptor.js.map +1 -0
- package/auto-host.interceptor.d.ts +9 -0
- package/auto-host.interceptor.js +20 -0
- package/auto-host.interceptor.js.map +1 -0
- package/caching/cache-manager.d.ts +42 -0
- package/caching/cache-manager.js +72 -0
- package/caching/cache-manager.js.map +1 -0
- package/caching/caching.interceptor.d.ts +6 -0
- package/caching/caching.interceptor.js +46 -0
- package/caching/caching.interceptor.js.map +1 -0
- package/caching/index.js +3 -0
- package/caching/index.js.map +1 -0
- package/common.interceptor.d.ts +10 -0
- package/common.interceptor.js +35 -0
- package/common.interceptor.js.map +1 -0
- package/headers.d.ts +8 -0
- package/headers.js +2 -0
- package/headers.js.map +1 -0
- package/index.js +6 -0
- package/index.js.map +1 -0
- package/package.json +6 -2
- package/eslint.config.cjs +0 -22
- package/project.json +0 -42
- package/src/api.interceptor.ts +0 -41
- package/src/auto-host.interceptor.ts +0 -23
- package/src/caching/cache-manager.ts +0 -83
- package/src/caching/caching.interceptor.ts +0 -58
- package/src/common.interceptor.ts +0 -37
- package/src/headers.ts +0 -8
- package/tsconfig.json +0 -21
- package/tsconfig.lib.json +0 -24
- package/tsconfig.spec.json +0 -28
- package/typedoc.json +0 -6
- package/vite.config.ts +0 -24
- /package/{src/caching/index.ts → caching/index.d.ts} +0 -0
- /package/{src/index.ts → index.d.ts} +0 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { HttpContextToken, HttpInterceptorFn } from '@ngify/http';
|
|
2
|
+
/** HTTP 令牌:允许拦截器处理 `Result#code` 不为 `0` 的错误 */
|
|
3
|
+
export declare const CATCH_RESULT_ERROR_TOKEN: HttpContextToken<boolean>;
|
|
4
|
+
/**
|
|
5
|
+
* 负责业务接口的拦截
|
|
6
|
+
* - 添加 `Api` 请求头
|
|
7
|
+
* - 捕获响应异常并提示
|
|
8
|
+
*/
|
|
9
|
+
export declare function useApiInterceptor(): HttpInterceptorFn;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { HttpContextToken, HttpResponse } from '@ngify/http';
|
|
2
|
+
import { WX_REQUSET_TOKEN } from '@ngify/http-wx';
|
|
3
|
+
import { overlay } from '@solar-taro/core';
|
|
4
|
+
import { tap } from 'rxjs';
|
|
5
|
+
/** HTTP 令牌:允许拦截器处理 `Result#code` 不为 `0` 的错误 */
|
|
6
|
+
export const CATCH_RESULT_ERROR_TOKEN = new HttpContextToken(() => true);
|
|
7
|
+
/**
|
|
8
|
+
* 负责业务接口的拦截
|
|
9
|
+
* - 添加 `Api` 请求头
|
|
10
|
+
* - 捕获响应异常并提示
|
|
11
|
+
*/
|
|
12
|
+
export function useApiInterceptor() {
|
|
13
|
+
return (request, next) => {
|
|
14
|
+
request = request.clone({
|
|
15
|
+
headers: request.headers.set('Api', 'v1')
|
|
16
|
+
});
|
|
17
|
+
request.context.set(WX_REQUSET_TOKEN, {
|
|
18
|
+
...request.context.get(WX_REQUSET_TOKEN),
|
|
19
|
+
enableHttp2: true,
|
|
20
|
+
// forceCellularNetwork: true
|
|
21
|
+
});
|
|
22
|
+
return next(request).pipe(tap((event) => {
|
|
23
|
+
if (event instanceof HttpResponse) {
|
|
24
|
+
const { body } = event;
|
|
25
|
+
if ((body === null || body === void 0 ? void 0 : body.code) !== 0 && request.context.get(CATCH_RESULT_ERROR_TOKEN)) {
|
|
26
|
+
// 延迟一下,确保不会被后面的 dismiss loading 给关掉 tips
|
|
27
|
+
setTimeout(() => {
|
|
28
|
+
overlay.tips('操作失败,原因:' + ((body === null || body === void 0 ? void 0 : body.msg) || '未知错误'));
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}));
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=api.interceptor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.interceptor.js","sourceRoot":"","sources":["../../../packages/http/src/api.interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAA4D,YAAY,EAAE,MAAM,aAAa,CAAC;AACvH,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAc,GAAG,EAAE,MAAM,MAAM,CAAC;AAEvC,+CAA+C;AAC/C,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,gBAAgB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;AAEzE;;;;GAIG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,CAAC,OAA6B,EAAE,IAAmB,EAAkC,EAAE;QAC5F,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC;YACtB,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC;SAC1C,CAAC,CAAC;QAEH,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE;YACpC,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;YACxC,WAAW,EAAE,IAAI;YACjB,6BAA6B;SAC9B,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CACvB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YACZ,IAAI,KAAK,YAAY,YAAY,EAAE,CAAC;gBAClC,MAAM,EAAE,IAAI,EAAE,GAAG,KAA6B,CAAC;gBAC/C,IAAI,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,IAAI,MAAK,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,EAAE,CAAC;oBACtE,yCAAyC;oBACzC,UAAU,CAAC,GAAG,EAAE;wBACd,OAAO,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,GAAG,KAAI,MAAM,CAAC,CAAC,CAAC;oBACnD,CAAC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CACH,CAAC;IACJ,CAAC,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { HttpContextToken, HttpInterceptorFn } from '@ngify/http';
|
|
2
|
+
export declare const AUTO_HOST_TOEKN: HttpContextToken<boolean>;
|
|
3
|
+
/**
|
|
4
|
+
* 自动为 / 开头的 URL 添加 host
|
|
5
|
+
* 可以使用 {@link AUTO_HOST_TOEKN} 来跳过该拦截器
|
|
6
|
+
* @param host
|
|
7
|
+
* @returns
|
|
8
|
+
*/
|
|
9
|
+
export declare function useAutoHostInterceptor(host: string): HttpInterceptorFn;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { HttpContextToken } from '@ngify/http';
|
|
2
|
+
export const AUTO_HOST_TOEKN = new HttpContextToken(() => true);
|
|
3
|
+
/**
|
|
4
|
+
* 自动为 / 开头的 URL 添加 host
|
|
5
|
+
* 可以使用 {@link AUTO_HOST_TOEKN} 来跳过该拦截器
|
|
6
|
+
* @param host
|
|
7
|
+
* @returns
|
|
8
|
+
*/
|
|
9
|
+
export function useAutoHostInterceptor(host) {
|
|
10
|
+
return (request, next) => {
|
|
11
|
+
if (request.context.get(AUTO_HOST_TOEKN) &&
|
|
12
|
+
request.url.startsWith('/')) {
|
|
13
|
+
return next(request.clone({
|
|
14
|
+
url: host + request.url
|
|
15
|
+
}));
|
|
16
|
+
}
|
|
17
|
+
return next(request);
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=auto-host.interceptor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-host.interceptor.js","sourceRoot":"","sources":["../../../packages/http/src/auto-host.interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAqB,MAAM,aAAa,CAAC;AAElE,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,gBAAgB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;AAEhE;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;QACvB,IACE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAC3B,CAAC;YACD,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;gBACxB,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC,GAAG;aACxB,CAAC,CAAC,CAAC;QACN,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { HttpContextToken, HttpRequest, HttpResponse } from '@ngify/http';
|
|
2
|
+
/**
|
|
3
|
+
* 缓存令牌,值可以为:
|
|
4
|
+
* - 布尔值,为 true 时,表示在一次会话中缓存永不过期,默认值为 false
|
|
5
|
+
* - 缓存时间,单位毫秒
|
|
6
|
+
*/
|
|
7
|
+
export declare const CACHEABLE_TOKEN: HttpContextToken<number | boolean>;
|
|
8
|
+
/** 缓存条目 */
|
|
9
|
+
export interface CacheEntry {
|
|
10
|
+
url: string;
|
|
11
|
+
response: HttpResponse<unknown>;
|
|
12
|
+
expire: number;
|
|
13
|
+
}
|
|
14
|
+
export declare class CacheManager {
|
|
15
|
+
private readonly cacheMap;
|
|
16
|
+
/**
|
|
17
|
+
* 获取缓存
|
|
18
|
+
* @param request
|
|
19
|
+
*/
|
|
20
|
+
get(request: HttpRequest<unknown>): HttpResponse<unknown> | null;
|
|
21
|
+
/**
|
|
22
|
+
* 缓存
|
|
23
|
+
* @param request
|
|
24
|
+
* @param response
|
|
25
|
+
*/
|
|
26
|
+
put(request: HttpRequest<unknown>, response: HttpResponse<unknown>): void;
|
|
27
|
+
/**
|
|
28
|
+
* 清扫过期缓存
|
|
29
|
+
*/
|
|
30
|
+
clear(): void;
|
|
31
|
+
/**
|
|
32
|
+
* 通过标记(字符串、正则)模糊查询以撤销缓存
|
|
33
|
+
* @param mark
|
|
34
|
+
* @param once 只撤销一个
|
|
35
|
+
*/
|
|
36
|
+
revoke(mark: string | RegExp, once?: boolean): void;
|
|
37
|
+
/**
|
|
38
|
+
* 撤销所有缓存
|
|
39
|
+
*/
|
|
40
|
+
revokeAll(): void;
|
|
41
|
+
}
|
|
42
|
+
export declare const cacheManager: CacheManager;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { HttpContextToken } from '@ngify/http';
|
|
2
|
+
/**
|
|
3
|
+
* 缓存令牌,值可以为:
|
|
4
|
+
* - 布尔值,为 true 时,表示在一次会话中缓存永不过期,默认值为 false
|
|
5
|
+
* - 缓存时间,单位毫秒
|
|
6
|
+
*/
|
|
7
|
+
export const CACHEABLE_TOKEN = new HttpContextToken(() => false);
|
|
8
|
+
export class CacheManager {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.cacheMap = new Map();
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 获取缓存
|
|
14
|
+
* @param request
|
|
15
|
+
*/
|
|
16
|
+
get(request) {
|
|
17
|
+
// 判断当前请求是否已被缓存,若未缓存则返回null
|
|
18
|
+
const entry = this.cacheMap.get(request.urlWithParams);
|
|
19
|
+
if (!entry) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
// 若缓存命中,则判断缓存是否过期,若已过期则返回null。否则返回请求对应的响应对象
|
|
23
|
+
return Date.now() > entry.expire ? null : entry.response;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 缓存
|
|
27
|
+
* @param request
|
|
28
|
+
* @param response
|
|
29
|
+
*/
|
|
30
|
+
put(request, response) {
|
|
31
|
+
const token = request.context.get(CACHEABLE_TOKEN);
|
|
32
|
+
const entry = {
|
|
33
|
+
url: request.urlWithParams,
|
|
34
|
+
response: response,
|
|
35
|
+
expire: Date.now() + (token === true ? Infinity : token)
|
|
36
|
+
};
|
|
37
|
+
this.cacheMap.set(request.urlWithParams, entry);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 清扫过期缓存
|
|
41
|
+
*/
|
|
42
|
+
clear() {
|
|
43
|
+
for (const [key, entry] of this.cacheMap) {
|
|
44
|
+
if (Date.now() > entry.expire) {
|
|
45
|
+
this.cacheMap.delete(key);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 通过标记(字符串、正则)模糊查询以撤销缓存
|
|
51
|
+
* @param mark
|
|
52
|
+
* @param once 只撤销一个
|
|
53
|
+
*/
|
|
54
|
+
revoke(mark, once) {
|
|
55
|
+
for (const key of this.cacheMap.keys()) {
|
|
56
|
+
if (mark instanceof RegExp ? mark.test(key) : key.includes(mark)) {
|
|
57
|
+
this.cacheMap.delete(key);
|
|
58
|
+
if (once) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 撤销所有缓存
|
|
66
|
+
*/
|
|
67
|
+
revokeAll() {
|
|
68
|
+
this.cacheMap.clear();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export const cacheManager = new CacheManager();
|
|
72
|
+
//# sourceMappingURL=cache-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-manager.js","sourceRoot":"","sources":["../../../../packages/http/src/caching/cache-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAA6B,MAAM,aAAa,CAAC;AAE1E;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,gBAAgB,CAAmB,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;AASnF,MAAM,OAAO,YAAY;IAAzB;QACmB,aAAQ,GAAG,IAAI,GAAG,EAAsB,CAAC;IA+D5D,CAAC;IA7DC;;;OAGG;IACH,GAAG,CAAC,OAA6B;QAC/B,2BAA2B;QAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAEvD,IAAI,CAAC,KAAK,EAAE,CAAC;YAAC,OAAO,IAAI,CAAC;QAAC,CAAC;QAC5B,4CAA4C;QAC5C,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC;IAC3D,CAAC;IAED;;;;OAIG;IACH,GAAG,CAAC,OAA6B,EAAE,QAA+B;QAChE,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAkB,CAAC;QACpE,MAAM,KAAK,GAAe;YACxB,GAAG,EAAE,OAAO,CAAC,aAAa;YAC1B,QAAQ,EAAE,QAAQ;YAClB,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;SACzD,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IAClD,CAAC;IAED;;OAEG;IACH,KAAK;QACH,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACzC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC9B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,IAAqB,EAAE,IAAc;QAC1C,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;YACvC,IAAI,IAAI,YAAY,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBACjE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC1B,IAAI,IAAI,EAAE,CAAC;oBAAC,OAAO;gBAAC,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACH,SAAS;QACP,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;CAEF;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { HttpResponse } from '@ngify/http';
|
|
2
|
+
import { finalize, of, share, tap } from 'rxjs';
|
|
3
|
+
import { CACHEABLE_TOKEN, cacheManager } from './cache-manager.js';
|
|
4
|
+
/**
|
|
5
|
+
* 判断请求是否可缓存
|
|
6
|
+
* 一般只有 GET 请求才需要缓存
|
|
7
|
+
* @param request
|
|
8
|
+
*/
|
|
9
|
+
function isCachable(request) {
|
|
10
|
+
const value = request.context.get(CACHEABLE_TOKEN);
|
|
11
|
+
return value === true || typeof value === 'number';
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 负责接口的缓存拦截
|
|
15
|
+
* - 请求需要携带 {@link CACHEABLE_TOKEN}
|
|
16
|
+
*/
|
|
17
|
+
export function useCacheInterceptor() {
|
|
18
|
+
const requestingMap = new Map();
|
|
19
|
+
return (request, next) => {
|
|
20
|
+
// 判断当前请求是否可缓存
|
|
21
|
+
if (!isCachable(request)) {
|
|
22
|
+
return next(request);
|
|
23
|
+
}
|
|
24
|
+
// 缓存命中则直接返回
|
|
25
|
+
const response = cacheManager.get(request);
|
|
26
|
+
if (response) {
|
|
27
|
+
return of(response);
|
|
28
|
+
}
|
|
29
|
+
// 如果可缓存的请求已经有正在请求的,就不重复发了
|
|
30
|
+
const requesting = requestingMap.get(request.urlWithParams);
|
|
31
|
+
if (requesting) {
|
|
32
|
+
return requesting;
|
|
33
|
+
}
|
|
34
|
+
// 发送请求,成功后缓存
|
|
35
|
+
const obs = next(request).pipe(tap(event => {
|
|
36
|
+
cacheManager.clear();
|
|
37
|
+
if (event instanceof HttpResponse) {
|
|
38
|
+
cacheManager.put(request, event);
|
|
39
|
+
}
|
|
40
|
+
}), finalize(() => requestingMap.delete(request.urlWithParams)), share());
|
|
41
|
+
// 存入请求中
|
|
42
|
+
requestingMap.set(request.urlWithParams, obs);
|
|
43
|
+
return obs;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=caching.interceptor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"caching.interceptor.js","sourceRoot":"","sources":["../../../../packages/http/src/caching/caching.interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4D,YAAY,EAAE,MAAM,aAAa,CAAC;AACrG,OAAO,EAAc,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEhE;;;;GAIG;AACH,SAAS,UAAU,CAAC,OAA6B;IAC/C,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACnD,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC;AACrD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB;IACjC,MAAM,aAAa,GAAG,IAAI,GAAG,EAA0C,CAAC;IACxE,OAAO,CAAC,OAA6B,EAAE,IAAmB,EAAkC,EAAE;QAC5F,cAAc;QACd,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;QAED,YAAY;QACZ,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,EAAE,CAAC,QAAQ,CAAC,CAAC;QACtB,CAAC;QAED,0BAA0B;QAC1B,MAAM,UAAU,GAAG,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAC5D,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,aAAa;QACb,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAC5B,GAAG,CAAC,KAAK,CAAC,EAAE;YACV,YAAY,CAAC,KAAK,EAAE,CAAC;YACrB,IAAI,KAAK,YAAY,YAAY,EAAE,CAAC;gBAClC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YACnC,CAAC;QACH,CAAC,CAAC,EACF,QAAQ,CAAC,GAAG,EAAE,CACZ,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAC5C,EACD,KAAK,EAAE,CACR,CAAC;QAEF,QAAQ;QACR,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;QAE9C,OAAO,GAAG,CAAC;IACb,CAAC,CAAC;AACJ,CAAC"}
|
package/caching/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/http/src/caching/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { HttpContextToken, HttpInterceptorFn } from '@ngify/http';
|
|
2
|
+
/** 是否捕获 HTTP 请求错误(!2XX),默认为 true */
|
|
3
|
+
export declare const CATCH_HTTP_ERROR_TOKEN: HttpContextToken<boolean>;
|
|
4
|
+
/**
|
|
5
|
+
* 一个公共拦截器
|
|
6
|
+
* - 捕获非 200 的 HTTP 请求错误并提示(除了 401)
|
|
7
|
+
* - 使用 {@link CATCH_HTTP_ERROR_TOKEN} 跳过该拦截器
|
|
8
|
+
* @returns
|
|
9
|
+
*/
|
|
10
|
+
export declare function useCommonInterceptor(): HttpInterceptorFn;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { HttpContextToken, HttpStatusCode } from '@ngify/http';
|
|
2
|
+
import { overlay, vibrator } from '@solar-taro/core';
|
|
3
|
+
import { catchError } from 'rxjs';
|
|
4
|
+
/** 是否捕获 HTTP 请求错误(!2XX),默认为 true */
|
|
5
|
+
export const CATCH_HTTP_ERROR_TOKEN = new HttpContextToken(() => true);
|
|
6
|
+
/**
|
|
7
|
+
* 一个公共拦截器
|
|
8
|
+
* - 捕获非 200 的 HTTP 请求错误并提示(除了 401)
|
|
9
|
+
* - 使用 {@link CATCH_HTTP_ERROR_TOKEN} 跳过该拦截器
|
|
10
|
+
* @returns
|
|
11
|
+
*/
|
|
12
|
+
export function useCommonInterceptor() {
|
|
13
|
+
return (request, next) => {
|
|
14
|
+
return next(request).pipe(catchError((error) => {
|
|
15
|
+
if (request.context.get(CATCH_HTTP_ERROR_TOKEN) && error.status !== HttpStatusCode.Unauthorized) {
|
|
16
|
+
vibrator.short();
|
|
17
|
+
setTimeout(() => {
|
|
18
|
+
var _a;
|
|
19
|
+
const message = (_a = error.error) === null || _a === void 0 ? void 0 : _a.msg;
|
|
20
|
+
if (message) {
|
|
21
|
+
overlay.tips('请求失败,原因:' + message);
|
|
22
|
+
}
|
|
23
|
+
else if (error.status >= 0) {
|
|
24
|
+
overlay.tips('请求失败,状态码:' + error.status);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
overlay.tips('请求失败,原因:未知错误');
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
throw error;
|
|
32
|
+
}));
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=common.interceptor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.interceptor.js","sourceRoot":"","sources":["../../../packages/http/src/common.interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAA+E,cAAc,EAAE,MAAM,aAAa,CAAC;AAC5I,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAc,MAAM,MAAM,CAAC;AAE9C,oCAAoC;AACpC,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,gBAAgB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;AAEvE;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO,CAAC,OAA6B,EAAE,IAAmB,EAAkC,EAAE;QAC5F,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CACvB,UAAU,CAAC,CAAC,KAAwB,EAAE,EAAE;YACtC,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,cAAc,CAAC,YAAY,EAAE,CAAC;gBAChG,QAAQ,CAAC,KAAK,EAAE,CAAC;gBACjB,UAAU,CAAC,GAAG,EAAE;;oBACd,MAAM,OAAO,GAAG,MAAA,KAAK,CAAC,KAAK,0CAAE,GAAG,CAAC;oBAEjC,IAAI,OAAO,EAAE,CAAC;wBACZ,OAAO,CAAC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,CAAC;oBACrC,CAAC;yBAAM,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;wBAC7B,OAAO,CAAC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;oBAC3C,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;oBAC/B,CAAC;gBACH,CAAC,CAAC,CAAA;YACJ,CAAC;YAED,MAAM,KAAK,CAAC;QACd,CAAC,CAAC,CACH,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
|
package/headers.d.ts
ADDED
package/headers.js
ADDED
package/headers.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headers.js","sourceRoot":"","sources":["../../../packages/http/src/headers.ts"],"names":[],"mappings":""}
|
package/index.js
ADDED
package/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../packages/http/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,WAAW,CAAC;AAC1B,cAAc,sBAAsB,CAAC;AACrC,cAAc,WAAW,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solar-taro/http",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -12,5 +12,9 @@
|
|
|
12
12
|
"@ngify/http": "^2.0.0",
|
|
13
13
|
"@ngify/http-wx": "^2.0.0",
|
|
14
14
|
"rxjs": "^7.8.0"
|
|
15
|
-
}
|
|
15
|
+
},
|
|
16
|
+
"types": "./index.d.ts",
|
|
17
|
+
"module": "./index.js",
|
|
18
|
+
"type": "module",
|
|
19
|
+
"main": "./index.js"
|
|
16
20
|
}
|
package/eslint.config.cjs
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
const baseConfig = require('../../eslint.config.cjs');
|
|
2
|
-
|
|
3
|
-
module.exports = [
|
|
4
|
-
...baseConfig,
|
|
5
|
-
{
|
|
6
|
-
files: ['**/*.json'],
|
|
7
|
-
rules: {
|
|
8
|
-
'@nx/dependency-checks': [
|
|
9
|
-
'error',
|
|
10
|
-
{
|
|
11
|
-
ignoredFiles: [
|
|
12
|
-
'{projectRoot}/eslint.config.{js,cjs,mjs}',
|
|
13
|
-
'{projectRoot}/vite.config.{js,ts,mjs,mts}',
|
|
14
|
-
],
|
|
15
|
-
},
|
|
16
|
-
],
|
|
17
|
-
},
|
|
18
|
-
languageOptions: {
|
|
19
|
-
parser: require('jsonc-eslint-parser'),
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
];
|
package/project.json
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "http",
|
|
3
|
-
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
4
|
-
"sourceRoot": "packages/http/src",
|
|
5
|
-
"projectType": "library",
|
|
6
|
-
"tags": [],
|
|
7
|
-
"targets": {
|
|
8
|
-
"build": {
|
|
9
|
-
"executor": "@nx/js:tsc",
|
|
10
|
-
"outputs": [
|
|
11
|
-
"{options.outputPath}"
|
|
12
|
-
],
|
|
13
|
-
"options": {
|
|
14
|
-
"outputPath": "dist/http",
|
|
15
|
-
"main": "packages/http/src/index.ts",
|
|
16
|
-
"tsConfig": "packages/http/tsconfig.lib.json",
|
|
17
|
-
"assets": [
|
|
18
|
-
"packages/http/*.md"
|
|
19
|
-
]
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
"postbuild": {
|
|
23
|
-
"executor": "nx:run-commands",
|
|
24
|
-
"dependsOn": [
|
|
25
|
-
"build"
|
|
26
|
-
],
|
|
27
|
-
"options": {
|
|
28
|
-
"commands": [
|
|
29
|
-
"node scripts/postbuild.js http"
|
|
30
|
-
]
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
"release:dev": {
|
|
34
|
-
"executor": "nx:run-commands",
|
|
35
|
-
"options": {
|
|
36
|
-
"commands": [
|
|
37
|
-
"yalc publish dist/http"
|
|
38
|
-
]
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
package/src/api.interceptor.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { HttpContextToken, HttpEvent, HttpHandlerFn, HttpInterceptorFn, HttpRequest, HttpResponse } from '@ngify/http';
|
|
2
|
-
import { WX_REQUSET_TOKEN } from '@ngify/http-wx';
|
|
3
|
-
import { Result } from '@solar-kit/planets/sun';
|
|
4
|
-
import { overlay } from '@solar-taro/core';
|
|
5
|
-
import { Observable, tap } from 'rxjs';
|
|
6
|
-
|
|
7
|
-
/** HTTP 令牌:允许拦截器处理 `Result#code` 不为 `0` 的错误 */
|
|
8
|
-
export const CATCH_RESULT_ERROR_TOKEN = new HttpContextToken(() => true);
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* 负责业务接口的拦截
|
|
12
|
-
* - 添加 `Api` 请求头
|
|
13
|
-
* - 捕获响应异常并提示
|
|
14
|
-
*/
|
|
15
|
-
export function useApiInterceptor(): HttpInterceptorFn {
|
|
16
|
-
return (request: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>> => {
|
|
17
|
-
request = request.clone({
|
|
18
|
-
headers: request.headers.set('Api', 'v1')
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
request.context.set(WX_REQUSET_TOKEN, {
|
|
22
|
-
...request.context.get(WX_REQUSET_TOKEN),
|
|
23
|
-
enableHttp2: true,
|
|
24
|
-
// forceCellularNetwork: true
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
return next(request).pipe(
|
|
28
|
-
tap((event) => {
|
|
29
|
-
if (event instanceof HttpResponse) {
|
|
30
|
-
const { body } = event as HttpResponse<Result>;
|
|
31
|
-
if (body?.code !== 0 && request.context.get(CATCH_RESULT_ERROR_TOKEN)) {
|
|
32
|
-
// 延迟一下,确保不会被后面的 dismiss loading 给关掉 tips
|
|
33
|
-
setTimeout(() => {
|
|
34
|
-
overlay.tips('操作失败,原因:' + (body?.msg || '未知错误'));
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
})
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { HttpContextToken, HttpInterceptorFn } from '@ngify/http';
|
|
2
|
-
|
|
3
|
-
export const AUTO_HOST_TOEKN = new HttpContextToken(() => true);
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* 自动为 / 开头的 URL 添加 host
|
|
7
|
-
* 可以使用 {@link AUTO_HOST_TOEKN} 来跳过该拦截器
|
|
8
|
-
* @param host
|
|
9
|
-
* @returns
|
|
10
|
-
*/
|
|
11
|
-
export function useAutoHostInterceptor(host: string): HttpInterceptorFn {
|
|
12
|
-
return (request, next) => {
|
|
13
|
-
if (
|
|
14
|
-
request.context.get(AUTO_HOST_TOEKN) &&
|
|
15
|
-
request.url.startsWith('/')
|
|
16
|
-
) {
|
|
17
|
-
return next(request.clone({
|
|
18
|
-
url: host + request.url
|
|
19
|
-
}));
|
|
20
|
-
}
|
|
21
|
-
return next(request);
|
|
22
|
-
};
|
|
23
|
-
}
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { HttpContextToken, HttpRequest, HttpResponse } from '@ngify/http';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* 缓存令牌,值可以为:
|
|
5
|
-
* - 布尔值,为 true 时,表示在一次会话中缓存永不过期,默认值为 false
|
|
6
|
-
* - 缓存时间,单位毫秒
|
|
7
|
-
*/
|
|
8
|
-
export const CACHEABLE_TOKEN = new HttpContextToken<boolean | number>(() => false);
|
|
9
|
-
|
|
10
|
-
/** 缓存条目 */
|
|
11
|
-
export interface CacheEntry {
|
|
12
|
-
url: string;
|
|
13
|
-
response: HttpResponse<unknown>;
|
|
14
|
-
expire: number;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export class CacheManager {
|
|
18
|
-
private readonly cacheMap = new Map<string, CacheEntry>();
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* 获取缓存
|
|
22
|
-
* @param request
|
|
23
|
-
*/
|
|
24
|
-
get(request: HttpRequest<unknown>): HttpResponse<unknown> | null {
|
|
25
|
-
// 判断当前请求是否已被缓存,若未缓存则返回null
|
|
26
|
-
const entry = this.cacheMap.get(request.urlWithParams);
|
|
27
|
-
|
|
28
|
-
if (!entry) { return null; }
|
|
29
|
-
// 若缓存命中,则判断缓存是否过期,若已过期则返回null。否则返回请求对应的响应对象
|
|
30
|
-
return Date.now() > entry.expire ? null : entry.response;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* 缓存
|
|
35
|
-
* @param request
|
|
36
|
-
* @param response
|
|
37
|
-
*/
|
|
38
|
-
put(request: HttpRequest<unknown>, response: HttpResponse<unknown>): void {
|
|
39
|
-
const token = request.context.get(CACHEABLE_TOKEN) as true | number;
|
|
40
|
-
const entry: CacheEntry = {
|
|
41
|
-
url: request.urlWithParams,
|
|
42
|
-
response: response,
|
|
43
|
-
expire: Date.now() + (token === true ? Infinity : token)
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
this.cacheMap.set(request.urlWithParams, entry);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* 清扫过期缓存
|
|
51
|
-
*/
|
|
52
|
-
clear() {
|
|
53
|
-
for (const [key, entry] of this.cacheMap) {
|
|
54
|
-
if (Date.now() > entry.expire) {
|
|
55
|
-
this.cacheMap.delete(key);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* 通过标记(字符串、正则)模糊查询以撤销缓存
|
|
62
|
-
* @param mark
|
|
63
|
-
* @param once 只撤销一个
|
|
64
|
-
*/
|
|
65
|
-
revoke(mark: string | RegExp, once?: boolean) {
|
|
66
|
-
for (const key of this.cacheMap.keys()) {
|
|
67
|
-
if (mark instanceof RegExp ? mark.test(key) : key.includes(mark)) {
|
|
68
|
-
this.cacheMap.delete(key);
|
|
69
|
-
if (once) { return; }
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* 撤销所有缓存
|
|
76
|
-
*/
|
|
77
|
-
revokeAll() {
|
|
78
|
-
this.cacheMap.clear();
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export const cacheManager = new CacheManager();
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { HttpEvent, HttpHandlerFn, HttpInterceptorFn, HttpRequest, HttpResponse } from '@ngify/http';
|
|
2
|
-
import { Observable, finalize, of, share, tap } from 'rxjs';
|
|
3
|
-
import { CACHEABLE_TOKEN, cacheManager } from './cache-manager';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* 判断请求是否可缓存
|
|
7
|
-
* 一般只有 GET 请求才需要缓存
|
|
8
|
-
* @param request
|
|
9
|
-
*/
|
|
10
|
-
function isCachable(request: HttpRequest<unknown>): boolean {
|
|
11
|
-
const value = request.context.get(CACHEABLE_TOKEN);
|
|
12
|
-
return value === true || typeof value === 'number';
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* 负责接口的缓存拦截
|
|
17
|
-
* - 请求需要携带 {@link CACHEABLE_TOKEN}
|
|
18
|
-
*/
|
|
19
|
-
export function useCacheInterceptor(): HttpInterceptorFn {
|
|
20
|
-
const requestingMap = new Map<string, Observable<HttpEvent<unknown>>>();
|
|
21
|
-
return (request: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>> => {
|
|
22
|
-
// 判断当前请求是否可缓存
|
|
23
|
-
if (!isCachable(request)) {
|
|
24
|
-
return next(request);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// 缓存命中则直接返回
|
|
28
|
-
const response = cacheManager.get(request);
|
|
29
|
-
if (response) {
|
|
30
|
-
return of(response);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// 如果可缓存的请求已经有正在请求的,就不重复发了
|
|
34
|
-
const requesting = requestingMap.get(request.urlWithParams);
|
|
35
|
-
if (requesting) {
|
|
36
|
-
return requesting;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// 发送请求,成功后缓存
|
|
40
|
-
const obs = next(request).pipe(
|
|
41
|
-
tap(event => {
|
|
42
|
-
cacheManager.clear();
|
|
43
|
-
if (event instanceof HttpResponse) {
|
|
44
|
-
cacheManager.put(request, event);
|
|
45
|
-
}
|
|
46
|
-
}),
|
|
47
|
-
finalize(() =>
|
|
48
|
-
requestingMap.delete(request.urlWithParams)
|
|
49
|
-
),
|
|
50
|
-
share()
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
// 存入请求中
|
|
54
|
-
requestingMap.set(request.urlWithParams, obs);
|
|
55
|
-
|
|
56
|
-
return obs;
|
|
57
|
-
};
|
|
58
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { HttpContextToken, HttpErrorResponse, HttpEvent, HttpHandlerFn, HttpInterceptorFn, HttpRequest, HttpStatusCode } from '@ngify/http';
|
|
2
|
-
import { overlay, vibrator } from '@solar-taro/core';
|
|
3
|
-
import { catchError, Observable } from 'rxjs';
|
|
4
|
-
|
|
5
|
-
/** 是否捕获 HTTP 请求错误(!2XX),默认为 true */
|
|
6
|
-
export const CATCH_HTTP_ERROR_TOKEN = new HttpContextToken(() => true);
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* 一个公共拦截器
|
|
10
|
-
* - 捕获非 200 的 HTTP 请求错误并提示(除了 401)
|
|
11
|
-
* - 使用 {@link CATCH_HTTP_ERROR_TOKEN} 跳过该拦截器
|
|
12
|
-
* @returns
|
|
13
|
-
*/
|
|
14
|
-
export function useCommonInterceptor(): HttpInterceptorFn {
|
|
15
|
-
return (request: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>> => {
|
|
16
|
-
return next(request).pipe(
|
|
17
|
-
catchError((error: HttpErrorResponse) => {
|
|
18
|
-
if (request.context.get(CATCH_HTTP_ERROR_TOKEN) && error.status !== HttpStatusCode.Unauthorized) {
|
|
19
|
-
vibrator.short();
|
|
20
|
-
setTimeout(() => {
|
|
21
|
-
const message = error.error?.msg;
|
|
22
|
-
|
|
23
|
-
if (message) {
|
|
24
|
-
overlay.tips('请求失败,原因:' + message);
|
|
25
|
-
} else if (error.status >= 0) {
|
|
26
|
-
overlay.tips('请求失败,状态码:' + error.status);
|
|
27
|
-
} else {
|
|
28
|
-
overlay.tips('请求失败,原因:未知错误');
|
|
29
|
-
}
|
|
30
|
-
})
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
throw error;
|
|
34
|
-
})
|
|
35
|
-
);
|
|
36
|
-
};
|
|
37
|
-
}
|
package/src/headers.ts
DELETED
package/tsconfig.json
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "../../tsconfig.base.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"forceConsistentCasingInFileNames": true,
|
|
5
|
-
"strict": true,
|
|
6
|
-
"noImplicitOverride": true,
|
|
7
|
-
"noImplicitReturns": true,
|
|
8
|
-
"noFallthroughCasesInSwitch": true,
|
|
9
|
-
"noPropertyAccessFromIndexSignature": true
|
|
10
|
-
},
|
|
11
|
-
"files": [],
|
|
12
|
-
"include": [],
|
|
13
|
-
"references": [
|
|
14
|
-
{
|
|
15
|
-
"path": "./tsconfig.lib.json"
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
"path": "./tsconfig.spec.json"
|
|
19
|
-
}
|
|
20
|
-
]
|
|
21
|
-
}
|
package/tsconfig.lib.json
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "./tsconfig.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"outDir": "../../dist/out-tsc",
|
|
5
|
-
"declaration": true
|
|
6
|
-
},
|
|
7
|
-
"include": [
|
|
8
|
-
"src/**/*.ts"
|
|
9
|
-
],
|
|
10
|
-
"exclude": [
|
|
11
|
-
"vite.config.ts",
|
|
12
|
-
"vite.config.mts",
|
|
13
|
-
"vitest.config.ts",
|
|
14
|
-
"vitest.config.mts",
|
|
15
|
-
"src/**/*.test.ts",
|
|
16
|
-
"src/**/*.spec.ts",
|
|
17
|
-
"src/**/*.test.tsx",
|
|
18
|
-
"src/**/*.spec.tsx",
|
|
19
|
-
"src/**/*.test.js",
|
|
20
|
-
"src/**/*.spec.js",
|
|
21
|
-
"src/**/*.test.jsx",
|
|
22
|
-
"src/**/*.spec.jsx"
|
|
23
|
-
]
|
|
24
|
-
}
|
package/tsconfig.spec.json
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "./tsconfig.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"outDir": "../../dist/out-tsc",
|
|
5
|
-
"types": [
|
|
6
|
-
"vitest/globals",
|
|
7
|
-
"vitest/importMeta",
|
|
8
|
-
"vite/client",
|
|
9
|
-
"node",
|
|
10
|
-
"vitest"
|
|
11
|
-
]
|
|
12
|
-
},
|
|
13
|
-
"include": [
|
|
14
|
-
"vite.config.ts",
|
|
15
|
-
"vite.config.mts",
|
|
16
|
-
"vitest.config.ts",
|
|
17
|
-
"vitest.config.mts",
|
|
18
|
-
"src/**/*.test.ts",
|
|
19
|
-
"src/**/*.spec.ts",
|
|
20
|
-
"src/**/*.test.tsx",
|
|
21
|
-
"src/**/*.spec.tsx",
|
|
22
|
-
"src/**/*.test.js",
|
|
23
|
-
"src/**/*.spec.js",
|
|
24
|
-
"src/**/*.test.jsx",
|
|
25
|
-
"src/**/*.spec.jsx",
|
|
26
|
-
"src/**/*.d.ts"
|
|
27
|
-
]
|
|
28
|
-
}
|
package/typedoc.json
DELETED
package/vite.config.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { nxCopyAssetsPlugin } from '@nx/vite/plugins/nx-copy-assets.plugin';
|
|
2
|
-
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
|
|
3
|
-
import { defineConfig } from 'vite';
|
|
4
|
-
|
|
5
|
-
export default defineConfig({
|
|
6
|
-
root: __dirname,
|
|
7
|
-
cacheDir: '../../node_modules/.vite/http',
|
|
8
|
-
plugins: [nxViteTsPaths(), nxCopyAssetsPlugin(['*.md'])],
|
|
9
|
-
// Uncomment this if you are using workers.
|
|
10
|
-
// worker: {
|
|
11
|
-
// plugins: [ nxViteTsPaths() ],
|
|
12
|
-
// },
|
|
13
|
-
test: {
|
|
14
|
-
watch: false,
|
|
15
|
-
globals: true,
|
|
16
|
-
environment: 'node',
|
|
17
|
-
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
18
|
-
reporters: ['default'],
|
|
19
|
-
coverage: {
|
|
20
|
-
reportsDirectory: '../../coverage/http',
|
|
21
|
-
provider: 'v8',
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
});
|
|
File without changes
|
|
File without changes
|