@itentialopensource/adapter-microsoft_graph 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ };