botium-core 1.14.10 → 1.15.3

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/botium-es.js CHANGED
@@ -27,20 +27,20 @@ import yaml from 'yaml';
27
27
  import child_process from 'child_process';
28
28
  import socket from 'socket.io-client';
29
29
  import bottleneck from 'bottleneck';
30
- import request from 'request';
31
30
  import mustache from 'mustache';
32
31
  import mimeTypes from 'mime-types';
33
32
  import ioredis from 'ioredis';
33
+ import undici from 'undici';
34
34
  import express from 'express';
35
35
  import bodyParser from 'body-parser';
36
36
 
37
37
  var name = "botium-core";
38
- var version$1 = "1.14.10";
38
+ var version$1 = "1.15.3";
39
39
  var description = "The Selenium for Chatbots";
40
40
  var main = "index.js";
41
41
  var module = "dist/botium-es.js";
42
42
  var engines = {
43
- node: ">=14.0.0"
43
+ node: ">=18.17"
44
44
  };
45
45
  var scripts = {
46
46
  postinstall: "node ./report.js",
@@ -89,7 +89,6 @@ var dependencies = {
89
89
  "promise-retry": "^2.0.1",
90
90
  "promise.allsettled": "^1.0.7",
91
91
  randomatic: "^3.1.1",
92
- request: "^2.88.2",
93
92
  rimraf: "^5.0.5",
94
93
  "sanitize-filename": "^1.6.3",
95
94
  slugify: "^1.6.6",
@@ -99,6 +98,7 @@ var dependencies = {
99
98
  "swagger-jsdoc": "^6.2.8",
100
99
  "swagger-ui-express": "^5.0.0",
101
100
  tinyglobby: "^0.2.10",
101
+ undici: "^6.21.0",
102
102
  uuid: "^9.0.1",
103
103
  "word-error-rate": "0.0.7",
104
104
  "write-yaml": "^1.0.0",
@@ -122,7 +122,7 @@ var devDependencies = {
122
122
  "eslint-plugin-promise": "^6.1.1",
123
123
  "eslint-plugin-standard": "^4.1.0",
124
124
  mocha: "^10.3.0",
125
- nock: "^13.5.1",
125
+ nock: "^14.0.0-beta.19",
126
126
  "npm-check-updates": "^16.14.15",
127
127
  nyc: "^15.1.0",
128
128
  rollup: "2.79.1",
@@ -225,6 +225,7 @@ var Capabilities = {
225
225
  SIMPLEREST_HEADERS_TEMPLATE: 'SIMPLEREST_HEADERS_TEMPLATE',
226
226
  SIMPLEREST_BODY_TEMPLATE: 'SIMPLEREST_BODY_TEMPLATE',
227
227
  SIMPLEREST_BODY_RAW: 'SIMPLEREST_BODY_RAW',
228
+ SIMPLEREST_BODY_FROM_JSON: 'SIMPLEREST_BODY_FROM_JSON',
228
229
  SIMPLEREST_START_HOOK: 'SIMPLEREST_START_HOOK',
229
230
  SIMPLEREST_STOP_HOOK: 'SIMPLEREST_STOP_HOOK',
230
231
  SIMPLEREST_REQUEST_HOOK: 'SIMPLEREST_REQUEST_HOOK',
@@ -302,6 +303,8 @@ var Capabilities = {
302
303
  SCRIPTING_CSV_UTTERANCE_STARTROW_HEADER: 'SCRIPTING_CSV_UTTERANCE_STARTROW_HEADER',
303
304
  SCRIPTING_CSV_UTTERANCE_STOP_ON_EMPTY: 'SCRIPTING_CSV_UTTERANCE_STOP_ON_EMPTY',
304
305
  SCRIPTING_NORMALIZE_TEXT: 'SCRIPTING_NORMALIZE_TEXT',
306
+ SCRIPTING_NORMALIZE_TEXT_REMOVE_CHARACTERES: 'SCRIPTING_NORMALIZE_TEXT_REMOVE_CHARACTERES',
307
+ SCRIPTING_NORMALIZE_TEXT_REMOVE_REGEXP: 'SCRIPTING_NORMALIZE_TEXT_REMOVE_REGEXP',
305
308
  SCRIPTING_ENABLE_MEMORY: 'SCRIPTING_ENABLE_MEMORY',
306
309
  SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS: 'SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS',
307
310
  SCRIPTING_ENABLE_SKIP_ASSERT_ERRORS: 'SCRIPTING_ENABLE_SKIP_ASSERT_ERRORS',
@@ -400,6 +403,7 @@ Capabilities.SIMPLEREST_VERB;
400
403
  Capabilities.SIMPLEREST_HEADERS_TEMPLATE;
401
404
  Capabilities.SIMPLEREST_BODY_TEMPLATE;
402
405
  Capabilities.SIMPLEREST_BODY_RAW;
406
+ Capabilities.SIMPLEREST_BODY_FROM_JSON;
403
407
  Capabilities.SIMPLEREST_START_HOOK;
404
408
  Capabilities.SIMPLEREST_STOP_HOOK;
405
409
  Capabilities.SIMPLEREST_REQUEST_HOOK;
@@ -472,6 +476,8 @@ Capabilities.SCRIPTING_CSV_UTTERANCE_STARTROW;
472
476
  Capabilities.SCRIPTING_CSV_UTTERANCE_STARTROW_HEADER;
473
477
  Capabilities.SCRIPTING_CSV_UTTERANCE_STOP_ON_EMPTY;
474
478
  Capabilities.SCRIPTING_NORMALIZE_TEXT;
479
+ Capabilities.SCRIPTING_NORMALIZE_TEXT_REMOVE_CHARACTERES;
480
+ Capabilities.SCRIPTING_NORMALIZE_TEXT_REMOVE_REGEXP;
475
481
  Capabilities.SCRIPTING_ENABLE_MEMORY;
476
482
  Capabilities.SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS;
477
483
  Capabilities.SCRIPTING_ENABLE_SKIP_ASSERT_ERRORS;
@@ -1544,7 +1550,31 @@ const {
1544
1550
  E_SCRIPTING_MEMORY_COLUMN_MODE: E_SCRIPTING_MEMORY_COLUMN_MODE$1
1545
1551
  } = Enums;
1546
1552
  const WHITE_SPACES_EXCEPT_SPACE_CHAR_AT_THE_END = /[\n\t\r]+$/;
1547
- const normalizeText$1 = (str, doCleanup) => {
1553
+ const normalizeText$1 = (str, doCleanupOrCaps) => {
1554
+ // TODO testlog
1555
+ debug$m('yxc1', doCleanupOrCaps);
1556
+ let basic;
1557
+ let charactersRemove = false;
1558
+ let regexpRemove = false;
1559
+ if (lodash.isBoolean(doCleanupOrCaps) || lodash.isNil(doCleanupOrCaps)) {
1560
+ debug$m('Normalize text: backward compatibility mode. Use caps instead of boolean flag');
1561
+ basic = !!doCleanupOrCaps;
1562
+ } else {
1563
+ const caps = doCleanupOrCaps;
1564
+ basic = !!caps[Capabilities.SCRIPTING_NORMALIZE_TEXT];
1565
+ if (caps[Capabilities.SCRIPTING_NORMALIZE_TEXT_REMOVE_CHARACTERES]) {
1566
+ charactersRemove = caps[Capabilities.SCRIPTING_NORMALIZE_TEXT_REMOVE_CHARACTERES];
1567
+ if (lodash.isString(charactersRemove)) {
1568
+ const splitted = charactersRemove.split(/(?<!\/),/).map(e => e.trim()).map(e => e.split('/,').join(',').split('//').join('/')).filter(c => c.length > 0);
1569
+ charactersRemove = splitted.length ? splitted : [charactersRemove];
1570
+ } else if (!lodash.isArray(charactersRemove)) {
1571
+ charactersRemove = false;
1572
+ }
1573
+ }
1574
+ if (caps[Capabilities.SCRIPTING_NORMALIZE_TEXT_REMOVE_REGEXP]) {
1575
+ regexpRemove = new RegExp(caps[Capabilities.SCRIPTING_NORMALIZE_TEXT_REMOVE_REGEXP], 'ug');
1576
+ }
1577
+ }
1548
1578
  if (str && lodash.isArray(str)) {
1549
1579
  str = str.join(' ');
1550
1580
  } else if (str && !lodash.isString(str)) {
@@ -1554,21 +1584,31 @@ const normalizeText$1 = (str, doCleanup) => {
1554
1584
  str = `${str}`;
1555
1585
  }
1556
1586
  }
1557
- if (str && doCleanup) {
1558
- // remove html tags
1559
- str = str.replace(/<p[^>]*>/g, ' ');
1560
- str = str.replace(/<\/p>/g, ' ');
1561
- str = str.replace(/<br[^>]*>/g, ' ');
1562
- str = str.replace(/<[^>]*>/g, '');
1563
- /* eslint-disable no-control-regex */
1564
- // remove not printable characters
1565
- str = str.replace(/[\x00-\x1F\x7F]/g, ' ');
1566
- /* eslint-enable no-control-regex */
1567
- // replace html entities
1568
- str = str.replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&#39;/g, '\'').replace(/&quot;/g, '"');
1569
- // replace two spaces with one
1570
- str = str.replace(/\s+/g, ' ');
1571
- str = str.split('\n').map(s => s.trim()).join('\n').trim();
1587
+ if (str) {
1588
+ if (basic) {
1589
+ // remove html tags
1590
+ str = str.replace(/<p[^>]*>/g, ' ');
1591
+ str = str.replace(/<\/p>/g, ' ');
1592
+ str = str.replace(/<br[^>]*>/g, ' ');
1593
+ str = str.replace(/<[^>]*>/g, '');
1594
+ /* eslint-disable no-control-regex */
1595
+ // remove not printable characters
1596
+ str = str.replace(/[\x00-\x1F\x7F]/g, ' ');
1597
+ /* eslint-enable no-control-regex */
1598
+ // replace html entities
1599
+ str = str.replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&#39;/g, '\'').replace(/&quot;/g, '"');
1600
+ // replace two spaces with one
1601
+ str = str.replace(/\s+/g, ' ');
1602
+ str = str.split('\n').map(s => s.trim()).join('\n').trim();
1603
+ }
1604
+ if (charactersRemove) {
1605
+ for (const character of charactersRemove) {
1606
+ str = str.split(character).join('');
1607
+ }
1608
+ }
1609
+ if (regexpRemove) {
1610
+ str = str.replace(regexpRemove, '');
1611
+ }
1572
1612
  }
1573
1613
  return str;
1574
1614
  };
@@ -3306,7 +3346,8 @@ class Convo$6 {
3306
3346
  scriptingMemory,
3307
3347
  botMsg,
3308
3348
  transcript,
3309
- transcriptStep
3349
+ transcriptStep,
3350
+ transcriptSteps
3310
3351
  });
3311
3352
  await this.scriptingEvents.onBotEnd({
3312
3353
  convo: this,
@@ -3532,7 +3573,7 @@ class Convo$6 {
3532
3573
  return tomatch;
3533
3574
  }
3534
3575
  _checkNormalizeText(container, str) {
3535
- return normalizeText(str, !!container.caps[Capabilities.SCRIPTING_NORMALIZE_TEXT]);
3576
+ return normalizeText(str, container.caps);
3536
3577
  }
3537
3578
  expandPartialConvos() {
3538
3579
  const _getIncludeLogicHookNames = convoStep => {
@@ -7595,7 +7636,7 @@ var BaseContainer_1 = class BaseContainer {
7595
7636
  try {
7596
7637
  await executeHook$1(this.caps, hook, Object.assign({
7597
7638
  container: this,
7598
- request
7639
+ fetch
7599
7640
  }, args));
7600
7641
  } catch (err) {
7601
7642
  debug$7(`_RunCustomHook ${name} finished with error: ${err.message || util.inspect(err)}`);
@@ -7882,6 +7923,10 @@ const {
7882
7923
  v4: uuidv4
7883
7924
  } = uuid;
7884
7925
  const debug$4 = debug$o('botium-connector-simplerest');
7926
+ const {
7927
+ ProxyAgent,
7928
+ Agent
7929
+ } = undici;
7885
7930
  const {
7886
7931
  startProxy
7887
7932
  } = proxy;
@@ -7958,6 +8003,16 @@ var SimpleRestContainer_1 = class SimpleRestContainer {
7958
8003
  }
7959
8004
  }
7960
8005
  Build() {
8006
+ const agentOptions = {
8007
+ connect: {
8008
+ rejectUnauthorized: !!this.caps[Capabilities.SIMPLEREST_STRICT_SSL] // Equivalent to strictSSL of request module
8009
+ }
8010
+ };
8011
+ if (this.caps[Capabilities.SIMPLEREST_PROXY_URL]) {
8012
+ this.dispatcher = new ProxyAgent(this.caps[Capabilities.SIMPLEREST_PROXY_URL], agentOptions);
8013
+ } else {
8014
+ this.dispatcher = new Agent(agentOptions);
8015
+ }
7961
8016
  return this._buildInbound();
7962
8017
  }
7963
8018
  Start() {
@@ -8098,6 +8153,27 @@ var SimpleRestContainer_1 = class SimpleRestContainer {
8098
8153
  Clean() {
8099
8154
  return this._cleanInbound();
8100
8155
  }
8156
+ _fetchify(requestOptions) {
8157
+ requestOptions.signal = AbortSignal.timeout(requestOptions.timeout);
8158
+ delete requestOptions.timeout;
8159
+ if (requestOptions.body && !lodash.isString(requestOptions.body)) {
8160
+ requestOptions.body = JSON.stringify(requestOptions.body);
8161
+ if (!requestOptions.headers) requestOptions.headers = {};
8162
+ if (!requestOptions.headers['Content-Type'] && !requestOptions.headers['content-type']) {
8163
+ requestOptions.headers['Content-Type'] = 'application/json';
8164
+ }
8165
+ }
8166
+ if (requestOptions.form) {
8167
+ if (requestOptions.body) {
8168
+ debug$4('Request.form and request.body are mutually exclusive');
8169
+ }
8170
+ requestOptions.body = new URLSearchParams(requestOptions.form).toString();
8171
+ // it is set automatically by fetch
8172
+ // requestOptions.headers['Content-Type'] = 'application/x-www-form-urlencoded'
8173
+ delete requestOptions.form;
8174
+ }
8175
+ return requestOptions;
8176
+ }
8101
8177
 
8102
8178
  // Separated just for better module testing
8103
8179
  async _processBodyAsync(body, headers, isFromUser, updateContext) {
@@ -8368,12 +8444,25 @@ var SimpleRestContainer_1 = class SimpleRestContainer {
8368
8444
  msg.sourceData = msg.sourceData || {};
8369
8445
  msg.sourceData.requestOptions = requestOptions;
8370
8446
  this.waitProcessQueue = [];
8371
- request(requestOptions, async (err, response, body) => {
8372
- if (err) {
8373
- return reject(new Error(`rest request failed: ${err.message}`));
8374
- } else {
8375
- if (response.statusCode >= 400) {
8376
- debug$4(`got error response: ${response.statusCode}/${response.statusMessage}`);
8447
+ try {
8448
+ fetch(requestOptions.uri, requestOptions).then(async bodyRaw => {
8449
+ let body;
8450
+ try {
8451
+ if (bodyRaw.headers.get('content-type').includes('application/json')) {
8452
+ try {
8453
+ body = await bodyRaw.json();
8454
+ } catch (err) {
8455
+ body = await bodyRaw.text();
8456
+ debug$4(`failed to parse body as text, using text instead: ${body}`);
8457
+ }
8458
+ } else {
8459
+ body = await bodyRaw.text();
8460
+ }
8461
+ } catch (err) {
8462
+ return reject(new Error(`cant parse body: ${err.message}`));
8463
+ }
8464
+ if (!bodyRaw.ok) {
8465
+ debug$4(`got error response: ${bodyRaw.status}/${bodyRaw.statusText}`);
8377
8466
  if (debug$4.enabled && body) {
8378
8467
  debug$4(Utils.shortenJsonString(body));
8379
8468
  }
@@ -8381,38 +8470,42 @@ var SimpleRestContainer_1 = class SimpleRestContainer {
8381
8470
  const jsonBody = Utils.toJsonWeak(body);
8382
8471
  const errKey = Object.keys(jsonBody).find(k => k.startsWith('err') || k.startsWith('fail'));
8383
8472
  if (errKey) {
8384
- return reject(new BotiumError(`got error response: ${response.statusCode}/${response.statusMessage} - ${jsonBody[errKey]}`, {
8473
+ return reject(new BotiumError(`got error response: ${bodyRaw.status}/${bodyRaw.statusText} - ${jsonBody[errKey]}`, {
8385
8474
  message: Utils.shortenJsonString(body)
8386
8475
  }));
8387
8476
  }
8388
8477
  }
8389
- return reject(new Error(`got error response: ${response.statusCode}/${response.statusMessage}`));
8478
+ return reject(new Error(`got error response: ${bodyRaw.status}/${bodyRaw.statusText}`));
8390
8479
  }
8391
8480
  if (body) {
8392
- debug$4(`got response code: ${response.statusCode}, body: ${Utils.shortenJsonString(body)}, headers: ${Utils.shortenJsonString(response.headers)}`);
8393
- this._storeCookiesFromResponse(response);
8394
- try {
8395
- body = await this._parseResponseBody(body);
8396
- } catch (err) {
8481
+ debug$4(`got response code: ${bodyRaw.status}/${bodyRaw.statusText}, body: ${Utils.shortenJsonString(body)}, headers: ${Utils.shortenJsonString(bodyRaw.headers)}`);
8482
+ this._storeCookiesFromResponse(bodyRaw);
8483
+ this._parseResponseBody(body).then(parsedBody => {
8484
+ body = parsedBody;
8485
+ if (body) {
8486
+ this._processBodyAsync(body, bodyRaw.headers, isFromUser, updateContext).then(() => resolve(this)).then(() => this._emptyWaitProcessQueue());
8487
+ } else {
8488
+ debug$4('ignoring response body (no string and no JSON object)');
8489
+ resolve(this);
8490
+ this._emptyWaitProcessQueue();
8491
+ }
8492
+ }).catch(err => {
8397
8493
  debug$4(`ignoring not JSON formatted response body: ${err.message}`);
8398
8494
  resolve(this);
8399
8495
  this._emptyWaitProcessQueue();
8400
- return;
8401
- }
8402
- if (body) {
8403
- this._processBodyAsync(body, response.headers, isFromUser, updateContext).then(() => resolve(this)).then(() => this._emptyWaitProcessQueue());
8404
- } else {
8405
- debug$4('ignoring response body (no string and no JSON object)');
8406
- resolve(this);
8407
- this._emptyWaitProcessQueue();
8408
- }
8496
+ });
8409
8497
  } else {
8410
- debug$4(`got response code: ${response.statusCode}, empty body`);
8498
+ debug$4(`got response code: ${bodyRaw.status}/${bodyRaw.statusText}, empty body`);
8411
8499
  resolve(this);
8412
8500
  this._emptyWaitProcessQueue();
8413
8501
  }
8414
- }
8415
- });
8502
+ }).catch(err => {
8503
+ // rest request failed: fetch failed - Cause code: ECONNREFUSED - Cause message: connect ECONNREFUSED 127.0.0.1:3006
8504
+ return reject(new Error(`rest request failed: ${err.message}${err.cause && err.cause.code ? ' - Cause code: ' + err.cause.code : ''}${err.cause && err.cause.message ? ' - Cause message: ' + err.cause.message : ''}`));
8505
+ });
8506
+ } catch (err) {
8507
+ return reject(new Error(`rest request failed: ${err.message}`));
8508
+ }
8416
8509
  }));
8417
8510
  }
8418
8511
  async _buildRequest(msg) {
@@ -8429,7 +8522,6 @@ var SimpleRestContainer_1 = class SimpleRestContainer {
8429
8522
  const requestOptions = {
8430
8523
  uri,
8431
8524
  method: this._getCapValue(Capabilities.SIMPLEREST_VERB) || this._getCapValue(Capabilities.SIMPLEREST_METHOD),
8432
- followAllRedirects: true,
8433
8525
  timeout
8434
8526
  };
8435
8527
  if (this.caps[Capabilities.SIMPLEREST_HEADERS_TEMPLATE]) {
@@ -8440,7 +8532,14 @@ var SimpleRestContainer_1 = class SimpleRestContainer {
8440
8532
  throw new Error(`composing headers from SIMPLEREST_HEADERS_TEMPLATE failed (${err.message})`);
8441
8533
  }
8442
8534
  }
8443
- if (this.caps[Capabilities.SIMPLEREST_BODY_TEMPLATE]) {
8535
+ // It is possible to mix json, and non-json request messages. So it can happen that both
8536
+ // SIMPLEREST_BODY_FROM_JSON and SIMPLEREST_BODY_TEMPLATE are set
8537
+ if (this.caps[Capabilities.SIMPLEREST_BODY_FROM_JSON] && msg.sourceData && Object.keys(msg.sourceData).length > 0) {
8538
+ requestOptions.body = msg.sourceData;
8539
+ requestOptions.json = true;
8540
+ if (!requestOptions.headers) requestOptions.headers = {};
8541
+ requestOptions.headers['Content-Type'] = 'application/json';
8542
+ } else if (this.caps[Capabilities.SIMPLEREST_BODY_TEMPLATE]) {
8444
8543
  const bodyRaw = this._getCapValue(Capabilities.SIMPLEREST_BODY_RAW);
8445
8544
  if (bodyRaw) {
8446
8545
  this.view.msg.messageText = nonEncodedMessage;
@@ -8453,6 +8552,10 @@ var SimpleRestContainer_1 = class SimpleRestContainer {
8453
8552
  if (requestOptions.json && (!requestOptions.body || Object.keys(requestOptions.body).length === 0)) {
8454
8553
  debug$4(`warning: requestOptions.body content seems to be empty - ${requestOptions.body} - capability: "${this.caps[Capabilities.SIMPLEREST_BODY_TEMPLATE]}"`);
8455
8554
  }
8555
+ if (!bodyRaw) {
8556
+ if (!requestOptions.headers) requestOptions.headers = {};
8557
+ requestOptions.headers['Content-Type'] = 'application/json';
8558
+ }
8456
8559
  } catch (err) {
8457
8560
  throw new Error(`composing body from SIMPLEREST_BODY_TEMPLATE failed (${err.message})`);
8458
8561
  }
@@ -8486,56 +8589,53 @@ var SimpleRestContainer_1 = class SimpleRestContainer {
8486
8589
  }
8487
8590
  }
8488
8591
  this._addRequestOptions(requestOptions);
8592
+ this._fetchify(requestOptions);
8489
8593
  await executeHook(this.caps, this.requestHook, Object.assign({
8490
8594
  requestOptions
8491
8595
  }, this.view));
8492
8596
  this._addRequestCookies(requestOptions);
8493
8597
  return requestOptions;
8494
8598
  }
8495
- async _waitForUrlResponse(pingConfig, retries) {
8599
+ async _waitForUrlResponse(httpConfig, retries) {
8496
8600
  const timeout = ms => new Promise(resolve => setTimeout(resolve, ms));
8497
8601
  let tries = 0;
8498
8602
  while (true) {
8499
- debug$4(`_waitForUrlResponse checking url ${pingConfig.uri} before proceed`);
8603
+ debug$4(`_waitForUrlResponse checking url ${httpConfig.uri} before proceed`);
8500
8604
  if (tries > retries) {
8501
8605
  throw new Error(`Failed to ping bot after ${retries} retries`);
8502
8606
  }
8503
8607
  tries++;
8504
- const {
8505
- err,
8506
- response,
8507
- body
8508
- } = await this.bottleneck(() => new Promise(resolve => {
8509
- request(pingConfig, (err, response, body) => {
8510
- resolve({
8511
- err,
8512
- response,
8513
- body
8514
- });
8515
- });
8516
- }));
8608
+ let bodyRaw;
8609
+ let body;
8610
+ let err;
8611
+ try {
8612
+ bodyRaw = await this.bottleneck(() => fetch(httpConfig.uri, httpConfig));
8613
+ body = await (httpConfig.json ? bodyRaw.json() : bodyRaw.text());
8614
+ } catch (e) {
8615
+ err = e;
8616
+ }
8517
8617
  if (err) {
8518
- debug$4(`_waitForUrlResponse error on url check ${pingConfig.uri}: ${err}`);
8618
+ debug$4(`_waitForUrlResponse error on url check ${httpConfig.uri}: ${err}`);
8519
8619
  if (tries <= retries) {
8520
- await timeout(pingConfig.timeout);
8620
+ await timeout(httpConfig.timeout);
8521
8621
  }
8522
- } else if (response.statusCode >= 400) {
8523
- debug$4(`_waitForUrlResponse on url check ${pingConfig.uri} got error response: ${response.statusCode}/${response.statusMessage}`);
8622
+ } else if (!bodyRaw.ok) {
8623
+ debug$4(`_waitForUrlResponse on url check ${httpConfig.uri} got error response: ${bodyRaw.status}/${bodyRaw.statusText}`);
8524
8624
  if (debug$4.enabled && body) {
8525
8625
  debug$4(Utils.shortenJsonString(body));
8526
8626
  }
8527
8627
  if (tries <= retries) {
8528
- await timeout(pingConfig.timeout);
8628
+ await timeout(httpConfig.timeout);
8529
8629
  }
8530
8630
  } else {
8531
- debug$4(`_waitForUrlResponse success on url check ${pingConfig.uri}: ${response.statusCode}/${response.statusMessage}`);
8532
- this._storeCookiesFromResponse(response);
8631
+ debug$4(`_waitForUrlResponse success on url check ${httpConfig.uri}: ${bodyRaw.status}/${bodyRaw.statusText}`);
8632
+ this._storeCookiesFromResponse(bodyRaw);
8533
8633
  if (debug$4.enabled && body) {
8534
- debug$4(`body: ${Utils.shortenJsonString(body)}, headers: ${Utils.shortenJsonString(response.headers)}`);
8634
+ debug$4(`body: ${Utils.shortenJsonString(body)}, headers: ${Utils.shortenJsonString(bodyRaw.headers)}`);
8535
8635
  }
8536
8636
  return {
8537
8637
  body,
8538
- headers: response.headers
8638
+ headers: bodyRaw.headers
8539
8639
  };
8540
8640
  }
8541
8641
  }
@@ -8687,7 +8787,6 @@ var SimpleRestContainer_1 = class SimpleRestContainer {
8687
8787
  const pollConfig = {
8688
8788
  method: verb,
8689
8789
  uri,
8690
- followAllRedirects: true,
8691
8790
  timeout
8692
8791
  };
8693
8792
  if (this.caps[Capabilities.SIMPLEREST_POLL_HEADERS]) {
@@ -8703,12 +8802,17 @@ var SimpleRestContainer_1 = class SimpleRestContainer {
8703
8802
  try {
8704
8803
  pollConfig.body = this._getMustachedCap(Capabilities.SIMPLEREST_POLL_BODY, !bodyRaw);
8705
8804
  pollConfig.json = !bodyRaw;
8805
+ if (!bodyRaw) {
8806
+ if (!pollConfig.headers) pollConfig.headers = {};
8807
+ pollConfig.headers['Content-Type'] = 'application/json';
8808
+ }
8706
8809
  } catch (err) {
8707
8810
  debug$4(`_runPolling: composing body from SIMPLEREST_POLL_BODY failed (${err.message})`);
8708
8811
  return;
8709
8812
  }
8710
8813
  }
8711
8814
  this._addRequestOptions(pollConfig);
8815
+ this._fetchify(pollConfig);
8712
8816
  try {
8713
8817
  await executeHook(this.caps, this.pollRequestHook, Object.assign({
8714
8818
  requestOptions: pollConfig
@@ -8718,34 +8822,34 @@ var SimpleRestContainer_1 = class SimpleRestContainer {
8718
8822
  return;
8719
8823
  }
8720
8824
  this._addRequestCookies(pollConfig);
8721
- request(pollConfig, async (err, response, body) => {
8722
- if (err) {
8723
- debug$4(`_runPolling: rest request failed: ${err.message}, request: ${JSON.stringify(pollConfig)}`);
8724
- } else {
8725
- if (response.statusCode >= 400) {
8726
- debug$4(`_runPolling: got error response: ${response.statusCode}/${response.statusMessage}, request: ${JSON.stringify(pollConfig)}`);
8727
- if (debug$4.enabled && body) {
8728
- debug$4(Utils.shortenJsonString(body));
8729
- }
8730
- } else if (body) {
8731
- debug$4(`_runPolling: got response code: ${response.statusCode}, body: ${Utils.shortenJsonString(body)}, headers: ${Utils.shortenJsonString(response.headers)}`);
8732
- this._storeCookiesFromResponse(response);
8733
- try {
8734
- body = await this._parseResponseBody(body);
8735
- } catch (err) {
8736
- debug$4(`_runPolling: ignoring not JSON formatted response body: ${err.message}`);
8737
- return;
8738
- }
8739
- if (body) {
8740
- setTimeout(() => this._processBodyAsync(body, response.headers, true, !!this.caps[Capabilities.SIMPLEREST_POLL_UPDATE_CONTEXT]), 0);
8741
- } else {
8742
- debug$4('_runPolling: ignoring response body (no string and no JSON object)');
8743
- }
8825
+ try {
8826
+ const bodyRaw = await fetch(pollConfig.uri, pollConfig);
8827
+ let body = await (pollConfig.json ? bodyRaw.json() : bodyRaw.text());
8828
+ if (!bodyRaw.ok) {
8829
+ debug$4(`_runPolling: got error response: ${bodyRaw.status}/${bodyRaw.statusText}, request: ${JSON.stringify(pollConfig)}`);
8830
+ if (debug$4.enabled && body) {
8831
+ debug$4(Utils.shortenJsonString(body));
8832
+ }
8833
+ } else if (body) {
8834
+ debug$4(`_runPolling: got response code: ${bodyRaw.status}/${bodyRaw.statusText}, body: ${Utils.shortenJsonString(body)}, headers: ${Utils.shortenJsonString(bodyRaw.headers)}`);
8835
+ this._storeCookiesFromResponse(bodyRaw);
8836
+ try {
8837
+ body = await this._parseResponseBody(body);
8838
+ } catch (err) {
8839
+ debug$4(`_runPolling: ignoring not JSON formatted response body: ${err.message}`);
8840
+ return;
8841
+ }
8842
+ if (body) {
8843
+ setTimeout(() => this._processBodyAsync(body, bodyRaw.headers, true, !!this.caps[Capabilities.SIMPLEREST_POLL_UPDATE_CONTEXT]), 0);
8744
8844
  } else {
8745
- debug$4(`_runPolling: got response code: ${response.statusCode}, empty body`);
8845
+ debug$4('_runPolling: ignoring response body (no string and no JSON object)');
8746
8846
  }
8847
+ } else {
8848
+ debug$4(`_runPolling: got response code: ${bodyRaw.status}/${bodyRaw.statusText}, empty body`);
8747
8849
  }
8748
- });
8850
+ } catch (err) {
8851
+ debug$4(`_runPolling: rest request failed: ${err.message}, request: ${JSON.stringify(pollConfig)}`);
8852
+ }
8749
8853
  }
8750
8854
  }
8751
8855
  async _startPolling() {
@@ -8768,7 +8872,6 @@ var SimpleRestContainer_1 = class SimpleRestContainer {
8768
8872
  const httpConfig = {
8769
8873
  method: verb,
8770
8874
  uri,
8771
- followAllRedirects: true,
8772
8875
  timeout
8773
8876
  };
8774
8877
  if (this.caps[`${capPrefix}_HEADERS`]) {
@@ -8788,6 +8891,7 @@ var SimpleRestContainer_1 = class SimpleRestContainer {
8788
8891
  }
8789
8892
  }
8790
8893
  this._addRequestOptions(httpConfig);
8894
+ this._fetchify(httpConfig);
8791
8895
  await executeHook(this.caps, this.requestHooks[capPrefix], Object.assign({
8792
8896
  requestOptions: httpConfig
8793
8897
  }, this.view));
@@ -8798,9 +8902,8 @@ var SimpleRestContainer_1 = class SimpleRestContainer {
8798
8902
  return response;
8799
8903
  }
8800
8904
  _addRequestOptions(httpConfig) {
8801
- httpConfig.strictSSL = !!this.caps[Capabilities.SIMPLEREST_STRICT_SSL];
8802
- if (this.caps[Capabilities.SIMPLEREST_PROXY_URL]) {
8803
- httpConfig.proxy = this.caps[Capabilities.SIMPLEREST_PROXY_URL];
8905
+ if (this.dispatcher) {
8906
+ httpConfig.dispatcher = this.dispatcher;
8804
8907
  }
8805
8908
  if (this.caps[Capabilities.SIMPLEREST_EXTRA_OPTIONS]) {
8806
8909
  lodash.merge(httpConfig, this.caps[Capabilities.SIMPLEREST_EXTRA_OPTIONS]);
@@ -8814,23 +8917,21 @@ var SimpleRestContainer_1 = class SimpleRestContainer {
8814
8917
  if (!requestOptions.headers) {
8815
8918
  requestOptions.headers = {};
8816
8919
  }
8817
- requestOptions.headers.Cookie = requestOptions.headers.Cookie ? `${requestOptions.headers.Cookie}; ${this.cookies[url.host]}` : this.cookies[url.host];
8920
+ if (this.cookies[url.host]) {
8921
+ requestOptions.headers.Cookie = requestOptions.headers.Cookie ? `${requestOptions.headers.Cookie}; ${this.cookies[url.host]}` : this.cookies[url.host];
8922
+ }
8818
8923
  }
8819
8924
  _storeCookiesFromResponse(response) {
8820
8925
  if (!this.caps[Capabilities.SIMPLEREST_COOKIE_REPLICATION] || !response) {
8821
8926
  return;
8822
8927
  }
8823
- const responseCookies = response.headers['set-cookie'];
8928
+ const responseCookies = response.headers.get('set-cookie');
8824
8929
  if (!responseCookies) {
8825
8930
  return;
8826
8931
  }
8827
- const host = lodash.get(response, 'request.uri.host');
8828
- let cookie;
8829
- responseCookies.forEach(cookieString => {
8830
- cookie = cookie ? `${cookie}; ${cookieString}` : cookieString;
8831
- });
8832
- if (cookie) {
8833
- this.cookies[host] = cookie;
8932
+ const host = response?.url ? new URL(response.url).host : null;
8933
+ if (host) {
8934
+ this.cookies[host] = responseCookies;
8834
8935
  }
8835
8936
  }
8836
8937
  };