@itentialopensource/adapter-microsoft_graph 1.0.0

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 (132) hide show
  1. package/.eslintignore +6 -0
  2. package/.eslintrc.js +18 -0
  3. package/.gitlab/.gitkeep +0 -0
  4. package/.gitlab/issue_templates/.gitkeep +0 -0
  5. package/.gitlab/issue_templates/Default.md +17 -0
  6. package/.gitlab/issue_templates/bugReportTemplate.md +42 -0
  7. package/.gitlab/issue_templates/featureRequestTemplate.md +14 -0
  8. package/.jshintrc +0 -0
  9. package/AUTH.md +39 -0
  10. package/BROKER.md +199 -0
  11. package/CALLS.md +170 -0
  12. package/CHANGELOG.md +9 -0
  13. package/CODE_OF_CONDUCT.md +43 -0
  14. package/CONTRIBUTING.md +172 -0
  15. package/ENHANCE.md +69 -0
  16. package/LICENSE +201 -0
  17. package/PROPERTIES.md +641 -0
  18. package/README.md +337 -0
  19. package/SUMMARY.md +9 -0
  20. package/SYSTEMINFO.md +11 -0
  21. package/TROUBLESHOOT.md +47 -0
  22. package/adapter.js +18798 -0
  23. package/adapterBase.js +1787 -0
  24. package/entities/.generic/action.json +214 -0
  25. package/entities/.generic/schema.json +28 -0
  26. package/entities/.system/action.json +50 -0
  27. package/entities/.system/mockdatafiles/getToken-default.json +3 -0
  28. package/entities/.system/mockdatafiles/healthcheck-default.json +3 -0
  29. package/entities/.system/schema.json +19 -0
  30. package/entities/.system/schemaTokenReq.json +53 -0
  31. package/entities/.system/schemaTokenResp.json +53 -0
  32. package/entities/Applications/action.json +127 -0
  33. package/entities/Applications/schema.json +35 -0
  34. package/entities/AzureADDevice/action.json +106 -0
  35. package/entities/AzureADDevice/schema.json +45 -0
  36. package/entities/Batch/action.json +24 -0
  37. package/entities/Batch/schema.json +19 -0
  38. package/entities/CaseCreation/action.json +249 -0
  39. package/entities/CaseCreation/schema.json +30 -0
  40. package/entities/Catalog/action.json +25 -0
  41. package/entities/Catalog/schema.json +19 -0
  42. package/entities/ConnectionSetup/action.json +148 -0
  43. package/entities/ConnectionSetup/schema.json +25 -0
  44. package/entities/ContentSync/action.json +65 -0
  45. package/entities/ContentSync/schema.json +21 -0
  46. package/entities/CreateDSR/action.json +45 -0
  47. package/entities/CreateDSR/schema.json +20 -0
  48. package/entities/Deployment/action.json +106 -0
  49. package/entities/Deployment/schema.json +34 -0
  50. package/entities/DeploymentAudience/action.json +66 -0
  51. package/entities/DeploymentAudience/schema.json +32 -0
  52. package/entities/Events/action.json +108 -0
  53. package/entities/Events/schema.json +34 -0
  54. package/entities/Files/action.json +108 -0
  55. package/entities/Files/schema.json +23 -0
  56. package/entities/Groups/action.json +25 -0
  57. package/entities/Groups/schema.json +19 -0
  58. package/entities/IdentitySync/action.json +105 -0
  59. package/entities/IdentitySync/schema.json +23 -0
  60. package/entities/Insights/action.json +46 -0
  61. package/entities/Insights/schema.json +20 -0
  62. package/entities/LabelManagement/action.json +106 -0
  63. package/entities/LabelManagement/schema.json +23 -0
  64. package/entities/Mail/action.json +212 -0
  65. package/entities/Mail/schema.json +72 -0
  66. package/entities/Memberships/action.json +167 -0
  67. package/entities/Memberships/schema.json +70 -0
  68. package/entities/Misc/action.json +66 -0
  69. package/entities/Misc/schema.json +21 -0
  70. package/entities/Notebooks/action.json +107 -0
  71. package/entities/Notebooks/schema.json +34 -0
  72. package/entities/OpenExtensions/action.json +65 -0
  73. package/entities/OpenExtensions/schema.json +54 -0
  74. package/entities/People/action.json +46 -0
  75. package/entities/People/schema.json +31 -0
  76. package/entities/SchemaExtensions/action.json +65 -0
  77. package/entities/SchemaExtensions/schema.json +32 -0
  78. package/entities/Search/action.json +24 -0
  79. package/entities/Search/schema.json +19 -0
  80. package/entities/Security/action.json +151 -0
  81. package/entities/Security/schema.json +58 -0
  82. package/entities/SharePoint/action.json +214 -0
  83. package/entities/SharePoint/schema.json +39 -0
  84. package/entities/Subscriptions/action.json +65 -0
  85. package/entities/Subscriptions/schema.json +32 -0
  86. package/entities/TasksPlanner/action.json +272 -0
  87. package/entities/TasksPlanner/schema.json +86 -0
  88. package/entities/TasksTodo/action.json +187 -0
  89. package/entities/TasksTodo/schema.json +49 -0
  90. package/entities/Teams/action.json +519 -0
  91. package/entities/Teams/schema.json +120 -0
  92. package/entities/TrackDSRStatus/action.json +108 -0
  93. package/entities/TrackDSRStatus/schema.json +23 -0
  94. package/entities/TriggerEventForExistingLabel/action.json +108 -0
  95. package/entities/TriggerEventForExistingLabel/schema.json +23 -0
  96. package/entities/Users/action.json +213 -0
  97. package/entities/Users/schema.json +50 -0
  98. package/entities/WorkflowAutomation/action.json +249 -0
  99. package/entities/WorkflowAutomation/schema.json +30 -0
  100. package/error.json +190 -0
  101. package/package.json +87 -0
  102. package/pronghorn.json +8654 -0
  103. package/propertiesDecorators.json +14 -0
  104. package/propertiesSchema.json +1248 -0
  105. package/refs?service=git-upload-pack +0 -0
  106. package/report/creationReport.json +1715 -0
  107. package/report/graph.json +14709 -0
  108. package/sampleProperties.json +195 -0
  109. package/test/integration/adapterTestBasicGet.js +83 -0
  110. package/test/integration/adapterTestConnectivity.js +93 -0
  111. package/test/integration/adapterTestIntegration.js +6059 -0
  112. package/test/unit/adapterBaseTestUnit.js +949 -0
  113. package/test/unit/adapterTestUnit.js +7492 -0
  114. package/utils/adapterInfo.js +206 -0
  115. package/utils/addAuth.js +94 -0
  116. package/utils/artifactize.js +146 -0
  117. package/utils/basicGet.js +50 -0
  118. package/utils/checkMigrate.js +63 -0
  119. package/utils/entitiesToDB.js +178 -0
  120. package/utils/findPath.js +74 -0
  121. package/utils/methodDocumentor.js +225 -0
  122. package/utils/modify.js +154 -0
  123. package/utils/packModificationScript.js +35 -0
  124. package/utils/patches2bundledDeps.js +90 -0
  125. package/utils/pre-commit.sh +32 -0
  126. package/utils/removeHooks.js +20 -0
  127. package/utils/setup.js +33 -0
  128. package/utils/tbScript.js +246 -0
  129. package/utils/tbUtils.js +490 -0
  130. package/utils/testRunner.js +298 -0
  131. package/utils/troubleshootingAdapter.js +195 -0
  132. package/workflows/README.md +3 -0
@@ -0,0 +1,490 @@
1
+ /* @copyright Itential, LLC 2020 */
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
+ const path = require('path');
9
+ const fs = require('fs-extra');
10
+ const cp = require('child_process');
11
+
12
+ module.exports = {
13
+ SERVICE_CONFIGS_COLLECTION: 'service_configs',
14
+ IAP_PROFILES_COLLECTION: 'iap_profiles',
15
+
16
+ /**
17
+ * @summary update newConnection properties in adapter config
18
+ *
19
+ * @function updateNewConnection
20
+ * @param {Object} config - adaper configuration object required by IAP
21
+ * @param {Object} newConnection - connection related property collection from user
22
+ */
23
+ updateNewConnection: (config, newConnection) => {
24
+ const updatedConfig = JSON.parse(JSON.stringify(config));
25
+ Object.keys(newConnection).forEach((key) => {
26
+ updatedConfig.properties.properties[key] = newConnection[key];
27
+ });
28
+ return updatedConfig;
29
+ },
30
+
31
+ /**
32
+ * @summary assemble heathcheck endpoint into an URL
33
+ *
34
+ * @function getHealthCheckEndpointURL
35
+ * @param {Object} endpoint - user updated healthcheck endpoint object
36
+ * @param {Object} config - adaper configuration object required by IAP
37
+ */
38
+ getHealthCheckEndpointURL: (endpoint, config) => {
39
+ const p = config.properties.properties;
40
+ const healthCheckEndpointURL = `${p.protocol}://${p.host}${p.base_path}${p.version}${endpoint.healthCheckEndpoint}`;
41
+ console.log({ healthCheckEndpointURL });
42
+ return healthCheckEndpointURL;
43
+ },
44
+
45
+ /**
46
+ * @summary persist healthcheck endpoint when user make update
47
+ *
48
+ * @function updateHealthCheckEndpoint
49
+ * @param {Object} newHealthCheckEndpoint - user confirmed healthcheck object
50
+ * @param {Object} healthCheckEndpoint - existing healthcheck object
51
+ * @param {Object} healthcheck - ./entities/.system/action.json object
52
+ */
53
+ updateHealthCheckEndpoint: (newHealthCheckEndpoint, healthCheckEndpoint, healthcheck) => {
54
+ if (newHealthCheckEndpoint.healthCheckEndpoint !== healthCheckEndpoint.healthCheckEndpoint) {
55
+ const p = healthcheck.actions[1].entitypath;
56
+ const newEntitypath = p.slice(0, 21) + newHealthCheckEndpoint.healthCheckEndpoint + p.slice(p.length - 8);
57
+ const updatedHealthcheck = JSON.parse(JSON.stringify(healthcheck));
58
+ updatedHealthcheck.actions[1].entitypath = newEntitypath;
59
+ console.log('updating healthcheck setting');
60
+ fs.writeFileSync('./entities/.system/action.json', JSON.stringify(updatedHealthcheck, null, 2));
61
+ }
62
+ },
63
+
64
+ /**
65
+ * @summary update authentication property given new input value from user
66
+ * compare values from auth and newAuth, if there's difference
67
+ * update adapter config
68
+ * @function updateAuth
69
+ * @param {Object} newAuth - user confirmed authentication object
70
+ * @param {Object} auth - existing authentication object
71
+ * @param {Object} config - adaper configuration object required by IAP
72
+ */
73
+ updateAuth: (newAuth, auth, config) => {
74
+ const updatedConfig = JSON.parse(JSON.stringify(config));
75
+ if (Object.keys(newAuth).every((key) => newAuth[key] === auth[key])) {
76
+ return config;
77
+ }
78
+ Object.keys(newAuth).forEach((key) => {
79
+ updatedConfig.properties.properties.authentication[key] = newAuth[key];
80
+ });
81
+ console.log(updatedConfig.properties.properties.authentication);
82
+ return updatedConfig;
83
+ },
84
+
85
+ /**
86
+ * @summary add mark current auth_method with `(current)`
87
+ *
88
+ * @function getDisplayAuthOptions
89
+ * @param {String} currentAuth - current auth method in adapter config
90
+ * @param {Array} authOptions - available auth method
91
+ */
92
+ getDisplayAuthOptions: (currentAuth, authOptions) => {
93
+ const displayAuthOptions = JSON.parse(JSON.stringify(authOptions));
94
+ displayAuthOptions[authOptions.indexOf(currentAuth)] += ' (current)';
95
+ return displayAuthOptions;
96
+ },
97
+
98
+ /**
99
+ * @summary decrypt IAP properties
100
+ * code from pronghorn-core/migration_scripts/installService.js
101
+ *
102
+ * @function decryptProperties
103
+ */
104
+ decryptProperties: (props, iapDir) => {
105
+ const { PropertyEncryption } = require(path.join(iapDir, 'node_modules/@itential/itential-utils'));
106
+ const propertyEncryption = new PropertyEncryption({
107
+ algorithm: 'aes-256-ctr',
108
+ key: 'TG9uZ0Rpc3RhbmNlUnVubmVyUHJvbmdob3JuCg==',
109
+ encoding: 'utf-8'
110
+ });
111
+ return propertyEncryption.decryptProps(props);
112
+ },
113
+
114
+ /**
115
+ * @summary create connection object for verification
116
+ *
117
+ * @function getConnection
118
+ * @param {Object} props - adapter config.properties
119
+ */
120
+ getConnection: (props) => {
121
+ const connection = {
122
+ host: props.properties.host,
123
+ base_path: props.properties.base_path,
124
+ protocol: props.properties.protocol,
125
+ version: props.properties.version,
126
+ port: props.properties.port
127
+ };
128
+ return connection;
129
+ },
130
+
131
+ /**
132
+ * @summary update connection properties based on user answer
133
+ *
134
+ * @function getNewProps
135
+ * @param {Array} answers - values collected from CLI
136
+ * @param {Object} connection - connection property verified by user
137
+ */
138
+ getNewProps: (answers, connection) => {
139
+ if (answers.every((answer) => answer === '')) {
140
+ return connection;
141
+ }
142
+ const newConnection = {};
143
+ const properties = Object.keys(connection);
144
+ for (let i = 0; i < answers.length; i += 1) {
145
+ if (answers[i]) {
146
+ newConnection[properties[i]] = Number.isNaN(Number(answers[i])) ? answers[i] : Number(answers[i]);
147
+ } else {
148
+ newConnection[properties[i]] = connection[properties[i]];
149
+ }
150
+ }
151
+ return newConnection;
152
+ },
153
+
154
+ /**
155
+ * @summary extract endpoint string from healthcheck object
156
+ *
157
+ * @function getHealthCheckEndpoint
158
+ * @param {Object} healthcheck - {Object} healthcheck - ./entities/.system/action.json object
159
+ */
160
+ getHealthCheckEndpoint: (healthcheck) => {
161
+ const endpoint = healthcheck.actions[1].entitypath.slice(21,
162
+ healthcheck.actions[1].entitypath.length - 8);
163
+ return { healthCheckEndpoint: endpoint };
164
+ },
165
+
166
+ /**
167
+ * @summary Verify that the adapter is in the correct directory
168
+ * - Within IAP
169
+ * - In node_modules/@ namespace
170
+ * verify the adapter is installed under node_modules/
171
+ * and is consistent with the name property of package.json
172
+ * and the node_modules/ is in the correct path within IAP
173
+ * @param {String} dirname - current path
174
+ * @param {String} name - name property from package.json
175
+ */
176
+ verifyInstallationDir: (dirname, name) => {
177
+ const pathArray = dirname.split(path.sep);
178
+ const expectedPath = `node_modules/${name}`;
179
+ const currentPath = pathArray.slice(pathArray.length - 3, pathArray.length).join('/');
180
+ if (currentPath.trim() !== expectedPath.trim()) {
181
+ throw new Error(`adapter should be installed under ${expectedPath} but is installed under ${currentPath}`);
182
+ }
183
+
184
+ const serverFile = path.join(dirname, '../../../', 'server.js');
185
+ if (!fs.existsSync(serverFile)) {
186
+ throw new Error(`adapter should be installed under IAP/${expectedPath}`);
187
+ }
188
+ console.log(`adapter correctly installed at ${currentPath}`);
189
+ },
190
+
191
+ /**
192
+ * @summary execute command and preserve the output the same as run command in shell
193
+ *
194
+ * @function systemSync
195
+ * @param {String} cmd - Command to execute
196
+ * @param {boolean} process - Whether stdout should be processed and returned
197
+ */
198
+ systemSync: function systemSync(cmd, process) {
199
+ if (process) {
200
+ let stdout;
201
+ try {
202
+ stdout = cp.execSync(cmd).toString();
203
+ } catch (error) {
204
+ console.log('execute command error', error.stdout.toString(), error.stderr.toString());
205
+ stdout = error.stdout.toString();
206
+ }
207
+ const output = this.getTestCount(stdout);
208
+ output.stdout = stdout;
209
+ return output;
210
+ }
211
+ try {
212
+ return cp.execSync(cmd, { stdio: 'inherit' });
213
+ } catch (error) {
214
+ return console.error(error.stdout);
215
+ }
216
+ },
217
+
218
+ /**
219
+ * @summary parses a string and returns the number parsed from startIndex backwards
220
+ *
221
+ * @function parseNum
222
+ * @param {String} inputStr - Any String
223
+ * @param {Number} startIndex - Index to begin parsing
224
+ */
225
+ parseNum: function parseNum(inputStr, startIndex) {
226
+ let count = '';
227
+ let currChar;
228
+ let start = startIndex;
229
+ while (currChar !== ' ') {
230
+ currChar = inputStr.charAt(start);
231
+ count = currChar + count;
232
+ start -= 1;
233
+ }
234
+ return parseInt(count, 10);
235
+ },
236
+
237
+ /**
238
+ * @summary Parses a mocha test result and returns the count of passing and failing tests
239
+ *
240
+ * @function getTestCount
241
+ * @param {String} testStr - Output from mocha test
242
+ */
243
+ getTestCount: function getTestCount(testStr) {
244
+ const passIndex = testStr.search('passing');
245
+ const failIndex = testStr.search('failing');
246
+ const passCount = passIndex >= 0 ? this.parseNum(testStr, passIndex - 2) : 0;
247
+ const failCount = failIndex >= 0 ? this.parseNum(testStr, failIndex - 2) : 0;
248
+ return { passCount, failCount };
249
+ },
250
+
251
+ /**
252
+ * @summary remove package-lock.json and node_modules directory if exists
253
+ * run npm install and print result to stdout
254
+ */
255
+ npmInstall: function npmInstall() {
256
+ fs.removeSync('../package-lock.json');
257
+ fs.removeSync('../node_modules/');
258
+ console.log('Run npm install ...');
259
+ this.systemSync('npm install');
260
+ },
261
+
262
+ /**
263
+ * @summary run lint, unit test and integration test
264
+ * print result to stdout
265
+ */
266
+ runTest: function runTest() {
267
+ this.systemSync('npm run lint:errors');
268
+ this.systemSync('npm run test:unit');
269
+ this.systemSync('npm run test:integration');
270
+ },
271
+
272
+ /**
273
+ * @summary run basicget with mocha
274
+ * @param {boolean} scriptFlag - whether the function is ran from a script
275
+ * print result to stdout
276
+ * returns mocha test results otherwise
277
+ */
278
+ runBasicGet: function runBasicGet(scriptFlag) {
279
+ const testPath = path.resolve(__dirname, '..', 'test/integration/adapterTestBasicGet.js');
280
+ return this.systemSync(`mocha ${testPath} --exit`, !scriptFlag);
281
+ },
282
+
283
+ /**
284
+ * @summary run connectivity with mocha
285
+ * @param {String} host - Host url to run healthcheck
286
+ * @param {boolean} scriptFlag - Whether the function is ran from a script
287
+ * print result to stdout if ran from script
288
+ * returns mocha test results otherwise
289
+ */
290
+ runConnectivity: function runConnectivity(host, scriptFlag) {
291
+ let testPath = 'test/integration/adapterTestConnectivity.js';
292
+ let executable = 'mocha';
293
+ if (!scriptFlag) {
294
+ testPath = path.resolve(__dirname, '..', testPath);
295
+ executable = path.join(__dirname, '..', 'node_modules/mocha/bin/mocha');
296
+ }
297
+ return this.systemSync(`${executable} ${testPath} --HOST=${host} --timeout 10000 --exit`, !scriptFlag);
298
+ },
299
+
300
+ /**
301
+ * @summary create Adapter property
302
+ *
303
+ * @function createAdapter
304
+ * @param {Object} pronghornProps - decrypted 'properties.json' from IAP root directory
305
+ * @param {Object} profileItem - pronghorn props saved in database
306
+ * @param {Object} adapterPronghorn - ./pronghorn.json in adapter dir
307
+ * @param {Object} sampleProperties - './sampleProperties.json' in adapter dir
308
+ */
309
+ createAdapter: function createAdapter(pronghornProps, profileItem, sampleProperties, adapterPronghorn) {
310
+ const iapDir = this.getIAPHome();
311
+ const packageFile = path.join(iapDir, 'package.json');
312
+ const info = JSON.parse(fs.readFileSync(packageFile));
313
+ const version = parseInt(info.version.split('.')[0], 10);
314
+
315
+ let adapter = {};
316
+ if (version >= 2020) {
317
+ adapter = {
318
+ isEncrypted: pronghornProps.pathProps.encrypted,
319
+ model: adapterPronghorn.id,
320
+ name: sampleProperties.id,
321
+ type: adapterPronghorn.type,
322
+ properties: sampleProperties,
323
+ loggerProps: profileItem.loggerProps
324
+ };
325
+ } else {
326
+ adapter = {
327
+ mongoProps: pronghornProps.mongoProps,
328
+ isEncrypted: pronghornProps.pathProps.encrypted,
329
+ model: adapterPronghorn.id,
330
+ name: sampleProperties.id,
331
+ type: adapterPronghorn.type,
332
+ properties: sampleProperties,
333
+ redisProps: profileItem.redisProps,
334
+ loggerProps: profileItem.loggerProps,
335
+ rabbitmq: profileItem.rabbitmq
336
+ };
337
+ adapter.mongoProps.pdb = true;
338
+ }
339
+
340
+ adapter.loggerProps.log_filename = `adapter-${adapter.name}.log`;
341
+ return adapter;
342
+ },
343
+
344
+ getPronghornProps: function getPronghornProps() {
345
+ const iapDir = this.getIAPHome();
346
+ console.log('Retrieving properties.json file...');
347
+ const rawProps = require(path.join(iapDir, 'properties.json'));
348
+ console.log('Decrypting properties...');
349
+ const pronghornProps = this.decryptProperties(rawProps, iapDir);
350
+ console.log('Found properties.\n');
351
+ return pronghornProps;
352
+ },
353
+
354
+ getAllAdapterInstances: async function getAllAdapterInstances() {
355
+ const database = await this.getIAPDatabaseConnection();
356
+ const { name } = require(path.join(__dirname, '..', 'package.json'));
357
+ const query = { model: name };
358
+ const options = { projection: { name: 1 } };
359
+ const adapterInstancesNames = await database.collection(this.SERVICE_CONFIGS_COLLECTION).find(
360
+ query,
361
+ options
362
+ ).toArray();
363
+ return adapterInstancesNames;
364
+ },
365
+
366
+ // get database connection and existing adapter config
367
+ getAdapterConfig: async function getAdapterConfig(adapterId) {
368
+ const database = await this.getIAPDatabaseConnection();
369
+ const { name } = require(path.join(__dirname, '..', 'package.json'));
370
+ let query = {};
371
+ if (!adapterId) {
372
+ query = { model: name };
373
+ } else {
374
+ query = { _id: adapterId };
375
+ }
376
+ const serviceItem = await database.collection(this.SERVICE_CONFIGS_COLLECTION).findOne(
377
+ query
378
+ );
379
+ const pronghornProps = await this.getPronghornProps();
380
+ return { database, serviceItem, pronghornProps };
381
+ },
382
+
383
+ /**
384
+ * @summary return async healthcheck result as a Promise
385
+ *
386
+ * @function request
387
+ * @param {Adapter} a - Adapter instance
388
+ */
389
+ request: function request(a) {
390
+ return new Promise((resolve, reject) => {
391
+ a.healthCheck(null, (data) => {
392
+ if (!data) reject(new Error('healthCheckEndpoint failed'));
393
+ resolve(data);
394
+ });
395
+ });
396
+ },
397
+
398
+ /**
399
+ * @summary deal with healthcheck response returned from adapter instace
400
+ *
401
+ * @function healthCheck
402
+ * @param {Adapter} a - Adapter instance
403
+ */
404
+ healthCheck: async function healthCheck(a) {
405
+ const result = await this.request(a)
406
+ .then((res) => {
407
+ console.log('healthCheckEndpoint OK');
408
+ return res;
409
+ })
410
+ .catch((error) => {
411
+ console.error(error.message);
412
+ return false;
413
+ });
414
+ return result;
415
+ },
416
+
417
+ /**
418
+ * @summary Obtain the IAP installation directory depending on how adapter is used:
419
+ * by IAP, or by npm run CLI interface
420
+ * @returns IAP installation directory or null if adapter running without IAP
421
+ * @function getIAPHome
422
+ */
423
+ getIAPHome: function getIAPHome() {
424
+ let IAPHomePath = null;
425
+ // check if adapter started via IAP, use path injected by core
426
+ if (process.env.iap_home) IAPHomePath = process.env.iap_home;
427
+ // check if adapter started via CLI `npm run <command>` so we have to be located under
428
+ // <IAP_HOME>/node_modules/@itentialopensource/<adapter_name>/ directory
429
+ const currentExecutionPath = this.getCurrentExecutionPath();
430
+ if (currentExecutionPath.indexOf('/node_modules') >= 0) {
431
+ [IAPHomePath] = currentExecutionPath.split('/node_modules');
432
+ }
433
+ return IAPHomePath;
434
+ },
435
+
436
+ /**
437
+ * @summary get current execution path without resolving symbolic links,
438
+ * use `pwd` command wihout '-P' option (resolving symlinks) https://linux.die.net/man/1/pwd
439
+ * @returns
440
+ * @function getCurrentExecutionPAth
441
+ */
442
+ getCurrentExecutionPath: function getCurrentExecutionPAth() {
443
+ const { stdout } = this.systemSync('pwd', true);
444
+ return stdout.trim();
445
+ },
446
+
447
+ /**
448
+ * @summary checks if command executed from <IAP_HOME>/node_modules/@itentialopensource/<adapter_name>/ location
449
+ * @returns true if command executed under <IAP_HOME>/node_modules/@itentialopensource/<adapter_name>/ path
450
+ * @function areWeUnderIAPinstallationDirectory
451
+ */
452
+ areWeUnderIAPinstallationDirectory: function areWeUnderIAPinstallationDirectory() {
453
+ return path.join(this.getCurrentExecutionPath(), '../../..') === this.getIAPHome();
454
+ },
455
+
456
+ getIAPDatabaseConnection: async function getIAPDatabaseConnection() {
457
+ const pronghornProps = await this.getPronghornProps();
458
+ const database = await this.connect(pronghornProps);
459
+ return database;
460
+ },
461
+
462
+ /**
463
+ * @summary connect to mongodb
464
+ *
465
+ * @function connect
466
+ * @param {Object} properties - pronghornProps
467
+ */
468
+ connect: async function connect(properties) {
469
+ let dbConnectionProperties = {};
470
+ if (properties.mongoProps) {
471
+ dbConnectionProperties = properties.mongoProps;
472
+ } else if (properties.mongo) {
473
+ if (properties.mongo.url) {
474
+ dbConnectionProperties.url = properties.mongo.url;
475
+ } else {
476
+ dbConnectionProperties.url = `mongodb://${properties.mongo.host}:${properties.mongo.port}`;
477
+ }
478
+ dbConnectionProperties.db = properties.mongo.database;
479
+ }
480
+ if (!dbConnectionProperties.url || !dbConnectionProperties.db) {
481
+ throw new Error('Mongo properties are not specified in IAP configuration!');
482
+ }
483
+ const iapDir = this.getIAPHome();
484
+ const { MongoDBConnection } = require(path.join(iapDir, 'node_modules/@itential/database'));
485
+ const connection = new MongoDBConnection(dbConnectionProperties);
486
+ const database = await connection.connect(true);
487
+ return database;
488
+ }
489
+
490
+ };