@zwa73/utils 1.0.232 → 1.0.233
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 +142 -69
- package/dist/UtilHttp.js +139 -109
- package/package.json +1 -1
package/dist/UtilHttp.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ 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 { RequiredOnly } from "@zwa73/js-utils";
|
|
6
5
|
/**网络请求返回值 */
|
|
7
6
|
export type RequestResult<T> = {
|
|
8
7
|
/**响应头 */
|
|
@@ -39,34 +38,47 @@ export type RequestOption = {
|
|
|
39
38
|
/**getquery请求所允许的数据 */
|
|
40
39
|
export type QueryRequestData = NodeJS.Dict<string | number | boolean | readonly string[] | readonly number[] | readonly boolean[] | null>;
|
|
41
40
|
/**请求处理函数 需调用req.end() */
|
|
42
|
-
export type RequestProcFn = (
|
|
41
|
+
export type RequestProcFn = (req: http.ClientRequest) => MPromise<void>;
|
|
42
|
+
/**结果处理函数 */
|
|
43
|
+
export type RequestParseFn<D, R> = (result: RequestResult<D> | undefined) => MPromise<R>;
|
|
43
44
|
/**数据处理函数 */
|
|
44
45
|
export type RequestReduceFn<T> = (acc: T, data: string) => MPromise<T>;
|
|
46
|
+
/**数据初始化函数 */
|
|
47
|
+
export type RequestInitFn<T> = (res: http.IncomingMessage) => MPromise<T>;
|
|
45
48
|
declare const AcceptTypeList: readonly ["json", "string"];
|
|
46
49
|
/**可用的接受类型 */
|
|
47
50
|
type AcceptType = typeof AcceptTypeList[number];
|
|
48
51
|
declare const SendTypeList: readonly ["json", "query", "formData", "none"];
|
|
49
52
|
/**可用的发送类型 */
|
|
50
53
|
type SendType = typeof SendTypeList[number];
|
|
51
|
-
/**accept处理数据
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
/**accept处理数据
|
|
55
|
+
* @template D - 接受时转换的数据类型
|
|
56
|
+
* @template R - 完成处理的数据类型
|
|
57
|
+
*/
|
|
58
|
+
type AcceptProcCtor<D, R, T> = (arg: T) => MPromise<AcceptProc<D, R>>;
|
|
59
|
+
type AcceptProc<D, R> = {
|
|
60
|
+
init: RequestInitFn<D>;
|
|
54
61
|
reduce: RequestReduceFn<D>;
|
|
55
|
-
parse:
|
|
62
|
+
parse: RequestParseFn<D, R>;
|
|
56
63
|
};
|
|
57
64
|
/**send处理数据 */
|
|
58
|
-
type
|
|
59
|
-
|
|
65
|
+
type SendProcCtor<T extends {}> = (opt: RequestOption, arg: T) => MPromise<SendProc>;
|
|
66
|
+
type SendProc = {
|
|
67
|
+
proc: RequestProcFn;
|
|
60
68
|
};
|
|
61
|
-
declare const SendNoneProc:
|
|
62
|
-
declare const AcceptStringProc:
|
|
63
|
-
declare const AcceptNoneProc:
|
|
69
|
+
declare const SendNoneProc: SendProcCtor<{}>;
|
|
70
|
+
declare const AcceptStringProc: AcceptProcCtor<string, RequestResult<string> | undefined, {}>;
|
|
71
|
+
declare const AcceptNoneProc: AcceptProcCtor<undefined, undefined, {}>;
|
|
64
72
|
/**send处理的参数 */
|
|
65
|
-
type SendParams<
|
|
73
|
+
type SendParams<S extends SendProcCtor<any>> = S extends SendProcCtor<infer P> ? P : never;
|
|
74
|
+
/**send处理的参数 */
|
|
75
|
+
type AcceptParams<A extends AcceptProcCtor<any, any, any>> = A extends AcceptProcCtor<any, any, infer P> ? P : never;
|
|
76
|
+
type HasConflict<A, B> = keyof A & keyof B extends never ? false : true;
|
|
77
|
+
type ConflictCheck<A, B, C> = HasConflict<A, B> extends true ? A & B & C & Error & "❌ A 与 B 有字段冲突" : HasConflict<A, C> extends true ? A & B & C & Error & "❌ A 与 C 有字段冲突" : HasConflict<B, C> extends true ? A & B & C & Error & "❌ B 与 C 有字段冲突" : A & B & C;
|
|
66
78
|
/**accept处理的结果 */
|
|
67
|
-
type ParseResult<P extends
|
|
79
|
+
type ParseResult<P extends AcceptProcCtor<any, any, any>> = P extends AcceptProcCtor<any, infer T, any> ? Awaited<T> : never;
|
|
68
80
|
/**http请求工具 */
|
|
69
|
-
export declare class UtilHttp<D extends Partial<RequestOption> & Required<Pick<RequestOption, 'protocol'>>, S extends
|
|
81
|
+
export declare class UtilHttp<D extends Partial<RequestOption> & Required<Pick<RequestOption, 'protocol'>>, S extends SendProcCtor<any>, A extends AcceptProcCtor<any, any, any>> {
|
|
70
82
|
private _data;
|
|
71
83
|
private _send;
|
|
72
84
|
private _accept;
|
|
@@ -74,11 +86,11 @@ export declare class UtilHttp<D extends Partial<RequestOption> & Required<Pick<R
|
|
|
74
86
|
/**设为https请求 */
|
|
75
87
|
static https(): UtilHttp<{
|
|
76
88
|
readonly protocol: "https:";
|
|
77
|
-
},
|
|
89
|
+
}, SendProcCtor<{}>, AcceptProcCtor<string, RequestResult<string> | undefined, {}>>;
|
|
78
90
|
/**设为http请求 */
|
|
79
91
|
static http(): UtilHttp<{
|
|
80
92
|
readonly protocol: "http:";
|
|
81
|
-
},
|
|
93
|
+
}, SendProcCtor<{}>, AcceptProcCtor<string, RequestResult<string> | undefined, {}>>;
|
|
82
94
|
/**从url创建 */
|
|
83
95
|
static url(urlStr: `${'http:' | 'https:'}//${string}`): UtilHttp<{
|
|
84
96
|
protocol: "http:" | "https:";
|
|
@@ -86,7 +98,7 @@ export declare class UtilHttp<D extends Partial<RequestOption> & Required<Pick<R
|
|
|
86
98
|
hostname: string;
|
|
87
99
|
path: string;
|
|
88
100
|
port: number | undefined;
|
|
89
|
-
},
|
|
101
|
+
}, SendProcCtor<{}>, AcceptProcCtor<string, RequestResult<string> | undefined, {}>>;
|
|
90
102
|
/**设为get方式的请求 */
|
|
91
103
|
get(): UtilHttp<D & {
|
|
92
104
|
method: "GET";
|
|
@@ -100,11 +112,6 @@ export declare class UtilHttp<D extends Partial<RequestOption> & Required<Pick<R
|
|
|
100
112
|
* 将会替换对应字段, 修改headers请用header函数
|
|
101
113
|
*/
|
|
102
114
|
option<OPT extends Partial<RequestOption>>(option: OPT): UtilHttp<D & OPT, S, A>;
|
|
103
|
-
/**完成参数
|
|
104
|
-
* 会检查必要参数完整性
|
|
105
|
-
* 将会替换对应字段, 修改headers请用header函数
|
|
106
|
-
*/
|
|
107
|
-
finalize<OPT extends PartialOption<RequestOption, D>>(option: OPT): UtilHttp<D & OPT, S, A>;
|
|
108
115
|
/**补充header */
|
|
109
116
|
header<HAD extends http.OutgoingHttpHeaders>(headers: HAD): UtilHttp<D & {
|
|
110
117
|
headers: HAD;
|
|
@@ -120,7 +127,10 @@ export declare class UtilHttp<D extends Partial<RequestOption> & Required<Pick<R
|
|
|
120
127
|
headers: {
|
|
121
128
|
"Content-Type": "application/json";
|
|
122
129
|
};
|
|
123
|
-
},
|
|
130
|
+
}, SendProcCtor<{
|
|
131
|
+
/**发送的json */
|
|
132
|
+
json: JToken;
|
|
133
|
+
}>, AcceptProcCtor<string, RequestResult<JToken> | undefined, {}>>;
|
|
124
134
|
/**收发皆为json的post预设 */
|
|
125
135
|
postJson(): UtilHttp<D & {
|
|
126
136
|
method: "POST";
|
|
@@ -128,15 +138,21 @@ export declare class UtilHttp<D extends Partial<RequestOption> & Required<Pick<R
|
|
|
128
138
|
headers: {
|
|
129
139
|
'Content-Type': "application/json";
|
|
130
140
|
};
|
|
131
|
-
},
|
|
141
|
+
}, SendProcCtor<{
|
|
142
|
+
/**发送的json */
|
|
143
|
+
json: JToken;
|
|
144
|
+
}>, AcceptProcCtor<string, RequestResult<JToken> | undefined, {}>>;
|
|
132
145
|
/**无查询参数获取json的get预设 */
|
|
133
146
|
getJson(): UtilHttp<D & {
|
|
134
147
|
method: "GET";
|
|
135
|
-
},
|
|
148
|
+
}, SendProcCtor<{}>, AcceptProcCtor<string, RequestResult<JToken> | undefined, {}>>;
|
|
136
149
|
/**有查询参数获取json的get预设 */
|
|
137
150
|
queryJson(): UtilHttp<D & {
|
|
138
151
|
method: "GET";
|
|
139
|
-
},
|
|
152
|
+
}, SendProcCtor<{
|
|
153
|
+
/**附加的查询表单数据 */
|
|
154
|
+
query: QueryRequestData;
|
|
155
|
+
}>, AcceptProcCtor<string, RequestResult<JToken> | undefined, {}>>;
|
|
140
156
|
/**收发皆为json的https-post预设 */
|
|
141
157
|
static httpsPostJson(): UtilHttp<{
|
|
142
158
|
readonly protocol: "https:";
|
|
@@ -146,7 +162,10 @@ export declare class UtilHttp<D extends Partial<RequestOption> & Required<Pick<R
|
|
|
146
162
|
headers: {
|
|
147
163
|
'Content-Type': "application/json";
|
|
148
164
|
};
|
|
149
|
-
},
|
|
165
|
+
}, SendProcCtor<{
|
|
166
|
+
/**发送的json */
|
|
167
|
+
json: JToken;
|
|
168
|
+
}>, AcceptProcCtor<string, RequestResult<JToken> | undefined, {}>>;
|
|
150
169
|
/**收发皆为json的http-post预设 */
|
|
151
170
|
static httpPostJson(): UtilHttp<{
|
|
152
171
|
readonly protocol: "http:";
|
|
@@ -156,66 +175,104 @@ export declare class UtilHttp<D extends Partial<RequestOption> & Required<Pick<R
|
|
|
156
175
|
headers: {
|
|
157
176
|
'Content-Type': "application/json";
|
|
158
177
|
};
|
|
159
|
-
},
|
|
178
|
+
}, SendProcCtor<{
|
|
179
|
+
/**发送的json */
|
|
180
|
+
json: JToken;
|
|
181
|
+
}>, AcceptProcCtor<string, RequestResult<JToken> | undefined, {}>>;
|
|
160
182
|
/**无查询参数获取json的https-get预设 */
|
|
161
183
|
static httpsGetJson(): UtilHttp<{
|
|
162
184
|
readonly protocol: "https:";
|
|
163
185
|
} & {
|
|
164
186
|
method: "GET";
|
|
165
|
-
},
|
|
187
|
+
}, SendProcCtor<{}>, AcceptProcCtor<string, RequestResult<JToken> | undefined, {}>>;
|
|
166
188
|
/**有查询参数获取json的https-get预设 */
|
|
167
189
|
static httpsQueryJson(): UtilHttp<{
|
|
168
190
|
readonly protocol: "http:";
|
|
169
191
|
} & {
|
|
170
192
|
method: "GET";
|
|
171
|
-
},
|
|
193
|
+
}, SendProcCtor<{
|
|
194
|
+
/**附加的查询表单数据 */
|
|
195
|
+
query: QueryRequestData;
|
|
196
|
+
}>, AcceptProcCtor<string, RequestResult<JToken> | undefined, {}>>;
|
|
172
197
|
/**无查询参数获取json的http-get预设 */
|
|
173
198
|
static httpGetJson(): UtilHttp<{
|
|
174
199
|
readonly protocol: "http:";
|
|
175
200
|
} & {
|
|
176
201
|
method: "GET";
|
|
177
|
-
},
|
|
202
|
+
}, SendProcCtor<{}>, AcceptProcCtor<string, RequestResult<JToken> | undefined, {}>>;
|
|
178
203
|
/**有查询参数获取json的http-get预设 */
|
|
179
204
|
static httpQueryJson(): UtilHttp<{
|
|
180
205
|
readonly protocol: "http:";
|
|
181
206
|
} & {
|
|
182
207
|
method: "GET";
|
|
183
|
-
},
|
|
208
|
+
}, SendProcCtor<{
|
|
209
|
+
/**附加的查询表单数据 */
|
|
210
|
+
query: QueryRequestData;
|
|
211
|
+
}>, AcceptProcCtor<string, RequestResult<JToken> | undefined, {}>>;
|
|
184
212
|
/**预设的接收数据类型*/
|
|
185
213
|
accept<T extends AcceptType>(t: T): {
|
|
186
|
-
readonly json: UtilHttp<D, S,
|
|
187
|
-
readonly string: UtilHttp<D, S,
|
|
188
|
-
readonly none: UtilHttp<D, S,
|
|
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, {}>>;
|
|
189
217
|
}[T];
|
|
190
|
-
acceptJson(): UtilHttp<D, S,
|
|
218
|
+
acceptJson(): UtilHttp<D, S, AcceptProcCtor<string, RequestResult<JToken> | undefined, {}>>;
|
|
191
219
|
acceptString(): UtilHttp<D, S, typeof AcceptStringProc>;
|
|
192
220
|
acceptNone(): UtilHttp<D, S, typeof AcceptNoneProc>;
|
|
221
|
+
acceptFile(): UtilHttp<D, S, AcceptProcCtor<{
|
|
222
|
+
promise: Promise<boolean>;
|
|
223
|
+
}, {
|
|
224
|
+
/**响应头 */
|
|
225
|
+
headers: http.IncomingHttpHeaders;
|
|
226
|
+
/**响应状态码 */
|
|
227
|
+
statusCode?: number;
|
|
228
|
+
/**保存文件路径 */
|
|
229
|
+
filepath: string;
|
|
230
|
+
} | undefined, {
|
|
231
|
+
acceptFilepath: string;
|
|
232
|
+
}>>;
|
|
193
233
|
/**自定的接收数据类型*/
|
|
194
|
-
acceptRaw<AD, AT>(proc:
|
|
234
|
+
acceptRaw<AD, AR, AT>(proc: AcceptProcCtor<AD, AR, AT>): UtilHttp<D, S, typeof proc>;
|
|
195
235
|
/**预设的发送数据类型 */
|
|
196
236
|
send<T extends SendType>(t: T): {
|
|
197
237
|
readonly json: UtilHttp<D & {
|
|
198
238
|
headers: {
|
|
199
239
|
"Content-Type": "application/json";
|
|
200
240
|
};
|
|
201
|
-
},
|
|
202
|
-
|
|
241
|
+
}, SendProcCtor<{
|
|
242
|
+
/**发送的json */
|
|
243
|
+
json: JToken;
|
|
244
|
+
}>, A>;
|
|
245
|
+
readonly query: UtilHttp<D, SendProcCtor<{
|
|
246
|
+
/**附加的查询表单数据 */
|
|
247
|
+
query: QueryRequestData;
|
|
248
|
+
}>, A>;
|
|
203
249
|
readonly formData: UtilHttp<D & {
|
|
204
250
|
headers: {
|
|
205
251
|
"Content-Type": "multipart/form-data";
|
|
206
252
|
};
|
|
207
|
-
},
|
|
253
|
+
}, SendProcCtor<{
|
|
254
|
+
/**form-data包提供的FormData表单数据 */
|
|
255
|
+
formdata: FormData;
|
|
256
|
+
}>, A>;
|
|
208
257
|
readonly form: UtilHttp<D & {
|
|
209
258
|
headers: {
|
|
210
259
|
"Content-Type": "application/x-www-form-urlencoded";
|
|
211
260
|
};
|
|
212
|
-
},
|
|
261
|
+
}, SendProcCtor<{
|
|
262
|
+
/**表单 */
|
|
263
|
+
form: QueryRequestData;
|
|
264
|
+
}>, A>;
|
|
213
265
|
readonly file: UtilHttp<D & {
|
|
214
266
|
headers: {
|
|
215
267
|
"Content-Type": "multipart/form-data";
|
|
216
268
|
};
|
|
217
|
-
},
|
|
218
|
-
|
|
269
|
+
}, SendProcCtor<{
|
|
270
|
+
/**文件路径 */
|
|
271
|
+
filepath: string;
|
|
272
|
+
/**文件名 */
|
|
273
|
+
filename?: string;
|
|
274
|
+
}>, A>;
|
|
275
|
+
readonly none: UtilHttp<D, SendProcCtor<{}>, A>;
|
|
219
276
|
}[T];
|
|
220
277
|
/**发送json
|
|
221
278
|
* 请求参数为 (token:JToken)
|
|
@@ -224,58 +281,74 @@ export declare class UtilHttp<D extends Partial<RequestOption> & Required<Pick<R
|
|
|
224
281
|
headers: {
|
|
225
282
|
"Content-Type": "application/json";
|
|
226
283
|
};
|
|
227
|
-
},
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
284
|
+
}, SendProcCtor<{
|
|
285
|
+
/**发送的json */
|
|
286
|
+
json: JToken;
|
|
287
|
+
}>, A>;
|
|
288
|
+
/**利用 appendQuery 直接将数据附加在path上发送请求 */
|
|
289
|
+
sendQuery(): UtilHttp<D, SendProcCtor<{
|
|
290
|
+
/**附加的查询表单数据 */
|
|
291
|
+
query: QueryRequestData;
|
|
292
|
+
}>, A>;
|
|
293
|
+
/**发送表单数据 */
|
|
235
294
|
sendFormData(): UtilHttp<D & {
|
|
236
295
|
headers: {
|
|
237
296
|
"Content-Type": "multipart/form-data";
|
|
238
297
|
};
|
|
239
|
-
},
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
298
|
+
}, SendProcCtor<{
|
|
299
|
+
/**form-data包提供的FormData表单数据 */
|
|
300
|
+
formdata: FormData;
|
|
301
|
+
}>, A>;
|
|
302
|
+
/**发送表单 */
|
|
243
303
|
sendForm(): UtilHttp<D & {
|
|
244
304
|
headers: {
|
|
245
305
|
"Content-Type": "application/x-www-form-urlencoded";
|
|
246
306
|
};
|
|
247
|
-
},
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
307
|
+
}, SendProcCtor<{
|
|
308
|
+
/**表单 */
|
|
309
|
+
form: QueryRequestData;
|
|
310
|
+
}>, A>;
|
|
311
|
+
/**发送文件 */
|
|
251
312
|
sendFile(): UtilHttp<D & {
|
|
252
313
|
headers: {
|
|
253
314
|
"Content-Type": "multipart/form-data";
|
|
254
315
|
};
|
|
255
|
-
},
|
|
316
|
+
}, SendProcCtor<{
|
|
317
|
+
/**文件路径 */
|
|
318
|
+
filepath: string;
|
|
319
|
+
/**文件名 */
|
|
320
|
+
filename?: string;
|
|
321
|
+
}>, A>;
|
|
256
322
|
sendNone(): UtilHttp<D, typeof SendNoneProc, A>;
|
|
257
323
|
/**自定的发送数据类型 */
|
|
258
|
-
sendRaw<T extends any[]>(proc:
|
|
324
|
+
sendRaw<T extends any[]>(proc: SendProcCtor<T>): UtilHttp<D, typeof proc, A>;
|
|
259
325
|
/**发送请求
|
|
260
326
|
* @param datas - 数据对象
|
|
261
327
|
*/
|
|
262
|
-
once
|
|
328
|
+
once<OPT extends PartialOption<RequestOption, D>>(arg: ConflictCheck<SendParams<S>, AcceptParams<A>, ({} extends OPT ? {
|
|
329
|
+
option?: OPT;
|
|
330
|
+
} : {
|
|
331
|
+
option: OPT;
|
|
332
|
+
})>): Promise<ParseResult<A>>;
|
|
263
333
|
/**重复发送网络请求
|
|
264
334
|
* @param verify - 有效性验证函数
|
|
265
335
|
* @param retries - 重试选项 默认 延迟:1000ms 间隔:180_000ms 重试:3次
|
|
266
336
|
* @param datas - 数据对象
|
|
267
337
|
*/
|
|
268
|
-
retry(
|
|
338
|
+
retry<OPT extends PartialOption<RequestOption, D>>(arg: ConflictCheck<SendParams<S>, AcceptParams<A>, {
|
|
269
339
|
verify?: StatusVerifyFn<ParseResult<A>>;
|
|
270
340
|
retries?: PromiseRetries;
|
|
271
|
-
}
|
|
341
|
+
} & ({} extends OPT ? {
|
|
342
|
+
option?: OPT;
|
|
343
|
+
} : {
|
|
344
|
+
option: OPT;
|
|
345
|
+
})>): Promise<import("@zwa73/js-utils").PromiseRetryResult<ParseResult<A>>>;
|
|
272
346
|
/**发送网络请求
|
|
273
|
-
* @param option
|
|
274
|
-
* @param
|
|
275
|
-
* @param
|
|
276
|
-
* @param init - 初始数据
|
|
347
|
+
* @param option - 网络请求选项
|
|
348
|
+
* @param reqProc - 请求处理函数 需调用req.end()
|
|
349
|
+
* @param acceptProc - 响应处理数据
|
|
277
350
|
*/
|
|
278
|
-
static request<T>(option: RequestOption,
|
|
351
|
+
static request<T>(option: RequestOption, sendProc: SendProc, acceptProc: Omit<AcceptProc<T, unknown>, 'parse'>): Promise<RequestResult<T> | undefined>;
|
|
279
352
|
/**构建query */
|
|
280
353
|
static buildQuery(base: string, data: QueryRequestData): string;
|
|
281
354
|
}
|
package/dist/UtilHttp.js
CHANGED
|
@@ -18,19 +18,19 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
18
18
|
const pathe_1 = __importDefault(require("pathe"));
|
|
19
19
|
const AcceptTypeList = ["json", "string"];
|
|
20
20
|
const SendTypeList = ["json", "query", "formData", "none"];
|
|
21
|
-
const SendNoneProc = {
|
|
22
|
-
proc:
|
|
23
|
-
};
|
|
24
|
-
const AcceptStringProc = {
|
|
25
|
-
init: '',
|
|
21
|
+
const SendNoneProc = () => ({
|
|
22
|
+
proc: req => void req.end()
|
|
23
|
+
});
|
|
24
|
+
const AcceptStringProc = () => ({
|
|
25
|
+
init: () => '',
|
|
26
26
|
reduce: (acc, dat) => acc + dat,
|
|
27
27
|
parse: (result) => result
|
|
28
|
-
};
|
|
29
|
-
const AcceptNoneProc = {
|
|
30
|
-
init: undefined,
|
|
28
|
+
});
|
|
29
|
+
const AcceptNoneProc = () => ({
|
|
30
|
+
init: () => undefined,
|
|
31
31
|
reduce: () => undefined,
|
|
32
32
|
parse: () => undefined
|
|
33
|
-
};
|
|
33
|
+
});
|
|
34
34
|
/**http请求工具 */
|
|
35
35
|
class UtilHttp {
|
|
36
36
|
_data;
|
|
@@ -80,14 +80,6 @@ class UtilHttp {
|
|
|
80
80
|
this._data = { ...this._data, ...option };
|
|
81
81
|
return this;
|
|
82
82
|
}
|
|
83
|
-
/**完成参数
|
|
84
|
-
* 会检查必要参数完整性
|
|
85
|
-
* 将会替换对应字段, 修改headers请用header函数
|
|
86
|
-
*/
|
|
87
|
-
finalize(option) {
|
|
88
|
-
this._data = { ...this._data, ...option };
|
|
89
|
-
return this;
|
|
90
|
-
}
|
|
91
83
|
/**补充header */
|
|
92
84
|
header(headers) {
|
|
93
85
|
this._data.headers = {
|
|
@@ -167,10 +159,10 @@ class UtilHttp {
|
|
|
167
159
|
return map[t];
|
|
168
160
|
}
|
|
169
161
|
acceptJson() {
|
|
170
|
-
const
|
|
171
|
-
init: '',
|
|
162
|
+
const acceptProc = () => ({
|
|
163
|
+
init: () => '',
|
|
172
164
|
reduce: (acc, curr) => acc + curr,
|
|
173
|
-
parse:
|
|
165
|
+
parse: result => {
|
|
174
166
|
if (result == undefined) {
|
|
175
167
|
UtilLogger_1.SLogger.warn(`json accept 接收反馈错误: 响应结果无效`);
|
|
176
168
|
return undefined;
|
|
@@ -190,8 +182,8 @@ class UtilHttp {
|
|
|
190
182
|
return { ...result, raw: data, data: null };
|
|
191
183
|
}
|
|
192
184
|
}
|
|
193
|
-
};
|
|
194
|
-
this._accept =
|
|
185
|
+
});
|
|
186
|
+
this._accept = acceptProc;
|
|
195
187
|
return this;
|
|
196
188
|
}
|
|
197
189
|
acceptString() {
|
|
@@ -202,6 +194,35 @@ class UtilHttp {
|
|
|
202
194
|
this._accept = AcceptNoneProc;
|
|
203
195
|
return this;
|
|
204
196
|
}
|
|
197
|
+
acceptFile() {
|
|
198
|
+
const acceptProc = (arg) => ({
|
|
199
|
+
init: res => {
|
|
200
|
+
const fileStream = fs_1.default.createWriteStream(arg.acceptFilepath);
|
|
201
|
+
const fileWritePromise = new Promise((resolve) => {
|
|
202
|
+
fileStream.on('error', err => {
|
|
203
|
+
UtilLogger_1.SLogger.warn(`file accept 文件流写入错误:`, err);
|
|
204
|
+
resolve(false); // 标记写入已结束, 但失败
|
|
205
|
+
});
|
|
206
|
+
fileStream.on('finish', () => {
|
|
207
|
+
resolve(true); // 标记写入成功
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
res.pipe(fileStream);
|
|
211
|
+
return { promise: fileWritePromise };
|
|
212
|
+
},
|
|
213
|
+
reduce: acc => acc,
|
|
214
|
+
parse: async (result) => {
|
|
215
|
+
if (result == undefined)
|
|
216
|
+
return undefined;
|
|
217
|
+
const success = await result.data.promise;
|
|
218
|
+
if (!success)
|
|
219
|
+
return undefined;
|
|
220
|
+
return { ...result, filepath: arg.acceptFilepath };
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
this._accept = acceptProc;
|
|
224
|
+
return this;
|
|
225
|
+
}
|
|
205
226
|
/**自定的接收数据类型*/
|
|
206
227
|
acceptRaw(proc) {
|
|
207
228
|
this._accept = proc;
|
|
@@ -225,97 +246,85 @@ class UtilHttp {
|
|
|
225
246
|
* 请求参数为 (token:JToken)
|
|
226
247
|
*/
|
|
227
248
|
sendJson() {
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
249
|
+
const sendProc = (opt, arg) => {
|
|
250
|
+
const { method } = opt;
|
|
251
|
+
const isPost = (method == "POST");
|
|
252
|
+
const data = JSON.stringify(arg.json);
|
|
253
|
+
this._data.headers ??= {};
|
|
254
|
+
this._data.headers['Content-Length'] = Buffer.byteLength(data);
|
|
255
|
+
return {
|
|
256
|
+
proc: (req) => {
|
|
236
257
|
if (isPost)
|
|
237
258
|
req.write(data);
|
|
238
259
|
req.end();
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
}
|
|
260
|
+
}
|
|
261
|
+
};
|
|
242
262
|
};
|
|
243
|
-
this._send =
|
|
263
|
+
this._send = sendProc;
|
|
244
264
|
this._data.headers ??= {};
|
|
245
265
|
this._data.headers['Content-Type'] = 'application/json';
|
|
246
266
|
return this;
|
|
247
267
|
}
|
|
248
|
-
/**利用 appendQuery 直接将数据附加在path上发送请求
|
|
249
|
-
* 请求参数为 (form:QueryRequestData)
|
|
250
|
-
*/
|
|
268
|
+
/**利用 appendQuery 直接将数据附加在path上发送请求 */
|
|
251
269
|
sendQuery() {
|
|
252
|
-
const
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
}
|
|
270
|
+
const sendProc = (opt, arg) => {
|
|
271
|
+
opt.path = UtilHttp.buildQuery(opt.path ?? '', arg.query);
|
|
272
|
+
return {
|
|
273
|
+
proc: (req) => void req.end()
|
|
274
|
+
};
|
|
258
275
|
};
|
|
259
|
-
this._send =
|
|
276
|
+
this._send = sendProc;
|
|
260
277
|
return this;
|
|
261
278
|
}
|
|
262
|
-
/**发送表单数据
|
|
263
|
-
* 请求参数为 (formData: FormData)
|
|
264
|
-
*/
|
|
279
|
+
/**发送表单数据 */
|
|
265
280
|
sendFormData() {
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
},
|
|
281
|
+
const sendProc = (opt, arg) => {
|
|
282
|
+
opt.headers = arg.formdata.getHeaders();
|
|
283
|
+
return {
|
|
284
|
+
proc: (req) => {
|
|
285
|
+
arg.formdata.pipe(req);
|
|
286
|
+
}
|
|
287
|
+
};
|
|
274
288
|
};
|
|
275
|
-
this._send =
|
|
289
|
+
this._send = sendProc;
|
|
276
290
|
this._data.headers ??= {};
|
|
277
291
|
this._data.headers['Content-Type'] = 'multipart/form-data';
|
|
278
292
|
return this;
|
|
279
293
|
}
|
|
280
|
-
/**发送表单
|
|
281
|
-
* 请求参数为 (form:QueryRequestData)
|
|
282
|
-
*/
|
|
294
|
+
/**发送表单 */
|
|
283
295
|
sendForm() {
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
296
|
+
const snedProc = (opt, arg) => {
|
|
297
|
+
const { method } = opt;
|
|
298
|
+
const isPost = (method == "POST");
|
|
299
|
+
const data = querystring_1.default.stringify(arg.form);
|
|
300
|
+
this._data.headers ??= {};
|
|
301
|
+
this._data.headers['Content-Length'] = Buffer.byteLength(data);
|
|
302
|
+
return {
|
|
303
|
+
proc: (req) => {
|
|
292
304
|
if (isPost)
|
|
293
305
|
req.write(data);
|
|
294
306
|
req.end();
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
}
|
|
307
|
+
}
|
|
308
|
+
};
|
|
298
309
|
};
|
|
299
|
-
this._send =
|
|
310
|
+
this._send = snedProc;
|
|
300
311
|
this._data.headers ??= {};
|
|
301
312
|
this._data.headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
|
302
313
|
return this;
|
|
303
314
|
}
|
|
304
|
-
/**发送文件
|
|
305
|
-
* 请求参数为 (filepath:string, filename?: string)
|
|
306
|
-
*/
|
|
315
|
+
/**发送文件 */
|
|
307
316
|
sendFile() {
|
|
308
|
-
const proc = {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
317
|
+
const proc = (opt, arg) => {
|
|
318
|
+
let { filepath, filename } = arg;
|
|
319
|
+
const formData = new form_data_1.default();
|
|
320
|
+
filename = filename ?? pathe_1.default.basename(filepath);
|
|
321
|
+
formData.append(filename, fs_1.default.createReadStream(filepath));
|
|
322
|
+
opt.headers = formData.getHeaders();
|
|
323
|
+
return {
|
|
324
|
+
proc: (req) => {
|
|
315
325
|
formData.pipe(req);
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
},
|
|
326
|
+
}
|
|
327
|
+
};
|
|
319
328
|
};
|
|
320
329
|
this._send = proc;
|
|
321
330
|
this._data.headers ??= {};
|
|
@@ -335,11 +344,11 @@ class UtilHttp {
|
|
|
335
344
|
/**发送请求
|
|
336
345
|
* @param datas - 数据对象
|
|
337
346
|
*/
|
|
338
|
-
async once(
|
|
339
|
-
const fullopt = this._data;
|
|
340
|
-
const
|
|
341
|
-
const {
|
|
342
|
-
const res = await UtilHttp.request(fullopt,
|
|
347
|
+
async once(arg) {
|
|
348
|
+
const fullopt = { ...this._data, ...arg.option ?? {} };
|
|
349
|
+
const sendProc = await this._send(fullopt, arg);
|
|
350
|
+
const { parse, ...acceptProc } = await this._accept(arg);
|
|
351
|
+
const res = await UtilHttp.request(fullopt, sendProc, acceptProc);
|
|
343
352
|
return parse(res);
|
|
344
353
|
}
|
|
345
354
|
/**重复发送网络请求
|
|
@@ -347,20 +356,21 @@ class UtilHttp {
|
|
|
347
356
|
* @param retries - 重试选项 默认 延迟:1000ms 间隔:180_000ms 重试:3次
|
|
348
357
|
* @param datas - 数据对象
|
|
349
358
|
*/
|
|
350
|
-
async retry(
|
|
351
|
-
let { retries, verify } =
|
|
359
|
+
async retry(arg) {
|
|
360
|
+
let { retries, verify } = arg;
|
|
352
361
|
retries ??= {};
|
|
353
362
|
retries.tryDelay = retries.tryDelay ?? 1000;
|
|
354
|
-
const procFn = async () => this.once(
|
|
363
|
+
const procFn = async () => this.once(arg);
|
|
355
364
|
return UtilFunctions_1.UtilFunc.retryPromise(procFn, verify, retries);
|
|
356
365
|
}
|
|
357
366
|
/**发送网络请求
|
|
358
|
-
* @param option
|
|
359
|
-
* @param
|
|
360
|
-
* @param
|
|
361
|
-
* @param init - 初始数据
|
|
367
|
+
* @param option - 网络请求选项
|
|
368
|
+
* @param reqProc - 请求处理函数 需调用req.end()
|
|
369
|
+
* @param acceptProc - 响应处理数据
|
|
362
370
|
*/
|
|
363
|
-
static async request(option,
|
|
371
|
+
static async request(option, sendProc, acceptProc) {
|
|
372
|
+
const { reduce: reqReduce, init: reqInit } = acceptProc;
|
|
373
|
+
const { proc: reqProc } = sendProc;
|
|
364
374
|
const { protocol, timeout, ...baseReqOpt } = option;
|
|
365
375
|
const plusTimeout = (timeout ?? 0) + 1000;
|
|
366
376
|
const hasTimeLimit = (timeout ? timeout >= 10_000 : false);
|
|
@@ -379,7 +389,7 @@ class UtilHttp {
|
|
|
379
389
|
clearTimeout(finallyTimeout);
|
|
380
390
|
resolve(t);
|
|
381
391
|
};
|
|
382
|
-
const resFunc = (res) => {
|
|
392
|
+
const resFunc = async (res) => {
|
|
383
393
|
try {
|
|
384
394
|
//请求超时
|
|
385
395
|
if (hasTimeLimit) {
|
|
@@ -387,14 +397,26 @@ class UtilHttp {
|
|
|
387
397
|
UtilLogger_1.SLogger.warn(`${flagName} http.response 触发 ${timeout} ms 超时, 继续挂起等待`);
|
|
388
398
|
});
|
|
389
399
|
}
|
|
390
|
-
let mergedata
|
|
400
|
+
let mergedata;
|
|
401
|
+
try {
|
|
402
|
+
mergedata = await reqInit(res);
|
|
403
|
+
}
|
|
404
|
+
catch (err) {
|
|
405
|
+
UtilLogger_1.SLogger.error(`${flagName} init函数错误:`, err);
|
|
406
|
+
finallyResolve(undefined);
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
391
409
|
res.setEncoding(option.responseEncode ?? 'utf8');
|
|
392
410
|
res.on('data', chunk => {
|
|
393
411
|
dataPromise = reduceQueue
|
|
394
|
-
.enqueue(async () =>
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
412
|
+
.enqueue(async () => {
|
|
413
|
+
try {
|
|
414
|
+
mergedata = await reqReduce(mergedata, chunk);
|
|
415
|
+
}
|
|
416
|
+
catch (err) {
|
|
417
|
+
UtilLogger_1.SLogger.error(`${flagName} reduce函数错误:`, err, `chunk:${chunk}\nmergedata:`, mergedata);
|
|
418
|
+
finallyResolve(undefined);
|
|
419
|
+
}
|
|
398
420
|
});
|
|
399
421
|
});
|
|
400
422
|
res.on('error', err => {
|
|
@@ -431,7 +453,7 @@ class UtilHttp {
|
|
|
431
453
|
finallyResolve(undefined);
|
|
432
454
|
});
|
|
433
455
|
try {
|
|
434
|
-
await
|
|
456
|
+
await reqProc(req);
|
|
435
457
|
}
|
|
436
458
|
catch (err) {
|
|
437
459
|
UtilLogger_1.SLogger.error(`${flagName} proc函数错误:`, err);
|
|
@@ -456,24 +478,30 @@ if (false)
|
|
|
456
478
|
const tool = UtilHttp
|
|
457
479
|
.url('https://httpbin.org/post')
|
|
458
480
|
.post()
|
|
459
|
-
.
|
|
481
|
+
.option({ timeout: 20000 });
|
|
460
482
|
//json
|
|
461
483
|
const sj = await tool.clone()
|
|
462
484
|
.sendJson()
|
|
463
485
|
.acceptJson()
|
|
464
|
-
.once({
|
|
486
|
+
.once({
|
|
487
|
+
json: { test: 1 },
|
|
488
|
+
});
|
|
465
489
|
console.log(sj);
|
|
466
490
|
//form
|
|
467
491
|
const sf = await tool.clone()
|
|
468
492
|
.sendForm()
|
|
469
493
|
.acceptJson()
|
|
470
|
-
.once({
|
|
494
|
+
.once({
|
|
495
|
+
form: { test: 1 }
|
|
496
|
+
});
|
|
471
497
|
console.log(sf);
|
|
472
498
|
//query
|
|
473
499
|
const sq = await tool.clone()
|
|
474
500
|
.sendQuery()
|
|
475
501
|
.acceptJson()
|
|
476
|
-
.once({
|
|
502
|
+
.once({
|
|
503
|
+
query: { test: 1 }
|
|
504
|
+
});
|
|
477
505
|
console.log(sq);
|
|
478
506
|
const filepath = pathe_1.default.join(__dirname, '..', 'input.wav');
|
|
479
507
|
//formData
|
|
@@ -487,6 +515,8 @@ if (false)
|
|
|
487
515
|
const sfile = await tool.clone()
|
|
488
516
|
.sendFile()
|
|
489
517
|
.acceptJson()
|
|
490
|
-
.once(
|
|
518
|
+
.once({
|
|
519
|
+
filepath: filepath
|
|
520
|
+
});
|
|
491
521
|
console.log(sfile);
|
|
492
522
|
})());
|