@zwa73/utils 1.0.233 → 1.0.235
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/UtilHttp.d.ts +49 -96
- package/dist/UtilHttp.js +75 -65
- package/package.json +1 -1
package/dist/UtilHttp.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { AnyString, JToken, MPromise, PartialOption, StatusVerifyFn } from "./Ut
|
|
|
2
2
|
import http from 'http';
|
|
3
3
|
import { PromiseRetries } from "./UtilFunctions";
|
|
4
4
|
import FormData from "form-data";
|
|
5
|
+
import { PromiseQueue } from "@zwa73/js-utils";
|
|
5
6
|
/**网络请求返回值 */
|
|
6
7
|
export type RequestResult<T> = {
|
|
7
8
|
/**响应头 */
|
|
@@ -13,6 +14,10 @@ export type RequestResult<T> = {
|
|
|
13
14
|
};
|
|
14
15
|
/**网络请求选项 */
|
|
15
16
|
export type RequestOption = {
|
|
17
|
+
/**请求之间的间隔, 单位毫秒 默认 1
|
|
18
|
+
* 如果用promise并发请求可能会导致req.write提前中断, 为避免此问题需要设置请求间隔
|
|
19
|
+
*/
|
|
20
|
+
interval?: number;
|
|
16
21
|
/**请求协议 */
|
|
17
22
|
protocol: 'http:' | 'https:';
|
|
18
23
|
/**超时时间/毫秒 最小为10_000 默认无限 */
|
|
@@ -45,30 +50,24 @@ export type RequestParseFn<D, R> = (result: RequestResult<D> | undefined) => MPr
|
|
|
45
50
|
export type RequestReduceFn<T> = (acc: T, data: string) => MPromise<T>;
|
|
46
51
|
/**数据初始化函数 */
|
|
47
52
|
export type RequestInitFn<T> = (res: http.IncomingMessage) => MPromise<T>;
|
|
48
|
-
declare const AcceptTypeList: readonly ["json", "string"];
|
|
49
|
-
/**可用的接受类型 */
|
|
50
|
-
type AcceptType = typeof AcceptTypeList[number];
|
|
51
|
-
declare const SendTypeList: readonly ["json", "query", "formData", "none"];
|
|
52
|
-
/**可用的发送类型 */
|
|
53
|
-
type SendType = typeof SendTypeList[number];
|
|
54
53
|
/**accept处理数据
|
|
55
54
|
* @template D - 接受时转换的数据类型
|
|
56
55
|
* @template R - 完成处理的数据类型
|
|
57
56
|
*/
|
|
58
|
-
type AcceptProcCtor<D, R, T> = (arg: T) => MPromise<
|
|
59
|
-
type
|
|
57
|
+
type AcceptProcCtor<D, R, T extends {}> = AcceptProcData<D, R> | ((arg: T) => MPromise<AcceptProcData<D, R>>);
|
|
58
|
+
type AcceptProcData<D, R> = {
|
|
60
59
|
init: RequestInitFn<D>;
|
|
61
|
-
reduce
|
|
60
|
+
reduce?: RequestReduceFn<D>;
|
|
62
61
|
parse: RequestParseFn<D, R>;
|
|
63
62
|
};
|
|
64
63
|
/**send处理数据 */
|
|
65
|
-
type SendProcCtor<T extends {}> = (opt: RequestOption, arg: T) => MPromise<
|
|
66
|
-
type
|
|
64
|
+
type SendProcCtor<T extends {}> = SendProcData | ((opt: RequestOption, arg: T) => MPromise<SendProcData>);
|
|
65
|
+
type SendProcData = {
|
|
67
66
|
proc: RequestProcFn;
|
|
68
67
|
};
|
|
69
68
|
declare const SendNoneProc: SendProcCtor<{}>;
|
|
70
69
|
declare const AcceptStringProc: AcceptProcCtor<string, RequestResult<string> | undefined, {}>;
|
|
71
|
-
declare const AcceptNoneProc: AcceptProcCtor<undefined, undefined, {}>;
|
|
70
|
+
declare const AcceptNoneProc: AcceptProcCtor<undefined, RequestResult<undefined> | undefined, {}>;
|
|
72
71
|
/**send处理的参数 */
|
|
73
72
|
type SendParams<S extends SendProcCtor<any>> = S extends SendProcCtor<infer P> ? P : never;
|
|
74
73
|
/**send处理的参数 */
|
|
@@ -127,10 +126,10 @@ export declare class UtilHttp<D extends Partial<RequestOption> & Required<Pick<R
|
|
|
127
126
|
headers: {
|
|
128
127
|
"Content-Type": "application/json";
|
|
129
128
|
};
|
|
130
|
-
},
|
|
129
|
+
}, (opt: RequestOption, arg: {
|
|
131
130
|
/**发送的json */
|
|
132
131
|
json: JToken;
|
|
133
|
-
}>,
|
|
132
|
+
}) => MPromise<SendProcData>, AcceptProcData<string, RequestResult<JToken> | undefined>>;
|
|
134
133
|
/**收发皆为json的post预设 */
|
|
135
134
|
postJson(): UtilHttp<D & {
|
|
136
135
|
method: "POST";
|
|
@@ -138,21 +137,21 @@ export declare class UtilHttp<D extends Partial<RequestOption> & Required<Pick<R
|
|
|
138
137
|
headers: {
|
|
139
138
|
'Content-Type': "application/json";
|
|
140
139
|
};
|
|
141
|
-
},
|
|
140
|
+
}, (opt: RequestOption, arg: {
|
|
142
141
|
/**发送的json */
|
|
143
142
|
json: JToken;
|
|
144
|
-
}>,
|
|
143
|
+
}) => MPromise<SendProcData>, AcceptProcData<string, RequestResult<JToken> | undefined>>;
|
|
145
144
|
/**无查询参数获取json的get预设 */
|
|
146
145
|
getJson(): UtilHttp<D & {
|
|
147
146
|
method: "GET";
|
|
148
|
-
}, SendProcCtor<{}>,
|
|
147
|
+
}, SendProcCtor<{}>, AcceptProcData<string, RequestResult<JToken> | undefined>>;
|
|
149
148
|
/**有查询参数获取json的get预设 */
|
|
150
149
|
queryJson(): UtilHttp<D & {
|
|
151
150
|
method: "GET";
|
|
152
|
-
},
|
|
151
|
+
}, (opt: RequestOption, arg: {
|
|
153
152
|
/**附加的查询表单数据 */
|
|
154
153
|
query: QueryRequestData;
|
|
155
|
-
}>,
|
|
154
|
+
}) => MPromise<SendProcData>, AcceptProcData<string, RequestResult<JToken> | undefined>>;
|
|
156
155
|
/**收发皆为json的https-post预设 */
|
|
157
156
|
static httpsPostJson(): UtilHttp<{
|
|
158
157
|
readonly protocol: "https:";
|
|
@@ -162,10 +161,10 @@ export declare class UtilHttp<D extends Partial<RequestOption> & Required<Pick<R
|
|
|
162
161
|
headers: {
|
|
163
162
|
'Content-Type': "application/json";
|
|
164
163
|
};
|
|
165
|
-
},
|
|
164
|
+
}, (opt: RequestOption, arg: {
|
|
166
165
|
/**发送的json */
|
|
167
166
|
json: JToken;
|
|
168
|
-
}>,
|
|
167
|
+
}) => MPromise<SendProcData>, AcceptProcData<string, RequestResult<JToken> | undefined>>;
|
|
169
168
|
/**收发皆为json的http-post预设 */
|
|
170
169
|
static httpPostJson(): UtilHttp<{
|
|
171
170
|
readonly protocol: "http:";
|
|
@@ -175,50 +174,46 @@ export declare class UtilHttp<D extends Partial<RequestOption> & Required<Pick<R
|
|
|
175
174
|
headers: {
|
|
176
175
|
'Content-Type': "application/json";
|
|
177
176
|
};
|
|
178
|
-
},
|
|
177
|
+
}, (opt: RequestOption, arg: {
|
|
179
178
|
/**发送的json */
|
|
180
179
|
json: JToken;
|
|
181
|
-
}>,
|
|
180
|
+
}) => MPromise<SendProcData>, AcceptProcData<string, RequestResult<JToken> | undefined>>;
|
|
182
181
|
/**无查询参数获取json的https-get预设 */
|
|
183
182
|
static httpsGetJson(): UtilHttp<{
|
|
184
183
|
readonly protocol: "https:";
|
|
185
184
|
} & {
|
|
186
185
|
method: "GET";
|
|
187
|
-
}, SendProcCtor<{}>,
|
|
186
|
+
}, SendProcCtor<{}>, AcceptProcData<string, RequestResult<JToken> | undefined>>;
|
|
188
187
|
/**有查询参数获取json的https-get预设 */
|
|
189
188
|
static httpsQueryJson(): UtilHttp<{
|
|
190
189
|
readonly protocol: "http:";
|
|
191
190
|
} & {
|
|
192
191
|
method: "GET";
|
|
193
|
-
},
|
|
192
|
+
}, (opt: RequestOption, arg: {
|
|
194
193
|
/**附加的查询表单数据 */
|
|
195
194
|
query: QueryRequestData;
|
|
196
|
-
}>,
|
|
195
|
+
}) => MPromise<SendProcData>, AcceptProcData<string, RequestResult<JToken> | undefined>>;
|
|
197
196
|
/**无查询参数获取json的http-get预设 */
|
|
198
197
|
static httpGetJson(): UtilHttp<{
|
|
199
198
|
readonly protocol: "http:";
|
|
200
199
|
} & {
|
|
201
200
|
method: "GET";
|
|
202
|
-
}, SendProcCtor<{}>,
|
|
201
|
+
}, SendProcCtor<{}>, AcceptProcData<string, RequestResult<JToken> | undefined>>;
|
|
203
202
|
/**有查询参数获取json的http-get预设 */
|
|
204
203
|
static httpQueryJson(): UtilHttp<{
|
|
205
204
|
readonly protocol: "http:";
|
|
206
205
|
} & {
|
|
207
206
|
method: "GET";
|
|
208
|
-
},
|
|
207
|
+
}, (opt: RequestOption, arg: {
|
|
209
208
|
/**附加的查询表单数据 */
|
|
210
209
|
query: QueryRequestData;
|
|
211
|
-
}>,
|
|
212
|
-
|
|
213
|
-
accept<T extends AcceptType>(t: T): {
|
|
214
|
-
readonly json: UtilHttp<D, S, AcceptProcCtor<string, RequestResult<JToken> | undefined, {}>>;
|
|
215
|
-
readonly string: UtilHttp<D, S, AcceptProcCtor<string, RequestResult<string> | undefined, {}>>;
|
|
216
|
-
readonly none: UtilHttp<D, S, AcceptProcCtor<undefined, undefined, {}>>;
|
|
217
|
-
}[T];
|
|
218
|
-
acceptJson(): UtilHttp<D, S, AcceptProcCtor<string, RequestResult<JToken> | undefined, {}>>;
|
|
210
|
+
}) => MPromise<SendProcData>, AcceptProcData<string, RequestResult<JToken> | undefined>>;
|
|
211
|
+
acceptJson(): UtilHttp<D, S, AcceptProcData<string, RequestResult<JToken> | undefined>>;
|
|
219
212
|
acceptString(): UtilHttp<D, S, typeof AcceptStringProc>;
|
|
220
213
|
acceptNone(): UtilHttp<D, S, typeof AcceptNoneProc>;
|
|
221
|
-
acceptFile(): UtilHttp<D, S,
|
|
214
|
+
acceptFile(): UtilHttp<D, S, (arg: {
|
|
215
|
+
acceptFilepath: string;
|
|
216
|
+
}) => MPromise<AcceptProcData<{
|
|
222
217
|
promise: Promise<boolean>;
|
|
223
218
|
}, {
|
|
224
219
|
/**响应头 */
|
|
@@ -227,53 +222,9 @@ export declare class UtilHttp<D extends Partial<RequestOption> & Required<Pick<R
|
|
|
227
222
|
statusCode?: number;
|
|
228
223
|
/**保存文件路径 */
|
|
229
224
|
filepath: string;
|
|
230
|
-
} | undefined
|
|
231
|
-
acceptFilepath: string;
|
|
232
|
-
}>>;
|
|
225
|
+
} | undefined>>>;
|
|
233
226
|
/**自定的接收数据类型*/
|
|
234
|
-
acceptRaw<AD, AR, AT>(proc: AcceptProcCtor<AD, AR, AT>): UtilHttp<D, S, typeof proc>;
|
|
235
|
-
/**预设的发送数据类型 */
|
|
236
|
-
send<T extends SendType>(t: T): {
|
|
237
|
-
readonly json: UtilHttp<D & {
|
|
238
|
-
headers: {
|
|
239
|
-
"Content-Type": "application/json";
|
|
240
|
-
};
|
|
241
|
-
}, SendProcCtor<{
|
|
242
|
-
/**发送的json */
|
|
243
|
-
json: JToken;
|
|
244
|
-
}>, A>;
|
|
245
|
-
readonly query: UtilHttp<D, SendProcCtor<{
|
|
246
|
-
/**附加的查询表单数据 */
|
|
247
|
-
query: QueryRequestData;
|
|
248
|
-
}>, A>;
|
|
249
|
-
readonly formData: UtilHttp<D & {
|
|
250
|
-
headers: {
|
|
251
|
-
"Content-Type": "multipart/form-data";
|
|
252
|
-
};
|
|
253
|
-
}, SendProcCtor<{
|
|
254
|
-
/**form-data包提供的FormData表单数据 */
|
|
255
|
-
formdata: FormData;
|
|
256
|
-
}>, A>;
|
|
257
|
-
readonly form: UtilHttp<D & {
|
|
258
|
-
headers: {
|
|
259
|
-
"Content-Type": "application/x-www-form-urlencoded";
|
|
260
|
-
};
|
|
261
|
-
}, SendProcCtor<{
|
|
262
|
-
/**表单 */
|
|
263
|
-
form: QueryRequestData;
|
|
264
|
-
}>, A>;
|
|
265
|
-
readonly file: UtilHttp<D & {
|
|
266
|
-
headers: {
|
|
267
|
-
"Content-Type": "multipart/form-data";
|
|
268
|
-
};
|
|
269
|
-
}, SendProcCtor<{
|
|
270
|
-
/**文件路径 */
|
|
271
|
-
filepath: string;
|
|
272
|
-
/**文件名 */
|
|
273
|
-
filename?: string;
|
|
274
|
-
}>, A>;
|
|
275
|
-
readonly none: UtilHttp<D, SendProcCtor<{}>, A>;
|
|
276
|
-
}[T];
|
|
227
|
+
acceptRaw<AD, AR, AT extends {}>(proc: AcceptProcCtor<AD, AR, AT>): UtilHttp<D, S, typeof proc>;
|
|
277
228
|
/**发送json
|
|
278
229
|
* 请求参数为 (token:JToken)
|
|
279
230
|
*/
|
|
@@ -281,44 +232,44 @@ export declare class UtilHttp<D extends Partial<RequestOption> & Required<Pick<R
|
|
|
281
232
|
headers: {
|
|
282
233
|
"Content-Type": "application/json";
|
|
283
234
|
};
|
|
284
|
-
},
|
|
235
|
+
}, (opt: RequestOption, arg: {
|
|
285
236
|
/**发送的json */
|
|
286
237
|
json: JToken;
|
|
287
|
-
}>, A>;
|
|
288
|
-
/**利用 appendQuery
|
|
289
|
-
sendQuery(): UtilHttp<D,
|
|
238
|
+
}) => MPromise<SendProcData>, A>;
|
|
239
|
+
/**利用 appendQuery 直接将表单附加在path上发送请求 */
|
|
240
|
+
sendQuery(): UtilHttp<D, (opt: RequestOption, arg: {
|
|
290
241
|
/**附加的查询表单数据 */
|
|
291
242
|
query: QueryRequestData;
|
|
292
|
-
}>, A>;
|
|
293
|
-
|
|
243
|
+
}) => MPromise<SendProcData>, A>;
|
|
244
|
+
/**发送form-data包提供的表单数据 */
|
|
294
245
|
sendFormData(): UtilHttp<D & {
|
|
295
246
|
headers: {
|
|
296
247
|
"Content-Type": "multipart/form-data";
|
|
297
248
|
};
|
|
298
|
-
},
|
|
249
|
+
}, (opt: RequestOption, arg: {
|
|
299
250
|
/**form-data包提供的FormData表单数据 */
|
|
300
251
|
formdata: FormData;
|
|
301
|
-
}>, A>;
|
|
252
|
+
}) => MPromise<SendProcData>, A>;
|
|
302
253
|
/**发送表单 */
|
|
303
254
|
sendForm(): UtilHttp<D & {
|
|
304
255
|
headers: {
|
|
305
256
|
"Content-Type": "application/x-www-form-urlencoded";
|
|
306
257
|
};
|
|
307
|
-
},
|
|
258
|
+
}, (opt: RequestOption, arg: {
|
|
308
259
|
/**表单 */
|
|
309
260
|
form: QueryRequestData;
|
|
310
|
-
}>, A>;
|
|
261
|
+
}) => MPromise<SendProcData>, A>;
|
|
311
262
|
/**发送文件 */
|
|
312
263
|
sendFile(): UtilHttp<D & {
|
|
313
264
|
headers: {
|
|
314
265
|
"Content-Type": "multipart/form-data";
|
|
315
266
|
};
|
|
316
|
-
},
|
|
267
|
+
}, (opt: RequestOption, arg: {
|
|
317
268
|
/**文件路径 */
|
|
318
269
|
filepath: string;
|
|
319
270
|
/**文件名 */
|
|
320
271
|
filename?: string;
|
|
321
|
-
}>, A>;
|
|
272
|
+
}) => MPromise<SendProcData>, A>;
|
|
322
273
|
sendNone(): UtilHttp<D, typeof SendNoneProc, A>;
|
|
323
274
|
/**自定的发送数据类型 */
|
|
324
275
|
sendRaw<T extends any[]>(proc: SendProcCtor<T>): UtilHttp<D, typeof proc, A>;
|
|
@@ -343,12 +294,14 @@ export declare class UtilHttp<D extends Partial<RequestOption> & Required<Pick<R
|
|
|
343
294
|
} : {
|
|
344
295
|
option: OPT;
|
|
345
296
|
})>): Promise<import("@zwa73/js-utils").PromiseRetryResult<ParseResult<A>>>;
|
|
297
|
+
/**控制请求间隔的队列 */
|
|
298
|
+
static requestQueue: PromiseQueue;
|
|
346
299
|
/**发送网络请求
|
|
347
300
|
* @param option - 网络请求选项
|
|
348
301
|
* @param reqProc - 请求处理函数 需调用req.end()
|
|
349
302
|
* @param acceptProc - 响应处理数据
|
|
350
303
|
*/
|
|
351
|
-
static request<T>(option: RequestOption, sendProc:
|
|
304
|
+
static request<T>(option: RequestOption, sendProc: SendProcData, acceptProc: Omit<AcceptProcData<T, unknown>, 'parse'>): Promise<RequestResult<T> | undefined>;
|
|
352
305
|
/**构建query */
|
|
353
306
|
static buildQuery(base: string, data: QueryRequestData): string;
|
|
354
307
|
}
|
package/dist/UtilHttp.js
CHANGED
|
@@ -16,21 +16,30 @@ const https_proxy_agent_1 = __importDefault(require("https-proxy-agent"));
|
|
|
16
16
|
const js_utils_1 = require("@zwa73/js-utils");
|
|
17
17
|
const fs_1 = __importDefault(require("fs"));
|
|
18
18
|
const pathe_1 = __importDefault(require("pathe"));
|
|
19
|
-
const
|
|
20
|
-
const SendTypeList = ["json", "query", "formData", "none"];
|
|
21
|
-
const SendNoneProc = () => ({
|
|
19
|
+
const SendNoneProc = {
|
|
22
20
|
proc: req => void req.end()
|
|
23
|
-
}
|
|
24
|
-
const AcceptStringProc =
|
|
21
|
+
};
|
|
22
|
+
const AcceptStringProc = {
|
|
25
23
|
init: () => '',
|
|
26
24
|
reduce: (acc, dat) => acc + dat,
|
|
27
|
-
parse:
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
parse: result => {
|
|
26
|
+
if (result == undefined) {
|
|
27
|
+
UtilLogger_1.SLogger.warn(`accept json 接收反馈错误: 响应结果无效`);
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const AcceptNoneProc = {
|
|
30
34
|
init: () => undefined,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
parse: result => {
|
|
36
|
+
if (result == undefined) {
|
|
37
|
+
UtilLogger_1.SLogger.warn(`accept none 接收反馈错误: 响应结果无效`);
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
34
43
|
/**http请求工具 */
|
|
35
44
|
class UtilHttp {
|
|
36
45
|
_data;
|
|
@@ -149,40 +158,31 @@ class UtilHttp {
|
|
|
149
158
|
}
|
|
150
159
|
//#endregion
|
|
151
160
|
//#region 接收数据类型
|
|
152
|
-
/**预设的接收数据类型*/
|
|
153
|
-
accept(t) {
|
|
154
|
-
const map = {
|
|
155
|
-
'json': this.acceptJson(),
|
|
156
|
-
'string': this.acceptString(),
|
|
157
|
-
'none': this.acceptNone(),
|
|
158
|
-
};
|
|
159
|
-
return map[t];
|
|
160
|
-
}
|
|
161
161
|
acceptJson() {
|
|
162
|
-
const acceptProc =
|
|
162
|
+
const acceptProc = {
|
|
163
163
|
init: () => '',
|
|
164
164
|
reduce: (acc, curr) => acc + curr,
|
|
165
165
|
parse: result => {
|
|
166
166
|
if (result == undefined) {
|
|
167
|
-
UtilLogger_1.SLogger.warn(`json
|
|
167
|
+
UtilLogger_1.SLogger.warn(`accept json 接收反馈错误: 响应结果无效`);
|
|
168
168
|
return undefined;
|
|
169
169
|
}
|
|
170
170
|
const { data, ...rest } = result;
|
|
171
171
|
if (data.trim() == "") {
|
|
172
|
-
UtilLogger_1.SLogger.warn(`json
|
|
172
|
+
UtilLogger_1.SLogger.warn(`accept json 接收反馈错误: 原始字符串为空`, UtilFunctions_1.UtilFunc.stringifyJToken(result, { compress: true, space: 2 }));
|
|
173
173
|
return { ...result, raw: "", data: null };
|
|
174
174
|
}
|
|
175
175
|
try {
|
|
176
176
|
const obj = JSON.parse(data.trim());
|
|
177
|
-
UtilLogger_1.SLogger.http(`json
|
|
177
|
+
UtilLogger_1.SLogger.http(`accept json 接受信息 data:`, UtilFunctions_1.UtilFunc.stringifyJToken(obj, { compress: true, space: 2 }), `result:`, UtilFunctions_1.UtilFunc.stringifyJToken(rest, { compress: true, space: 2 }));
|
|
178
178
|
return { ...rest, data: obj };
|
|
179
179
|
}
|
|
180
180
|
catch (err) {
|
|
181
|
-
UtilLogger_1.SLogger.warn(`json
|
|
181
|
+
UtilLogger_1.SLogger.warn(`accept json 接收反馈错误:`, err, UtilFunctions_1.UtilFunc.stringifyJToken(result, { compress: true, space: 2 }));
|
|
182
182
|
return { ...result, raw: data, data: null };
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
|
-
}
|
|
185
|
+
};
|
|
186
186
|
this._accept = acceptProc;
|
|
187
187
|
return this;
|
|
188
188
|
}
|
|
@@ -200,7 +200,7 @@ class UtilHttp {
|
|
|
200
200
|
const fileStream = fs_1.default.createWriteStream(arg.acceptFilepath);
|
|
201
201
|
const fileWritePromise = new Promise((resolve) => {
|
|
202
202
|
fileStream.on('error', err => {
|
|
203
|
-
UtilLogger_1.SLogger.warn(`file
|
|
203
|
+
UtilLogger_1.SLogger.warn(`accept file 文件流写入错误:`, err);
|
|
204
204
|
resolve(false); // 标记写入已结束, 但失败
|
|
205
205
|
});
|
|
206
206
|
fileStream.on('finish', () => {
|
|
@@ -210,10 +210,11 @@ class UtilHttp {
|
|
|
210
210
|
res.pipe(fileStream);
|
|
211
211
|
return { promise: fileWritePromise };
|
|
212
212
|
},
|
|
213
|
-
reduce: acc => acc,
|
|
214
213
|
parse: async (result) => {
|
|
215
|
-
if (result == undefined)
|
|
214
|
+
if (result == undefined) {
|
|
215
|
+
UtilLogger_1.SLogger.warn(`accept file 接收反馈错误: 响应结果无效`);
|
|
216
216
|
return undefined;
|
|
217
|
+
}
|
|
217
218
|
const success = await result.data.promise;
|
|
218
219
|
if (!success)
|
|
219
220
|
return undefined;
|
|
@@ -230,18 +231,6 @@ class UtilHttp {
|
|
|
230
231
|
}
|
|
231
232
|
//#endregion
|
|
232
233
|
//#region 发送数据类型
|
|
233
|
-
/**预设的发送数据类型 */
|
|
234
|
-
send(t) {
|
|
235
|
-
const map = {
|
|
236
|
-
'json': this.sendJson(),
|
|
237
|
-
'query': this.sendQuery(),
|
|
238
|
-
'formData': this.sendFormData(),
|
|
239
|
-
'form': this.sendForm(),
|
|
240
|
-
'file': this.sendFile(),
|
|
241
|
-
'none': this.sendNone(),
|
|
242
|
-
};
|
|
243
|
-
return map[t];
|
|
244
|
-
}
|
|
245
234
|
/**发送json
|
|
246
235
|
* 请求参数为 (token:JToken)
|
|
247
236
|
*/
|
|
@@ -253,7 +242,7 @@ class UtilHttp {
|
|
|
253
242
|
this._data.headers ??= {};
|
|
254
243
|
this._data.headers['Content-Length'] = Buffer.byteLength(data);
|
|
255
244
|
return {
|
|
256
|
-
proc:
|
|
245
|
+
proc: req => {
|
|
257
246
|
if (isPost)
|
|
258
247
|
req.write(data);
|
|
259
248
|
req.end();
|
|
@@ -265,24 +254,29 @@ class UtilHttp {
|
|
|
265
254
|
this._data.headers['Content-Type'] = 'application/json';
|
|
266
255
|
return this;
|
|
267
256
|
}
|
|
268
|
-
/**利用 appendQuery
|
|
257
|
+
/**利用 appendQuery 直接将表单附加在path上发送请求 */
|
|
269
258
|
sendQuery() {
|
|
270
259
|
const sendProc = (opt, arg) => {
|
|
271
260
|
opt.path = UtilHttp.buildQuery(opt.path ?? '', arg.query);
|
|
272
261
|
return {
|
|
273
|
-
proc:
|
|
262
|
+
proc: req => void req.end()
|
|
274
263
|
};
|
|
275
264
|
};
|
|
276
265
|
this._send = sendProc;
|
|
277
266
|
return this;
|
|
278
267
|
}
|
|
279
|
-
|
|
268
|
+
/**发送form-data包提供的表单数据 */
|
|
280
269
|
sendFormData() {
|
|
281
270
|
const sendProc = (opt, arg) => {
|
|
271
|
+
const { method } = opt;
|
|
272
|
+
const isPost = (method == "POST");
|
|
282
273
|
opt.headers = arg.formdata.getHeaders();
|
|
283
274
|
return {
|
|
284
275
|
proc: (req) => {
|
|
285
|
-
|
|
276
|
+
if (isPost)
|
|
277
|
+
arg.formdata.pipe(req);
|
|
278
|
+
else
|
|
279
|
+
req.end();
|
|
286
280
|
}
|
|
287
281
|
};
|
|
288
282
|
};
|
|
@@ -300,7 +294,7 @@ class UtilHttp {
|
|
|
300
294
|
this._data.headers ??= {};
|
|
301
295
|
this._data.headers['Content-Length'] = Buffer.byteLength(data);
|
|
302
296
|
return {
|
|
303
|
-
proc:
|
|
297
|
+
proc: req => {
|
|
304
298
|
if (isPost)
|
|
305
299
|
req.write(data);
|
|
306
300
|
req.end();
|
|
@@ -315,14 +309,19 @@ class UtilHttp {
|
|
|
315
309
|
/**发送文件 */
|
|
316
310
|
sendFile() {
|
|
317
311
|
const proc = (opt, arg) => {
|
|
312
|
+
const { method } = opt;
|
|
313
|
+
const isPost = (method == "POST");
|
|
318
314
|
let { filepath, filename } = arg;
|
|
319
315
|
const formData = new form_data_1.default();
|
|
320
316
|
filename = filename ?? pathe_1.default.basename(filepath);
|
|
321
317
|
formData.append(filename, fs_1.default.createReadStream(filepath));
|
|
322
318
|
opt.headers = formData.getHeaders();
|
|
323
319
|
return {
|
|
324
|
-
proc:
|
|
325
|
-
|
|
320
|
+
proc: req => {
|
|
321
|
+
if (isPost)
|
|
322
|
+
formData.pipe(req);
|
|
323
|
+
else
|
|
324
|
+
req.end();
|
|
326
325
|
}
|
|
327
326
|
};
|
|
328
327
|
};
|
|
@@ -346,8 +345,12 @@ class UtilHttp {
|
|
|
346
345
|
*/
|
|
347
346
|
async once(arg) {
|
|
348
347
|
const fullopt = { ...this._data, ...arg.option ?? {} };
|
|
349
|
-
const sendProc =
|
|
350
|
-
|
|
348
|
+
const sendProc = typeof this._send === 'function'
|
|
349
|
+
? await this._send(fullopt, arg)
|
|
350
|
+
: this._send;
|
|
351
|
+
const { parse, ...acceptProc } = typeof this._accept === 'function'
|
|
352
|
+
? await this._accept(arg)
|
|
353
|
+
: this._accept;
|
|
351
354
|
const res = await UtilHttp.request(fullopt, sendProc, acceptProc);
|
|
352
355
|
return parse(res);
|
|
353
356
|
}
|
|
@@ -363,6 +366,8 @@ class UtilHttp {
|
|
|
363
366
|
const procFn = async () => this.once(arg);
|
|
364
367
|
return UtilFunctions_1.UtilFunc.retryPromise(procFn, verify, retries);
|
|
365
368
|
}
|
|
369
|
+
/**控制请求间隔的队列 */
|
|
370
|
+
static requestQueue = new js_utils_1.PromiseQueue();
|
|
366
371
|
/**发送网络请求
|
|
367
372
|
* @param option - 网络请求选项
|
|
368
373
|
* @param reqProc - 请求处理函数 需调用req.end()
|
|
@@ -371,12 +376,15 @@ class UtilHttp {
|
|
|
371
376
|
static async request(option, sendProc, acceptProc) {
|
|
372
377
|
const { reduce: reqReduce, init: reqInit } = acceptProc;
|
|
373
378
|
const { proc: reqProc } = sendProc;
|
|
374
|
-
const { protocol, timeout, ...baseReqOpt } = option;
|
|
375
|
-
const plusTimeout =
|
|
376
|
-
const hasTimeLimit =
|
|
379
|
+
const { protocol, timeout = 0, interval = 1, ...baseReqOpt } = option;
|
|
380
|
+
const plusTimeout = timeout + 1000;
|
|
381
|
+
const hasTimeLimit = timeout >= 10_000;
|
|
377
382
|
const flagName = `UtilCom.request ${protocol}${baseReqOpt.method} ${UtilFunctions_1.UtilFunc.genUUID()}`;
|
|
378
383
|
const reduceQueue = new js_utils_1.PromiseQueue();
|
|
379
384
|
let dataPromise = null;
|
|
385
|
+
//等待间隔
|
|
386
|
+
if (UtilHttp.requestQueue.length > 0)
|
|
387
|
+
await UtilHttp.requestQueue.enqueue(async () => UtilFunctions_1.UtilFunc.sleep(interval));
|
|
380
388
|
return new Promise(async (resolve, rejecte) => {
|
|
381
389
|
const finallyTimeout = hasTimeLimit
|
|
382
390
|
? setTimeout(() => {
|
|
@@ -407,18 +415,20 @@ class UtilHttp {
|
|
|
407
415
|
return;
|
|
408
416
|
}
|
|
409
417
|
res.setEncoding(option.responseEncode ?? 'utf8');
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
418
|
+
if (reqReduce) {
|
|
419
|
+
res.on('data', chunk => {
|
|
420
|
+
dataPromise = reduceQueue
|
|
421
|
+
.enqueue(async () => {
|
|
422
|
+
try {
|
|
423
|
+
mergedata = await reqReduce(mergedata, chunk);
|
|
424
|
+
}
|
|
425
|
+
catch (err) {
|
|
426
|
+
UtilLogger_1.SLogger.error(`${flagName} reduce函数错误:`, err, `chunk:${chunk}\nmergedata:`, mergedata);
|
|
427
|
+
finallyResolve(undefined);
|
|
428
|
+
}
|
|
429
|
+
});
|
|
420
430
|
});
|
|
421
|
-
}
|
|
431
|
+
}
|
|
422
432
|
res.on('error', err => {
|
|
423
433
|
UtilLogger_1.SLogger.warn(`${flagName} 接收反馈错误:`, err);
|
|
424
434
|
finallyResolve(undefined);
|