@itentialopensource/adapter-selector_ai 0.1.1

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.
Files changed (117) hide show
  1. package/.eslintignore +5 -0
  2. package/.eslintrc.js +19 -0
  3. package/.jshintrc +3 -0
  4. package/AUTH.md +39 -0
  5. package/BROKER.md +211 -0
  6. package/CALLS.md +405 -0
  7. package/CODE_OF_CONDUCT.md +43 -0
  8. package/CONTRIBUTING.md +13 -0
  9. package/ENHANCE.md +69 -0
  10. package/LICENSE +201 -0
  11. package/PROPERTIES.md +661 -0
  12. package/README.md +344 -0
  13. package/SUMMARY.md +9 -0
  14. package/SYSTEMINFO.md +14 -0
  15. package/TAB1.md +8 -0
  16. package/TAB2.md +314 -0
  17. package/TROUBLESHOOT.md +56 -0
  18. package/UTILITIES.md +473 -0
  19. package/adapter.js +4039 -0
  20. package/adapterBase.js +1488 -0
  21. package/entities/.generic/action.json +214 -0
  22. package/entities/.generic/schema.json +28 -0
  23. package/entities/.system/action.json +50 -0
  24. package/entities/.system/mockdatafiles/getToken-default.json +3 -0
  25. package/entities/.system/mockdatafiles/healthcheck-default.json +3 -0
  26. package/entities/.system/schema.json +19 -0
  27. package/entities/.system/schemaTokenReq.json +53 -0
  28. package/entities/.system/schemaTokenResp.json +53 -0
  29. package/entities/InventorySchemaCreation/action.json +24 -0
  30. package/entities/InventorySchemaCreation/schema.json +19 -0
  31. package/entities/InventorySchemaDelete/action.json +24 -0
  32. package/entities/InventorySchemaDelete/schema.json +19 -0
  33. package/entities/InventorySchemaDeleteType/action.json +24 -0
  34. package/entities/InventorySchemaDeleteType/schema.json +19 -0
  35. package/entities/InventorySchemaFileDownload/action.json +24 -0
  36. package/entities/InventorySchemaFileDownload/schema.json +19 -0
  37. package/entities/InventorySchemaFileUpload/action.json +24 -0
  38. package/entities/InventorySchemaFileUpload/schema.json +19 -0
  39. package/entities/InventorySchemaUpdate/action.json +24 -0
  40. package/entities/InventorySchemaUpdate/schema.json +19 -0
  41. package/entities/InventoryV2SchemaDeleteAll/action.json +24 -0
  42. package/entities/InventoryV2SchemaDeleteAll/schema.json +19 -0
  43. package/entities/InventoryV2SchemaDeleteType/action.json +24 -0
  44. package/entities/InventoryV2SchemaDeleteType/schema.json +19 -0
  45. package/entities/InventoryV2SchemaUpdate/action.json +24 -0
  46. package/entities/InventoryV2SchemaUpdate/schema.json +19 -0
  47. package/entities/InventoryV2SchemaUpload/action.json +24 -0
  48. package/entities/InventoryV2SchemaUpload/schema.json +19 -0
  49. package/entities/MetastoreInventoryBulkDataUpload/action.json +24 -0
  50. package/entities/MetastoreInventoryBulkDataUpload/schema.json +19 -0
  51. package/entities/MetastoreInventoryCSVDataUpload/action.json +24 -0
  52. package/entities/MetastoreInventoryCSVDataUpload/schema.json +19 -0
  53. package/entities/MetastoreInventoryCsvFileExport/action.json +25 -0
  54. package/entities/MetastoreInventoryCsvFileExport/schema.json +19 -0
  55. package/entities/MetastoreInventoryDataDelete/action.json +24 -0
  56. package/entities/MetastoreInventoryDataDelete/schema.json +19 -0
  57. package/entities/MetastoreInventoryDataDownload/action.json +46 -0
  58. package/entities/MetastoreInventoryDataDownload/schema.json +20 -0
  59. package/entities/MetastoreInventoryDataEdit/action.json +24 -0
  60. package/entities/MetastoreInventoryDataEdit/schema.json +19 -0
  61. package/entities/MetastoreInventoryDataUpload/action.json +24 -0
  62. package/entities/MetastoreInventoryDataUpload/schema.json +19 -0
  63. package/entities/MetastoreInventoryFilesExport/action.json +24 -0
  64. package/entities/MetastoreInventoryFilesExport/schema.json +19 -0
  65. package/entities/MetastoreInventoryFilesImport/action.json +24 -0
  66. package/entities/MetastoreInventoryFilesImport/schema.json +30 -0
  67. package/entities/MetastoreInventoryItems/action.json +25 -0
  68. package/entities/MetastoreInventoryItems/schema.json +19 -0
  69. package/entities/MetastoreInventoryNameDelete/action.json +24 -0
  70. package/entities/MetastoreInventoryNameDelete/schema.json +19 -0
  71. package/entities/MetastoreInventoryNameUpdate/action.json +24 -0
  72. package/entities/MetastoreInventoryNameUpdate/schema.json +19 -0
  73. package/entities/MetastoreInventoryNameUpload/action.json +24 -0
  74. package/entities/MetastoreInventoryNameUpload/schema.json +19 -0
  75. package/entities/MetastoreInventoryNamesDownload/action.json +25 -0
  76. package/entities/MetastoreInventoryNamesDownload/schema.json +19 -0
  77. package/entities/MetastoreInventorySchemaGet/action.json +25 -0
  78. package/entities/MetastoreInventorySchemaGet/schema.json +19 -0
  79. package/entities/MetastoreInventorySystem/action.json +130 -0
  80. package/entities/MetastoreInventorySystem/schema.json +24 -0
  81. package/entities/MetastoreV2InventorySchemaGet/action.json +25 -0
  82. package/entities/MetastoreV2InventorySchemaGet/schema.json +19 -0
  83. package/error.json +190 -0
  84. package/metadata.json +58 -0
  85. package/package.json +77 -0
  86. package/pronghorn.json +2508 -0
  87. package/propertiesDecorators.json +14 -0
  88. package/propertiesSchema.json +1635 -0
  89. package/report/adapterInfo.json +10 -0
  90. package/report/auto-adapter-openapi.json +1330 -0
  91. package/report/creationReport.json +765 -0
  92. package/report/metastore-inventory-manager.yaml-OpenApi3Json.json +2366 -0
  93. package/sampleProperties.json +260 -0
  94. package/test/integration/adapterTestBasicGet.js +117 -0
  95. package/test/integration/adapterTestConnectivity.js +117 -0
  96. package/test/integration/adapterTestIntegration.js +1295 -0
  97. package/test/unit/adapterBaseTestUnit.js +1626 -0
  98. package/test/unit/adapterTestUnit.js +2288 -0
  99. package/utils/adapterInfo.js +156 -0
  100. package/utils/argParser.js +44 -0
  101. package/utils/checkMigrate.js +102 -0
  102. package/utils/entitiesToDB.js +190 -0
  103. package/utils/findPath.js +74 -0
  104. package/utils/logger.js +26 -0
  105. package/utils/methodDocumentor.js +273 -0
  106. package/utils/modify.js +153 -0
  107. package/utils/mongoDbConnection.js +79 -0
  108. package/utils/mongoUtils.js +162 -0
  109. package/utils/pre-commit.sh +32 -0
  110. package/utils/removeHooks.js +20 -0
  111. package/utils/setup.js +33 -0
  112. package/utils/taskMover.js +308 -0
  113. package/utils/tbScript.js +103 -0
  114. package/utils/tbUtils.js +347 -0
  115. package/utils/testRunner.js +298 -0
  116. package/utils/troubleshootingAdapter.js +177 -0
  117. package/utils/updateAdapterConfig.js +158 -0
@@ -0,0 +1,347 @@
1
+ /* @copyright Itential, LLC 2025 */
2
+
3
+ /* eslint import/no-extraneous-dependencies: warn */
4
+ /* eslint global-require: warn */
5
+ /* eslint import/no-dynamic-require: warn */
6
+ /* eslint-disable no-console */
7
+
8
+ /**
9
+ * This script contains manhy of the basic troubleshooting scripts. In addition, it contains helper functions
10
+ * that are utilized by other utilities.
11
+ *
12
+ * This utility is utilized by tbScript when the troubleshooting scripts are run via the CLI. It is also utilized
13
+ * by the adapterBase.js when the troubleshooting scripts are exposed by the adapter and run through Platform
14
+ * Workflow or any other Platform component.
15
+ */
16
+
17
+ const path = require('path');
18
+ const cp = require('child_process');
19
+ const axios = require('axios');
20
+ const log = require('./logger');
21
+ const MongoDBConnection = require('./mongoDbConnection');
22
+
23
+ module.exports = {
24
+ SERVICE_CONFIGS_COLLECTION: 'service_configs',
25
+ IAP_PROFILES_COLLECTION: 'iap_profiles',
26
+
27
+ /**
28
+ * @summary create Adapter instance
29
+ *
30
+ * @function getAdapterInstance
31
+ * @param {Object} adapter - adaper configuration object required by IAP
32
+ */
33
+ getAdapterInstance: (adapter) => {
34
+ const Adapter = require('../adapter');
35
+ const adapterProps = JSON.parse(JSON.stringify(adapter.properties.properties));
36
+ adapterProps.stub = false;
37
+ return new Adapter(
38
+ adapter.id,
39
+ adapterProps
40
+ );
41
+ },
42
+
43
+ /**
44
+ * @summary Makes a GET call using axios
45
+ *
46
+ * @function get
47
+ * @param {String} url - url to make the call to
48
+ */
49
+ get: (url) => {
50
+ const config = {
51
+ method: 'get',
52
+ url
53
+ };
54
+ return axios(config);
55
+ },
56
+
57
+ /**
58
+ * @summary update newConnection properties in adapter config
59
+ *
60
+ * @function updateNewConnection
61
+ * @param {Object} config - adaper configuration object required by IAP
62
+ * @param {Object} newConnection - connection related property collection from user
63
+ */
64
+ updateNewConnection: (config, newConnection) => {
65
+ const updatedConfig = JSON.parse(JSON.stringify(config));
66
+ Object.keys(newConnection).forEach((key) => {
67
+ updatedConfig.properties.properties[key] = newConnection[key];
68
+ });
69
+ return updatedConfig;
70
+ },
71
+
72
+ /**
73
+ * @summary assemble heathcheck endpoint into an URL
74
+ *
75
+ * @function getHealthCheckEndpointURL
76
+ * @param {Object} endpoint - user updated healthcheck endpoint object
77
+ * @param {Object} config - adaper configuration object required by IAP
78
+ */
79
+ getHealthCheckEndpointURL: (endpoint, config) => {
80
+ const p = config.properties.properties;
81
+ // Handle base_path and version properly
82
+ let basePath = '';
83
+ if (p.base_path && p.base_path !== '/') {
84
+ basePath = p.base_path.startsWith('/') ? p.base_path : `/${p.base_path}`;
85
+ }
86
+
87
+ let version = '';
88
+ if (p.version) {
89
+ version = p.version.startsWith('/') ? p.version : `/${p.version}`;
90
+ }
91
+
92
+ const healthCheckEndpointURL = `${p.protocol}://${p.host}${basePath}${version}${endpoint.healthCheckEndpoint}`;
93
+ log.info({ healthCheckEndpointURL });
94
+ return healthCheckEndpointURL;
95
+ },
96
+
97
+ /**
98
+ * @summary update authentication property given new input value from user
99
+ * compare values from auth and newAuth, if there's difference
100
+ * update adapter config
101
+ * @function updateAuth
102
+ * @param {Object} newAuth - user confirmed authentication object
103
+ * @param {Object} auth - existing authentication object
104
+ * @param {Object} config - adaper configuration object required by IAP
105
+ */
106
+ updateAuth: (newAuth, auth, config) => {
107
+ const updatedConfig = JSON.parse(JSON.stringify(config));
108
+ if (Object.keys(newAuth).every((key) => newAuth[key] === auth[key])) {
109
+ return config;
110
+ }
111
+ Object.keys(newAuth).forEach((key) => {
112
+ updatedConfig.properties.properties.authentication[key] = newAuth[key];
113
+ });
114
+ log.info(updatedConfig.properties.properties.authentication);
115
+ return updatedConfig;
116
+ },
117
+
118
+ /**
119
+ * @summary add mark current auth_method with `(current)`
120
+ *
121
+ * @function getDisplayAuthOptions
122
+ * @param {String} currentAuth - current auth method in adapter config
123
+ * @param {Array} authOptions - available auth method
124
+ */
125
+ getDisplayAuthOptions: (currentAuth, authOptions) => {
126
+ const displayAuthOptions = JSON.parse(JSON.stringify(authOptions));
127
+ displayAuthOptions[authOptions.indexOf(currentAuth)] += ' (current)';
128
+ return displayAuthOptions;
129
+ },
130
+
131
+ /**
132
+ * @summary create connection object for verification
133
+ *
134
+ * @function getConnection
135
+ * @param {Object} props - adapter config.properties
136
+ */
137
+ getConnection: (props) => {
138
+ const connection = {
139
+ host: props.properties.host,
140
+ base_path: props.properties.base_path,
141
+ protocol: props.properties.protocol,
142
+ version: props.properties.version,
143
+ port: props.properties.port
144
+ };
145
+ return connection;
146
+ },
147
+
148
+ /**
149
+ * @summary update connection properties based on user answer
150
+ *
151
+ * @function getNewProps
152
+ * @param {Array} answers - values collected from CLI
153
+ * @param {Object} connection - connection property verified by user
154
+ */
155
+ getNewProps: (answers, connection) => {
156
+ if (answers.every((answer) => answer === '')) {
157
+ return connection;
158
+ }
159
+ const newConnection = {};
160
+ const properties = Object.keys(connection);
161
+ for (let i = 0; i < answers.length; i += 1) {
162
+ if (answers[i]) {
163
+ newConnection[properties[i]] = Number.isNaN(Number(answers[i])) ? answers[i] : Number(answers[i]);
164
+ } else {
165
+ newConnection[properties[i]] = connection[properties[i]];
166
+ }
167
+ }
168
+ return newConnection;
169
+ },
170
+
171
+ /**
172
+ * @summary extract endpoint string from healthcheck object
173
+ *
174
+ * @function getHealthCheckEndpoint
175
+ * @param {Object} healthcheck - {Object} healthcheck - ./entities/.system/action.json object
176
+ */
177
+ getHealthCheckEndpoint: (healthcheck) => {
178
+ const endpoint = healthcheck.actions[1].entitypath.slice(21, healthcheck.actions[1].entitypath.length - 8);
179
+ return { healthCheckEndpoint: endpoint };
180
+ },
181
+
182
+ /**
183
+ * @summary execute command and preserve the output the same as run command in shell
184
+ *
185
+ * @function systemSync
186
+ * @param {String} cmd - Command to execute
187
+ * @param {boolean} process - Whether stdout should be processed and returned
188
+ */
189
+ systemSync: function systemSync(cmd, process) {
190
+ if (process) {
191
+ let stdout;
192
+ try {
193
+ stdout = cp.execSync(cmd).toString();
194
+ } catch (error) {
195
+ log.info('execute command error', error.stdout.toString(), error.stderr.toString());
196
+ stdout = error.stdout.toString();
197
+ }
198
+ const output = this.getTestCount(stdout);
199
+ output.stdout = stdout;
200
+ return output;
201
+ }
202
+ try {
203
+ return cp.execSync(cmd, { stdio: 'inherit' });
204
+ } catch (error) {
205
+ return console.error(error.stdout);
206
+ }
207
+ },
208
+
209
+ /**
210
+ * @summary parses a string and returns the number parsed from startIndex backwards
211
+ *
212
+ * @function parseNum
213
+ * @param {String} inputStr - Any String
214
+ * @param {Number} startIndex - Index to begin parsing
215
+ */
216
+ parseNum: function parseNum(inputStr, startIndex) {
217
+ let count = '';
218
+ let currChar;
219
+ let start = startIndex;
220
+ while (currChar !== ' ') {
221
+ currChar = inputStr.charAt(start);
222
+ count = currChar + count;
223
+ start -= 1;
224
+ }
225
+ return parseInt(count, 10);
226
+ },
227
+
228
+ /**
229
+ * @summary Parses a mocha test result and returns the count of passing and failing tests
230
+ *
231
+ * @function getTestCount
232
+ * @param {String} testStr - Output from mocha test
233
+ */
234
+ getTestCount: function getTestCount(testStr) {
235
+ const passIndex = testStr.search('passing');
236
+ const failIndex = testStr.search('failing');
237
+ const passCount = passIndex >= 0 ? this.parseNum(testStr, passIndex - 2) : 0;
238
+ const failCount = failIndex >= 0 ? this.parseNum(testStr, failIndex - 2) : 0;
239
+ return { passCount, failCount };
240
+ },
241
+
242
+ /**
243
+ * @summary run lint, unit test and integration test
244
+ * print result to stdout
245
+ */
246
+ runTest: function runTest() {
247
+ this.systemSync('npm run lint:errors');
248
+ this.systemSync('npm run test:unit');
249
+ this.systemSync('npm run test:integration');
250
+ },
251
+
252
+ /**
253
+ * @summary run basicget with mocha
254
+ * @param {boolean} scriptFlag - whether the function is ran from a script
255
+ * @param {number} maxCalls - how many GETs to run (defaults to 5)
256
+ * print result to stdout
257
+ * returns mocha test results otherwise
258
+ */
259
+ runBasicGet: function runBasicGet(props, scriptFlag, maxCalls = 5) {
260
+ let testPath = 'test/integration/adapterTestBasicGet.js';
261
+ let executable = 'mocha';
262
+ if (!scriptFlag) {
263
+ testPath = path.resolve(__dirname, '..', testPath);
264
+ executable = path.join(__dirname, '..', 'node_modules/mocha/bin/mocha.js');
265
+ }
266
+ // if caller passed a number, add the flag
267
+ const mcFlag = Number.isInteger(maxCalls) ? ` --MAXCALLS=${maxCalls}` : '';
268
+ const cmd = `${executable} ${testPath} --PROPS='${JSON.stringify(props)}'${mcFlag} --timeout 60000 --exit`;
269
+ return this.systemSync(cmd, !scriptFlag);
270
+ },
271
+
272
+ /**
273
+ * @summary run connectivity with mocha
274
+ * @param {String} host - Host url to run healthcheck
275
+ * @param {boolean} scriptFlag - Whether the function is ran from a script
276
+ * print result to stdout if ran from script
277
+ * returns mocha test results otherwise
278
+ */
279
+ runConnectivity: function runConnectivity(host, scriptFlag) {
280
+ let testPath = 'test/integration/adapterTestConnectivity.js';
281
+ let executable = 'mocha';
282
+ if (!scriptFlag) {
283
+ testPath = path.resolve(__dirname, '..', testPath);
284
+ executable = path.join(__dirname, '..', 'node_modules/mocha/bin/mocha.js');
285
+ }
286
+ return this.systemSync(`${executable} ${testPath} --HOST=${host} --timeout 10000 --exit`, !scriptFlag);
287
+ },
288
+
289
+ /**
290
+ * @summary return async healthcheck result as a Promise
291
+ *
292
+ * @function request
293
+ * @param {Adapter} a - Adapter instance
294
+ */
295
+ request: function request(a) {
296
+ return new Promise((resolve, reject) => {
297
+ a.healthCheck(null, (data) => {
298
+ if (!data) reject(new Error('healthCheckEndpoint failed'));
299
+ resolve(data);
300
+ });
301
+ });
302
+ },
303
+
304
+ /**
305
+ * @summary deal with healthcheck response returned from adapter instace
306
+ *
307
+ * @function healthCheck
308
+ * @param {Adapter} a - Adapter instance
309
+ */
310
+ healthCheck: async function healthCheck(a) {
311
+ const result = await this.request(a)
312
+ .then((res) => {
313
+ log.info('healthCheckEndpoint OK');
314
+ return res;
315
+ })
316
+ .catch((error) => {
317
+ console.error(error.message);
318
+ return false;
319
+ });
320
+ return result;
321
+ },
322
+
323
+ /**
324
+ * @summary connect to mongodb
325
+ *
326
+ * @function connect
327
+ * @param {Object} properties - pronghornProps
328
+ */
329
+ connect: async function connect(properties) {
330
+ const connection = new MongoDBConnection(properties);
331
+ const database = await connection.connect();
332
+ return database;
333
+ },
334
+
335
+ /**
336
+ * @summary close mongodb connection
337
+ *
338
+ * @function closeConnection
339
+ * @param {Object} connection - MongoDB connection instance
340
+ */
341
+ closeConnection: async function closeConnection(connection) {
342
+ if (connection && connection.closeConnection) {
343
+ await connection.closeConnection();
344
+ }
345
+ }
346
+
347
+ };
@@ -0,0 +1,298 @@
1
+ #!/usr/bin/env node
2
+ /* @copyright Itential, LLC 2019 */
3
+
4
+ const execute = require('child_process').exec;
5
+ const fs = require('fs-extra');
6
+ const rl = require('readline-sync');
7
+
8
+ /**
9
+ * This script will determine the type of integration test to run
10
+ * based on input. If other information is needed, it will solicit
11
+ * that input and then edit the integration test accordingly.
12
+ */
13
+
14
+ let stub = true;
15
+ let isRapidFail = false;
16
+ let isSaveMockData = false;
17
+ let host = 'replace.hostorip.here';
18
+ let username = 'username';
19
+ let password = 'password';
20
+ let protocol = 'http';
21
+ let port = 80;
22
+ let sslenable = false;
23
+ let sslinvalid = false;
24
+ const dstub = true;
25
+ const disRapidFail = false;
26
+ const disSaveMockData = false;
27
+ const dhost = 'replace.hostorip.here';
28
+ const dusername = 'username';
29
+ const dpassword = 'password';
30
+ const dprotocol = 'http';
31
+ const dport = 80;
32
+ const dsslenable = false;
33
+ const dsslinvalid = false;
34
+
35
+ let stderror = false;
36
+ let running = false;
37
+
38
+ /**
39
+ * Updates the integration test file with the proper vars
40
+ */
41
+ function replaceTestVars(test) {
42
+ if (!fs.existsSync(test)) {
43
+ console.log(`Could not find ${test}`);
44
+ return 'error';
45
+ }
46
+
47
+ let intTest = fs.readFileSync(test, 'utf8');
48
+
49
+ // replace stub variable but check if it exists first
50
+ let sindex = intTest.indexOf('samProps.stub');
51
+ let eindex = intTest.indexOf(';', sindex);
52
+ let replStr = intTest.substring(sindex, eindex + 1);
53
+ if (sindex > -1) {
54
+ intTest = intTest.replace(replStr, `samProps.stub = ${stub};`);
55
+ }
56
+
57
+ // replace isRapidFail variable but check if it exists first
58
+ sindex = intTest.indexOf('const isRapidFail');
59
+ eindex = intTest.indexOf(';', sindex);
60
+ replStr = intTest.substring(sindex, eindex + 1);
61
+ if (sindex > -1) {
62
+ intTest = intTest.replace(replStr, `const isRapidFail = ${isRapidFail};`);
63
+ }
64
+
65
+ // replace isSaveMockData variable but check if it exists first
66
+ sindex = intTest.indexOf('const isSaveMockData');
67
+ eindex = intTest.indexOf(';', sindex);
68
+ replStr = intTest.substring(sindex, eindex + 1);
69
+ if (sindex > -1) {
70
+ intTest = intTest.replace(replStr, `const isSaveMockData = ${isSaveMockData};`);
71
+ }
72
+
73
+ // replace host variable
74
+ sindex = intTest.indexOf('samProps.host');
75
+ eindex = intTest.indexOf(';', sindex);
76
+ replStr = intTest.substring(sindex, eindex + 1);
77
+ intTest = intTest.replace(replStr, `samProps.host = '${host}';`);
78
+
79
+ // replace username variable
80
+ sindex = intTest.indexOf('samProps.authentication.username');
81
+ eindex = intTest.indexOf(';', sindex);
82
+ replStr = intTest.substring(sindex, eindex + 1);
83
+ intTest = intTest.replace(replStr, `samProps.authentication.username = '${username}';`);
84
+
85
+ // replace password variable
86
+ sindex = intTest.indexOf('samProps.authentication.password');
87
+ eindex = intTest.indexOf(';', sindex);
88
+ replStr = intTest.substring(sindex, eindex + 1);
89
+ intTest = intTest.replace(replStr, `samProps.authentication.password = '${password}';`);
90
+
91
+ // replace protocol variable
92
+ sindex = intTest.indexOf('samProps.protocol');
93
+ eindex = intTest.indexOf(';', sindex);
94
+ replStr = intTest.substring(sindex, eindex + 1);
95
+ intTest = intTest.replace(replStr, `samProps.protocol = '${protocol}';`);
96
+
97
+ // replace port variable
98
+ sindex = intTest.indexOf('samProps.port');
99
+ eindex = intTest.indexOf(';', sindex);
100
+ replStr = intTest.substring(sindex, eindex + 1);
101
+ intTest = intTest.replace(replStr, `samProps.port = ${port};`);
102
+
103
+ // replace sslenable variable
104
+ sindex = intTest.indexOf('samProps.ssl.enabled');
105
+ eindex = intTest.indexOf(';', sindex);
106
+ replStr = intTest.substring(sindex, eindex + 1);
107
+ intTest = intTest.replace(replStr, `samProps.ssl.enabled = ${sslenable};`);
108
+
109
+ // replace sslinvalid variable
110
+ sindex = intTest.indexOf('samProps.ssl.accept_invalid_cert');
111
+ eindex = intTest.indexOf(';', sindex);
112
+ replStr = intTest.substring(sindex, eindex + 1);
113
+ intTest = intTest.replace(replStr, `samProps.ssl.accept_invalid_cert = ${sslinvalid};`);
114
+
115
+ console.log(`Updates to ${test} complete`);
116
+ fs.writeFileSync(test, intTest);
117
+ return 'success';
118
+ }
119
+
120
+ /**
121
+ * Updates the integration test file and runs the script
122
+ */
123
+ function runTest(callback) {
124
+ replaceTestVars('test/integration/adapterTestIntegration.js');
125
+
126
+ let cmdPath = 'npm run test:integration';
127
+ console.log('\nRUNNING INTEGRATION TESTS - THIS WILL TAKE SOME TIME AND WILL NOT PRINT UNTIL TEST IS COMPLETE!\n');
128
+ if (stderror) {
129
+ console.log('\nNOTE: standard error from tests is included - unless test failed, these may be expected errors:\n');
130
+ cmdPath += ' 2>&1';
131
+ } else {
132
+ console.log('stderr not shown');
133
+ }
134
+
135
+ return execute(cmdPath, (cerror, stdout) => {
136
+ console.log('executed tests:\n');
137
+ console.log(`${stdout}\n`);
138
+ if (cerror) {
139
+ console.log('\x1b[31m%s\x1b[0m', '\nexec error:\n');
140
+ console.log('\x1b[31m%s\x1b[0m', `${cerror}\n`);
141
+ }
142
+ // reset the defaults
143
+ stub = dstub;
144
+ isRapidFail = disRapidFail;
145
+ isSaveMockData = disSaveMockData;
146
+ host = dhost;
147
+ username = dusername;
148
+ password = dpassword;
149
+ protocol = dprotocol;
150
+ port = dport;
151
+ sslenable = dsslenable;
152
+ sslinvalid = dsslinvalid;
153
+ replaceTestVars('test/integration/adapterTestIntegration.js');
154
+ return callback('done');
155
+ });
156
+ }
157
+
158
+ /**
159
+ * Updates the unit test file and runs the script
160
+ */
161
+ function runUnitTest(callback) {
162
+ let cmdPath = 'npm run test:unit';
163
+ console.log('\nRUNNING UNIT TESTS - THIS WILL TAKE SOME TIME AND WILL NOT PRINT UNTIL TEST IS COMPLETE!\n');
164
+
165
+ if (stderror) {
166
+ console.log('\nNOTE: standard error from tests is included- unless test failed, these may be expected errors:\n');
167
+ cmdPath += ' 2>&1';
168
+ } else {
169
+ console.log('stderr not shown');
170
+ }
171
+
172
+ return execute(cmdPath, (cerror, stdout) => {
173
+ console.log('executed tests:\n');
174
+ console.log(`${stdout}\n`);
175
+
176
+ if (cerror) {
177
+ console.log('\x1b[31m%s\x1b[0m', '\nexec error:\n');
178
+ console.log('\x1b[31m%s\x1b[0m', `${cerror}\n`);
179
+ }
180
+
181
+ return callback('done');
182
+ });
183
+ }
184
+
185
+ // print process.argv
186
+ const args = process.argv.slice(2);
187
+
188
+ // go through the arguments that where provided
189
+ for (let a = 0; a < args.length; a += 1) {
190
+ if (args[a].toUpperCase() === '-H' || args[a].toUpperCase() === '--HELP') {
191
+ let message = '\nThis tool is used to make it easier to run integration tests.\n';
192
+ message += '\n';
193
+ message += 'Options:\n';
194
+ message += '-h, --help: Prints this message\n';
195
+ message += '-f, --failfast: Fail the test when the first test fails\n';
196
+ message += '-m, --mockdata: Update mock data files with the results from testing (only if running integrated)\n';
197
+ message += '-r, --reset: Resets the variables back to stub settings and removes credentials\n';
198
+ message += '-s, --stderror: Displays the standard error from the run, this can have data even if all the tests pass\n';
199
+ message += '-u, --unit: Runs just the unit tests as well\n';
200
+ console.log(message);
201
+ running = true;
202
+ }
203
+
204
+ if (args[a].toUpperCase() === '-F' || args[a].toUpperCase() === '--FAILFAST') {
205
+ isRapidFail = true;
206
+ }
207
+ if (args[a].toUpperCase() === '-M' || args[a].toUpperCase() === '--MOCKDATA') {
208
+ isSaveMockData = true;
209
+ }
210
+ if (args[a].toUpperCase() === '-R' || args[a].toUpperCase() === '--RESET') {
211
+ running = true;
212
+ replaceTestVars('test/integration/adapterTestIntegration.js');
213
+ replaceTestVars('test/unit/adapterTestUnit.js');
214
+ console.log('test reset complete');
215
+ }
216
+ if (args[a].toUpperCase() === '-S' || args[a].toUpperCase() === '--STDERROR') {
217
+ stderror = true;
218
+ }
219
+ if (args[a].toUpperCase() === '-U' || args[a].toUpperCase() === '--UNIT') {
220
+ running = true;
221
+ runUnitTest((status) => {
222
+ console.log(status);
223
+ process.exit(1);
224
+ });
225
+ }
226
+ }
227
+
228
+ if (!running) {
229
+ // how are we running the test?
230
+ let answer = rl.question('\nDo you want to run the integration test integrated with the other system? (no): ');
231
+ if (answer && (answer.toLowerCase() === 'yes' || answer.toLowerCase() === 'y')) {
232
+ stub = false;
233
+ console.log('Need more information about the integration!');
234
+ } else {
235
+ running = true;
236
+ runTest((status) => {
237
+ console.log(status);
238
+ process.exit(1);
239
+ });
240
+ }
241
+
242
+ if (!running) {
243
+ // how are we running the test?
244
+ answer = rl.question('\nWhat is the dns or ip of the system you want to test with? (localhost): ');
245
+ if (answer) {
246
+ host = answer;
247
+ } else {
248
+ host = 'localhost';
249
+ }
250
+
251
+ // need the username to authenticate with
252
+ answer = rl.question('\nWhat is the username to authenticate, if no authentication just return? (username): ');
253
+ if (answer) {
254
+ username = answer;
255
+ }
256
+
257
+ // need the password to authenticate with
258
+ answer = rl.question('\nWhat is the password to authenticate, if no authentication just return? (password): ', { hideEchoBack: true });
259
+ if (answer) {
260
+ password = answer;
261
+ }
262
+
263
+ // need the protocol used with other system
264
+ answer = rl.question('\nWhat is the protocol used to communicate with the system? (http): ');
265
+ if (answer) {
266
+ protocol = answer;
267
+ }
268
+
269
+ if (protocol === 'https') {
270
+ // if protocol is https, set default port to 443
271
+ port = 443;
272
+ // need the port used with other system
273
+ answer = rl.question('\nWhat is the port used to communicate with the system? (443): ');
274
+ port = 443; // update default answer to 443 for https
275
+ if (answer) {
276
+ port = Number(answer);
277
+ }
278
+
279
+ // turn on ssl and accept invalid certs
280
+ sslenable = true;
281
+ sslinvalid = true;
282
+ runTest((status) => {
283
+ console.log(status);
284
+ process.exit(1);
285
+ });
286
+ } else {
287
+ // need the port used with other system
288
+ answer = rl.question('\nWhat is the port used to communicate with the system? (80): ');
289
+ if (answer) {
290
+ port = Number(answer);
291
+ }
292
+ runTest((status) => {
293
+ console.log(status);
294
+ process.exit(1);
295
+ });
296
+ }
297
+ }
298
+ }