@anjianshi/utils 3.0.7 → 3.0.8
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/package.json +4 -4
- package/safe-request.d.ts +10 -1
- package/safe-request.js +25 -12
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anjianshi/utils",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.8",
|
|
4
4
|
"description": "Common JavaScript Utils",
|
|
5
5
|
"homepage": "https://github.com/anjianshi/js-packages/utils",
|
|
6
6
|
"bugs": {
|
|
@@ -31,12 +31,12 @@
|
|
|
31
31
|
"redis": "^5.5.6",
|
|
32
32
|
"typescript": "^5.8.3",
|
|
33
33
|
"vconsole": "^3.15.1",
|
|
34
|
-
"@anjianshi/presets-
|
|
34
|
+
"@anjianshi/presets-eslint-base": "6.0.0",
|
|
35
35
|
"@anjianshi/presets-eslint-node": "6.0.0",
|
|
36
36
|
"@anjianshi/presets-eslint-react": "6.0.0",
|
|
37
|
+
"@anjianshi/presets-eslint-typescript": "6.0.0",
|
|
37
38
|
"@anjianshi/presets-typescript": "3.2.5",
|
|
38
|
-
"@anjianshi/presets-
|
|
39
|
-
"@anjianshi/presets-eslint-typescript": "6.0.0"
|
|
39
|
+
"@anjianshi/presets-prettier": "3.0.5"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"@emotion/react": "^11.14.0",
|
package/safe-request.d.ts
CHANGED
|
@@ -15,8 +15,10 @@ interface Options {
|
|
|
15
15
|
data?: FormData | Record<string, any>;
|
|
16
16
|
/** 超时时间,不指定或设为 0 代表不限 */
|
|
17
17
|
timeout?: number;
|
|
18
|
+
/** 是否把响应内容作为二进制处理(结果是 blob) */
|
|
19
|
+
binary?: boolean;
|
|
18
20
|
}
|
|
19
|
-
type FormattedOptions = Required<Pick<Options, 'url' | 'method' | 'headers' | 'body' | 'timeout'>>;
|
|
21
|
+
type FormattedOptions = Required<Pick<Options, 'url' | 'method' | 'headers' | 'body' | 'timeout' | 'binary'>>;
|
|
20
22
|
type PredefinedOptions = Pick<Options, 'urlPrefix' | 'method' | 'headers' | 'timeout'>;
|
|
21
23
|
/**
|
|
22
24
|
* 建立一个请求发起器,并可预设部分选项。
|
|
@@ -37,6 +39,13 @@ export declare class SafeRequestClient {
|
|
|
37
39
|
formatOptions(input: Options): Promise<FormattedOptions>;
|
|
38
40
|
/** 请求发起前调用此方法补充 Headers 内容 */
|
|
39
41
|
protected getHeaders(options: FormattedOptions, inputOptions: Options): Record<string, string> | undefined | Promise<Record<string, string> | undefined>;
|
|
42
|
+
/**
|
|
43
|
+
* 解析响应内容
|
|
44
|
+
* - 若 options.binary 为 true,返回二进制结果
|
|
45
|
+
* - 若 response Content-Type 为 'text/' 开头,返回文本结果
|
|
46
|
+
* - 若 response Content-Type 为 'application/json' 开头,返回 JSON 结构
|
|
47
|
+
* - 其他情况,尝试解析成 JSON,成功则返回 JSON 否则返回纯文本
|
|
48
|
+
*/
|
|
40
49
|
protected parseResponse<T>(options: FormattedOptions, response: Response): Promise<Result<T>>;
|
|
41
50
|
/** 若请求未成功发起,会触发此回调来生成失败信息 */
|
|
42
51
|
protected onRequestError(error: Error, url: string): import("./lang/result.js").Failed<undefined>;
|
package/safe-request.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { sleep } from './lang/async.js';
|
|
2
|
-
import { failed, handleException } from './lang/result.js';
|
|
2
|
+
import { success, failed, handleException } from './lang/result.js';
|
|
3
3
|
import { getLogger } from './logging/index.js';
|
|
4
4
|
import { combineUrl } from './url.js';
|
|
5
5
|
/**
|
|
@@ -60,7 +60,7 @@ export class SafeRequestClient {
|
|
|
60
60
|
}
|
|
61
61
|
async formatOptions(input) {
|
|
62
62
|
const predefined = this.prefefinedOptions;
|
|
63
|
-
const { urlPrefix = predefined.urlPrefix ?? '', url: rawUrl, query = {}, method = predefined.method ?? 'GET', headers: rawHeaders = {}, body: rawBody = null, data, timeout = predefined.timeout ?? 0, } = input;
|
|
63
|
+
const { urlPrefix = predefined.urlPrefix ?? '', url: rawUrl, query = {}, method = predefined.method ?? 'GET', headers: rawHeaders = {}, body: rawBody = null, data, timeout = predefined.timeout ?? 0, binary = false, } = input;
|
|
64
64
|
const headers = {
|
|
65
65
|
...(predefined.headers ?? {}),
|
|
66
66
|
...rawHeaders,
|
|
@@ -82,6 +82,7 @@ export class SafeRequestClient {
|
|
|
82
82
|
headers,
|
|
83
83
|
body,
|
|
84
84
|
timeout,
|
|
85
|
+
binary,
|
|
85
86
|
};
|
|
86
87
|
Object.assign(options.headers, await this.getHeaders(options, input));
|
|
87
88
|
return options;
|
|
@@ -94,19 +95,31 @@ export class SafeRequestClient {
|
|
|
94
95
|
inputOptions) {
|
|
95
96
|
return undefined;
|
|
96
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* 解析响应内容
|
|
100
|
+
* - 若 options.binary 为 true,返回二进制结果
|
|
101
|
+
* - 若 response Content-Type 为 'text/' 开头,返回文本结果
|
|
102
|
+
* - 若 response Content-Type 为 'application/json' 开头,返回 JSON 结构
|
|
103
|
+
* - 其他情况,尝试解析成 JSON,成功则返回 JSON 否则返回纯文本
|
|
104
|
+
*/
|
|
97
105
|
async parseResponse(options, response) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
return result;
|
|
106
|
+
if (options.binary) {
|
|
107
|
+
return (await handleException(response.blob()));
|
|
108
|
+
}
|
|
102
109
|
const contentType = (response.headers.get('Content-Type') ?? '').toLowerCase().trim();
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
110
|
+
const textResult = await handleException(response.text());
|
|
111
|
+
if (contentType.startsWith('text/') || !textResult.success)
|
|
112
|
+
return textResult;
|
|
113
|
+
let jsonResult;
|
|
114
|
+
try {
|
|
115
|
+
jsonResult = success(JSON.parse(textResult.data));
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
jsonResult = failed(error.message);
|
|
107
119
|
}
|
|
108
|
-
|
|
109
|
-
|
|
120
|
+
if (contentType.startsWith('application/json') || jsonResult.success)
|
|
121
|
+
return jsonResult;
|
|
122
|
+
return textResult;
|
|
110
123
|
}
|
|
111
124
|
/** 若请求未成功发起,会触发此回调来生成失败信息 */
|
|
112
125
|
onRequestError(error, url) {
|