botium-core 1.12.6 → 1.13.2

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
@@ -10,7 +10,7 @@ import randomatic from 'randomatic';
10
10
  import lodash from 'lodash';
11
11
  import boolean$1 from 'boolean';
12
12
  import events from 'events';
13
- import debug$l from 'debug';
13
+ import debug$m from 'debug';
14
14
  import vm2 from 'vm2';
15
15
  import isClass from 'is-class';
16
16
  import crypto from 'crypto';
@@ -36,7 +36,7 @@ import express from 'express';
36
36
  import bodyParser from 'body-parser';
37
37
 
38
38
  var name = "botium-core";
39
- var version$1 = "1.12.6";
39
+ var version$1 = "1.13.2";
40
40
  var description = "The Selenium for Chatbots";
41
41
  var main = "index.js";
42
42
  var module = "dist/botium-es.js";
@@ -68,25 +68,25 @@ var bugs = {
68
68
  };
69
69
  var homepage = "https://www.botium.ai";
70
70
  var dependencies = {
71
- "@babel/runtime": "^7.17.9",
72
- async: "^3.2.3",
71
+ "@babel/runtime": "^7.18.6",
72
+ async: "^3.2.4",
73
73
  "body-parser": "^1.20.0",
74
74
  boolean: "^3.2.0",
75
75
  bottleneck: "^2.19.5",
76
- "csv-parse": "^5.0.4",
76
+ "csv-parse": "^5.3.0",
77
77
  debug: "^4.3.4",
78
78
  esprima: "^4.0.1",
79
- express: "^4.17.3",
79
+ express: "^4.18.1",
80
80
  globby: "11.0.4",
81
- ioredis: "^5.0.4",
81
+ ioredis: "^5.1.0",
82
82
  "is-class": "^0.0.9",
83
83
  "is-json": "^2.0.1",
84
84
  jsonpath: "^1.1.1",
85
85
  lodash: "^4.17.21",
86
- "markdown-it": "^12.3.2",
86
+ "markdown-it": "^13.0.1",
87
87
  "mime-types": "^2.1.35",
88
88
  mkdirp: "^1.0.4",
89
- moment: "^2.29.3",
89
+ moment: "^2.29.4",
90
90
  mustache: "^4.2.0",
91
91
  "promise-retry": "^2.0.1",
92
92
  "promise.allsettled": "^1.0.5",
@@ -95,39 +95,39 @@ var dependencies = {
95
95
  rimraf: "^3.0.2",
96
96
  "sanitize-filename": "^1.6.3",
97
97
  slugify: "^1.6.5",
98
- "socket.io": "^4.4.1",
99
- "socket.io-client": "^4.4.1",
98
+ "socket.io": "^4.5.1",
99
+ "socket.io-client": "^4.5.1",
100
100
  "socketio-auth": "^0.1.1",
101
101
  "swagger-jsdoc": "^6.2.1",
102
- "swagger-ui-express": "^4.3.0",
102
+ "swagger-ui-express": "^4.4.0",
103
103
  uuid: "^8.3.2",
104
- vm2: "^3.9.9",
104
+ vm2: "^3.9.10",
105
105
  "write-yaml": "^1.0.0",
106
106
  xlsx: "^0.18.5",
107
- xregexp: "^5.1.0",
108
- yaml: "^2.0.1"
107
+ xregexp: "^5.1.1",
108
+ yaml: "^2.1.1"
109
109
  };
110
110
  var devDependencies = {
111
- "@babel/core": "^7.17.9",
112
- "@babel/node": "^7.16.8",
113
- "@babel/plugin-transform-runtime": "^7.17.0",
114
- "@babel/preset-env": "^7.16.11",
111
+ "@babel/core": "^7.18.6",
112
+ "@babel/node": "^7.18.6",
113
+ "@babel/plugin-transform-runtime": "^7.18.6",
114
+ "@babel/preset-env": "^7.18.6",
115
115
  chai: "^4.3.6",
116
116
  "chai-as-promised": "^7.1.1",
117
117
  "cross-env": "^7.0.3",
118
- eslint: "^8.13.0",
118
+ eslint: "^8.19.0",
119
119
  "eslint-config-standard": "^17.0.0",
120
120
  "eslint-plugin-import": "^2.26.0",
121
- "eslint-plugin-n": "^15.1.0",
121
+ "eslint-plugin-n": "^15.2.4",
122
122
  "eslint-plugin-promise": "^6.0.0",
123
123
  "eslint-plugin-standard": "^4.1.0",
124
124
  "license-checker": "^25.0.1",
125
125
  "license-compatibility-checker": "^0.3.5",
126
- mocha: "^9.2.2",
127
- nock: "^13.2.4",
128
- "npm-check-updates": "^12.5.9",
126
+ mocha: "^10.0.0",
127
+ nock: "^13.2.8",
128
+ "npm-check-updates": "^15.2.6",
129
129
  nyc: "^15.1.0",
130
- rollup: "^2.70.2",
130
+ rollup: "^2.76.0",
131
131
  "rollup-plugin-babel": "^4.4.0",
132
132
  "rollup-plugin-commonjs": "^10.1.0",
133
133
  "rollup-plugin-json": "^4.0.0",
@@ -276,6 +276,10 @@ var Capabilities = {
276
276
  SCRIPTING_XLSX_SHEETNAMES_PCONVOS: 'SCRIPTING_XLSX_SHEETNAMES_PCONVOS',
277
277
  SCRIPTING_XLSX_SHEETNAMES_UTTERANCES: 'SCRIPTING_XLSX_SHEETNAMES_UTTERANCES',
278
278
  SCRIPTING_XLSX_SHEETNAMES_SCRIPTING_MEMORY: 'SCRIPTING_XLSX_SHEETNAMES_SCRIPTING_MEMORY',
279
+ // hidden capability. All newly in Box created testsets will have this as true. CsvCompiler
280
+ // - throws less error (Box reads csv files as utterances, and convo. Compiler cant throw exception if a file is correct, but box tries to load it with incorrect script type)
281
+ // 4 or more colums are compiled just as utterances.
282
+ SCRIPTING_CSV_LEGACY_MODE_OFF: 'SCRIPTING_CSV_LEGACY_MODE_OFF',
279
283
  SCRIPTING_CSV_DELIMITER: 'SCRIPTING_CSV_DELIMITER',
280
284
  SCRIPTING_CSV_SKIP_HEADER: 'SCRIPTING_CSV_SKIP_HEADER',
281
285
  SCRIPTING_CSV_QUOTE: 'SCRIPTING_CSV_QUOTE',
@@ -285,6 +289,9 @@ var Capabilities = {
285
289
  SCRIPTING_CSV_MULTIROW_COLUMN_TEXT: 'SCRIPTING_CSV_MULTIROW_COLUMN_TEXT',
286
290
  SCRIPTING_CSV_QA_COLUMN_QUESTION: 'SCRIPTING_CSV_QA_COLUMN_QUESTION',
287
291
  SCRIPTING_CSV_QA_COLUMN_ANSWER: 'SCRIPTING_CSV_QA_COLUMN_ANSWER',
292
+ SCRIPTING_CSV_UTTERANCE_STARTROW: 'SCRIPTING_CSV_UTTERANCE_STARTROW',
293
+ SCRIPTING_CSV_UTTERANCE_STARTROW_HEADER: 'SCRIPTING_CSV_UTTERANCE_STARTROW_HEADER',
294
+ SCRIPTING_CSV_UTTERANCE_STOP_ON_EMPTY: 'SCRIPTING_CSV_UTTERANCE_STOP_ON_EMPTY',
288
295
  SCRIPTING_NORMALIZE_TEXT: 'SCRIPTING_NORMALIZE_TEXT',
289
296
  SCRIPTING_ENABLE_MEMORY: 'SCRIPTING_ENABLE_MEMORY',
290
297
  SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS: 'SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS',
@@ -426,6 +433,7 @@ Capabilities.SCRIPTING_XLSX_SHEETNAMES;
426
433
  Capabilities.SCRIPTING_XLSX_SHEETNAMES_PCONVOS;
427
434
  Capabilities.SCRIPTING_XLSX_SHEETNAMES_UTTERANCES;
428
435
  Capabilities.SCRIPTING_XLSX_SHEETNAMES_SCRIPTING_MEMORY;
436
+ Capabilities.SCRIPTING_CSV_LEGACY_MODE_OFF;
429
437
  Capabilities.SCRIPTING_CSV_DELIMITER;
430
438
  Capabilities.SCRIPTING_CSV_SKIP_HEADER;
431
439
  Capabilities.SCRIPTING_CSV_QUOTE;
@@ -435,6 +443,9 @@ Capabilities.SCRIPTING_CSV_MULTIROW_COLUMN_SENDER;
435
443
  Capabilities.SCRIPTING_CSV_MULTIROW_COLUMN_TEXT;
436
444
  Capabilities.SCRIPTING_CSV_QA_COLUMN_QUESTION;
437
445
  Capabilities.SCRIPTING_CSV_QA_COLUMN_ANSWER;
446
+ Capabilities.SCRIPTING_CSV_UTTERANCE_STARTROW;
447
+ Capabilities.SCRIPTING_CSV_UTTERANCE_STARTROW_HEADER;
448
+ Capabilities.SCRIPTING_CSV_UTTERANCE_STOP_ON_EMPTY;
438
449
  Capabilities.SCRIPTING_NORMALIZE_TEXT;
439
450
  Capabilities.SCRIPTING_ENABLE_MEMORY;
440
451
  Capabilities.SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS;
@@ -1177,7 +1188,7 @@ LogicHookConsts.DEFAULT_USER_INPUTS;
1177
1188
  const {
1178
1189
  NodeVM: NodeVM$2
1179
1190
  } = vm2;
1180
- const debug$k = debug$l('botium-core-asserterUtils');
1191
+ const debug$l = debug$m('botium-core-asserterUtils');
1181
1192
  const {
1182
1193
  BotiumError: BotiumError$6
1183
1194
  } = BotiumError_1;
@@ -1242,7 +1253,7 @@ var LogicHookUtils_1 = class LogicHookUtils {
1242
1253
  _fetchAsserters() {
1243
1254
  this.caps[Capabilities.ASSERTERS].forEach(asserter => {
1244
1255
  if (this.asserters[asserter.ref]) {
1245
- debug$k(`${asserter.ref} asserter already exists, overwriting.`);
1256
+ debug$l(`${asserter.ref} asserter already exists, overwriting.`);
1246
1257
  }
1247
1258
 
1248
1259
  this.asserters[asserter.ref] = this._loadClass(asserter, 'asserter');
@@ -1256,7 +1267,7 @@ var LogicHookUtils_1 = class LogicHookUtils {
1256
1267
  _fetchLogicHooks() {
1257
1268
  this.caps[Capabilities.LOGIC_HOOKS].forEach(logicHook => {
1258
1269
  if (this.logicHooks[logicHook.ref]) {
1259
- debug$k(`${logicHook.ref} logic hook already exists, overwriting.`);
1270
+ debug$l(`${logicHook.ref} logic hook already exists, overwriting.`);
1260
1271
  }
1261
1272
 
1262
1273
  this.logicHooks[logicHook.ref] = this._loadClass(logicHook, 'logichook');
@@ -1270,7 +1281,7 @@ var LogicHookUtils_1 = class LogicHookUtils {
1270
1281
  _fetchUserInputs() {
1271
1282
  this.caps[Capabilities.USER_INPUTS].forEach(userInput => {
1272
1283
  if (this.userInputs[userInput.ref]) {
1273
- debug$k(`${userInput.ref} userinput already exists, overwriting.`);
1284
+ debug$l(`${userInput.ref} userinput already exists, overwriting.`);
1274
1285
  }
1275
1286
 
1276
1287
  this.userInputs[userInput.ref] = this._loadClass(userInput, 'userinput');
@@ -1413,7 +1424,7 @@ var LogicHookUtils_1 = class LogicHookUtils {
1413
1424
  });
1414
1425
  return vm.run(script);
1415
1426
  } catch (err) {
1416
- throw new Error(`${err.message || err}`);
1427
+ throw new Error(`Script ${key} is not valid - ${err.message || err}`);
1417
1428
  }
1418
1429
  } else {
1419
1430
  throw new Error(`Script "${key}" is not valid - only functions and javascript code accepted`);
@@ -1504,7 +1515,7 @@ var LogicHookUtils_1 = class LogicHookUtils {
1504
1515
  }
1505
1516
  }
1506
1517
 
1507
- loadErr.forEach(debug$k);
1518
+ loadErr.forEach(debug$l);
1508
1519
  }
1509
1520
 
1510
1521
  throw new Error(`Failed to fetch ${ref} ${hookType}, no idea how to load ...`);
@@ -2363,7 +2374,7 @@ var helper = {
2363
2374
  linesToScriptingMemories: linesToScriptingMemories$2
2364
2375
  };
2365
2376
 
2366
- const debug$j = debug$l('botium-core-ScriptingMemory');
2377
+ const debug$k = debug$m('botium-core-ScriptingMemory');
2367
2378
  const {
2368
2379
  v1: uuidv1
2369
2380
  } = uuid;
@@ -2621,7 +2632,7 @@ const extractVarNames = text => {
2621
2632
  };
2622
2633
 
2623
2634
  const fill = (container, scriptingMemory, result, utterance, scriptingEvents) => {
2624
- debug$j(`fill start: ${util.inspect(scriptingMemory)}`);
2635
+ debug$k(`fill start: ${util.inspect(scriptingMemory)}`);
2625
2636
  let varRegex;
2626
2637
 
2627
2638
  switch (container.caps[Capabilities.SCRIPTING_MEMORY_MATCHING_MODE]) {
@@ -2665,14 +2676,14 @@ const fill = (container, scriptingMemory, result, utterance, scriptingEvents) =>
2665
2676
  const varName = varMatches[i - 1];
2666
2677
 
2667
2678
  if (RESERVED_WORDS.indexOf(varName) >= 0) {
2668
- debug$j(`fill Variable "${varName}" is not overwritten, because it is reserved word. `);
2679
+ debug$k(`fill Variable "${varName}" is not overwritten, because it is reserved word. `);
2669
2680
  } else {
2670
2681
  scriptingMemory[varName] = resultMatches[i];
2671
2682
  }
2672
2683
  }
2673
2684
  }
2674
2685
  });
2675
- debug$j(`fill end: ${util.inspect(scriptingMemory)}`);
2686
+ debug$k(`fill end: ${util.inspect(scriptingMemory)}`);
2676
2687
  }
2677
2688
  };
2678
2689
 
@@ -2691,7 +2702,48 @@ ScriptingMemory.extractVarNames;
2691
2702
  ScriptingMemory.RESERVED_WORDS;
2692
2703
  ScriptingMemory.SCRIPTING_FUNCTIONS;
2693
2704
 
2694
- const debug$i = debug$l('botium-core-Convo');
2705
+ const debug$j = debug$m('botium-core-RetryHelper');
2706
+ var RetryHelper_1 = class RetryHelper {
2707
+ constructor(caps, section, options = {}) {
2708
+ this.retryErrorPatterns = [];
2709
+ const onErrorRegexp = caps[`RETRY_${section.toUpperCase()}_ONERROR_REGEXP`] || [];
2710
+
2711
+ if (onErrorRegexp) {
2712
+ if (lodash.isArray(onErrorRegexp)) {
2713
+ onErrorRegexp.forEach(r => {
2714
+ if (lodash.isString(r)) this.retryErrorPatterns.push(new RegExp(r, 'i'));else this.retryErrorPatterns.push(r);
2715
+ });
2716
+ } else if (lodash.isString(onErrorRegexp)) {
2717
+ this.retryErrorPatterns.push(new RegExp(onErrorRegexp, 'i'));
2718
+ } else {
2719
+ this.retryErrorPatterns.push(onErrorRegexp);
2720
+ }
2721
+ } // to turn on retries, NUMRETRIES or ONERROR_REGEXP has to be set
2722
+
2723
+
2724
+ this.retrySettings = {
2725
+ retries: caps[`RETRY_${section.toUpperCase()}_NUMRETRIES`] || (!lodash.isNil(options.numRetries) ? options.numRetries : this.retryErrorPatterns.length === 0 ? 0 : 1),
2726
+ factor: caps[`RETRY_${section.toUpperCase()}_FACTOR`] || (lodash.isNil(options.factor) ? 1 : options.factor),
2727
+ minTimeout: caps[`RETRY_${section.toUpperCase()}_MINTIMEOUT`] || (lodash.isNil(options.minTimeout) ? 1000 : options.minTimeout)
2728
+ };
2729
+ debug$j(`Retry for ${section} is ${this.retrySettings.retries > 0 ? 'enabled' : 'disabled'}. Settings: ${JSON.stringify(this.retrySettings)} Patterns: ${JSON.stringify(this.retryErrorPatterns.map(r => r.toString()))}`);
2730
+ }
2731
+
2732
+ shouldRetry(err) {
2733
+ if (!err) return false;
2734
+ if (this.retryErrorPatterns.length === 0) return true;
2735
+ const errString = util.inspect(err);
2736
+
2737
+ for (const re of this.retryErrorPatterns) {
2738
+ if (errString.match(re)) return true;
2739
+ }
2740
+
2741
+ return false;
2742
+ }
2743
+
2744
+ };
2745
+
2746
+ const debug$i = debug$m('botium-core-Convo');
2695
2747
  const {
2696
2748
  BotiumError: BotiumError$4,
2697
2749
  botiumErrorFromErr: botiumErrorFromErr$1,
@@ -2916,6 +2968,26 @@ class Convo$6 {
2916
2968
  }
2917
2969
 
2918
2970
  async Run(container) {
2971
+ const retryHelper = new RetryHelper_1(container.caps, 'CONVO');
2972
+ return promiseRetry(async (retry, number) => {
2973
+ return this.RunImpl(container).catch(err => {
2974
+ const retryRemaining = retryHelper.retrySettings.retries - number + 1;
2975
+
2976
+ if (retryHelper.shouldRetry(err)) {
2977
+ debug$i(`Convo failed with error "${err.message || JSON.stringify(err)}". Retry ${retryRemaining > 0 ? 'enabled' : 'disabled'} (remaining #${retryRemaining}/${retryHelper.retrySettings.retries}, criterion matches)`);
2978
+ retry(err);
2979
+ } else {
2980
+ if (retryHelper.retryErrorPatterns.length > 0) {
2981
+ debug$i(`Convo failed with error "${err.message || JSON.stringify(err)}". Retry 'disabled' (remaining (#${retryRemaining}/${retryHelper.retrySettings.retries}), criterion does not match)`);
2982
+ }
2983
+
2984
+ throw err;
2985
+ }
2986
+ });
2987
+ }, retryHelper.retrySettings);
2988
+ }
2989
+
2990
+ async RunImpl(container) {
2919
2991
  const transcript = new Transcript({
2920
2992
  steps: [],
2921
2993
  attachments: [],
@@ -3587,42 +3659,6 @@ var Convo_1 = {
3587
3659
  ConvoStep: ConvoStep$1
3588
3660
  };
3589
3661
 
3590
- var RetryHelper_1 = class RetryHelper {
3591
- constructor(caps, section) {
3592
- this.retrySettings = {
3593
- retries: caps[`RETRY_${section.toUpperCase()}_NUMRETRIES`] || 1,
3594
- factor: caps[`RETRY_${section.toUpperCase()}_FACTOR`] || 1,
3595
- minTimeout: caps[`RETRY_${section.toUpperCase()}_MINTIMEOUT`] || 1000
3596
- };
3597
- this.retryErrorPatterns = [];
3598
- const onErrorRegexp = caps[`RETRY_${section.toUpperCase()}_ONERROR_REGEXP`] || [];
3599
-
3600
- if (onErrorRegexp) {
3601
- if (lodash.isArray(onErrorRegexp)) {
3602
- onErrorRegexp.forEach(r => {
3603
- if (lodash.isString(r)) this.retryErrorPatterns.push(new RegExp(r, 'i'));else this.retryErrorPatterns.push(r);
3604
- });
3605
- } else if (lodash.isString(onErrorRegexp)) {
3606
- this.retryErrorPatterns.push(new RegExp(onErrorRegexp, 'i'));
3607
- } else {
3608
- this.retryErrorPatterns.push(onErrorRegexp);
3609
- }
3610
- }
3611
- }
3612
-
3613
- shouldRetry(err) {
3614
- if (!err || this.retryErrorPatterns.length === 0) return false;
3615
- const errString = util.inspect(err);
3616
-
3617
- for (const re of this.retryErrorPatterns) {
3618
- if (errString.match(re)) return true;
3619
- }
3620
-
3621
- return false;
3622
- }
3623
-
3624
- };
3625
-
3626
3662
  const {
3627
3663
  toString,
3628
3664
  quoteRegexpString
@@ -3945,7 +3981,7 @@ var JsonToJson = {
3945
3981
  const {
3946
3982
  NodeVM
3947
3983
  } = vm2;
3948
- const debug$h = debug$l('botium-core-HookUtils');
3984
+ const debug$h = debug$m('botium-core-HookUtils');
3949
3985
  const {
3950
3986
  BotiumError: BotiumError$3
3951
3987
  } = BotiumError_1;
@@ -4095,7 +4131,7 @@ var Script = {
4095
4131
  precompile: precompile$1
4096
4132
  };
4097
4133
 
4098
- const debug$g = debug$l('botium-core-PrecompilerMarkdownRasa');
4134
+ const debug$g = debug$m('botium-core-PrecompilerMarkdownRasa');
4099
4135
  const htmlCommentRegexp = /(<!--.*?-->)/g;
4100
4136
 
4101
4137
  var precompile = (caps, scriptBuffer, options, filename) => {
@@ -4211,7 +4247,7 @@ var MarkdownRasa = {
4211
4247
  precompile: precompile
4212
4248
  };
4213
4249
 
4214
- const debug$f = debug$l('botium-core-CapabilitiesUtils');
4250
+ const debug$f = debug$m('botium-core-CapabilitiesUtils');
4215
4251
  const {
4216
4252
  toJsonWeak
4217
4253
  } = Utils;
@@ -4323,7 +4359,7 @@ var CapabilitiesUtils = {
4323
4359
  flatCababilities: flatCababilities$1
4324
4360
  };
4325
4361
 
4326
- const debug$e = debug$l('botium-core-Precompilers');
4362
+ const debug$e = debug$m('botium-core-Precompilers');
4327
4363
  const {
4328
4364
  isJsonObject
4329
4365
  } = Utils;
@@ -4473,7 +4509,7 @@ var Utterance_1 = class Utterance {
4473
4509
 
4474
4510
  };
4475
4511
 
4476
- const debug$d = debug$l('botium-core-CompilerXlsx');
4512
+ const debug$d = debug$m('botium-core-CompilerXlsx');
4477
4513
  const {
4478
4514
  E_SCRIPTING_MEMORY_COLUMN_MODE
4479
4515
  } = Enums;
@@ -5246,7 +5282,7 @@ var CompilerTxt_1 = class CompilerTxt extends CompilerBase_1 {
5246
5282
  const {
5247
5283
  parse
5248
5284
  } = sync;
5249
- const debug$c = debug$l('botium-core-CompilerCsv');
5285
+ const debug$c = debug$m('botium-core-CompilerCsv');
5250
5286
  const {
5251
5287
  Convo: Convo$3
5252
5288
  } = Convo_1;
@@ -5295,6 +5331,8 @@ var CompilerCsv_1 = class CompilerCsv extends CompilerBase_1 {
5295
5331
  return [];
5296
5332
  }
5297
5333
 
5334
+ const legacyModeOn = !this._GetOptionalCapability(Capabilities.SCRIPTING_CSV_LEGACY_MODE_OFF, false);
5335
+
5298
5336
  let delimiter = this._GetOptionalCapability(Capabilities.SCRIPTING_CSV_DELIMITER);
5299
5337
 
5300
5338
  if (!delimiter) {
@@ -5322,7 +5360,8 @@ var CompilerCsv_1 = class CompilerCsv extends CompilerBase_1 {
5322
5360
  delimiter,
5323
5361
  escape: this.caps[Capabilities.SCRIPTING_CSV_ESCAPE],
5324
5362
  quote: this.caps[Capabilities.SCRIPTING_CSV_QUOTE],
5325
- columns: false
5363
+ columns: false,
5364
+ relax_column_count: true
5326
5365
  });
5327
5366
  } catch (err) {
5328
5367
  throw new Error(`Invalid CSV: ${err.message || err}`);
@@ -5332,126 +5371,181 @@ var CompilerCsv_1 = class CompilerCsv extends CompilerBase_1 {
5332
5371
  return [];
5333
5372
  }
5334
5373
 
5335
- if (rows[0].length === 1) {
5336
- debug$c('Found 1-column CSV file, treating it as utterance file');
5374
+ const columnCount = rows[0].length;
5375
+ debug$c(`Legacy mode ${legacyModeOn ? 'on' : 'off'} rows ${rows.length} columns ${columnCount}`);
5337
5376
 
5338
- if (scriptType === Constants.SCRIPTING_TYPE_UTTERANCES) {
5339
- const result = [{
5340
- name: rows[0][0],
5341
- utterances: rows.slice(1).map(r => r[0])
5342
- }];
5343
- this.context.AddUtterances(result);
5344
- return result;
5345
- } else {
5377
+ if (scriptType === Constants.SCRIPTING_TYPE_CONVO || scriptType === Constants.SCRIPTING_TYPE_PCONVO) {
5378
+ if (columnCount === 1 || !legacyModeOn && columnCount > 3) {
5379
+ debug$c(`Invalid column count '${columnCount}' in convo mode`);
5346
5380
  return [];
5347
5381
  }
5348
- }
5349
5382
 
5350
- if (scriptType !== Constants.SCRIPTING_TYPE_CONVO && scriptType !== Constants.SCRIPTING_TYPE_PCONVO) {
5351
- return [];
5352
- }
5383
+ let header = null;
5353
5384
 
5354
- let header = null;
5385
+ if (rows.length > 0 && this.caps[Capabilities.SCRIPTING_CSV_SKIP_HEADER]) {
5386
+ header = rows[0];
5387
+ rows = rows.slice(1);
5388
+ }
5355
5389
 
5356
- if (rows.length > 0 && this.caps[Capabilities.SCRIPTING_CSV_SKIP_HEADER]) {
5357
- header = rows[0];
5358
- rows = rows.slice(1);
5359
- }
5390
+ if (rows.length === 0) {
5391
+ debug$c('Datarows not found in convo mode');
5392
+ return [];
5393
+ }
5360
5394
 
5361
- if (rows.length === 0) {
5362
- return [];
5363
- }
5395
+ const lineNumberBase = this.caps[Capabilities.SCRIPTING_CSV_SKIP_HEADER] ? 2 : 1;
5364
5396
 
5365
- const lineNumberBase = this.caps[Capabilities.SCRIPTING_CSV_SKIP_HEADER] ? 2 : 1;
5397
+ if (columnCount === 2) {
5398
+ let colQuestion = DEFAULT_QA_COLUMN_QUESTION;
5399
+ let colAnswer = DEFAULT_QA_COLUMN_ANSWER;
5366
5400
 
5367
- if (rows[0].length === 2) {
5368
- debug$c('Found 2-column CSV file, treating it as question/answer file');
5369
- let colQuestion = DEFAULT_QA_COLUMN_QUESTION;
5370
- let colAnswer = DEFAULT_QA_COLUMN_ANSWER;
5401
+ if (header) {
5402
+ if (this.caps[Capabilities.SCRIPTING_CSV_QA_COLUMN_QUESTION] !== undefined) {
5403
+ colQuestion = _findColIndex(header, this.caps[Capabilities.SCRIPTING_CSV_QA_COLUMN_QUESTION]);
5404
+ }
5371
5405
 
5372
- if (header) {
5373
- if (this.caps[Capabilities.SCRIPTING_CSV_QA_COLUMN_QUESTION] !== undefined) {
5374
- colQuestion = _findColIndex(header, this.caps[Capabilities.SCRIPTING_CSV_QA_COLUMN_QUESTION]);
5406
+ if (this.caps[Capabilities.SCRIPTING_CSV_QA_COLUMN_ANSWER] !== undefined) {
5407
+ colAnswer = _findColIndex(header, this.caps[Capabilities.SCRIPTING_CSV_QA_COLUMN_ANSWER]);
5408
+ }
5375
5409
  }
5376
5410
 
5377
- if (this.caps[Capabilities.SCRIPTING_CSV_QA_COLUMN_ANSWER] !== undefined) {
5378
- colAnswer = _findColIndex(header, this.caps[Capabilities.SCRIPTING_CSV_QA_COLUMN_ANSWER]);
5379
- }
5380
- }
5411
+ const convos = rows.map((row, i) => new Convo$3(this.context, {
5412
+ header: {
5413
+ name: `L${i + lineNumberBase}`
5414
+ },
5415
+ conversation: [Object.assign({}, linesToConvoStep$2([row[colQuestion]], 'me', this.context, undefined, true), {
5416
+ stepTag: `L${i + lineNumberBase}-Question`
5417
+ }), Object.assign({}, linesToConvoStep$2([row[colAnswer]], 'bot', this.context, undefined, true), {
5418
+ stepTag: `L${i + lineNumberBase}-Answer`
5419
+ })]
5420
+ }));
5381
5421
 
5382
- const convos = rows.map((row, i) => new Convo$3(this.context, {
5383
- header: {
5384
- name: `L${i + lineNumberBase}`
5385
- },
5386
- conversation: [Object.assign({}, linesToConvoStep$2([row[colQuestion]], 'me', this.context, undefined, true), {
5387
- stepTag: `L${i + lineNumberBase}-Question`
5388
- }), Object.assign({}, linesToConvoStep$2([row[colAnswer]], 'bot', this.context, undefined, true), {
5389
- stepTag: `L${i + lineNumberBase}-Answer`
5390
- })]
5391
- }));
5422
+ if (scriptType === Constants.SCRIPTING_TYPE_CONVO) {
5423
+ this.context.AddConvos(convos);
5424
+ } else if (scriptType === Constants.SCRIPTING_TYPE_PCONVO) {
5425
+ this.context.AddPartialConvos(convos);
5426
+ }
5392
5427
 
5393
- if (scriptType === Constants.SCRIPTING_TYPE_CONVO) {
5394
- this.context.AddConvos(convos);
5395
- } else if (scriptType === Constants.SCRIPTING_TYPE_PCONVO) {
5396
- this.context.AddPartialConvos(convos);
5428
+ debug$c(`Found 2-column CSV file, treating it as question/answer file, extracted ${convos.length} convos`);
5429
+ return convos;
5397
5430
  }
5398
5431
 
5399
- return convos;
5400
- }
5432
+ if (columnCount >= 3) {
5433
+ let colConversationId = DEFAULT_MULTIROW_COLUMN_CONVERSATION;
5434
+ let colSender = DEFAULT_MULTIROW_COLUMN_SENDER;
5435
+ let colText = DEFAULT_MULTIROW_COLUMN_TEXT;
5436
+
5437
+ if (header) {
5438
+ if (this.caps[Capabilities.SCRIPTING_CSV_MULTIROW_COLUMN_CONVERSATION_ID] !== undefined) {
5439
+ colConversationId = _findColIndex(header, this.caps[Capabilities.SCRIPTING_CSV_MULTIROW_COLUMN_CONVERSATION_ID]);
5440
+ }
5401
5441
 
5402
- if (rows[0].length >= 3) {
5403
- debug$c('Found 3-column CSV file, treating it as multi-row conversation file');
5404
- let colConversationId = DEFAULT_MULTIROW_COLUMN_CONVERSATION;
5405
- let colSender = DEFAULT_MULTIROW_COLUMN_SENDER;
5406
- let colText = DEFAULT_MULTIROW_COLUMN_TEXT;
5442
+ if (this.caps[Capabilities.SCRIPTING_CSV_MULTIROW_COLUMN_SENDER] !== undefined) {
5443
+ colSender = _findColIndex(header, this.caps[Capabilities.SCRIPTING_CSV_MULTIROW_COLUMN_SENDER]);
5444
+ }
5407
5445
 
5408
- if (header) {
5409
- if (this.caps[Capabilities.SCRIPTING_CSV_MULTIROW_COLUMN_CONVERSATION_ID] !== undefined) {
5410
- colConversationId = _findColIndex(header, this.caps[Capabilities.SCRIPTING_CSV_MULTIROW_COLUMN_CONVERSATION_ID]);
5446
+ if (this.caps[Capabilities.SCRIPTING_CSV_MULTIROW_COLUMN_TEXT] !== undefined) {
5447
+ colText = _findColIndex(header, this.caps[Capabilities.SCRIPTING_CSV_MULTIROW_COLUMN_TEXT]);
5448
+ }
5411
5449
  }
5412
5450
 
5413
- if (this.caps[Capabilities.SCRIPTING_CSV_MULTIROW_COLUMN_SENDER] !== undefined) {
5414
- colSender = _findColIndex(header, this.caps[Capabilities.SCRIPTING_CSV_MULTIROW_COLUMN_SENDER]);
5415
- }
5451
+ const conversationIds = lodash.uniq(rows.map(r => r[colConversationId]));
5452
+
5453
+ const convos = conversationIds.map(conversationId => {
5454
+ const convoRows = rows.map((row, i) => {
5455
+ if (row[colConversationId] === conversationId) {
5456
+ return Object.assign({}, linesToConvoStep$2([row[colText]], row[colSender], this.context, undefined, true), {
5457
+ stepTag: `L${i + lineNumberBase}`
5458
+ });
5459
+ }
5460
+
5461
+ return null;
5462
+ }).filter(c => c);
5463
+ return new Convo$3(this.context, {
5464
+ header: {
5465
+ name: conversationId
5466
+ },
5467
+ conversation: convoRows
5468
+ });
5469
+ });
5416
5470
 
5417
- if (this.caps[Capabilities.SCRIPTING_CSV_MULTIROW_COLUMN_TEXT] !== undefined) {
5418
- colText = _findColIndex(header, this.caps[Capabilities.SCRIPTING_CSV_MULTIROW_COLUMN_TEXT]);
5471
+ if (scriptType === Constants.SCRIPTING_TYPE_CONVO) {
5472
+ this.context.AddConvos(convos);
5473
+ } else if (scriptType === Constants.SCRIPTING_TYPE_PCONVO) {
5474
+ this.context.AddPartialConvos(convos);
5419
5475
  }
5476
+
5477
+ debug$c(`Found 3-column CSV file, treating it as multi-row conversation file, extracted ${convos.length} convos`);
5478
+ return convos;
5479
+ }
5480
+ } else if (scriptType === Constants.SCRIPTING_TYPE_UTTERANCES) {
5481
+ if (columnCount === 2 || columnCount === 3 || legacyModeOn && columnCount > 4) {
5482
+ debug$c(`Invalid column count '${columnCount}' in utterances mode`);
5483
+ return [];
5420
5484
  }
5421
5485
 
5422
- const conversationIds = lodash.uniq(rows.map(r => r[colConversationId]));
5486
+ const result = [];
5487
+ const startRow = this._GetOptionalCapability(Capabilities.SCRIPTING_CSV_UTTERANCE_STARTROW, 2) - 1;
5423
5488
 
5424
- const convos = conversationIds.map(conversationId => {
5425
- const convoRows = rows.map((row, i) => {
5426
- if (row[colConversationId] === conversationId) {
5427
- return Object.assign({}, linesToConvoStep$2([row[colText]], row[colSender], this.context, undefined, true), {
5428
- stepTag: `L${i + lineNumberBase}`
5429
- });
5489
+ const startRowHeader = this._GetOptionalCapability(Capabilities.SCRIPTING_CSV_UTTERANCE_STARTROW_HEADER);
5490
+
5491
+ const stopOnEmpty = this._GetOptionalCapability(Capabilities.SCRIPTING_CSV_UTTERANCE_STOP_ON_EMPTY);
5492
+
5493
+ for (let col = 0; col < columnCount; col++) {
5494
+ const name = rows[0][col];
5495
+
5496
+ if (!name || name.trim().length === 0) {
5497
+ debug$c(`Column ${col + 1} has no header, skipping`);
5498
+ continue;
5499
+ }
5500
+
5501
+ const uttStruct = {
5502
+ name,
5503
+ utterances: []
5504
+ };
5505
+ let skip = !!startRowHeader;
5506
+
5507
+ const getData = row => {
5508
+ return rows[row][col] ? rows[row][col].trim() : false;
5509
+ }; //
5510
+
5511
+
5512
+ for (let row = startRow; row < rows.length && (skip || !stopOnEmpty || !!getData(row)); row++) {
5513
+ // eslint-disable-line no-unmodified-loop-condition
5514
+ const data = getData(row);
5515
+
5516
+ if (!data) {
5517
+ continue;
5430
5518
  }
5431
5519
 
5432
- return null;
5433
- }).filter(c => c);
5434
- return new Convo$3(this.context, {
5435
- header: {
5436
- name: conversationId
5437
- },
5438
- conversation: convoRows
5439
- });
5440
- });
5520
+ if (!skip) {
5521
+ uttStruct.utterances.push(data);
5522
+ } else {
5523
+ if (startRowHeader === rows[row][col]) {
5524
+ skip = false;
5525
+ }
5526
+ }
5527
+ }
5441
5528
 
5442
- if (scriptType === Constants.SCRIPTING_TYPE_CONVO) {
5443
- this.context.AddConvos(convos);
5444
- } else if (scriptType === Constants.SCRIPTING_TYPE_PCONVO) {
5445
- this.context.AddPartialConvos(convos);
5529
+ if (uttStruct.utterances.length === 0) {
5530
+ // liveperson, skipping meta intents
5531
+ debug$c(`Column ${col + 1} has no utterances, skipping`);
5532
+ continue;
5533
+ }
5534
+
5535
+ result.push(uttStruct);
5446
5536
  }
5447
5537
 
5448
- return convos;
5538
+ debug$c(`Multi-column utterance file, extracted ${result.length} utterances`);
5539
+ this.context.AddUtterances(result);
5540
+ return result;
5541
+ } else {
5542
+ return [];
5449
5543
  }
5450
5544
  }
5451
5545
 
5452
5546
  };
5453
5547
 
5454
- const debug$b = debug$l('botium-core-CompilerObject');
5548
+ const debug$b = debug$m('botium-core-CompilerObject');
5455
5549
  const {
5456
5550
  Convo: Convo$2
5457
5551
  } = Convo_1;
@@ -5628,7 +5722,7 @@ var CompilerJson_1 = class CompilerJson extends CompilerObjectBase_1 {
5628
5722
 
5629
5723
  };
5630
5724
 
5631
- const debug$a = debug$l('botium-core-CompilerMarkdown');
5725
+ const debug$a = debug$m('botium-core-CompilerMarkdown');
5632
5726
  const md = new markdownIt();
5633
5727
  const {
5634
5728
  Convo: Convo$1
@@ -5759,7 +5853,7 @@ var CompilerMarkdown_1 = class CompilerMarkdown extends CompilerBase_1 {
5759
5853
  };
5760
5854
 
5761
5855
  promise.shim();
5762
- const debug$9 = debug$l('botium-core-ScriptingProvider');
5856
+ const debug$9 = debug$m('botium-core-ScriptingProvider');
5763
5857
  const {
5764
5858
  Convo,
5765
5859
  ConvoStep
@@ -5772,7 +5866,7 @@ const {
5772
5866
  const {
5773
5867
  getMatchFunction
5774
5868
  } = MatchFunctions;
5775
- const globPattern = '**/+(*.convo.txt|*.utterances.txt|*.pconvo.txt|*.scriptingmemory.txt|*.xlsx|*.xlsm|*.convo.csv|*.pconvo.csv|*.yaml|*.yml|*.json|*.md|*.markdown)';
5869
+ const globPattern = '**/+(*.convo.txt|*.utterances.txt|*.pconvo.txt|*.scriptingmemory.txt|*.xlsx|*.xlsm|*.convo.csv|*.pconvo.csv|*.utterances.csv|*.yaml|*.yml|*.json|*.md|*.markdown)';
5776
5870
  const skipPattern = /^skip[.\-_]/i;
5777
5871
 
5778
5872
  const p = (retryHelper, fn) => {
@@ -6467,6 +6561,10 @@ var ScriptingProvider_1 = class ScriptingProvider {
6467
6561
  result = this.ReadScriptFromBuffer(scriptBuffer, Constants.SCRIPTING_FORMAT_CSV, Constants.SCRIPTING_TYPE_CONVO);
6468
6562
  } else if (filename.endsWith('.pconvo.csv')) {
6469
6563
  result = this.ReadScriptFromBuffer(scriptBuffer, Constants.SCRIPTING_FORMAT_CSV, Constants.SCRIPTING_TYPE_PCONVO);
6564
+ } else if (filename.endsWith('.pconvo.csv')) {
6565
+ result = this.ReadScriptFromBuffer(scriptBuffer, Constants.SCRIPTING_FORMAT_CSV, Constants.SCRIPTING_TYPE_PCONVO);
6566
+ } else if (filename.endsWith('.utterance.csv')) {
6567
+ result = this.ReadScriptFromBuffer(scriptBuffer, Constants.SCRIPTING_FORMAT_CSV, Constants.SCRIPTING_TYPE_UTTERANCES);
6470
6568
  } else if (filename.endsWith('.yaml') || filename.endsWith('.yml')) {
6471
6569
  result = this.ReadScriptFromBuffer(scriptBuffer, Constants.SCRIPTING_FORMAT_YAML, [Constants.SCRIPTING_TYPE_UTTERANCES, Constants.SCRIPTING_TYPE_PCONVO, Constants.SCRIPTING_TYPE_CONVO, Constants.SCRIPTING_TYPE_SCRIPTING_MEMORY]);
6472
6570
  } else if (filename.endsWith('.json')) {
@@ -7325,7 +7423,7 @@ var NoRepo_1 = class NoRepo extends BaseRepo_1 {
7325
7423
  };
7326
7424
 
7327
7425
  var ProcessUtils = createCommonjsModule(function (module) {
7328
- const debug = debug$l('botium-core-ProcessUtils');
7426
+ const debug = debug$m('botium-core-ProcessUtils');
7329
7427
  module.exports = {
7330
7428
  childCommandLineRun: (cmd, ignoreErrors = false, processOptions = {}) => {
7331
7429
  const cmdOptions = cmd.split(' ');
@@ -7377,7 +7475,7 @@ var ProcessUtils = createCommonjsModule(function (module) {
7377
7475
  ProcessUtils.childCommandLineRun;
7378
7476
  ProcessUtils.childProcessRun;
7379
7477
 
7380
- const debug$8 = debug$l('botium-core-GitRepo');
7478
+ const debug$8 = debug$m('botium-core-GitRepo');
7381
7479
  var GitRepo_1 = class GitRepo extends BaseRepo_1 {
7382
7480
  Validate() {
7383
7481
  return super.Validate().then(() => {
@@ -7548,7 +7646,7 @@ var Queue_1 = class Queue {
7548
7646
 
7549
7647
  };
7550
7648
 
7551
- const debug$7 = debug$l('botium-connector-BaseContainer');
7649
+ const debug$7 = debug$m('botium-connector-BaseContainer');
7552
7650
  const {
7553
7651
  executeHook: executeHook$1,
7554
7652
  getHook: getHook$1
@@ -7779,7 +7877,7 @@ var BaseContainer_1 = class BaseContainer {
7779
7877
 
7780
7878
  };
7781
7879
 
7782
- const debug$6 = debug$l('botium-connector-GridContainer');
7880
+ const debug$6 = debug$m('botium-connector-GridContainer');
7783
7881
  var GridContainer_1 = class GridContainer extends BaseContainer_1 {
7784
7882
  Validate() {
7785
7883
  return super.Validate().then(() => {
@@ -8003,7 +8101,7 @@ var InProcessContainer_1 = class InProcessContainer extends BaseContainer_1 {
8003
8101
 
8004
8102
  };
8005
8103
 
8006
- const debug$5 = debug$l('botium-core-inbound-proxy');
8104
+ const debug$5 = debug$m('botium-core-inbound-proxy');
8007
8105
 
8008
8106
  const buildRedisHandler = (redisurl, topic) => {
8009
8107
  const redis = new ioredis(redisurl);
@@ -8086,7 +8184,7 @@ proxy.startProxy;
8086
8184
  const {
8087
8185
  v4: uuidv4
8088
8186
  } = uuid;
8089
- const debug$4 = debug$l('botium-connector-simplerest');
8187
+ const debug$4 = debug$m('botium-connector-simplerest');
8090
8188
  const {
8091
8189
  startProxy
8092
8190
  } = proxy;
@@ -8647,6 +8745,10 @@ var SimpleRestContainer_1 = class SimpleRestContainer {
8647
8745
  try {
8648
8746
  requestOptions.body = this._getMustachedCap(Capabilities.SIMPLEREST_BODY_TEMPLATE, !bodyRaw);
8649
8747
  requestOptions.json = !bodyRaw;
8748
+
8749
+ if (requestOptions.json && (!requestOptions.body || Object.keys(requestOptions.body).length === 0)) {
8750
+ debug$4(`warning: requestOptions.body content seems to be empty - ${requestOptions.body} - capability: "${this.caps[Capabilities.SIMPLEREST_BODY_TEMPLATE]}"`);
8751
+ }
8650
8752
  } catch (err) {
8651
8753
  throw new Error(`composing body from SIMPLEREST_BODY_TEMPLATE failed (${err.message})`);
8652
8754
  }
@@ -9116,7 +9218,7 @@ var SimpleRestContainer_1 = class SimpleRestContainer {
9116
9218
 
9117
9219
  };
9118
9220
 
9119
- const debug$3 = debug$l('botium-connector-PluginConnectorContainer-helper');
9221
+ const debug$3 = debug$m('botium-connector-PluginConnectorContainer-helper');
9120
9222
  const {
9121
9223
  BotiumError
9122
9224
  } = BotiumError_1;
@@ -9285,7 +9387,7 @@ var plugins = {
9285
9387
  tryLoadPlugin: tryLoadPlugin$1
9286
9388
  };
9287
9389
 
9288
- const debug$2 = debug$l('botium-connector-PluginConnectorContainer');
9390
+ const debug$2 = debug$m('botium-connector-PluginConnectorContainer');
9289
9391
  const {
9290
9392
  tryLoadPlugin
9291
9393
  } = plugins;
@@ -9443,7 +9545,7 @@ var require$$2 = getCjsExportFromNamespace(_package$1);
9443
9545
  const {
9444
9546
  boolean
9445
9547
  } = boolean$1;
9446
- const debug$1 = debug$l('botium-core-BotDriver');
9548
+ const debug$1 = debug$m('botium-core-BotDriver');
9447
9549
  const {
9448
9550
  version
9449
9551
  } = require$$2;
@@ -9812,7 +9914,7 @@ var BotDriver_1 = class BotDriver {
9812
9914
 
9813
9915
  };
9814
9916
 
9815
- const debug = debug$l('botium-core-Plugins');
9917
+ const debug = debug$m('botium-core-Plugins');
9816
9918
  const PLUGIN_TYPE_CONNECTOR = 'PLUGIN_TYPE_CONNECTOR';
9817
9919
  const PLUGIN_TYPE_ASSERTER = 'PLUGIN_TYPE_ASSERTER';
9818
9920
  const PLUGIN_TYPE_LOGICHOOK = 'PLUGIN_TYPE_LOGICHOOK';