runner-runtime 1.0.89 → 1.0.91

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/events/api.js DELETED
@@ -1,2581 +0,0 @@
1
- const FileType = require("file-type"),
2
- contentDisposition = require("content-disposition"),
3
- aTools = require("apipost-tools"),
4
- isSvg = require("is-svg"),
5
- JSONbig = require("json-bigint")({ storeAsString: true }),
6
- stripJsonComments = require("strip-json-comments"),
7
- mime = require("mime"),
8
- { mockExp } = require('exp-mock'),
9
- tough = require("tough-cookie"),
10
- Buffer = require("buffer/").Buffer,
11
- isImage = require("is-image");
12
- const { getAPIFromCollection, smartUrlJoin, jsfGenerate, replace2RegExp, getParentTargetIDs, encodeURIComponentUnique, base64toCacheFile, getInsideVariables, convertEndRuntimeState, getCaseInsensitive, camelCaseToSnakeCase } = require('../libs/utils'),
13
- { generateHarFromRequest } = require('../libs/2har'),
14
-
15
- _ = require('lodash');
16
- const sdk = require("postman-collection"),
17
- Url = sdk.Url,
18
- PostmanEvent = sdk.Event;
19
- const Mock = require('mockjs5-pro');
20
- const { v4: uuidv4 } = require("uuid");
21
-
22
- const fs = require("fs");
23
- const { minimatch } = require("minimatch");
24
- const runtime = require("postman-runtime-pro");
25
-
26
- // 将api转postman请求参数
27
- const convert2PostmanRequest = (request, option) => {
28
- const pmRequest = {};
29
- const systemConfigs = _.get(option, 'system_configs', {});
30
-
31
- // 自动识别请求参数的Mock变量
32
- const autoReplaceMockVar = (para) => {
33
- try {
34
- return _.toInteger(systemConfigs?.auto_gen_mock_url) > 0 ? Mock.mock(para) : para;
35
- } catch (e) {
36
- return para;
37
- }
38
- };
39
-
40
- // 处理 url
41
- const raw = autoReplaceMockVar(_.get(request, "url") || _.get(request, "request.url"));
42
- const uri = new Url(raw);
43
-
44
- // 清除原有query参数
45
- try {
46
- uri?.query.clear();
47
- } catch (e) { }
48
-
49
- // 遍历重置query参数
50
- const queryAddEqual = _.toInteger(
51
- _.get(request, "request.query.query_add_equal") || -1
52
- );
53
-
54
- _.forEach(_.get(request, "request.query.parameter"), (item) => {
55
- if (_.isObject(item) && item?.is_checked > 0) {
56
- let { key, value, schema } = item;
57
- key = String(autoReplaceMockVar(_.trim(key)));
58
- value = String(autoReplaceMockVar(value));
59
-
60
- if (value == '' && _.isObject(schema)) {
61
- const tmpValue = jsfGenerate(schema, [], option?.lang, option?.custom_functions || {});
62
-
63
- if (!_.isUndefined(tmpValue)) {
64
- value = tmpValue;
65
- }
66
- }
67
- if (key != "") {
68
- if (value == "" && queryAddEqual < 1) {
69
- // 不拼接 = 号
70
- uri?.query?.members?.push(new sdk.QueryParam({ key, value: null }));
71
- } else {
72
- uri?.query?.members?.push(new sdk.QueryParam({ key, value, }));
73
- }
74
- }
75
- }
76
- }
77
- );
78
-
79
- if (option?.env?.env_id == '2' && !_.includes(_.keys(uri?.query?.toObject()), 'target_id')) {
80
- uri?.query?.members?.push(new sdk.QueryParam({ key: 'target_id', value: request?.target_id, }));
81
- }
82
-
83
- // path 参数
84
- const uriVariable = [];
85
-
86
- if (_.isArray(_.get(uri, "path"))) {
87
- const transformed = _.map(_.get(uri, "path"), (item) => {
88
- if (_.startsWith(item, "{") && !_.startsWith(item, "{{") && _.endsWith(item, "}") && !_.endsWith(item, "}}")) {
89
- return ":" + item.slice(1, -1);
90
- }
91
- return item; // 不需要替换的元素直接返回
92
- });
93
-
94
- _.set(uri, "path", transformed);
95
- }
96
- _.forEach(
97
- _.get(request, "request.restful.parameter"), (item) => {
98
- if (_.isObject(item) && item?.is_checked > 0) {
99
- let { key, value, schema } = item;
100
- key = autoReplaceMockVar(_.trim(key));
101
- value = autoReplaceMockVar(value);
102
-
103
- if (value == '' && _.isObject(schema)) {
104
- const tmpValue = jsfGenerate(schema, [], option?.lang, option?.custom_functions || {});
105
-
106
- if (!_.isUndefined(tmpValue)) {
107
- value = tmpValue;
108
- }
109
- }
110
-
111
- if (key != "") {
112
- uriVariable.push({ key, value });
113
- }
114
- }
115
- }
116
- );
117
-
118
- if (_.isUndefined(uri?.protocol)) {
119
- const varPattern = /^{{.*}}/;
120
- if (!_.startsWith(_.first(uri?.host), "{{") && !varPattern.test(_.first(uri?.host))) {
121
- _.set(uri, "protocol", "http");
122
- }
123
- }
124
-
125
- const rawUrl = String(uri);
126
-
127
- if (uri?.query?.members?.length > 0) {
128
- try {
129
- _.set(uri, "query", uri?.query?.toJSON());
130
- } catch (e) {
131
- _.set(uri, "query", uri?.query?.toObject());
132
- }
133
- } else {
134
- _.set(uri, "query", undefined);
135
- }
136
-
137
- _.set(pmRequest, "url", {
138
- raw: rawUrl,
139
- variable: uriVariable,
140
- ...uri,
141
- });
142
-
143
- // 处理协议
144
- _.set(pmRequest, "protocol", _.get(request, "protocol") || "http/1.1");
145
-
146
- // 处理 method
147
- let method = _.get(request, "method") || "GET";
148
-
149
- if (_.includes(['CONNECT'], _.toUpper(method))) {
150
- method = 'GET';
151
- }
152
-
153
- _.set(pmRequest, "method", method);
154
-
155
- // 处理认证
156
- const auth = {};
157
- const authType = _.get(request, "request.auth.type") || "noauth";
158
-
159
- if (_.isString(authType) && authType != "noauth" && authType != "inherit") {
160
- switch (authType) {
161
- case "kv":
162
- _.assign(auth, {
163
- type: "apikey",
164
- apikey: [
165
- {
166
- key: "in",
167
- value: _.get(request, `request.auth.kv.in`) || "header",
168
- type: "string",
169
- },
170
- {
171
- key: "value",
172
- value:
173
- autoReplaceMockVar(_.get(request, `request.auth.kv.value`)) || "",
174
- type: "string",
175
- },
176
- {
177
- key: "key",
178
- value:
179
- autoReplaceMockVar(_.get(request, `request.auth.kv.key`)) || "",
180
- type: "string",
181
- },
182
- ],
183
- });
184
- break;
185
- case "basic":
186
- _.assign(auth, {
187
- type: "basic",
188
- basic: [
189
- {
190
- key: "password",
191
- value:
192
- autoReplaceMockVar(_.get(request, `request.auth.basic.password`)) || "",
193
- type: "string",
194
- },
195
- {
196
- key: "username",
197
- value:
198
- autoReplaceMockVar(_.get(request, `request.auth.basic.username`)) || "",
199
- type: "string",
200
- },
201
- ],
202
- });
203
- break;
204
- case "bearer":
205
- _.assign(auth, {
206
- type: "bearer",
207
- bearer: [
208
- {
209
- key: "token",
210
- value:
211
- autoReplaceMockVar(_.get(request, `request.auth.bearer.key`)) ||
212
- "",
213
- type: "string",
214
- },
215
- ],
216
- });
217
- break;
218
- case "digest":
219
- const keyMap = {
220
- username: "username",
221
- password: "password",
222
- realm: "realm",
223
- nonce: "nonce",
224
- algorithm: "algorithm",
225
- qop: "qop",
226
- opaque: "opaque",
227
- nc: "nonceCount",
228
- cnonce: "clientNonce",
229
- disableRetryRequest: "disableRetryRequest",
230
- };
231
- _.set(auth, "type", authType);
232
- _.set(auth, authType, []);
233
-
234
- _.forEach(_.get(request, `request.auth.${authType}`), (val, key) => {
235
- key = keyMap[autoReplaceMockVar(key)];
236
- if (_.isString(val)) {
237
- val = autoReplaceMockVar(val);
238
- }
239
-
240
- const value = _.isBoolean(val) ? val : (_.isInteger(val) ? !!val : _.isString(val) ? val : "");
241
- const type = (_.isInteger(val) || _.isBoolean(val)) ? "boolean" : "string";
242
- auth[authType].push({ key, value, type });
243
- }
244
- );
245
-
246
- if (_.keys(_.get(request, `request.auth.${authType}`)).indexOf("disableRetryRequest") == -1) {
247
- auth[authType].push({
248
- key: "disableRetryRequest",
249
- value: false,
250
- type: "boolean",
251
- });
252
- }
253
- break;
254
- case "hawk":
255
- case "oauth1":
256
- case "oauth2":
257
- case "awsv4":
258
- case "ntlm":
259
- case "jwt":
260
- case "asap":
261
- case "edgegrid": // TODO 将增加 asap和jwt,需前端增加相关参数
262
- _.set(auth, "type", authType);
263
- _.set(auth, authType, []);
264
- _.forEach(_.get(request, `request.auth.${authType}`), (val, key) => {
265
- if (_.isString(val)) {
266
- val = autoReplaceMockVar(val);
267
- }
268
-
269
- key = autoReplaceMockVar(key);
270
- const value = _.isBoolean(val) ? val : (_.isInteger(val) ? !!val : _.isString(val) ? val : "");
271
- const type = (_.isInteger(val) || _.isBoolean(val)) ? "boolean" : "string";
272
- auth[authType].push({ key, value, type });
273
- }
274
- );
275
- break;
276
- }
277
- }
278
-
279
- !_.isEmpty(auth) && _.set(pmRequest, "auth", auth);
280
-
281
- // 处理 header
282
- const header = [];
283
- _.forEach(_.get(request, "request.header.parameter"), (item) => {
284
- if (_.isObject(item) && item?.is_checked > 0) {
285
- let disabled = item?.is_checked > 0 ? false : true;
286
- let { key, value, schema } = item;
287
- key = autoReplaceMockVar(_.trim(key));
288
- value = autoReplaceMockVar(value);
289
-
290
- if (value == '' && _.isObject(schema)) {
291
- const tmpValue = jsfGenerate(schema, [], option?.lang, option?.custom_functions || {});
292
-
293
- if (!_.isUndefined(tmpValue)) {
294
- value = tmpValue;
295
- }
296
- }
297
- key != "" && header.push({ key, value, disabled });
298
- }
299
- }
300
- );
301
-
302
- let accessToken = ""; // 用于oauth2的access_token
303
- if (auth?.type == "oauth2") {
304
- if (_.isArray(auth?.oauth2)) {
305
- const addTokenItem = _.find(auth.oauth2, { key: "addTokenTo" });
306
- const headerPrefixItem = _.find(auth.oauth2, { key: "headerPrefix" });
307
- const accessTokenItem = _.find(auth.oauth2, { key: "access_token" });
308
- if (accessTokenItem?.value) {
309
- accessToken = accessTokenItem.value;
310
- if (headerPrefixItem?.value) {
311
- accessToken = headerPrefixItem.value + " " + accessToken;
312
- } else {
313
- accessToken = "Bearer " + accessToken;
314
- }
315
- if (addTokenItem?.value == "header") {
316
- header.push({ key: "Authorization", value: accessToken, disabled: false });
317
- accessToken = ""; //设置完成自动清空
318
- } else if (addTokenItem?.value == "queryParams") {
319
- accessToken = accessTokenItem.value; //重置为最新
320
- const oldUri = pmRequest.url.raw;
321
- const urlObj = new URL(oldUri);
322
- urlObj.searchParams.set('access_token', accessToken);
323
- const query = pmRequest.url.query || [];
324
- query.push({ key: "access_token", value: accessToken });
325
- _.set(pmRequest, "url", {
326
- ...pmRequest.url,
327
- raw: urlObj.toString(),
328
- query: query,
329
- });
330
- accessToken = ""; //设置完成自动清空
331
- } else {
332
- accessToken = ""; //不添加
333
- }
334
- }
335
- }
336
- }
337
-
338
- const keyMap = new Map();
339
- const duplicates = [];
340
-
341
- // 遍历header数组,记录每个key的最新item
342
- _.forEach(header, (item, index) => {
343
- const lowerKey = item.key.toLowerCase();
344
- if (keyMap.has(lowerKey)) {
345
- duplicates.push(keyMap.get(lowerKey));
346
- }
347
- keyMap.set(lowerKey, index);
348
- });
349
-
350
- // 如果有重复项,倒序剔除这些index的值
351
- if (duplicates.length > 0) {
352
- _.forEachRight(duplicates, (dupIndex) => {
353
- if (dupIndex > -1) {
354
- header.splice(dupIndex, 1);
355
- }
356
- });
357
- }
358
-
359
- _.set(pmRequest, "header", header);
360
-
361
- // 处理 cookie
362
- try {
363
- if (pmRequest?.url?.raw != "") {
364
- let cookieUrlParse = {};
365
-
366
- if (_.isString(_.get(request, 'initVarReplacedUrl')) && !_.isEmpty(_.get(request, 'initVarReplacedUrl'))) {
367
- cookieUrlParse = new Url(_.get(request, 'initVarReplacedUrl'))
368
- }
369
-
370
- const cookieStr = [];
371
-
372
- _.forEach(_.get(request, "request.cookie.parameter"), (item) => {
373
- if (_.isObject(item)) {
374
- let name = encodeURIComponentUnique(
375
- autoReplaceMockVar(item.key || item.name)
376
- );
377
-
378
- let value = autoReplaceMockVar(item.value);
379
-
380
- if (value == '' && _.isObject(item?.schema)) {
381
- const tmpValue = jsfGenerate(item?.schema, [], option?.lang, option?.custom_functions || {});
382
-
383
- if (!_.isUndefined(tmpValue)) {
384
- value = tmpValue;
385
- }
386
- }
387
-
388
- if (_.isUndefined(_.get(request, "request.cookie.cookie_encode")) || _.parseInt(_.get(request, "request.cookie.cookie_encode")) > 0) {
389
- value = encodeURIComponentUnique(value);
390
- }
391
-
392
- let cookie = _.assign(item, { key: name, name, value });
393
- let host = !_.isEmpty(pmRequest?.url?.host) ? _.join(pmRequest?.url?.host, ".") : pmRequest?.url?.raw;
394
- let urlPath = pmRequest?.url?.path;
395
-
396
- if (!_.isEmpty(cookieUrlParse)) {
397
- host = !_.isEmpty(cookieUrlParse.host) ? _.join(cookieUrlParse.host, ".") : _.get(request, 'initVarReplacedUrl');
398
- urlPath = cookieUrlParse.path
399
- }
400
-
401
- let pathStr = _.join(urlPath, "/");
402
-
403
- if (!_.startsWith(pathStr, '/') && _.startsWith(cookie?.path, '/')) {
404
- pathStr = `/${pathStr}`;
405
- }
406
-
407
- if (!_.endsWith(pathStr, '/') && _.endsWith(cookie?.path, '/')) {
408
- pathStr = `${pathStr}/`;
409
- }
410
-
411
- if ((_.isUndefined(cookie?.domain) || minimatch(host, cookie?.domain) || _.endsWith(host, cookie?.domain)) && (_.isUndefined(cookie?.path) || cookie?.path == '/' || _.startsWith(pathStr || "/", cookie?.path)) && (_.isUndefined(cookie?.expires) || _.gt(new Date(String(cookie?.expires)), new Date()))) {
412
- cookieStr.push(`${cookie.name}=${cookie.value}`);
413
- }
414
- }
415
- }
416
- );
417
-
418
- if (!_.isEmpty(cookieStr)) {
419
- const foundItem = _.find(
420
- pmRequest.header,
421
- (item) => _.toLower(item.key) === _.toLower("cookie")
422
- );
423
-
424
- if (foundItem) {
425
- foundItem.value = _.join(cookieStr, ";");
426
- } else {
427
- pmRequest.header.push({
428
- key: "Cookie",
429
- value: _.join(cookieStr, ";"),
430
- });
431
- }
432
- }
433
- }
434
- } catch (e) { }
435
-
436
- // 处理body
437
- const body = {};
438
- const bodyMode = _.get(request, "request.body.mode") || "none";
439
-
440
- if (_.isString(bodyMode) && bodyMode != "none") {
441
- const modeMap = {
442
- "form-data": "formdata",
443
- plain: "text",
444
- binary: "file",
445
- msgpack: "msgpack",
446
- };
447
-
448
- switch (bodyMode) {
449
- case "form-data":
450
- case "urlencoded":
451
- _.set(body, "mode", modeMap[bodyMode] ? modeMap[bodyMode] : bodyMode);
452
- _.set(body, body.mode, []);
453
-
454
- const parameter = _.get(request, `request.body.parameter`);
455
-
456
- _.forEach(parameter, (item) => {
457
- if (_.isObject(item)) {
458
- if (item.is_checked > 0 && autoReplaceMockVar(item.key) != '') {
459
- if (bodyMode == "form-data" && _.toLower(item.field_type) === "file") {
460
- const src = base64toCacheFile(
461
- item.key,
462
- item.value,
463
- item.file_base64,
464
- request?.target_id
465
- );
466
- body[body.mode].push({
467
- key: autoReplaceMockVar(item.key),
468
- src,
469
- type: "file",
470
- disabled: false,
471
- });
472
- } else {
473
- let { value, schema } = item;
474
- value = autoReplaceMockVar(value);
475
-
476
- if (value == '' && _.isObject(schema)) {
477
- const tmpValue = jsfGenerate(schema, [], option?.lang, option?.custom_functions || {});
478
-
479
- if (!_.isUndefined(tmpValue)) {
480
- value = tmpValue;
481
- }
482
- }
483
-
484
- if (bodyMode == "form-data" && item.content_type != "") {
485
- body[body.mode].push({
486
- key: autoReplaceMockVar(item.key),
487
- value,
488
- type: "text",
489
- disabled: false,
490
- contentType: item.content_type,
491
- });
492
- } else {
493
- body[body.mode].push({
494
- key: autoReplaceMockVar(item.key),
495
- value,
496
- type: "text",
497
- disabled: false,
498
- });
499
- }
500
- }
501
- }
502
- }
503
- }
504
- );
505
- break;
506
- case "binary":
507
- const src = base64toCacheFile(
508
- "binary",
509
- _.get(request, `request.body.binary.file_path`),
510
- _.get(request, `request.body.binary.data_url`),
511
- request?.target_id
512
- );
513
- _.assign(body, {
514
- mode: "file",
515
- file: {
516
- src,
517
- },
518
- });
519
- break;
520
- default:
521
- let raw = autoReplaceMockVar(_.get(request, `request.body.raw`));
522
-
523
- if (bodyMode == "msgpack") {
524
- const msgpack = require("msgpack5")();
525
- try {
526
- raw = msgpack.encode(JSONbig.parse(stripJsonComments(raw))).slice();
527
- Object.setPrototypeOf(raw, Object.getPrototypeOf({}));
528
- } catch (e) { }
529
-
530
- const foundItem = _.find(
531
- pmRequest.header,
532
- (item) => _.toLower(item.key) === _.toLower("content-type")
533
- );
534
-
535
- if (foundItem) {
536
- foundItem.value = "application/msgpack";
537
- } else {
538
- pmRequest.header.push({
539
- key: "content-type",
540
- value: "application/msgpack",
541
- });
542
- }
543
- } else if (bodyMode == "json" && option?.request_param_auto_json > 0) {
544
- try {
545
- raw = JSONbig.stringify(JSONbig.parse(stripJsonComments(raw)));
546
- Object.setPrototypeOf(raw, Object.getPrototypeOf({}));
547
- } catch (e) { }
548
- }
549
-
550
- _.assign(body, {
551
- mode: "raw",
552
- raw,
553
- options: {
554
- raw: {
555
- language: modeMap[bodyMode] ? modeMap[bodyMode] : bodyMode,
556
- },
557
- },
558
- });
559
- break;
560
- }
561
- }
562
-
563
- !_.isEmpty(body) && _.set(pmRequest, "body", body);
564
-
565
- return pmRequest;
566
- }
567
-
568
- // 转postman请求选项
569
- const convert2PostmanOptions = (request, option, variables) => {
570
- // 请求信息
571
- const { requestJson } = request;
572
-
573
- // localVariables
574
- const tmpLocalVariables = [];
575
- _.forEach(_.get(variables, "variables"), (value, key) => {
576
- tmpLocalVariables.push({
577
- value,
578
- key,
579
- type: "any",
580
- enabled: true,
581
- });
582
- });
583
-
584
- const localVariables = new sdk.VariableScope({
585
- values: tmpLocalVariables,
586
- });
587
-
588
- // 创建迭代数据
589
- const iterationData = _.get(variables, 'iterationData');
590
- const data = [iterationData];
591
-
592
- // 初始化 environment
593
- const envVariables = [];
594
- _.forEach(_.get(variables, "environment"), (value, key) => {
595
- envVariables.push({
596
- value,
597
- key,
598
- type: "any",
599
- enabled: true,
600
- });
601
- });
602
-
603
- const environment = new sdk.VariableScope({
604
- values: envVariables,
605
- });
606
-
607
- // 初始化 globals
608
- const globalsVariables = [];
609
- _.forEach(_.defaults(_.get(variables, "globals") || {}, getInsideVariables()), (value, key) => {
610
- globalsVariables.push({
611
- value,
612
- key,
613
- type: "any",
614
- enabled: true,
615
- });
616
- }
617
- );
618
-
619
- // 创建一个全局变量对象
620
- const globals = new sdk.VariableScope({
621
- values: globalsVariables,
622
- });
623
-
624
- const protocolVersion = (requestJson?.protocol == 'http/1.1' || _.includes(['sse'], requestJson?.target_type) || _.isEmpty(requestJson?.target_type)) ? 'http1' : (requestJson?.protocol == 'auto' ? 'auto' : 'http2');
625
- const requester = {
626
- strictSSL: false,
627
- protocolVersion,
628
- timings: true,
629
- verbose: false,
630
- implicitCacheControl: true,
631
- implicitTraceHeader: false,
632
- followOriginalHttpMethod: _.get(option, "system_configs.follow_original_method") > 0 ? true : false,
633
- followRedirects: _.get(option, "system_configs.auto_redirect") > 0 ? true : false,
634
- maxRedirects: _.max([_.toInteger(_.get(option, "system_configs.max_redirect_time")), 5])
635
- };
636
-
637
- // 设置extendedRootCA证书
638
- if (_.get(option, "system_configs.ca_cert.open") > 0 && _.trim(_.get(option, "system_configs.ca_cert.path")) != "") {
639
- _.set(requester, `extendedRootCA`, _.trim(_.get(option, "system_configs.ca_cert.path")));
640
- }
641
-
642
- // 设置客户端证书
643
- const certificates = [];
644
- _.forEach(_.get(option, "system_configs.client_cert"), (cert, host) => {
645
- const uri = new Url(host);
646
- if (_.isObject(cert)) {
647
- if (uri.port <= 0) {
648
- host = `${uri.protocol}://${_.join(uri.host, ".")}:443`;
649
- }
650
-
651
- ['key', 'crt', 'pfx'].forEach((type) => {
652
- let fileUrl = _.get(cert, `${type}.file_url`);
653
-
654
- if (_.isEmpty(fileUrl)) {
655
- if (!_.isEmpty(_.get(cert, `${type}.file_base64`))) {
656
- fileUrl = base64toCacheFile(
657
- _.get(cert, `${type}.file_name`),
658
- _.get(cert, `${type}.file_name`),
659
- _.get(cert, `${type}.file_base64`),
660
- uuidv4()
661
- )
662
- }
663
- }
664
-
665
- if (!_.isEmpty(fileUrl)) {
666
- try {
667
- fs.statSync(fileUrl);
668
- _.set(cert, `${type}.file_url`, fileUrl);
669
- } catch (e) { }
670
- }
671
- })
672
-
673
- const certObj = {
674
- name: `Client cert for ${host}`,
675
- matches: [host, `${host}/*`],
676
- passphrase: cert?.password,
677
- };
678
-
679
- ['key', 'crt', 'pfx'].forEach((type) => {
680
- if (!_.isEmpty(_.get(cert, `${type}.file_url`))) {
681
- _.set(certObj, type == 'crt' ? "cert" : type, { src: _.get(cert, `${type}.file_url`) })
682
- }
683
- })
684
-
685
- certificates.push(certObj);
686
- }
687
- }
688
- );
689
- let requestTimeout = _.toInteger(_.get(option, "system_configs.send_timeout"));
690
-
691
- // fix 请求超时时间除0外,最大值为一周,0为永不超时
692
- if (!_.inRange(requestTimeout, 0, 604800)) {
693
- requestTimeout = 0;
694
- }
695
-
696
- const options = {
697
- // abortOnFailure: false,
698
- // abortOnError: false,
699
- timeout: {
700
- request: requestTimeout,
701
- script: 0,
702
- global: 0,
703
- },
704
- delay: {
705
- item: 0,
706
- iteration: 0,
707
- },
708
- iterationCount: 1,
709
- fileResolver: require("fs"),
710
- data,
711
- environment,
712
- localVariables,
713
- globals,
714
- requester,
715
- systemProxy: async function (url, callback) {
716
- try {
717
- // 设置代理
718
- const proxy = {}, urlParsed = new Url(url), uriHost = _.toLower(_.join(urlParsed?.host, "."));
719
-
720
- if (_.get(option, "system_configs.proxy.type") == 1) {
721
- // 自定义代理
722
- const match = _.get(option, "system_configs.proxy.auth.host").match(
723
- /(([^:]+):(\d+))/
724
- );
725
-
726
- if (_.isArray(match) && _.toInteger(match[3]) > 0) {
727
- // 检查当前host是否匹配 bypass
728
- let bypass = _.get(option, "system_configs.proxy.bypass");
729
-
730
- if (_.isString(bypass)) {
731
- bypass = bypass.split(",");
732
- }
733
-
734
- let bypassMatch = _.find(bypass, (o) => {
735
- return minimatch(uriHost, o);
736
- });
737
-
738
- // 检查当前协议是否匹配 protocol
739
- let protocols = _.get(option, "system_configs.proxy.protocols");
740
-
741
- if (_.isString(protocols)) {
742
- protocols = protocols.split(",");
743
- }
744
-
745
- let protocolMatch = _.find(protocols, (o) => {
746
- return (_.toLower(urlParsed?.protocol) || "http") == _.toLower(o);
747
- });
748
-
749
- // 不匹配 bypass 且 匹配 protocol
750
- if (!bypassMatch && protocolMatch) {
751
- _.set(proxy, "host", match[2]);
752
- _.set(proxy, "port", _.toInteger(match[3]));
753
- }
754
- }
755
- } else if (_.get(option, "system_configs.proxy.type") == -1) {
756
- // 获取系统代理
757
- let noProxy = _.isString(_.get(process, "env.NO_PROXY")) && _.get(option, "system_configs.proxy.envfirst") > 0 ? String(_.get(process, "env.NO_PROXY")).split(",") : [];
758
-
759
- let unNoProxyMatch = _.isEmpty(noProxy) || _.isUndefined(_.find(noProxy, (o) => { return minimatch(uriHost, o); }));
760
-
761
- if (unNoProxyMatch) {
762
- const env_proxy = String(urlParsed?.protocol == "https" ? _.get(process, "env.HTTPS_PROXY") : _.get(process, "env.HTTP_PROXY"));
763
-
764
- if ((_.get(option, "system_configs.proxy.envfirst") > 0 || _.isEmpty(_.get(process, "versions.electron"))) && !_.isEmpty(env_proxy) && env_proxy != "undefined") {
765
- let env_proxy_parse = new Url(env_proxy);
766
- _.set(proxy, "host", _.join(env_proxy_parse?.host, ".") || "");
767
- _.set(proxy, "port", _.toInteger(env_proxy_parse?.port) > 0 ? _.toInteger(env_proxy_parse?.port) : 0);
768
- } else if (!_.isEmpty(_.get(process, "versions.electron"))) {
769
- try {
770
- const electronProxy = await require("electron").session.defaultSession.resolveProxy(url);
771
- const match = electronProxy.match(/PROXY (([^:]+):(\d+))/);
772
-
773
- if (_.isObject(match) && _.isString(match[2]) && !_.isEmpty(match[2]) && _.toInteger(match[3]) > 0
774
- ) {
775
- _.set(proxy, "host", match[2]);
776
- _.set(proxy, "port", _.toInteger(match[3]));
777
- }
778
- } catch (e) { }
779
- }
780
- }
781
- }
782
-
783
- if (_.isString(proxy.host) && proxy.host != "") {
784
- _.set(proxy, "tunnel", _.toLower(urlParsed?.protocol) == "http" ? false : true);
785
- _.set(proxy, "authenticate", _.get(option, "system_configs.proxy.auth.authenticate") > 0 ? true : false);
786
-
787
- if (proxy.authenticate) {
788
- _.set(proxy, "username", _.get(option, "system_configs.proxy.auth.username"));
789
- _.set(proxy, "password", _.get(option, "system_configs.proxy.auth.password"));
790
- }
791
- }
792
-
793
- if (!_.isEmpty(proxy) && _.isString(proxy.host) && proxy.host != "" && proxy.host != "undefined") {
794
- return callback(null, proxy)
795
- } else {
796
- return callback(null, null)
797
- }
798
- } catch (e) {
799
- return callback(null, null)
800
- }
801
- }
802
- };
803
-
804
- // 证书
805
- if (!_.isEmpty(certificates)) {
806
- _.assign(options, {
807
- certificates: new sdk.CertificateList(
808
- {},
809
- certificates
810
- )
811
- })
812
- }
813
-
814
- return options;
815
- }
816
-
817
- // 转 postman 事件
818
- const convert2PostmanEvent = (request, listen, option) => {
819
- const { requestJson } = request;
820
- const { database_configs, env, dynamic_option, custom_functions } = option;
821
-
822
- let customFuncScript = '';
823
- _.forEach(custom_functions, (script, name) => {
824
- name = _.trim(name);
825
- if (name != '') {
826
- customFuncScript = `
827
- ${customFuncScript}
828
-
829
- function ${name}(text) {
830
- try{
831
- ${script}
832
- }catch(e){
833
- return text;
834
- }
835
- }
836
- `;
837
- }
838
- })
839
-
840
- const sysScript = [
841
- // "(async function(){",
842
- "const response = {};",
843
- `
844
- const splitCookieString = (input)=> {
845
- let index = input.indexOf('=');
846
- if (index === -1) {
847
- return [input];
848
- }
849
- return [input.slice(0, index), input.slice(index + 1)];
850
- }
851
- `,
852
-
853
- `
854
- const getMainProcessSocketPath = ()=>{
855
- try{
856
- return atob("${_.get(process, 'env.ELECTRON_PIPE')}");
857
- }catch(e){
858
- return "${_.get(process, 'env.ELECTRON_PIPE')}";
859
- }
860
- }
861
- `,
862
-
863
- "let lodashv4 = require('lodash');",
864
- "let { mockExp } = require('exp-mock');",
865
- "let Mock = require('mockjs');",
866
- "let xml2json = xml2Json;",
867
- "let JSON5 = require('json5');",
868
- "let aTools = require('apipost-tools');",
869
- "let jsonpath = require('jsonpath');",
870
- `let _envTmpVariablesData = ${JSON.stringify(env)}`,
871
- `let _dynamicValueOptions = ${JSON.stringify(dynamic_option)}`,
872
- "let $ = {}; $.md5 = function(str){return CryptoJS.MD5(str).toString()};$.ajax = pm.ajaxSendRequest;",
873
- `pm.environment.getPreUrl = function(){return _.get(_envTmpVariablesData, "env_pre_url");}`,
874
- `pm.environment.getName = function(){return _.get(_envTmpVariablesData, "env_name");}`,
875
- "pm.environment.getCollection = function(){return pm.environment.toObject();}",
876
- `pm.variables.getPreUrl = function(){return _.get(_envTmpVariablesData, "env_pre_url");}`,
877
- `pm.variables.getName = function(){return _.get(_envTmpVariablesData, "env_name");}`,
878
- "pm.variables.getCollection = function(){return pm.environment.toObject();}",
879
- "pm.environment.delete = pm.environment.unset;",
880
- "pm.variables.delete = pm.variables.unset;",
881
- "pm.globals.delete = pm.globals.unset;",
882
- "pm.Visualizing = pm.visualizer.set", // 兼容旧版本的可视化
883
- `
884
- // Database
885
- pm.queryDatabase = async (dbconfig) => {
886
- const { query } = dbconfig;
887
- const { createUnixClient } = require('net'), socketPath = getMainProcessSocketPath();
888
-
889
- try{
890
- const result = await createUnixClient(socketPath, JSON.stringify({
891
- action: 'queryDatabase',
892
- data: { dbconfig, query }
893
- }));
894
-
895
- return JSON.parse(Buffer.from(JSON.parse(result.toString())).toString());
896
- }catch(e){
897
- console.error("Database error: " + String(e))
898
- throw new Error(String(e));
899
- // return { err: 'error', result:String(e)}
900
- }
901
- };
902
-
903
- // pm.execute/Async
904
- pm.executeAsync = pm.execute = async (file, args, option) => {
905
- const { createUnixClient } = require('net'), socketPath = getMainProcessSocketPath();
906
-
907
- try {
908
- const result = await createUnixClient(socketPath, JSON.stringify({
909
- action: 'execute',
910
- data: { file, args, option }
911
- }));
912
-
913
- const resultObj = JSON.parse(Buffer.from(JSON.parse(result.toString())).toString());
914
-
915
- if(resultObj?.err == 'success'){
916
- return resultObj?.result
917
- }else{
918
- console.error("pm.execute error: " + String(resultObj?.result))
919
- throw new Error(resultObj?.result);
920
- }
921
- }catch (e) {
922
- console.error("pm.execute error: " + String(e))
923
- throw new Error(e);
924
- }
925
- };
926
- `,
927
- `
928
- let _requestTmpBodyObject = request?.data
929
- try{
930
- _requestTmpBodyObject = JSON.stringify(JSON5.parse(request?.data));
931
- }catch(e){}
932
-
933
- try{
934
- let _requestTmpVariablesData = ${JSON.stringify({ name: requestJson?.name })}
935
- _.assign(request, {
936
- request_headers: pm.request?.headers?.toObject(),
937
- request_bodys: _requestTmpBodyObject,
938
- request_querys: pm.request?.url?.query?.toObject(),
939
- request_variables: pm.request?.url?.variables?.toObject(),
940
- mode: "${_.get(requestJson, "request.body.mode")}",
941
- contentType: pm.request?.headers?.get('content-type'),
942
- id: "${requestJson?.sample_id || requestJson?.target_id}",
943
- name: _.get(_requestTmpVariablesData, "name") || "HTTP request",
944
- url: String(pm.request?.url),
945
- uri: pm.request?.url
946
- });
947
- }catch(e){}
948
-
949
- // 获取最终请求body
950
- try{
951
- pm.getFinalRequestRawBody = () => {
952
- let requestBody = pm.variables.replaceIn(request.request_bodys);
953
-
954
- if(lodashv4.isString(requestBody)){
955
- const regex = /{{([^}]+)}}/g;
956
- const matches = requestBody.match(regex);
957
- if (!lodashv4.isEmpty(matches)) {
958
- lodashv4.forEach(matches, (match) => {
959
- try {
960
- const tmpVal = mockExp(match, _dynamicValueOptions?.all_vars || {}, _dynamicValueOptions?.lang || 'en', _dynamicValueOptions?.custom_functions || {});
961
-
962
- if (tmpVal != match && !lodashv4.isUndefined(tmpVal)) {
963
- requestBody = lodashv4.replace(requestBody, match, tmpVal);
964
- }
965
- } catch (e) { }
966
- })
967
- }
968
-
969
- pm.setRequestBody(requestBody);
970
- }
971
-
972
- return requestBody;
973
- }
974
- }catch(e){
975
- pm.getFinalRequestRawBody = () => {}
976
- }
977
-
978
- // 变量替换(含动态值)
979
- try{
980
- pm.mock = (str) => {
981
- if(lodashv4.isString(str)){
982
- const regex = /{{([^}]+)}}/g;
983
- const matches = str.match(regex);
984
- if (!lodashv4.isEmpty(matches)) {
985
- lodashv4.forEach(matches, (match) => {
986
- try {
987
- const tmpVal = mockExp(match, _dynamicValueOptions?.all_vars || {}, _dynamicValueOptions?.lang || 'en', _dynamicValueOptions?.custom_functions || {});
988
-
989
- if (tmpVal != match && !lodashv4.isUndefined(tmpVal)) {
990
- str = lodashv4.replace(str, match, tmpVal);
991
- }
992
- } catch (e) { }
993
- })
994
- }
995
-
996
- }
997
- return str;
998
- }
999
- }catch(e){
1000
- pm.mock = (str) => {return str}
1001
- }
1002
- `,
1003
- "if(_.isObject(pm.response)){",
1004
- "try{",
1005
- "_.set(response, 'headers', pm.response.headers?.toObject());",
1006
- "}catch(e){}",
1007
- `try{ // 设置cookie
1008
- response.cookies = {};
1009
- const responseCookies = lodashv4.get(pm.response.headers.toObject(), 'set-cookie');
1010
- lodashv4.forEach(lodashv4.isArray(responseCookies)?responseCookies:[responseCookies], (cookieStr) => {
1011
- let cookieArr = splitCookieString(lodashv4.head(lodashv4.split(cookieStr, ';')));
1012
- let cookieValue = lodashv4.join(lodashv4.tail(cookieArr),'');
1013
-
1014
- if(cookieArr[0] && cookieValue){
1015
- try{
1016
- _.set(response.cookies, cookieArr[0], decodeURIComponent(cookieValue))
1017
- }catch(e){
1018
- _.set(response.cookies, cookieArr[0], cookieValue)
1019
- }
1020
- }
1021
- })
1022
- }catch(e){}
1023
- `,
1024
- "_.set(pm, 'response.raw.responseText', pm.response.text());",
1025
- "_.set(response, 'raw.responseText', pm.response.text());",
1026
- "try{",
1027
- "_.set(response, 'json', pm.response.json());",
1028
- "_.set(response, 'raw.json', pm.response.json());",
1029
- "}catch(e){_.set(response, 'raw.json', {})}",
1030
- "_.set(response, 'raw.status', pm.response.code);",
1031
- "_.set(response, 'raw.responseTime', pm.response.responseTime);",
1032
- " pm.response.setBody = function (body) {",
1033
- " if (typeof body !== 'string') {",
1034
- " body = JSON.stringify(body);",
1035
- " }",
1036
- " if (typeof body === 'string') {",
1037
- " const originalText = _.cloneDeep(pm.response.text());",
1038
- " try {",
1039
- " const originalJson = _.cloneDeep(pm.response.json());",
1040
- " pm.response.originalJson = function () {",
1041
- " return originalJson;",
1042
- " };",
1043
- " }",
1044
- " catch (e) {",
1045
- " pm.response.originalJson = function () {",
1046
- " return null;",
1047
- " };",
1048
- " }",
1049
- " pm.response.originalText = function () {",
1050
- " return originalText;",
1051
- " };",
1052
- ` pm.response.stream = {type: "Buffer", data:Array.from(Buffer.from(body))};`,
1053
- ` pm.variables.set("_pm.response.setBody", body);`,
1054
- " }",
1055
- " };",
1056
- "",
1057
- " pm.response.setCode = function (code) {",
1058
- " if (typeof code === 'number') {",
1059
- " pm.response.originalCode = function () {",
1060
- " return pm.response.code;",
1061
- " };",
1062
- "",
1063
- " pm.response.code = code;",
1064
- ` pm.variables.set("_pm.response.code", code);`,
1065
- " }",
1066
- " };",
1067
- "}",
1068
- "const apipost = postman;",
1069
- "const apt = fox = ea = echoapi = insomnia = pm;", // TODO 兼容旧版本apipost的语法、增加更多三方库
1070
- `
1071
- // Compatible with tc
1072
- const expect = pm.expect;
1073
- const assert = pm.assert;
1074
- assert.equal = (source, dist) => { return source === dist }
1075
- const tc = {};
1076
- try {
1077
- // global
1078
- tc.loadModule = require;
1079
- tc.info = {};
1080
- tc.delay = sleep;
1081
-
1082
- // Ignored library
1083
- tc.exec = () => { console.warn("The tc.exec script syntax of Thunder client is not supported.") }
1084
- tc.runRequest = () => { console.warn("The tc.runRequest script syntax of Thunder client is not supported, Please use pm.sendRequest() instead.") }
1085
- tc.skipRequest = () => { console.warn("The tc.skipRequest script syntax of Thunder client is not supported.") }
1086
- tc.chartHTML = () => { console.warn("The tc.chartHTML script syntax of Thunder client is not supported.") }
1087
- tc.retryRequest = () => { console.warn("The tc.retryRequest script syntax of Thunder client is not supported.") }
1088
- tc.runRequest = () => { console.warn("The tc.runRequest script syntax of Thunder client is not supported.") }
1089
- tc.setCookie = () => { console.warn("The tc.setCookie script syntax of Thunder client is not supported.") }
1090
- tc.clearCookies = () => { console.warn("The tc.clearCookies script syntax of Thunder client is not supported.") }
1091
- tc.getCookies = () => { console.warn("The tc.getCookies script syntax of Thunder client is not supported.") }
1092
- tc.readFile = () => { console.warn("The tc.readFile script syntax of Thunder client is not supported.") }
1093
- tc.loadFromPath = () => { console.warn("The tc.loadFromPath script syntax of Thunder client is not supported.") }
1094
-
1095
- // test
1096
- tc.test = (name, func) => {
1097
- if (lodashv4.isFunction(func)) {
1098
- if(!lodashv4.isUndefined(func())){
1099
- try{
1100
- pm.test(name, func)
1101
- }catch(e){}
1102
- }else{
1103
- pm.test(name, pm.expect(func()).to.equal(true))
1104
- }
1105
- } else {
1106
- pm.test(name, pm.expect(lodashv4.toInteger(func) > 0 ? true : false).to.equal(true))
1107
- }
1108
- }
1109
-
1110
- // var
1111
- tc.setVar = (key, value) => { pm.environment.set(key, value) };
1112
- tc.getVar = (key) => { return pm.environment.get(key) };
1113
-
1114
- // Param
1115
- tc.setParam = (key, value) => { pm.setRequestQuery(key, value) };
1116
-
1117
- // request
1118
- tc.request = lodashv4.cloneDeep(request);
1119
- tc.request.body = {};
1120
- tc.request.name = request.name;
1121
- tc.request.id = request.id;
1122
- tc.request.name = request.name;
1123
- tc.request.setHeader = (key, value) => { pm.setRequestHeader(key, value) };
1124
- tc.request.getHeader = (key) => { return pm.request.headers.get(key) };
1125
- tc.request.setBody = (key, value) => { pm.setRequestBody(key, value) };
1126
-
1127
- // response
1128
- if (lodashv4.isObject(pm.response)) {
1129
- tc.response = lodashv4.cloneDeep(response);
1130
- tc.response.size = pm.response.responseSize;
1131
- tc.response.status = pm.response.code;
1132
- tc.response.time = pm.response.responseTime;
1133
- tc.response.text = response?.raw?.responseText;
1134
- tc.response.contentType = lodashv4.get(response, 'headers.content-type');
1135
- tc.response.cookies = lodashv4.toPairs(lodashv4.get(tc, 'response.cookies')).map(([key, value]) => ({ key, value }));
1136
- tc.response.headers = lodashv4.cloneDeep(lodashv4.cloneDeep(pm.response.headers.toJSON()));
1137
- tc.response.getHeader = (key) => { return lodashv4.get(response.headers, lodashv4.toLower(key)) };
1138
- tc.response.getBinary = () => { console.warn("The tc.getBinary script syntax of Thunder client is not supported.") }
1139
- }
1140
- } catch (e) {
1141
- console.warn("Thunder Client script has an issue; please check manually. EchoAPI is fully compatible with Postman.")
1142
- }
1143
-
1144
- // 自定义函数
1145
- ${customFuncScript}
1146
- `, // 兼容 thuner client
1147
- ];
1148
-
1149
- const pmEvent = {
1150
- prerequest: [],
1151
- test: [],
1152
- };
1153
- const eventMap = {
1154
- pre_tasks: "prerequest",
1155
- post_tasks: "test",
1156
- };
1157
-
1158
- _.forEach(_.keys(eventMap), (type) => {
1159
- let exec = _.join(sysScript, "\n");
1160
- _.forEach(_.get(requestJson, `request.${type}`), (item) => {
1161
- if (_.isObject(item)) {
1162
- if (item.enabled > 0) {
1163
- switch (item.type) {
1164
- case "customScript": // done
1165
- if (!_.isEmpty(item?.data) && _.isString(item?.data) && item?.data != 'undefined') {
1166
- exec = `${exec}\n${_.trim(item?.data)}\n`;
1167
- }
1168
- break;
1169
- case "database": // done
1170
- let dbconfig = database_configs[item.data?.connectionId] || {};
1171
-
1172
- if (!_.isEmpty(dbconfig)) {
1173
- dbconfig = JSON.stringify(dbconfig, null, "\t");
1174
- exec = `${exec}
1175
- ! await (async function(){
1176
- const dbData = ${JSON.stringify(item.data || { query: '' })}
1177
- const query = pm.variables.replaceIn(lodashv4.get(dbData, "query"));
1178
- const method = pm.variables.replaceIn(lodashv4.get(dbData, "method") || "");
1179
-
1180
- try{
1181
- let dbResultList = await pm.queryDatabase(lodashv4.assign(${dbconfig},{
1182
- method:method,
1183
- query:query
1184
- }));
1185
-
1186
- let {err, result} = dbResultList;
1187
-
1188
- if(err == 'success'){
1189
- if(${item.data?.isConsoleOutput} > 0){
1190
- console.log(query, result)
1191
- }
1192
- if(lodashv4.isObject(result)){
1193
- lodashv4.forEach(${JSON.stringify(item.data?.variables || [])}, (item) => {
1194
- let extra_value = jsonpath.value(result, lodashv4.trim(item?.pattern) || "$");
1195
- pm[item?.type].set(item?.name, extra_value);
1196
- });
1197
- }else{
1198
- if(!lodashv4.isObject(result)){
1199
- lodashv4.forEach(${JSON.stringify(item.data?.variables || [])}, (item) => {
1200
- let extra_value = result;
1201
- pm[item?.type].set(item?.name, extra_value);
1202
- });
1203
- }
1204
- }
1205
- }else{
1206
- console.error(query, String(result))
1207
- }
1208
- }catch(e){};
1209
- })();`;
1210
- }
1211
- break;
1212
- case "wait": // done
1213
- const timeout = _.toInteger(item?.data);
1214
-
1215
- if (timeout > 0) {
1216
- exec = `${exec}\nsleep(${timeout});`;
1217
- }
1218
- break;
1219
- case "assert": //done
1220
- exec = `${exec}
1221
- !(function(){
1222
- let assertObjectData = ${JSON.stringify(item)};
1223
- let responseData = '';
1224
- let expertData = null;
1225
- let expertExpression = '';
1226
- let expertValue = null;
1227
-
1228
- if(_.get(assertObjectData, "data.type") == 'responseJson'){
1229
- try{
1230
- responseData = pm.response.json();
1231
- }catch(e){
1232
- responseData = xml2Json(pm.response.text()) || {}
1233
- }
1234
-
1235
- expertData = jsonpath.value(responseData, _.get(assertObjectData, "data.expression.path") || "$");
1236
- }else if(_.get(assertObjectData, "data.type") == 'responseXml'){
1237
- try{
1238
- responseData = pm.response.text();
1239
- var xpath = require('xpath');
1240
- var dom = require('xmldom').DOMParser;
1241
- expertData = String(xpath.select(_.get(assertObjectData, "data.expression.path"), new dom().parseFromString(responseData, 'text/xml')));
1242
- }catch(e){}
1243
- }else if(_.get(assertObjectData, "data.type") == 'responseText'){
1244
- expertData = pm.response.text();
1245
- }else if(_.get(assertObjectData, "data.type") == 'responseHeader'){
1246
- expertData = pm.response.headers.get(_.get(assertObjectData, "data.expression.path"));
1247
- }else if(_.get(assertObjectData, "data.type") == 'responseCookie'){
1248
- expertData = _.get(response.cookies, _.get(assertObjectData, "data.expression.path"));
1249
- }else if(_.get(assertObjectData, "data.type") == 'responseCode'){
1250
- expertData = pm.response.code;
1251
- }else if(_.get(assertObjectData, "data.type") == 'responseTime'){
1252
- expertData = pm.response.responseTime;
1253
- }else if(_.get(assertObjectData, "data.type") == 'responseSize'){
1254
- expertData = pm.response.responseSize;
1255
- }else if(_.get(assertObjectData, "data.type") == 'tempVars'){
1256
- expertData = pm.variables.get(_.trim(_.get(assertObjectData, "data.expression.path"), '{}'));
1257
- }else if(_.get(assertObjectData, "data.type") == 'envVars'){
1258
- expertData = pm.environment.get(_.trim(_.get(assertObjectData, "data.expression.path"), '{}'));
1259
- }else if(_.get(assertObjectData, "data.type") == 'globalVars'){
1260
- expertData = pm.globals.get(_.trim(_.get(assertObjectData, "data.expression.path"), '{}'));
1261
- }
1262
-
1263
- expertValue = pm.variables.replaceIn(_.get(assertObjectData, "data.expression.compareValue"));
1264
-
1265
- if(_.get(assertObjectData, "data.expression.compareType") == "eq"){
1266
- expertExpression = null;
1267
- pm.test(_.get(assertObjectData, "name"), function () {
1268
- pm.expect(String(expertData)).to.eql(String(expertValue));
1269
- });
1270
- }else if(_.get(assertObjectData, "data.expression.compareType") == "uneq"){
1271
- expertExpression = null;
1272
- pm.test(_.get(assertObjectData, "name"), function () {
1273
- pm.expect(String(expertData)).to.not.eql(String(expertValue));
1274
- });
1275
- }else if(_.get(assertObjectData, "data.expression.compareType") == "lt"){
1276
- expertExpression = null;
1277
- pm.test(_.get(assertObjectData, "name"), function () {
1278
- pm.expect(lodashv4.toNumber(expertData)).to.be.below(lodashv4.toNumber(expertValue));
1279
- });
1280
- }else if(_.get(assertObjectData, "data.expression.compareType") == "lte"){
1281
- expertExpression = null;
1282
- pm.test(_.get(assertObjectData, "name"), function () {
1283
- pm.expect(lodashv4.toNumber(expertData)).to.be.at.most(lodashv4.toNumber(expertValue));
1284
- });
1285
- }else if(_.get(assertObjectData, "data.expression.compareType") == "gt"){
1286
- expertExpression = null;
1287
- pm.test(_.get(assertObjectData, "name"), function () {
1288
- pm.expect(lodashv4.toNumber(expertData)).to.be.above(lodashv4.toNumber(expertValue));
1289
- });
1290
- }else if(_.get(assertObjectData, "data.expression.compareType") == "gte"){
1291
- expertExpression = null;
1292
- pm.test(_.get(assertObjectData, "name"), function () {
1293
- pm.expect(lodashv4.toNumber(expertData)).to.be.at.least(lodashv4.toNumber(expertValue));
1294
- });
1295
- }else if(_.get(assertObjectData, "data.expression.compareType") == "includes"){
1296
- expertExpression = null;
1297
- pm.test(_.get(assertObjectData, "name"), function () {
1298
- pm.expect(String(expertData)).to.include(String(expertValue));
1299
- });
1300
- }else if(_.get(assertObjectData, "data.expression.compareType") == "unincludes"){
1301
- expertExpression = null;
1302
- pm.test(_.get(assertObjectData, "name"), function () {
1303
- pm.expect(String(expertData)).to.not.include(String(expertValue));
1304
- });
1305
- }else if(_.get(assertObjectData, "data.expression.compareType") == "null"){
1306
- expertExpression = null;
1307
- pm.test(_.get(assertObjectData, "name"), function () {
1308
- pm.expect(expertData).to.be.empty;
1309
- });
1310
- }else if(_.get(assertObjectData, "data.expression.compareType") == "notnull"){
1311
- expertExpression = null;
1312
- pm.test(_.get(assertObjectData, "name"), function () {
1313
- pm.expect(String(expertData)).to.not.be.empty;
1314
- });
1315
- }else if(_.get(assertObjectData, "data.expression.compareType") == "exist"){
1316
- expertExpression = null;
1317
- pm.test(_.get(assertObjectData, "name"), function () {
1318
- pm.expect(expertData).to.exist;
1319
- });
1320
- }else if(_.get(assertObjectData, "data.expression.compareType") == "notexist"){
1321
- expertExpression = null;
1322
- pm.test(_.get(assertObjectData, "name"), function () {
1323
- pm.expect(expertData).to.not.exist;
1324
- });
1325
- }else if(_.get(assertObjectData, "data.expression.compareType") == "regularmatch"){
1326
- expertExpression = null;
1327
-
1328
- if(!lodashv4.isEmpty(expertValue)){
1329
- expertValue = new RegExp(lodashv4.trim(expertValue, '/'));
1330
-
1331
- pm.test(_.get(assertObjectData, "name"), function () {
1332
- pm.expect(expertData).to.match(expertValue);
1333
- });
1334
- }
1335
- }else if(_.get(assertObjectData, "data.expression.compareType") == "belongscollection"){
1336
- expertExpression = null;
1337
- pm.test(_.get(assertObjectData, "name"), function () {
1338
- pm.expect(String(expertData)).to.be.oneOf(lodashv4.split(expertValue, ","));
1339
- });
1340
- }else if(_.get(assertObjectData, "data.expression.compareType") == "notbelongscollection"){
1341
- expertExpression = null;
1342
- pm.test(_.get(assertObjectData, "name"), function () {
1343
- pm.expect(String(expertData)).to.not.be.oneOf(lodashv4.split(expertValue, ","));
1344
- });
1345
- }
1346
- })();
1347
- `;
1348
- break;
1349
- case "pickVars": //done
1350
- const varTypeMap = {
1351
- tempVars: "variables",
1352
- envVars: "environment",
1353
- globalVars: "globals",
1354
- };
1355
- exec = `${exec}\n
1356
- !(function(){
1357
- `
1358
- switch (item.data?.source) {
1359
- case "requestHeader":
1360
- exec = `${exec}\n
1361
- let varSource = request?.headers;
1362
- `;
1363
- break;
1364
- case "requestBody":
1365
- exec = `${exec}\n
1366
- let varSource = request?.request_bodys;
1367
- if(typeof varSource === 'string'){
1368
- try{
1369
- varSource = JSON5.parse(varSource)
1370
- }catch(e){}
1371
- }
1372
- `;
1373
- break;
1374
- case "responseJson":
1375
- exec = `${exec}\n
1376
- let varSource = '';
1377
-
1378
- try{
1379
- varSource = pm.response.json();
1380
- }catch(e){
1381
- varSource = xml2Json(pm.response.text())
1382
- }
1383
- `;
1384
- break;
1385
- case "responseXml":
1386
- case "responseText":
1387
- exec = `${exec}\n
1388
- let varSource = pm.response.text();
1389
- `;
1390
- break;
1391
- case "responseHeader":
1392
- exec = `${exec}\n
1393
- let varSource = pm.response.headers;
1394
- `;
1395
- break;
1396
- case "responseCookie":
1397
- exec = `${exec}\n
1398
- let varSource = response.cookies;
1399
- `;
1400
- break;
1401
- case "responseCode":
1402
- exec = `${exec}\n
1403
- let varSource = pm.response.code;
1404
- `;
1405
- break;
1406
- case "responseTime":
1407
- exec = `${exec}\n
1408
- let varSource = pm.response.responseTime;
1409
- `;
1410
- break;
1411
- case "responseSize":
1412
- exec = `${exec}\n
1413
- let varSource = pm.response.responseSize;
1414
- `;
1415
- break;
1416
- }
1417
-
1418
- _.forEach(item.data?.variables, (varItem) => {
1419
- if (_.isObject(varItem) && varItem?.name != "" && !_.isUndefined(varTypeMap[varItem?.type])) {
1420
- switch (item.data?.source) {
1421
- case 'requestHeader':
1422
- exec = `${exec}\n
1423
- !(function(){
1424
- let pickVars = ${JSON.stringify(varItem)};
1425
- try{
1426
- pm[${JSON.stringify(varTypeMap[varItem?.type])}].set(_.get(pickVars,"name"), _.get(varSource, lodashv4.toLower(_.trim(_.get(pickVars,"expression")))));
1427
- }catch(e){}
1428
- })();
1429
- `;
1430
- break;
1431
- case 'requestBody':
1432
- exec = `${exec}\n
1433
- !(function(){
1434
- let pickVars = ${JSON.stringify(varItem)};
1435
- pm[${JSON.stringify(varTypeMap[varItem?.type])}].set(_.get(pickVars,"name"), jsonpath.value(varSource, _.trim(_.get(pickVars,"expression")) || "$"));
1436
- })();
1437
- `;
1438
- break;
1439
- case "responseJson":
1440
- exec = `${exec}\n
1441
- !(function(){
1442
- let pickVars = ${JSON.stringify(varItem)};
1443
- pm[${JSON.stringify(varTypeMap[varItem?.type])}].set(_.get(pickVars,"name"), jsonpath.value(varSource, _.trim(_.get(pickVars,"expression")) || "$"));
1444
- })();
1445
- `;
1446
- break;
1447
- case "responseXml":
1448
- exec = `${exec}\n
1449
- !(function(){
1450
- let pickVars = ${JSON.stringify(varItem)};
1451
- let xmlValue = '';
1452
- var xpath = require('xpath');
1453
- var dom = require('xmldom').DOMParser;
1454
-
1455
- try{
1456
- xmlValue = String(xpath.select(_.trim(_.get(pickVars,"expression")), new dom().parseFromString(varSource, 'text/xml')));
1457
- }catch(e){}
1458
-
1459
- pm[${JSON.stringify(varTypeMap[varItem?.type])}].set(_.get(pickVars, "name"), xmlValue);
1460
- })();
1461
- `;
1462
- break;
1463
- case "responseHeader":
1464
- exec = `${exec}\n
1465
- !(function(){
1466
- let pickVars = ${JSON.stringify(varItem)};
1467
- try{
1468
- pm[${JSON.stringify(varTypeMap[varItem?.type])}].set(_.get(pickVars,"name"), varSource.get(_.trim(_.get(pickVars,"expression"))));
1469
- }catch(e){}
1470
- })();
1471
- `;
1472
- break;
1473
- case "responseCookie":
1474
- exec = `${exec}\n
1475
- !(function(){
1476
- let pickVars = ${JSON.stringify(varItem)};
1477
- pm[${JSON.stringify(varTypeMap[varItem?.type])}].set(_.get(pickVars,"name"), _.get(varSource, _.trim(_.get(pickVars,"expression"))));
1478
- })();
1479
- `;
1480
- break;
1481
- case "responseText":
1482
- case "responseCode":
1483
- case "responseTime":
1484
- case "responseSize":
1485
- exec = `${exec}\n
1486
- !(function(){
1487
- let pickVars = ${JSON.stringify(varItem)};
1488
- pm[${JSON.stringify(varTypeMap[varItem?.type])}].set(_.trim(_.get(pickVars, "name")), varSource);
1489
- })();
1490
- `;
1491
- break;
1492
- }
1493
- }
1494
- }
1495
- );
1496
- exec = `${exec}
1497
- })();`
1498
- break;
1499
- }
1500
- }
1501
- }
1502
- }
1503
- );
1504
-
1505
- exec = `${exec}\n
1506
- if(_.isObject(pm.response)){
1507
- if(!_.isFunction(pm.response.originalText) || pm.response.originalText() == pm.response.text()){
1508
- if(response?.raw?.responseText != pm.response.text()){
1509
- pm.response.setBody(response?.raw?.responseText);
1510
- }else if(pm.response?.raw?.responseText != pm.response.text()){
1511
- pm.response.setBody(pm.response?.raw?.responseText);
1512
- }
1513
- }
1514
- }
1515
- `;
1516
- let execArr = _.split(exec, "\n");
1517
- // execArr.push("})()");
1518
- pmEvent[eventMap[type]].push({
1519
- listen: eventMap[type],
1520
- script: {
1521
- exec: execArr,
1522
- type: "text/javascript",
1523
- },
1524
- });
1525
- });
1526
-
1527
- return pmEvent[listen];
1528
- }
1529
-
1530
- // 转换pm request为输出的request
1531
- function convert2EchoRequest(request, requestJson, postmanJSON, history) {
1532
- const cloneRequest = _.assign(_.cloneDeep(request), _.pick(requestJson, ['project_id', 'target_id', 'name']));
1533
-
1534
- // 请求体类型
1535
- cloneRequest.mode = _.get(requestJson, "request.body.mode");
1536
-
1537
- // 其他请求参数
1538
- try {
1539
- cloneRequest.paths = _.fromPairs((_.get(postmanJSON, "url.variable") || []).map((item) => [item.key, item.value,])) || {};
1540
- } catch (e) { }
1541
-
1542
- try {
1543
- const allRequestHeaders = _.mapValues(_.keyBy(_.get(history, 'execution.data[0].request.headers') || {}, 'key'), 'value');
1544
-
1545
- if (!_.isEmpty(allRequestHeaders) && _.isObject(allRequestHeaders)) {
1546
- cloneRequest.headers = allRequestHeaders;
1547
- } else {
1548
- cloneRequest.headers = _.reduce(cloneRequest.headers?.toJSON(), (obj, item) => {
1549
- obj[item.key] = item.value;
1550
- return obj;
1551
- }, {}
1552
- );
1553
- }
1554
- } catch (e) { }
1555
-
1556
- try {
1557
- cloneRequest.querys = cloneRequest.url?.query?.toObject();
1558
- cloneRequest.url = String(cloneRequest.url);
1559
- } catch (e) { }
1560
-
1561
- try {
1562
- cloneRequest.body = _.get(request, `body.${_.get(request, "body.mode")}`);
1563
-
1564
- if (cloneRequest.mode == "msgpack") {
1565
- const msgpack = require("msgpack5")();
1566
- try {
1567
- cloneRequest.body = JSON.stringify(msgpack.decode(Buffer.from(_.values(cloneRequest.body))));
1568
- } catch (e) { }
1569
- }
1570
-
1571
- try {
1572
- cloneRequest.body = cloneRequest.body.toObject();
1573
- } catch (e) { }
1574
- } catch (e) { }
1575
-
1576
- try {
1577
- cloneRequest.uri = request?.url.toJSON();
1578
- _.forEach(cloneRequest.uri, (value, key) => {
1579
- if (key == "query") {
1580
- cloneRequest.uri[key] = value.toObject();
1581
- } else if (key == "host") {
1582
- cloneRequest.uri[key] = _.join(value, ".");
1583
- } else if (key == "path") {
1584
- cloneRequest.uri[key] = _.join(value, "/");
1585
- } else {
1586
- if (_.isArray(value)) {
1587
- cloneRequest.uri[key] = _.join(value, "");
1588
- }
1589
- }
1590
- });
1591
- } catch (e) { }
1592
-
1593
- // 获取cookies
1594
- cloneRequest.cookies = {};
1595
-
1596
- try {
1597
- const cookiesString = cloneRequest.headers?.cookie;
1598
- if (!_.isEmpty(cookiesString) && _.isString(cookiesString)) {
1599
- _.forEach(_.split(cookiesString, ";"), (cookie) => {
1600
- const { key, value } = tough.Cookie.parse(cookie).toJSON();
1601
- cloneRequest.cookies[key] = value;
1602
- });
1603
- }
1604
- } catch (e) { }
1605
-
1606
- return cloneRequest;
1607
- }
1608
-
1609
- // 转换pm response为输出的response
1610
- async function convert2EchoResponse(response, history) {
1611
- const cloneResponse = _.cloneDeep(response);
1612
- _.unset(cloneResponse, "_details");
1613
-
1614
- // 响应体
1615
- try {
1616
- _.assign(cloneResponse, {
1617
- body: String(cloneResponse.stream),
1618
- });
1619
- } catch (e) { }
1620
-
1621
- // 判断适合什么格式输出
1622
- try {
1623
- let fitForShow = "Monaco";
1624
- let mimeType = {
1625
- ext: "json",
1626
- mime: "application/json",
1627
- };
1628
-
1629
- if (isSvg(cloneResponse.body)) {
1630
- _.assign(mimeType, {
1631
- ext: "svg",
1632
- mime: "image/svg+xml",
1633
- });
1634
- fitForShow = "Image";
1635
- } else {
1636
- const fileType = await FileType.fromBuffer(cloneResponse.stream);
1637
-
1638
- if (_.isObject(fileType)) {
1639
- _.assign(mimeType, fileType);
1640
- if (isImage(`test.${mimeType?.ext}`)) {
1641
- fitForShow = "Image";
1642
- } else if (mimeType?.ext == "pdf") {
1643
- fitForShow = "Pdf";
1644
- } else if (mimeType?.ext == "xml") {
1645
- fitForShow = "Monaco";
1646
- } else {
1647
- fitForShow = "Other";
1648
- }
1649
- } else {
1650
- const contentType = getCaseInsensitive(cloneResponse?.headers || {}, "content-type") || "";
1651
- if (!_.isEmpty(contentType)) {
1652
- mimeType = {
1653
- ext: mime.getExtension(contentType),
1654
- mime: mime.getType(mime.getExtension(contentType)),
1655
- };
1656
- } else {
1657
- const ext = aTools.isJson(cloneResponse.body) ? "json" : aTools.isJsonp(cloneResponse.body) ? "jsonp" : "html";
1658
- mimeType = {
1659
- ext: ext,
1660
- mime: mime.getType(ext) || "application/jsonp",
1661
- };
1662
- }
1663
- }
1664
- }
1665
-
1666
- _.assign(cloneResponse, { mimeType, fitForShow });
1667
- } catch (e) { }
1668
-
1669
- // 响应头对象
1670
- const responseHeader = {};
1671
- try {
1672
- _.assign(
1673
- responseHeader,
1674
- _.reduce(
1675
- response.headers?.toJSON(),
1676
- (obj, item) => {
1677
- if (obj[item.key]) {
1678
- if (!Array.isArray(obj[item.key])) {
1679
- obj[item.key] = [obj[item.key]];
1680
- }
1681
- obj[item.key].push(item.value);
1682
- } else {
1683
- obj[item.key] = item.value;
1684
- }
1685
- return obj;
1686
- },
1687
- {}
1688
- )
1689
- );
1690
- } catch (e) { }
1691
-
1692
- // 响应头
1693
- try {
1694
- _.assign(cloneResponse, {
1695
- headers: responseHeader,
1696
- });
1697
- } catch (e) { }
1698
-
1699
- // 缓存文件名
1700
- let cacheFileName = `${cloneResponse?.id}.${cloneResponse?.mimeType?.ext}`;
1701
- try {
1702
- cacheFileName = _.get(contentDisposition.parse(getCaseInsensitive(responseHeader || {}, "content-disposition")), "parameters.filename");
1703
-
1704
- if (_.isString(cacheFileName)) {
1705
- try {
1706
- cacheFileName = decodeURIComponent(cacheFileName);
1707
- } catch (e) { }
1708
- }
1709
- } catch (e) { }
1710
-
1711
- cloneResponse.filename = cacheFileName;
1712
-
1713
- // cookie
1714
- cloneResponse.cookies = {};
1715
- cloneResponse.arrCookies = [];
1716
-
1717
- let cookieArrs = getCaseInsensitive(responseHeader || {}, "set-cookie");
1718
- if (_.isString(cookieArrs)) {
1719
- cookieArrs = [cookieArrs];
1720
- }
1721
-
1722
- try {
1723
- _.forEach(cookieArrs, (cookie) => {
1724
- const cookieJson = tough.Cookie.parse(cookie).toJSON();
1725
- _.assign(cookieJson, {
1726
- name: cookieJson?.key,
1727
- cookie_id: aTools.snowflakeId(`cookie_id_${uuidv4()}`),
1728
- });
1729
- cloneResponse.arrCookies.push(cookieJson);
1730
- const { key, value } = cookieJson;
1731
- cloneResponse.cookies[key] = value;
1732
- });
1733
- } catch (e) { }
1734
-
1735
- const requestStart =
1736
- _.get(history, "execution.data.0.timings.requestStart") || Date.now();
1737
- _.assign(cloneResponse, {
1738
- proxy: _.get(history, "execution.data.0.request.proxy") || {},
1739
- timings: _.mapKeys(
1740
- _.get(history, "execution.data.0.timings.offset") || {},
1741
- (value, key) => _.snakeCase(key)
1742
- ),
1743
- requestStart,
1744
- response_at: requestStart,
1745
- });
1746
-
1747
- return cloneResponse;
1748
- }
1749
-
1750
- const preProcessMockExp = (request, requestPara, AllVars, option) => {
1751
- const { postmanJSON } = requestPara;
1752
- const { lang, custom_functions } = option;
1753
- const customFunctions = _.cloneDeep(custom_functions);
1754
-
1755
- // 识别变量
1756
- const regex = /{{([^}]+)}}/g;
1757
-
1758
- // 替换 URL 中可能的变量
1759
- let url = String(request?.url || '');
1760
- if (!_.isEmpty(url)) {
1761
- const matches = url.match(regex);
1762
- if (!_.isEmpty(matches)) {
1763
- _.forEach(matches, (match) => {
1764
- try {
1765
- const tmpVal = mockExp(match, AllVars, lang, customFunctions);
1766
-
1767
- if (tmpVal != match && !_.isUndefined(tmpVal)) {
1768
- url = _.replace(url, match, tmpVal);
1769
- }
1770
- } catch (e) { }
1771
- })
1772
-
1773
- _.set(request, 'url', new sdk.Url(url));
1774
- }
1775
- }
1776
-
1777
- // 重置 restful
1778
- _.forEach(_.get(postmanJSON, 'url.path'), (item, key) => { //variable
1779
- if (_.startsWith(item, ":")) {
1780
- const pathVarKey = _.findKey(_.get(postmanJSON, 'url.variable'), (vars) => {
1781
- return vars?.key == _.trimStart(item, ':')
1782
- });
1783
-
1784
- if (_.startsWith(_.get(postmanJSON, `url.variable.${pathVarKey}.value`), '{{') && _.endsWith(_.get(postmanJSON, `url.variable.${pathVarKey}.value`), '}}') && !_.isUndefined(_.get(request, `url.path.${key}`))) {
1785
- _.set(postmanJSON, `url.variable.${pathVarKey}.value`, _.get(request, `url.path.${key}`));
1786
- }
1787
- }
1788
- })
1789
-
1790
- // 替换 Header 中可能的变量
1791
- if (!_.isEmpty(request.headers)) {
1792
- request?.headers?.each((item) => {
1793
- if (!item?.disabled) {
1794
- ['key', 'value'].forEach((type) => {
1795
- let currentPara = String(_.get(item, type));
1796
- const matches = currentPara.match(regex);
1797
- if (!_.isEmpty(matches)) {
1798
- _.forEach(matches, (match) => {
1799
- try {
1800
- const tmpVal = mockExp(match, AllVars, lang, customFunctions);
1801
- if (tmpVal != match && !_.isUndefined(tmpVal)) {
1802
- currentPara = _.replace(currentPara, match, tmpVal);
1803
-
1804
- }
1805
- } catch (e) { }
1806
- })
1807
-
1808
- _.set(item, type, currentPara)
1809
- }
1810
- })
1811
- }
1812
- })
1813
- }
1814
-
1815
- // 替换 body 中可能的变量
1816
- const bodyMode = _.get(request, 'body.mode');
1817
- switch (bodyMode) {
1818
- case 'urlencoded':
1819
- case 'formdata':
1820
- if (!_.isEmpty(request?.body[bodyMode])) {
1821
- request?.body[bodyMode].each((item, key) => {
1822
- if (!item?.disabled) {
1823
- ['key', 'value'].forEach((type) => {
1824
- let currentPara = _.get(item, type);
1825
- if (_.isString(currentPara)) {
1826
- const matches = currentPara.match(regex);
1827
-
1828
- if (!_.isEmpty(matches)) {
1829
- _.forEach(matches, (match) => {
1830
- try {
1831
- const tmpVal = mockExp(match, AllVars, lang, customFunctions);
1832
- if (tmpVal != match && !_.isUndefined(tmpVal)) {
1833
- currentPara = _.replace(currentPara, match, tmpVal);
1834
- }
1835
- } catch (e) { }
1836
- })
1837
-
1838
- _.set(item, type, currentPara);
1839
- }
1840
- }
1841
- })
1842
- }
1843
- })
1844
- }
1845
- break;
1846
- default:
1847
- let rawBody = _.get(request, 'body.raw');
1848
- if (_.isString(rawBody) && !_.isEmpty(rawBody)) {
1849
- const matches = rawBody.match(regex);
1850
- if (!_.isEmpty(matches)) {
1851
- _.forEach(matches, (match) => {
1852
- try {
1853
- const tmpVal = mockExp(match, AllVars, lang, customFunctions);
1854
- if (tmpVal != match && !_.isUndefined(tmpVal)) {
1855
- rawBody = _.replace(rawBody, match, tmpVal);
1856
- }
1857
- } catch (e) { }
1858
- })
1859
-
1860
- _.set(request, 'body.raw', rawBody);
1861
- }
1862
- }
1863
- break;
1864
- }
1865
-
1866
- return request;
1867
- }
1868
-
1869
- // 初始化api请求参数
1870
- const initRequestJson = (event, option) => {
1871
-
1872
- // 获取具体的请求详情
1873
- const requestJson = _.assign(_.pick(event, ['event_id', 'test_id']), _.pick(event?.data, ['target_id', 'project_id']));
1874
-
1875
- if (_.includes(['api', 'sample', 'sse', 'request'], event?.type)) {
1876
- // 原接口信息
1877
- if (_.toInteger(event?.auto_sync) > 0 || _.includes(['http_request', 'get_parsed_request'], option?.scene)) {
1878
- _.assign(requestJson, getAPIFromCollection(option?.collection, _.get(event, `data.target_id`)));
1879
- } else { // 从 data的 apiData 获取
1880
- _.assign(requestJson, _.get(event, `data.apiData`));
1881
- }
1882
-
1883
- // 向上查询获取最终参数
1884
- const parentIDs = [];
1885
-
1886
- // 为向上查询获取最终参数做准备,获取正确的 parent_id
1887
- if (_.includes(['sample'], event?.type)) {
1888
- const sampleTargetID = _.get(getAPIFromCollection(option?.collection, _.get(event, `data.target_id`)), 'parent_id');
1889
- // const sampleTargetID = _.get(getAPIFromCollection(option?.collection, _.get(event, `data.parent_id`)), 'target_id');
1890
-
1891
- if (_.isString(sampleTargetID) && sampleTargetID) {
1892
- getParentTargetIDs(option?.collection, sampleTargetID, parentIDs);
1893
- // getParentTargetIDs(option?.collection, requestJson?.sampleTargetID, parentIDs);
1894
- }
1895
- } else {
1896
- getParentTargetIDs(option?.collection, _.get(event, `data.target_id`), parentIDs);
1897
- }
1898
-
1899
- if (!_.includes(parentIDs, "0")) {
1900
- parentIDs.push("0");
1901
- }
1902
-
1903
- // 设置 ["header", "body", "query", "cookie"]
1904
- _.forEach(parentIDs, (parent_id) => {
1905
- const request = {};
1906
- if (parent_id == "0") {
1907
- _.assign(request, _.get(option, "project.request"));
1908
- } else {
1909
- // 目录参数
1910
- _.assign(request, _.get(getAPIFromCollection(option?.collection, parent_id), "request"));
1911
- }
1912
-
1913
- if (_.isObject(request) && !_.isEmpty(request)) {
1914
- ["header", "body", "query", "cookie"].forEach((parameter) => {
1915
- let arrPara = _.filter(_.get(request, `${parameter}.parameter`), (item) => { return _.toInteger(item.is_system) > 0 || item.is_checked > 0 });
1916
-
1917
- if (!_.isEmpty(arrPara) && _.isArray(arrPara)) {
1918
- const filterOrginParaArr = _.filter(_.get(requestJson, `request.${parameter}.parameter`), item => item.is_checked > 0) || []
1919
- const orginPara = _.chain(filterOrginParaArr)
1920
- .groupBy('key')
1921
- .map((group) => _.reduce(group, (acc, item) => item.is_checked > 0 ? item : acc, group[group.length - 1]))
1922
- .value();
1923
-
1924
- const mergePara = _.chain(arrPara)
1925
- .groupBy('key')
1926
- .map((group) => _.reduce(group, (acc, item) => item.is_checked > 0 ? item : acc, group[group.length - 1]))
1927
- .value();
1928
-
1929
- if (parameter == 'header') {
1930
- _.set(
1931
- requestJson,
1932
- `request.${parameter}.parameter`,
1933
- _.unionBy(
1934
- orginPara,
1935
- mergePara,
1936
- (value) => {
1937
- return _.toLower(value['key']);
1938
- }
1939
- )
1940
- );
1941
- } else {
1942
- _.set(
1943
- requestJson,
1944
- `request.${parameter}.parameter`,
1945
- _.unionBy(
1946
- orginPara,
1947
- mergePara,
1948
- "key"
1949
- )
1950
- );
1951
- }
1952
- }
1953
- })
1954
- }
1955
- });
1956
-
1957
- // 设置 ['auth,pre_script,test,pre_tasks,post_tasks']
1958
- let commPara = {}, envServerID = _.get(requestJson, 'server_id');
1959
-
1960
- _.forEach(_.reverse(parentIDs), (parent_id) => {
1961
- const request = {};
1962
- if (parent_id == "0") {
1963
- // 全局参数
1964
- _.assign(request, _.get(option, "project.request"));
1965
- } else {
1966
- // 目录参数
1967
- const parentEnvServerID = _.get(getAPIFromCollection(option?.collection, parent_id), "server_id");
1968
- if (_.isUndefined(_.get(requestJson, 'server_id')) && _.isString(parentEnvServerID)) {
1969
- envServerID = parentEnvServerID;
1970
- }
1971
-
1972
- _.assign(request, _.get(getAPIFromCollection(option?.collection, parent_id), "request"));
1973
- }
1974
-
1975
- if (_.isObject(request) && !_.isEmpty(request)) {
1976
- ["auth", "pre_script", "test", "pre_tasks", "post_tasks",].forEach((parameter) => {
1977
- const tmpPara = _.get(request, `${parameter}`);
1978
-
1979
- if (!_.isEmpty(tmpPara)) {
1980
- if (_.isArray(tmpPara)) {
1981
- commPara[parameter] = _.union(commPara[parameter], tmpPara);
1982
- } else if (_.isObject(tmpPara)) {
1983
- if (parameter == "auth" && _.get(tmpPara, "type") != "inherit") {
1984
- _.set(commPara, "auth.type", _.get(tmpPara, "type"));
1985
- _.set(commPara, `auth.${_.get(tmpPara, "type")}`, _.get(tmpPara, `${_.get(tmpPara, "type")}`));
1986
- }
1987
- } else if (_.isString(tmpPara)) {
1988
- commPara[parameter] = `${commPara[parameter]}\n${tmpPara}`;
1989
- }
1990
- }
1991
- });
1992
- }
1993
- });
1994
-
1995
- _.forEach(commPara, (paras, key) => {
1996
- if (!_.isEmpty(paras)) {
1997
- if (_.isArray(paras)) {
1998
- _.set(requestJson, `request.${key}`, _.union(paras, _.get(requestJson, `request.${key}`)));
1999
- } else if (_.isObject(paras)) {
2000
- if (key == "auth" && _.get(requestJson, "request.auth.type") == "inherit") {
2001
- _.set(requestJson, "request.auth.type", _.get(paras, "type"));
2002
- _.set(requestJson, `request.auth.${_.get(paras, "type")}`, _.get(paras, `${_.get(paras, "type")}`));
2003
- }
2004
- } else if (_.isString(paras)) {
2005
- _.set(requestJson, `request.${key}`, `${paras}\n${_.get(requestJson, `request.${key}`)}`);
2006
- }
2007
- }
2008
- });
2009
-
2010
- _.unset(commPara);
2011
-
2012
- // 处理 cookie 控制器传来的cookie,并将其他cookie参数一并转为 cookieArr 数组
2013
- const cookieArr = [];
2014
- if (_.get(option, "cookies.switch") > 0 && _.isArray(_.get(option, "cookies.data"))) {
2015
- // 先处理管理器的cookie
2016
- _.forEach(_.get(option, "cookies.data"), (item) => {
2017
- let key = _.trim(item?.key);
2018
- if (_.isObject(item) && !_.isEmpty(key)) {
2019
- let currentKey = _.find(cookieArr, _.matchesProperty("key", key));
2020
-
2021
- // Fixed an issue where cookies do not take effect when domain input is irregular
2022
- let cookieDomain = item?.domain;
2023
- try {
2024
- const domainParse = new Url(item?.domain);
2025
- cookieDomain = _.join(domainParse?.host, '.')
2026
- } catch (e) { }
2027
-
2028
-
2029
- const currentCookie = {
2030
- key: key,
2031
- value: item?.value,
2032
- domain: cookieDomain,
2033
- path: (item?.path != 'undefined' ? item?.path : '/') || "/",
2034
- expires: item?.expires || new Date(new Date().getTime() + 3600 * 1000),
2035
- maxAge: item?.maxAge || 3600,
2036
- secure: !!_.toInteger(item?.secure),
2037
- httpOnly: !!_.toInteger(item?.httpOnly),
2038
- sameSite: item?.sameSite || "strict",
2039
- };
2040
-
2041
- if (currentKey > -1) {
2042
- cookieArr[currentKey] = currentCookie;
2043
- } else {
2044
- cookieArr.push(currentCookie);
2045
- }
2046
- }
2047
- }
2048
- );
2049
- }
2050
-
2051
- if (_.isArray(_.get(requestJson, "request.cookie.parameter"))) {
2052
- // 处理接口中的cookie
2053
- _.forEach(_.get(requestJson, "request.cookie.parameter"), (item) => {
2054
- let key = _.trim(item?.key);
2055
- if (_.isObject(item) && !_.isEmpty(key) && item?.is_checked > 0) {
2056
- let currentKey = _.find(cookieArr, _.matchesProperty("key", key));
2057
- let currentCookie = {
2058
- key: key,
2059
- value: item?.value,
2060
- schema: item?.schema
2061
- };
2062
- if (currentKey > -1) {
2063
- cookieArr[currentKey] = currentCookie;
2064
- } else {
2065
- cookieArr.push(currentCookie);
2066
- }
2067
- }
2068
- }
2069
- );
2070
- }
2071
-
2072
- _.set(requestJson, "request.cookie.parameter", cookieArr);
2073
- _.unset(cookieArr);
2074
-
2075
- // 前置URL
2076
- if (!_.isString(envServerID) || _.toString(envServerID) === "0") {
2077
- envServerID = "1";
2078
- }
2079
-
2080
- const requestUrl = _.isString(_.get(requestJson, 'url')) ? _.get(requestJson, 'url') : _.get(requestJson, 'request.url');
2081
- const { globals, env } = option;
2082
-
2083
- // 获取前置url
2084
- let envPreUrl = _.trim(_.get(requestJson, 'pre_url', ''));
2085
-
2086
- if (envPreUrl == '') {
2087
- envPreUrl = _.trim(_.get(_.find(_.get(option, `env.env_pre_urls`), (server) => {
2088
- return server?.server_id == envServerID;
2089
- }), 'uri'));
2090
- }
2091
-
2092
- if (envPreUrl != '') {
2093
- if (option?.env?.env_id == '2' && !_.endsWith(envPreUrl, '/')) {
2094
- envPreUrl = `${envPreUrl}/`;
2095
- }
2096
-
2097
- if (!_.startsWith(envPreUrl, '{{') && !_.startsWith(_.toLower(envPreUrl), 'http://') && !_.startsWith(_.toLower(envPreUrl), 'https://')) {
2098
- _.set(requestJson, "url", smartUrlJoin('http://', envPreUrl, requestUrl));
2099
- } else {
2100
- _.set(requestJson, "url", smartUrlJoin(envPreUrl, requestUrl));
2101
- }
2102
- }
2103
-
2104
- // 设置 initVarReplacedUrl
2105
- let initVarReplacedUrl = requestJson?.url;
2106
- _.forEach(_.assign({}, globals, _.get(env, 'environment')), (value, key) => {
2107
- initVarReplacedUrl = replace2RegExp(initVarReplacedUrl, `{{${key}}}`, String(value))
2108
- })
2109
-
2110
- _.set(requestJson, "initVarReplacedUrl", initVarReplacedUrl);
2111
- } else if (_.includes(['script'], event?.type)) {
2112
- _.set(requestJson, "request.pre_tasks", [
2113
- {
2114
- type: "customScript",
2115
- enabled: 1,
2116
- data: event?.data?.content,
2117
- },
2118
- ]);
2119
- } else if (_.includes(['assert'], event?.type)) {
2120
- _.set(requestJson, "name", "脚本断言");
2121
- _.set(requestJson, "request.pre_tasks", [
2122
- {
2123
- type: "customScript",
2124
- enabled: 1,
2125
- data: event?.data?.content,
2126
- },
2127
- ]);
2128
- } else if (_.includes(['sql'], event?.type)) { // 数据库
2129
- _.set(requestJson, "request.pre_tasks", [
2130
- {
2131
- "type": "database",
2132
- "id": event?.event_id,
2133
- "name": "Database",
2134
- "enabled": 1,
2135
- "data": _.assign({
2136
- "connectionId": "",
2137
- "query": "",
2138
- "isConsoleOutput": 1,
2139
- "variables": []
2140
- }, event?.data)
2141
- }
2142
- ])
2143
- } else if (_.includes(['assert_visual'], event?.type)) {
2144
- const { type, expression } = event?.data?.data || {};
2145
-
2146
- if (_.isString(type) && !_.isEmpty(expression)) {
2147
- _.set(requestJson, "name", "可视化断言");
2148
- _.set(requestJson, "request.pre_tasks", [
2149
- {
2150
- "type": "assert",
2151
- "id": event?.event_id,
2152
- "name": "Visual assertion",
2153
- "enabled": 1,
2154
- "data": {
2155
- type,
2156
- "expression": _.assign({
2157
- "compareType": "eq",
2158
- "compareValue": "",
2159
- "path": ""
2160
- }, expression)
2161
- }
2162
- }
2163
- ])
2164
- }
2165
- }
2166
-
2167
- const postmanJSON = convert2PostmanRequest(requestJson, option);
2168
- return { requestJson, postmanJSON };
2169
- }
2170
-
2171
- // module exports
2172
- module.exports = (event, option, callback, eventRuntimeData, eventResultList) => {
2173
- const { scene } = option;
2174
- return new Promise((resolve, reject) => {
2175
- try {
2176
- const { requestJson, postmanJSON } = initRequestJson(event, option)
2177
-
2178
- const collection = new sdk.Item({
2179
- name: _.get(requestJson, "name") || "New request", request: postmanJSON, event: [], protocolProfileBehavior: {
2180
- disableBodyPruning: true,
2181
- disabledSystemHeaders: {
2182
- 'accept': true,
2183
- 'accept-encoding': true,
2184
- 'connection': true
2185
- }
2186
- }
2187
- });
2188
- const options = convert2PostmanOptions({ requestJson, postmanJSON }, option, eventRuntimeData?.variables || {});
2189
- const runner = new runtime.Runner();
2190
-
2191
- runner.run(
2192
- new sdk.Collection({
2193
- info: {
2194
- name: _.get(requestJson, "name") || "New request",
2195
- },
2196
- item: [collection]
2197
- }), options, (err, run) => {
2198
- if (err) {
2199
- reject({
2200
- action: 'systemError',
2201
- message: String(err),
2202
- event_id: event?.event_id
2203
- });
2204
- } else {
2205
- // init eventRuntimeData for apis
2206
- _.set(eventRuntimeData, [event?.event_id, 'exception'], null)
2207
- _.set(eventRuntimeData, [event?.event_id, 'error'], null)
2208
- _.set(eventRuntimeData, [event?.event_id, 'console'], [])
2209
- _.set(eventRuntimeData, [event?.event_id, 'assertions'], [])
2210
- _.set(eventRuntimeData, [event?.event_id, 'visualizer'], { error: null, processed_template: "" })
2211
-
2212
- // start run request
2213
- run.start({
2214
- // script error
2215
- exception(cursor, err) {
2216
- if (err) {
2217
- if (!_.includes(['assert_visual', 'assert'], event?.type)) {
2218
- const scriptType = _.get(cursor, cursor?.scriptId);
2219
- _.set(eventRuntimeData, [event?.event_id, "exception", scriptType], err);
2220
- _.set(eventRuntimeData, [event?.event_id, 'error'], {
2221
- error_type: scriptType,
2222
- message: err?.message
2223
- })
2224
-
2225
- if (_.includes(['prerequest', 'test'], scriptType)) {
2226
- if (_.isUndefined(_.get(eventRuntimeData, [event?.event_id, "console"]))) {
2227
- _.set(eventRuntimeData, [event?.event_id, "console"], []);
2228
- }
2229
-
2230
- const time = Date.now()
2231
- eventRuntimeData[event?.event_id].console.push(
2232
- {
2233
- time,
2234
- "level": "error",
2235
- "args": [String(err?.message)]
2236
- }
2237
- )
2238
- }
2239
-
2240
- if (scriptType === 'prerequest') {
2241
- try {
2242
- run.abort();
2243
- if (_.isUndefined(_.get(eventRuntimeData, [event?.event_id, "request"]))) {
2244
- _.set(eventRuntimeData, [event?.event_id, "request"], _.pick(requestJson, ['name', 'method', 'url']));
2245
- }
2246
- } catch (e) { }
2247
- }
2248
- }
2249
- }
2250
- },
2251
-
2252
- // script print
2253
- console(cursor, level, ...args) {
2254
- if (_.isUndefined(_.get(eventRuntimeData, [event?.event_id, "console"]))) {
2255
- _.set(eventRuntimeData, [event?.event_id, "console"], []);
2256
- }
2257
- const time = Date.now()
2258
- eventRuntimeData[event?.event_id].console.push({ time, level, args })
2259
- },
2260
-
2261
- // Called just before sending a request
2262
- beforeRequest(err, cursor, request, item) {
2263
- const AllVars = getInsideVariables();
2264
- ["globals", "environment", "variables"].forEach((varName) => {
2265
- _.assign(AllVars, _.get(eventRuntimeData, `variables.${varName}`))
2266
- })
2267
- preProcessMockExp(request, { postmanJSON }, AllVars, _.pick(option, ['lang', 'custom_functions']))
2268
-
2269
- if (_.includes(['get_parsed_request'], scene)) {
2270
- callback(generateHarFromRequest(request));
2271
- try {
2272
- run.abort();
2273
- } catch (e) { }
2274
- resolve();
2275
- }
2276
- },
2277
-
2278
- beforePrerequest(err, cursor, events, item) {
2279
- if (!err) {
2280
- const pmEvent = convert2PostmanEvent({ requestJson, postmanJSON }, "prerequest", option);
2281
-
2282
- _.forEach(pmEvent, (event) => {
2283
- const script = new PostmanEvent(event);
2284
- events.push(script);
2285
- _.set(cursor, script?.script?.id, script?.listen);
2286
- });
2287
- }
2288
- },
2289
-
2290
- prerequest(err, cursor, results, item) {
2291
- if (!err) {
2292
- _.forEach(results, (result) => {
2293
- _.forEach(['_variables', 'environment', 'globals'], (varType) => {
2294
- const currentVar = _.get(result, `result.${varType}`);
2295
- const currentVarObject = {};
2296
-
2297
- try {
2298
- _.forEach(_.get(currentVar.toJSON(), 'values'), (item) => {
2299
- currentVarObject[item?.key] = item?.value;
2300
- })
2301
- } catch (e) { }
2302
-
2303
- try {
2304
- // Delete the variables that have been destroyed
2305
- const unsetKeys = _.difference(_.keys(_.get(eventRuntimeData, ['variables', varType])), _.keys(currentVarObject));
2306
-
2307
- _.forEach(unsetKeys, (unsetKey) => {
2308
- if (varType == 'globals' && !_.includes(_.keys(getInsideVariables()), unsetKey)) {
2309
- _.unset(eventRuntimeData, ['variables', '_globals', unsetKey])
2310
- _.unset(eventRuntimeData, ['variables', varType, unsetKey])
2311
- } else if (varType == '_variables') {
2312
- _.unset(eventRuntimeData, ['variables', 'variables', unsetKey])
2313
- } else {
2314
- _.unset(eventRuntimeData, ['variables', varType, unsetKey])
2315
- }
2316
- })
2317
-
2318
- // Set new variable values for the undestroyed ones
2319
- _.forEach(currentVarObject, (val, key) => {
2320
- let setPath = varType;
2321
- if (varType === '_variables') {
2322
- setPath = 'variables';
2323
- }
2324
-
2325
- if (varType === 'globals' && !_.includes(_.keys(getInsideVariables()), key)) {
2326
- _.set(eventRuntimeData, ["variables", '_globals', key], val)
2327
- }
2328
- _.set(eventRuntimeData, ["variables", setPath, key], val)
2329
- })
2330
- } catch (e) { }
2331
- })
2332
- })
2333
- }
2334
- },
2335
-
2336
- // responseStart: (err, cursor, response, request, item, cookies, history) => {
2337
- // if (_.includes(['get_parsed_request'], scene)) {
2338
- // callback(generateHarFromRequest(request));
2339
- // try {
2340
- // run.abort();
2341
- // } catch (e) { }
2342
- // resolve();
2343
- // }
2344
- // },
2345
-
2346
- response: async (err, cursor, response, request, item, cookies, history) => {
2347
- if (!_.includes(['get_parsed_request'], scene)) {
2348
- callback(generateHarFromRequest(request));
2349
- try {
2350
- run.abort();
2351
- } catch (e) { }
2352
- resolve();
2353
- } else {
2354
- if (!err) {
2355
- _.set(eventRuntimeData, [event?.event_id, "response"], await convert2EchoResponse(response, history));
2356
- } else {
2357
- if (!_.includes(['script', 'sql', 'assert_visual', 'assert'], event?.type)) {
2358
- _.set(eventRuntimeData, [event?.event_id, "exception", 'prerequest'], String(err));
2359
- _.set(eventRuntimeData, [event?.event_id, 'error'], {
2360
- error_type: 'prerequest',
2361
- message: String(err)
2362
- })
2363
-
2364
- if (_.isUndefined(_.get(eventRuntimeData, [event?.event_id, "console"]))) {
2365
- _.set(eventRuntimeData, [event?.event_id, "console"], []);
2366
- }
2367
-
2368
- const time = Date.now()
2369
- eventRuntimeData[event?.event_id].console.push(
2370
- {
2371
- time,
2372
- "level": "error",
2373
- "args": [String(err?.message)]
2374
- }
2375
- )
2376
- }
2377
- }
2378
-
2379
- const requestOptions = convert2EchoRequest(request, requestJson, postmanJSON, history);
2380
- _.set(eventRuntimeData, [event?.event_id, "request"], requestOptions);
2381
- }
2382
- },
2383
-
2384
- beforeTest(err, cursor, events, item) {
2385
- if (!err) {
2386
- if (!_.includes(['get_parsed_request'], scene)) {
2387
- const pmEvent = convert2PostmanEvent({ requestJson, postmanJSON }, "test", option);
2388
- _.forEach(pmEvent, (event) => {
2389
- const script = new PostmanEvent(event);
2390
- events.push(script);
2391
- _.set(cursor, script?.script?.id, script?.listen);
2392
- });
2393
- }
2394
- }
2395
- },
2396
-
2397
- test(err, cursor, results, item) {
2398
- if (!err) {
2399
- if (!_.includes(['get_parsed_request'], scene)) {
2400
- _.forEach(results, (result) => {
2401
- _.forEach(['_variables', 'environment', 'globals'], (varType) => {
2402
- const currentVar = _.get(result, `result.${varType}`);
2403
- const currentVarObject = {};
2404
-
2405
- try {
2406
- _.forEach(_.get(currentVar.toJSON(), 'values'), (item) => {
2407
- currentVarObject[item?.key] = item?.value;
2408
- })
2409
- } catch (e) { }
2410
-
2411
- try {
2412
- // Delete the variables that have been destroyed
2413
- const unsetKeys = _.difference(_.keys(_.get(eventRuntimeData, ['variables', varType])), _.keys(currentVarObject));
2414
-
2415
- _.forEach(unsetKeys, (unsetKey) => {
2416
- if (varType == 'globals' && !_.includes(_.keys(getInsideVariables()), unsetKey)) {
2417
- _.unset(eventRuntimeData, ['variables', '_globals', unsetKey])
2418
- _.unset(eventRuntimeData, ['variables', varType, unsetKey])
2419
- } else if (varType == '_variables') {
2420
- _.unset(eventRuntimeData, ['variables', 'variables', unsetKey])
2421
- } else {
2422
- _.unset(eventRuntimeData, ['variables', varType, unsetKey])
2423
- }
2424
- })
2425
-
2426
- // Set new variable values for the undestroyed ones
2427
- _.forEach(currentVarObject, (val, key) => {
2428
- let setPath = varType;
2429
- if (varType === '_variables') {
2430
- setPath = 'variables';
2431
- }
2432
-
2433
- if (varType === 'globals' && !_.includes(_.keys(getInsideVariables()), key)) {
2434
- _.set(eventRuntimeData, ["variables", '_globals', key], val)
2435
- }
2436
- _.set(eventRuntimeData, ["variables", setPath, key], val)
2437
- })
2438
- } catch (e) { }
2439
- })
2440
- })
2441
-
2442
- const tmpResponseBody = _.get(eventRuntimeData, ['variables', 'variables', '_pm.response.setBody']);
2443
- const tmpResponseCode = _.toInteger(_.get(eventRuntimeData, ['variables', 'variables', '_pm.response.code']));
2444
-
2445
- if (_.isString(tmpResponseBody)) {
2446
- _.set(eventRuntimeData, [event?.event_id, "response", "stream"], {
2447
- type: "Buffer",
2448
- data: Array.from(Buffer.from(tmpResponseBody))
2449
- })
2450
-
2451
- _.set(eventRuntimeData, [event?.event_id, "response", "body"], tmpResponseBody)
2452
- }
2453
-
2454
- if (tmpResponseCode > 0) {
2455
- _.set(eventRuntimeData, [event?.event_id, "response", "code"], tmpResponseCode)
2456
- }
2457
- }
2458
- }
2459
- },
2460
-
2461
- assertion(cursor, assertions) {
2462
- if (!_.includes(['get_parsed_request'], scene)) {
2463
- if (!_.isEmpty(assertions) && _.isArray(assertions)) {
2464
- if (_.isUndefined(_.get(eventRuntimeData, [event?.event_id, "assertions"]))) {
2465
- _.set(eventRuntimeData, [event?.event_id, "assertions"], []);
2466
- }
2467
-
2468
- eventRuntimeData[event?.event_id].assertions = _.unionWith(_.concat(_.get(eventRuntimeData, [event?.event_id, "assertions"]), assertions), _.isEqual);
2469
- }
2470
- }
2471
- },
2472
-
2473
- item(err, cursor, item, visualizer, result) {
2474
- if (!_.includes(['get_parsed_request'], scene)) {
2475
- if (!err && _.isObject(visualizer)) {
2476
- const { error, processedTemplate } = visualizer;
2477
- _.set(eventRuntimeData[event?.event_id], "visualizer", { error, processed_template: processedTemplate });
2478
- } else {
2479
- _.set(eventRuntimeData[event?.event_id], "visualizer", { error: null, processed_template: "" });
2480
- }
2481
- }
2482
- },
2483
-
2484
- responseData(cursor, data) {
2485
- if (!_.includes(['get_parsed_request'], scene) && requestJson?.target_type === 'sse') {
2486
- callback({
2487
- action: "sse",
2488
- data: {
2489
- stream: data,
2490
- size: _.size(data),
2491
- time: Date.now()
2492
- },
2493
- msg: "success",
2494
- error: null,
2495
- })
2496
- }
2497
- },
2498
-
2499
- done(err, summary) {
2500
- if (!_.includes(['get_parsed_request'], scene)) {
2501
- if (!err) {
2502
- const success_assert = _.filter(_.get(eventRuntimeData, [event?.event_id, "assertions"]), (item) => {
2503
- return item?.passed === false
2504
- })
2505
-
2506
- let httpCode = 'Ok';
2507
-
2508
- if (!_.inRange(_.toInteger(_.get(eventRuntimeData, [event?.event_id, 'response', 'code'])), 200, 300)) {
2509
- httpCode = _.get(eventRuntimeData, [event?.event_id, 'response', 'status']) || _.get(eventRuntimeData, [event?.event_id, 'error', 'message']);
2510
- }
2511
- _.set(eventRuntimeData, [event?.event_id, "status"], {
2512
- assert: _.get(eventRuntimeData, [event?.event_id, "assertions"], []),
2513
- success_assert,
2514
- http: httpCode
2515
- });
2516
- }
2517
-
2518
- // 返回结果
2519
- try {
2520
- const runtimeState = convertEndRuntimeState(eventRuntimeData, event?.event_id) || {}
2521
- const tempVars = _.pick(_.get(eventRuntimeData, 'variables'), ['environment', '_globals']);
2522
- const toLowerResponseJson = _.assign(camelCaseToSnakeCase(_.get(eventRuntimeData, event?.event_id)), _.pick(runtimeState, ['startTime', 'endTime', 'currentVariables']));
2523
- const finalRequestResult = _.assign(
2524
- _.pick(requestJson, ['parent_id', 'project_id', 'test_id', 'target_id']),
2525
- _.defaults(_.pick(toLowerResponseJson, ['error', 'iteration_id', 'startTime', 'endTime', 'currentVariables']), { error: null }),
2526
- {
2527
- action: 'request',
2528
- // type: 'request',
2529
- type: event?.type,
2530
- data: _.assign(
2531
- {
2532
- variables: {
2533
- globals: _.get(tempVars, '_globals', {}),
2534
- environment: _.get(tempVars, 'environment', {})
2535
- }
2536
- },
2537
- _.omit(_.cloneDeep(toLowerResponseJson), ['error'])
2538
- ),
2539
- event_id: event?.event_id,
2540
- }
2541
- );
2542
-
2543
- if (scene === 'auto_test' || requestJson?.target_type === 'sse') { // 纯粹为了兼容老的数据返回格式 todo...
2544
- if (_.includes(['assert', 'assert_visual', 'api', 'sample', 'script', 'sql'], event?.type)) {
2545
- eventResultList.push(_.assign(camelCaseToSnakeCase(_.get(_.cloneDeep(eventRuntimeData), event?.event_id)), _.pick(event, ['type', 'event_id', 'test_id', 'iteration_id'])));
2546
-
2547
- callback({
2548
- action: 'request',
2549
- data: _.assign(finalRequestResult, {
2550
- // type: 'request'
2551
- type: event?.type
2552
- })
2553
- })
2554
- }
2555
- } else {
2556
- callback(finalRequestResult);
2557
- }
2558
- } catch (e) {
2559
- reject({
2560
- action: 'systemError',
2561
- message: String(e),
2562
- event_id: event?.event_id
2563
- });
2564
- }
2565
- }
2566
-
2567
- resolve();
2568
- }
2569
- })
2570
- }
2571
- }
2572
- );
2573
- } catch (e) {
2574
- reject({
2575
- action: 'systemError',
2576
- message: String(e),
2577
- event_id: event?.event_id
2578
- });
2579
- }
2580
- });
2581
- }