@zwa73/utils 1.0.195 → 1.0.197
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/UtilClass.js +1 -0
- package/dist/UtilCom.d.ts +97 -121
- package/dist/UtilCom.js +197 -193
- package/dist/UtilFunctions.d.ts +2 -2
- package/dist/UtilInterfaces.d.ts +6 -6
- package/package.json +1 -1
- package/src/UtilClass.ts +6 -0
- package/src/UtilCom.ts +282 -273
- package/src/UtilCom_bak.txt +345 -0
- package/src/UtilFunctions.ts +3 -3
- package/src/UtilInterfaces.ts +6 -6
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import { AnyString,JToken, MPromise, StatusVerifyFn } from "@/src/UtilInterfaces";
|
|
2
|
+
import https from 'https';
|
|
3
|
+
import http from 'http';
|
|
4
|
+
import { SLogger } from "@/src/UtilLogger";
|
|
5
|
+
import { RepeatPromiseOpt, UtilFunc } from "@/src/UtilFunctions";
|
|
6
|
+
import qs from "querystring";
|
|
7
|
+
|
|
8
|
+
/**网络请求返回值 */
|
|
9
|
+
export type ComResp<T> = {
|
|
10
|
+
/**响应头 */
|
|
11
|
+
headers: http.IncomingHttpHeaders;
|
|
12
|
+
/**响应状态码 */
|
|
13
|
+
statusCode?: number;
|
|
14
|
+
/**响应数据 */
|
|
15
|
+
data: T;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**网络请求选项 */
|
|
19
|
+
export type ComRequestOption = {
|
|
20
|
+
/**请求协议 */
|
|
21
|
+
protocol: 'http:'|'https:';
|
|
22
|
+
/**超时时间/毫秒 最小为10_000 默认无限 */
|
|
23
|
+
timeout?:number;
|
|
24
|
+
/**请求域名 */
|
|
25
|
+
hostname: string;
|
|
26
|
+
/**请求路径 */
|
|
27
|
+
path?: string;
|
|
28
|
+
/**请求方式 post 为 */
|
|
29
|
+
method: 'POST'|'GET';
|
|
30
|
+
/**端口 */
|
|
31
|
+
port?:number;
|
|
32
|
+
/**请求头 */
|
|
33
|
+
headers?: {
|
|
34
|
+
/**内容类型 */
|
|
35
|
+
'Content-Type'?: 'application/json'|AnyString;
|
|
36
|
+
/**内容长度 一般无需填写 应为buffer长度而非字符串长度 */
|
|
37
|
+
'Content-Length'?: number;
|
|
38
|
+
};
|
|
39
|
+
}&http.RequestOptions;
|
|
40
|
+
|
|
41
|
+
/**get请求所允许的数据 */
|
|
42
|
+
export type GetReqData = NodeJS.Dict<
|
|
43
|
+
| string
|
|
44
|
+
| number
|
|
45
|
+
| boolean
|
|
46
|
+
| readonly string[]
|
|
47
|
+
| readonly number[]
|
|
48
|
+
| readonly boolean[]
|
|
49
|
+
| null
|
|
50
|
+
>;
|
|
51
|
+
|
|
52
|
+
/**请求处理函数 需调用req.end() */
|
|
53
|
+
export type ProcReqFn = ((req:http.ClientRequest)=>MPromise<void>);
|
|
54
|
+
/**数据处理函数 */
|
|
55
|
+
export type ReduceDataFn<T> = (acc:T,data:string)=>MPromise<T>;
|
|
56
|
+
|
|
57
|
+
/**网络工具 */
|
|
58
|
+
export namespace UtilCom{
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
/**网络请求
|
|
62
|
+
* @param comReqOpt - 网络请求选项
|
|
63
|
+
* @param procReq - 请求处理函数 需调用req.end()
|
|
64
|
+
* @param reduceData - 数据处理函数
|
|
65
|
+
* @param initData - 初始数据
|
|
66
|
+
*/
|
|
67
|
+
export async function comReq<T>(
|
|
68
|
+
comReqOpt:ComRequestOption,
|
|
69
|
+
procReq:ProcReqFn,
|
|
70
|
+
reduceData:ReduceDataFn<T>,
|
|
71
|
+
initData:T,
|
|
72
|
+
){
|
|
73
|
+
const {protocol,timeout,...baseReqOpt} = comReqOpt;
|
|
74
|
+
|
|
75
|
+
const hasTimeLimit = (timeout ? timeout>=10_000 : false );
|
|
76
|
+
|
|
77
|
+
const flagName = `${comReq.name}.${protocol}${baseReqOpt.method}`;
|
|
78
|
+
|
|
79
|
+
return new Promise<ComResp<T>|undefined>(async (resolve, rejecte)=>{
|
|
80
|
+
const resFunc = (res:http.IncomingMessage)=>{
|
|
81
|
+
try{
|
|
82
|
+
//请求超时
|
|
83
|
+
if(hasTimeLimit){
|
|
84
|
+
res.setTimeout(timeout!, ()=>{
|
|
85
|
+
SLogger.warn(`${flagName} 接收反馈超时: ${timeout} ms`);
|
|
86
|
+
resolve(undefined);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
let mergedata:T = initData;
|
|
91
|
+
res.setEncoding('utf8');
|
|
92
|
+
res.on('data', async chunk => mergedata=await reduceData(mergedata,chunk));
|
|
93
|
+
|
|
94
|
+
res.on('error',(e)=>{
|
|
95
|
+
SLogger.warn(`${flagName} 接收反馈错误:${e}`);
|
|
96
|
+
resolve(undefined);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
res.on('end',()=>{
|
|
100
|
+
resolve({
|
|
101
|
+
headers: res.headers,
|
|
102
|
+
statusCode: res.statusCode,
|
|
103
|
+
data: mergedata,
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
}catch(err){
|
|
107
|
+
SLogger.warn(`${flagName} 未知错误:${err}`);
|
|
108
|
+
resolve(undefined);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
//路由 http/https
|
|
113
|
+
const req:http.ClientRequest= protocol=="https:"
|
|
114
|
+
? https.request(baseReqOpt as http.RequestOptions, resFunc)
|
|
115
|
+
: http.request(baseReqOpt as http.RequestOptions, resFunc);
|
|
116
|
+
|
|
117
|
+
//请求超时
|
|
118
|
+
if(hasTimeLimit){
|
|
119
|
+
req.setTimeout(timeout!, ()=>{
|
|
120
|
+
SLogger.warn(`${flagName} 发送请求超时: ${timeout} ms`);
|
|
121
|
+
req.destroy();
|
|
122
|
+
});
|
|
123
|
+
//req.on('timeout', ()=>{
|
|
124
|
+
// SLogger.warn(`${flagName} 发送请求超时(timeout): ${timeLimit} ms`);
|
|
125
|
+
// req.destroy();
|
|
126
|
+
//});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
req.on('error', (e)=>{
|
|
130
|
+
SLogger.warn(`${flagName} 发送请求错误:${e}`);
|
|
131
|
+
resolve(undefined);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
await procReq(req);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**发送json的网络请求
|
|
139
|
+
* @param comReqOpt - 网络请求选项
|
|
140
|
+
* @param reqData - 数据对象
|
|
141
|
+
* @returns 结果 undefined 为未能成功接收
|
|
142
|
+
*/
|
|
143
|
+
async function jsonReq<T extends ComRequestOption>(
|
|
144
|
+
comReqOpt:T,
|
|
145
|
+
reqData?:T['method'] extends "POST" ? JToken :GetReqData
|
|
146
|
+
){
|
|
147
|
+
const {method} = comReqOpt;
|
|
148
|
+
const isPost = (method=="POST");
|
|
149
|
+
|
|
150
|
+
if (!isPost && reqData != undefined) {
|
|
151
|
+
const queryString = qs.stringify(reqData as GetReqData);
|
|
152
|
+
if (queryString) {
|
|
153
|
+
// 检查当前路径是否已经包含问号
|
|
154
|
+
const separator = comReqOpt?.path?.includes('?') ? '&' : '?';
|
|
155
|
+
comReqOpt.path += separator + queryString;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const procReq = (req:http.ClientRequest)=>{
|
|
160
|
+
if(isPost) req.write(JSON.stringify(reqData));
|
|
161
|
+
req.end();
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const reduceData = (acc:string,data:string)=>acc+data;
|
|
165
|
+
const result = await comReq(comReqOpt,procReq,reduceData,"");
|
|
166
|
+
if(result==undefined) return undefined;
|
|
167
|
+
const {data,...rest} = result;
|
|
168
|
+
|
|
169
|
+
if(data.trim()==""){
|
|
170
|
+
SLogger.warn(`${jsonReq.name} 接收反馈错误: 原始字符串为空`);
|
|
171
|
+
return {...result,raw:"",data:null};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
try{
|
|
175
|
+
const obj = JSON.parse(data.trim()) as JToken;
|
|
176
|
+
SLogger.http(`${jsonReq.name} 接受信息:`,UtilFunc.stringifyJToken(obj,{compress:true,space:2}));
|
|
177
|
+
return{...rest,data:obj};
|
|
178
|
+
}
|
|
179
|
+
catch(e){
|
|
180
|
+
SLogger.warn(`${jsonReq.name} 接收反馈错误:${e}\n原始字符串:${data}`);
|
|
181
|
+
return {...result,raw:data,data:null};
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**重复发送json的网络请求
|
|
186
|
+
* @async
|
|
187
|
+
* @param comReqOpt - 网络请求选项
|
|
188
|
+
* @param reqData - 数据对象
|
|
189
|
+
* @param verifyFn - 有效性验证函数
|
|
190
|
+
* @param repeatOpt - 重试选项 默认 延迟:1000ms 间隔:180_000ms 重试:3次
|
|
191
|
+
* @returns 结果 undefined 为未能成功接收
|
|
192
|
+
*/
|
|
193
|
+
async function repeatJsonComReq<T extends ComRequestOption>(
|
|
194
|
+
comReqOpt:T,
|
|
195
|
+
reqData?:T['method'] extends "POST" ? JToken :GetReqData,
|
|
196
|
+
verifyFn?:StatusVerifyFn<ComResp<JToken>|undefined>,
|
|
197
|
+
repeatOpt:RepeatPromiseOpt={},
|
|
198
|
+
){
|
|
199
|
+
repeatOpt.tryDelay = repeatOpt.tryDelay??1000;
|
|
200
|
+
const procFn = ()=>jsonReq(comReqOpt,reqData);
|
|
201
|
+
return UtilFunc.repeatPromise(procFn,verifyFn,repeatOpt);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**发送一个 https POST 请求并接受数据
|
|
205
|
+
* @async
|
|
206
|
+
* @param comReqOpt - 请求参数
|
|
207
|
+
* @param reqData - 数据对象
|
|
208
|
+
* @returns 结果 undefined 为未能成功接收
|
|
209
|
+
*/
|
|
210
|
+
export function httpsPost(comReqOpt:Omit<ComRequestOption,'protocol'|'method'>,reqData?:JToken){
|
|
211
|
+
return jsonReq({
|
|
212
|
+
...comReqOpt,
|
|
213
|
+
method:"POST",
|
|
214
|
+
protocol:"https:",
|
|
215
|
+
},reqData);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**发送一个 http POST 请求并接受数据
|
|
219
|
+
* @async
|
|
220
|
+
* @param comReqOpt - 请求参数
|
|
221
|
+
* @param reqData - 数据对象
|
|
222
|
+
* @returns 结果 undefined 为未能成功接收
|
|
223
|
+
*/
|
|
224
|
+
export function httpPost(comReqOpt:Omit<ComRequestOption,'protocol'|'method'>,reqData?:JToken){
|
|
225
|
+
return jsonReq({
|
|
226
|
+
...comReqOpt,
|
|
227
|
+
method:"POST",
|
|
228
|
+
protocol:"http:",
|
|
229
|
+
},reqData);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**发送一个 https GET 请求并接受数据
|
|
233
|
+
* @async
|
|
234
|
+
* @param comReqOpt - 请求参数
|
|
235
|
+
* @param reqData - 数据对象
|
|
236
|
+
* @returns 结果 undefined 为未能成功接收
|
|
237
|
+
*/
|
|
238
|
+
export function httpsGet(comReqOpt:Omit<ComRequestOption,'protocol'|'method'>,reqData?:GetReqData){
|
|
239
|
+
return jsonReq({
|
|
240
|
+
...comReqOpt,
|
|
241
|
+
method:"GET",
|
|
242
|
+
protocol:"https:",
|
|
243
|
+
},reqData);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**发送一个 http GET 请求并接受数据
|
|
247
|
+
* @async
|
|
248
|
+
* @param comReqOpt - 请求参数
|
|
249
|
+
* @param reqData - 数据对象
|
|
250
|
+
* @returns 结果 undefined 为未能成功接收
|
|
251
|
+
*/
|
|
252
|
+
export function httpGet(comReqOpt:Omit<ComRequestOption,'protocol'|'method'>,reqData?:GetReqData){
|
|
253
|
+
return jsonReq({
|
|
254
|
+
...comReqOpt,
|
|
255
|
+
method:"GET",
|
|
256
|
+
protocol:"http:",
|
|
257
|
+
},reqData);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
/**重复一个 https POST请求并接受数据
|
|
262
|
+
* @async
|
|
263
|
+
* @param comReqOpt - 网络请求选项
|
|
264
|
+
* @param reqData - 数据对象
|
|
265
|
+
* @param verifyFn - 有效性验证函数
|
|
266
|
+
* @param repeatOpt - 重试选项 默认 延迟:1000ms 间隔:180_000ms 重试:3次
|
|
267
|
+
* @returns 结果 undefined 为未能成功接收
|
|
268
|
+
*/
|
|
269
|
+
export function httpsRepeatPost(
|
|
270
|
+
comReqOpt:Omit<ComRequestOption,'protocol'|'method'>,
|
|
271
|
+
reqData?:JToken,
|
|
272
|
+
verifyFn?:StatusVerifyFn<JToken|undefined>,
|
|
273
|
+
repeatOpt?:RepeatPromiseOpt
|
|
274
|
+
){
|
|
275
|
+
return repeatJsonComReq({
|
|
276
|
+
...comReqOpt,
|
|
277
|
+
method:"POST",
|
|
278
|
+
protocol:"https:",
|
|
279
|
+
},reqData,verifyFn,repeatOpt);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**重复一个 http POST请求并接受数据
|
|
283
|
+
* @async
|
|
284
|
+
* @param comReqOpt - 网络请求选项
|
|
285
|
+
* @param reqData - 数据对象
|
|
286
|
+
* @param verifyFn - 有效性验证函数
|
|
287
|
+
* @param repeatOpt - 重试选项 默认 延迟:1000ms 间隔:180_000ms 重试:3次
|
|
288
|
+
* @returns 结果 undefined 为未能成功接收
|
|
289
|
+
*/
|
|
290
|
+
export function httpRepeatPost(
|
|
291
|
+
comReqOpt:Omit<ComRequestOption,'protocol'|'method'>,
|
|
292
|
+
reqData?:JToken,
|
|
293
|
+
verifyFn?:StatusVerifyFn<JToken|undefined>,
|
|
294
|
+
repeatOpt?:RepeatPromiseOpt
|
|
295
|
+
){
|
|
296
|
+
return repeatJsonComReq({
|
|
297
|
+
...comReqOpt,
|
|
298
|
+
method:"POST",
|
|
299
|
+
protocol:"http:",
|
|
300
|
+
},reqData,verifyFn,repeatOpt);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**重复一个 https GET 请求并接受数据
|
|
304
|
+
* @async
|
|
305
|
+
* @param comReqOpt - 网络请求选项
|
|
306
|
+
* @param reqData - 数据对象
|
|
307
|
+
* @param verifyFn - 有效性验证函数
|
|
308
|
+
* @param repeatOpt - 重试选项 默认 延迟:1000ms 间隔:180_000ms 重试:3次
|
|
309
|
+
* @returns 结果 undefined 为未能成功接收
|
|
310
|
+
*/
|
|
311
|
+
export function httpsRepeatGet(
|
|
312
|
+
comReqOpt:Omit<ComRequestOption,'protocol'|'method'>,
|
|
313
|
+
reqData?:GetReqData,
|
|
314
|
+
verifyFn?:StatusVerifyFn<JToken|undefined>,
|
|
315
|
+
repeatOpt?:RepeatPromiseOpt
|
|
316
|
+
){
|
|
317
|
+
return repeatJsonComReq({
|
|
318
|
+
...comReqOpt,
|
|
319
|
+
method:"GET",
|
|
320
|
+
protocol:"https:",
|
|
321
|
+
},reqData,verifyFn,repeatOpt);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**重复一个 http GET 请求并接受数据
|
|
325
|
+
* @async
|
|
326
|
+
* @param comReqOpt - 网络请求选项
|
|
327
|
+
* @param reqData - 数据对象
|
|
328
|
+
* @param verifyFn - 有效性验证函数
|
|
329
|
+
* @param repeatOpt - 重试选项 默认 延迟:1000ms 间隔:180_000ms 重试:3次
|
|
330
|
+
* @returns 结果 undefined 为未能成功接收
|
|
331
|
+
*/
|
|
332
|
+
export function httpRepeatGet(
|
|
333
|
+
comReqOpt:Omit<ComRequestOption,'protocol'|'method'>,
|
|
334
|
+
reqData?:GetReqData,
|
|
335
|
+
verifyFn?:StatusVerifyFn<JToken|undefined>,
|
|
336
|
+
repeatOpt?:RepeatPromiseOpt
|
|
337
|
+
){
|
|
338
|
+
return repeatJsonComReq({
|
|
339
|
+
...comReqOpt,
|
|
340
|
+
method:"GET",
|
|
341
|
+
protocol:"http:",
|
|
342
|
+
},reqData,verifyFn,repeatOpt);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
}
|
package/src/UtilFunctions.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as crypto from "crypto";
|
|
2
|
-
import { PRecord, AnyFunc, ExtractOutcome, IJData, JObject, JToken, Keyable, Literal, Matchable, MatchableFlag, Outcome,
|
|
2
|
+
import { PRecord, AnyFunc, ExtractOutcome, IJData, JObject, JToken, Keyable, Literal, Matchable, MatchableFlag, Outcome, PromiseStatus, StatusVerifyFn, ProperSubsetCheck, UnionToIntersection, AnyRecord, AllExtends, SrtSegment, MPromise } from "@/src/UtilInterfaces";
|
|
3
3
|
import * as cp from "child_process";
|
|
4
4
|
import { LogLevel, SLogger } from "@/src/UtilLogger";
|
|
5
5
|
import { Completed, Failed, FailedLike, None, StatusSymbol, Success, SuccessLike, Terminated, Timeout } from "./UtilSymbol";
|
|
@@ -51,7 +51,7 @@ type PromiseResult<T> = {
|
|
|
51
51
|
/**请求结果 */
|
|
52
52
|
result:T;
|
|
53
53
|
/**请求状态 */
|
|
54
|
-
stat:
|
|
54
|
+
stat:PromiseStatus;
|
|
55
55
|
/**请求下标/序号 */
|
|
56
56
|
index:number;
|
|
57
57
|
};
|
|
@@ -228,7 +228,7 @@ static getNeverResolvedPromise<T>():Promise<T>{
|
|
|
228
228
|
* @returns 重复结果
|
|
229
229
|
*/
|
|
230
230
|
@LogTimeAsync("repeatPromise ",true)
|
|
231
|
-
static async repeatPromise<T>(procFn:()=>Promise<T>,verifyFn?:
|
|
231
|
+
static async repeatPromise<T>(procFn:()=>Promise<T>,verifyFn?:StatusVerifyFn<T>,opt:RepeatPromiseOpt = {}):
|
|
232
232
|
Promise<RepeatPromiseResult<T>>{
|
|
233
233
|
opt.count = opt.count??3;
|
|
234
234
|
opt.tryInterval = opt.tryInterval??180_000;
|
package/src/UtilInterfaces.ts
CHANGED
|
@@ -140,14 +140,14 @@ export type ExclusiveJObject<B extends JObject,T extends JToken,K extends string
|
|
|
140
140
|
TMP extends JArray = ExclusiveRecursive<B,T,K>> = TMP[number];
|
|
141
141
|
|
|
142
142
|
|
|
143
|
-
|
|
144
|
-
* 成功 将直接返回
|
|
145
|
-
* 终止 将直接返回
|
|
143
|
+
/**Promise完成状态 成功/失败/终止
|
|
144
|
+
* 成功 将直接返回 结果
|
|
145
|
+
* 终止 将直接返回 结果
|
|
146
146
|
* 失败 将重试
|
|
147
147
|
*/
|
|
148
|
-
export type
|
|
149
|
-
|
|
150
|
-
export type
|
|
148
|
+
export type PromiseStatus = Success|Failed|Terminated;
|
|
149
|
+
/**状态验证函数 */
|
|
150
|
+
export type StatusVerifyFn<T> = (obj:T)=>Promise<PromiseStatus>|PromiseStatus;
|
|
151
151
|
|
|
152
152
|
/**获取Promise的结果类型 如同await那样
|
|
153
153
|
* @deprecated 请使用官方的 Awaited<T> 类型
|