@itentialopensource/adapter-microsoft_office365 0.6.1 → 0.8.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.
package/CHANGELOG.md CHANGED
@@ -1,4 +1,12 @@
1
1
 
2
+ ## 0.8.0 [02-13-2026]
3
+
4
+ * minor/auto-migrate/20260213-112338
5
+
6
+ See merge request itentialopensource/adapters/adapter-microsoft_office365!31
7
+
8
+ ---
9
+
2
10
  ## 0.3.4 [10-15-2024]
3
11
 
4
12
  * Changes made at 2024.10.14_20:32PM
package/PROPERTIES.md CHANGED
@@ -54,7 +54,8 @@ This section defines **all** the properties that are available for the adapter,
54
54
  "healthcheck_on_timeout": false,
55
55
  "return_raw": false,
56
56
  "archiving": false,
57
- "return_request": false
57
+ "return_request": false,
58
+ "keep_alive_interval": 0
58
59
  },
59
60
  "ssl": {
60
61
  "ecdhCurve": "",
@@ -403,6 +404,10 @@ The request section defines properties to help handle requests.
403
404
  <td style="padding:15px">return_request</td>
404
405
  <td style="padding:15px">Optional flag. Default is false. Will return the actual request that is made including headers. This should only be used during debugging issues as there could be credentials in the actual request.</td>
405
406
  </tr>
407
+ <tr>
408
+ <td style="padding:15px">keep_alive_interval</td>
409
+ <td style="padding:15px">Optional. TCP keep-alive interval in seconds for long-lived connections. Set to 0 to disable keep-alive (default). When enabled, minimum value is 30 seconds.</td>
410
+ </tr>
406
411
  </table>
407
412
  <br>
408
413
 
package/TAB2.md CHANGED
@@ -139,7 +139,8 @@ Sample Properties can be used to help you configure the adapter in the Itential
139
139
  "healthcheck_on_timeout": true,
140
140
  "return_raw": false,
141
141
  "archiving": false,
142
- "return_request": false
142
+ "return_request": false,
143
+ "keep_alive_interval": 0
143
144
  },
144
145
  "proxy": {
145
146
  "enabled": false,
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@itentialopensource/adapter-microsoft_office365",
3
- "version": "0.6.1",
3
+ "version": "0.8.0",
4
4
  "description": "This adapter integrates with system described as: odataServiceForNamespaceMicrosoft.graph.",
5
5
  "main": "adapter.js",
6
6
  "systemName": "Microsoft Office 365",
7
- "wizardVersion": "3.8.0",
8
- "engineVersion": "1.79.2",
7
+ "wizardVersion": "3.12.1",
8
+ "engineVersion": "1.82.5",
9
9
  "adapterType": "http",
10
10
  "scripts": {
11
11
  "preinstall": "node utils/setup.js",
@@ -40,8 +40,8 @@
40
40
  ],
41
41
  "license": "Apache-2.0",
42
42
  "engines": {
43
- "node": ">= 14.0.0",
44
- "npm": ">= 6.0.0"
43
+ "node": ">= 18.18.0",
44
+ "npm": ">= 9.8.1"
45
45
  },
46
46
  "repository": {
47
47
  "type": "git",
@@ -50,14 +50,14 @@
50
50
  "author": "Itential",
51
51
  "homepage": "https://gitlab.com/itentialopensource/adapters/adapter-microsoft_office365#readme",
52
52
  "dependencies": {
53
- "@itentialopensource/adapter-utils": "6.0.3",
53
+ "@itentialopensource/adapter-utils": "6.1.14",
54
54
  "acorn": "8.14.1",
55
55
  "ajv": "8.17.1",
56
- "axios": "1.12.2",
56
+ "axios": "1.13.5",
57
57
  "commander": "11.1.0",
58
58
  "fs-extra": "11.3.0",
59
59
  "json-query": "2.2.2",
60
- "mocha": "10.8.2",
60
+ "mocha": "11.3.0",
61
61
  "mocha-param": "2.0.1",
62
62
  "mongodb": "4.17.2",
63
63
  "ping": "0.4.4",
@@ -61,7 +61,7 @@
61
61
  "boolean",
62
62
  "string"
63
63
  ],
64
- "description": "When true the metrics collected by the adapter will be stored in mongo or on the filesystem",
64
+ "description": "When true the metrics collected by the adapter will be stored in mongo or in the adapter. If a full path is provided, metrics will be saved in the path provided.",
65
65
  "default": false
66
66
  },
67
67
  "stub": {
@@ -458,7 +458,7 @@
458
458
  "type": "integer",
459
459
  "description": "How often the healthcheck should run (in milliseconds).",
460
460
  "default": 300000,
461
- "minimum": 60000,
461
+ "minimum": 30000,
462
462
  "maximum": 3600000
463
463
  },
464
464
  "protocol": {
@@ -693,6 +693,13 @@
693
693
  "type": "boolean",
694
694
  "description": "This property turns on returning the response information - need to be carefull in case credentials are in the path",
695
695
  "default": false
696
+ },
697
+ "keep_alive_interval": {
698
+ "type": "integer",
699
+ "description": "TCP keep-alive interval in milliseconds to prevent connection timeout during long-running requests. 0 = disabled (default). Minimum value when enabled is 30000ms (30 seconds). Values below 30000ms will be auto-corrected to 30000ms with a warning.",
700
+ "default": 0,
701
+ "minimum": 0,
702
+ "maximum": 3600000
696
703
  }
697
704
  },
698
705
  "required": [
@@ -1104,7 +1111,7 @@
1104
1111
  },
1105
1112
  "requestFields": {
1106
1113
  "type": "object",
1107
- "description": "The json object with response fields of the call to getDevice",
1114
+ "description": "The json object with request fields of the call to getDevice",
1108
1115
  "additionalProperties": {
1109
1116
  "type": [
1110
1117
  "string",
@@ -1247,7 +1254,7 @@
1247
1254
  },
1248
1255
  "requestFields": {
1249
1256
  "type": "object",
1250
- "description": "The json object with response fields of the call to getDevice",
1257
+ "description": "The json object with request fields of the call to getDevice",
1251
1258
  "additionalProperties": {
1252
1259
  "type": [
1253
1260
  "string",
@@ -1358,7 +1365,7 @@
1358
1365
  },
1359
1366
  "requestFields": {
1360
1367
  "type": "object",
1361
- "description": "The json object with response fields of the call to getDevice",
1368
+ "description": "The json object with request fields of the call to getDevice",
1362
1369
  "additionalProperties": {
1363
1370
  "type": [
1364
1371
  "string",
@@ -1454,7 +1461,7 @@
1454
1461
  },
1455
1462
  "requestFields": {
1456
1463
  "type": "object",
1457
- "description": "The json object with response fields of the call to getDevice",
1464
+ "description": "The json object with request fields of the call to getDevice",
1458
1465
  "additionalProperties": {
1459
1466
  "type": [
1460
1467
  "string",
@@ -1539,7 +1546,7 @@
1539
1546
  },
1540
1547
  "requestFields": {
1541
1548
  "type": "object",
1542
- "description": "The json object with response fields of the call to getDevice",
1549
+ "description": "The json object with request fields of the call to getDevice",
1543
1550
  "additionalProperties": {
1544
1551
  "type": [
1545
1552
  "string",
@@ -1622,12 +1629,12 @@
1622
1629
  "properties": {
1623
1630
  "path": {
1624
1631
  "type": "string",
1625
- "description": "The fully qualified path of the call to getDevice (e.g. /rest/api/device/{deviceid})",
1632
+ "description": "The fully qualified path of the call to populate the cache (e.g. /rest/api/devices)",
1626
1633
  "default": ""
1627
1634
  },
1628
1635
  "method": {
1629
1636
  "type": "string",
1630
- "description": "The method of the call to getDevice",
1637
+ "description": "The method of the call to populate the cache",
1631
1638
  "default": "GET"
1632
1639
  },
1633
1640
  "pagination": {
@@ -1664,7 +1671,7 @@
1664
1671
  },
1665
1672
  "query": {
1666
1673
  "type": "object",
1667
- "description": "The json object with query parameters of the call to getDevice",
1674
+ "description": "The json object with query parameters of the call to populate the cache",
1668
1675
  "additionalProperties": {
1669
1676
  "type": [
1670
1677
  "string",
@@ -1674,7 +1681,7 @@
1674
1681
  },
1675
1682
  "body": {
1676
1683
  "type": "object",
1677
- "description": "The json object with body of the call to getDevice",
1684
+ "description": "The json object with body of the call to populate the cache",
1678
1685
  "additionalProperties": {
1679
1686
  "type": [
1680
1687
  "string",
@@ -1684,7 +1691,7 @@
1684
1691
  },
1685
1692
  "headers": {
1686
1693
  "type": "object",
1687
- "description": "The json object with headers of the call to getDevice",
1694
+ "description": "The json object with headers of the call to populate the cache",
1688
1695
  "additionalProperties": {
1689
1696
  "type": [
1690
1697
  "string",
@@ -1703,7 +1710,7 @@
1703
1710
  },
1704
1711
  "requestFields": {
1705
1712
  "type": "object",
1706
- "description": "The json object with response fields of the call to getDevice",
1713
+ "description": "The json object with request fields of the call to populate the cache",
1707
1714
  "additionalProperties": {
1708
1715
  "type": [
1709
1716
  "string",
@@ -1719,7 +1726,7 @@
1719
1726
  },
1720
1727
  "responseFields": {
1721
1728
  "type": "object",
1722
- "description": "The json object with response fields of the call to getDevice",
1729
+ "description": "The json object with response fields of the call to populate the cache",
1723
1730
  "additionalProperties": {
1724
1731
  "type": [
1725
1732
  "string",
@@ -1760,4 +1767,4 @@
1760
1767
  }
1761
1768
  }
1762
1769
  }
1763
- }
1770
+ }
@@ -0,0 +1,120 @@
1
+ {
2
+ "errors": [],
3
+ "statistics": [
4
+ {
5
+ "owner": "errorJson",
6
+ "description": "New adapter errors available for use",
7
+ "value": 0
8
+ },
9
+ {
10
+ "owner": "errorJson",
11
+ "description": "Adapter errors no longer available for use",
12
+ "value": 0
13
+ },
14
+ {
15
+ "owner": "errorJson",
16
+ "description": "Adapter errors that have been updated (e.g. recommendation changes)",
17
+ "value": 31
18
+ },
19
+ {
20
+ "owner": "packageJson",
21
+ "description": "Number of production dependencies",
22
+ "value": 15
23
+ },
24
+ {
25
+ "owner": "packageJson",
26
+ "description": "Number of development dependencies",
27
+ "value": 6
28
+ },
29
+ {
30
+ "owner": "packageJson",
31
+ "description": "Number of npm scripts",
32
+ "value": 17
33
+ },
34
+ {
35
+ "owner": "packageJson",
36
+ "description": "Runtime Library dependency",
37
+ "value": "6.1.7"
38
+ },
39
+ {
40
+ "owner": "propertiesSchemaJson",
41
+ "description": "Adapter properties defined in the propertiesSchema file",
42
+ "value": 83
43
+ },
44
+ {
45
+ "owner": "markdown",
46
+ "description": "Number of lines in the README.md",
47
+ "value": 345
48
+ },
49
+ {
50
+ "owner": "markdown",
51
+ "description": "Number of lines in the SUMMARY.md",
52
+ "value": 9
53
+ },
54
+ {
55
+ "owner": "markdown",
56
+ "description": "Number of lines in the PROPERTIES.md",
57
+ "value": 682
58
+ },
59
+ {
60
+ "owner": "markdown",
61
+ "description": "Number of lines in the TROUBLESHOOT.md",
62
+ "value": 57
63
+ },
64
+ {
65
+ "owner": "markdown",
66
+ "description": "Number of lines in the ENHANCE.md",
67
+ "value": 70
68
+ },
69
+ {
70
+ "owner": "markdown",
71
+ "description": "Number of lines in the BROKER.md",
72
+ "value": 70
73
+ },
74
+ {
75
+ "owner": "unitTestJS",
76
+ "description": "Number of lines of code in unit tests",
77
+ "value": 1768
78
+ },
79
+ {
80
+ "owner": "unitTestJS",
81
+ "description": "Number of unit tests",
82
+ "value": 88
83
+ },
84
+ {
85
+ "owner": "integrationTestJS",
86
+ "description": "Number of lines of code in integration tests",
87
+ "value": 700
88
+ },
89
+ {
90
+ "owner": "integrationTestJS",
91
+ "description": "Number of integration tests",
92
+ "value": 19
93
+ },
94
+ {
95
+ "owner": "staticFile",
96
+ "description": "Number of lines of code in adapterBase.js",
97
+ "value": 1527
98
+ },
99
+ {
100
+ "owner": "staticFile",
101
+ "description": "Number of static files added",
102
+ "value": 37
103
+ },
104
+ {
105
+ "owner": "Overall",
106
+ "description": "Total lines of Code",
107
+ "value": 3995
108
+ },
109
+ {
110
+ "owner": "Overall",
111
+ "description": "Total Tests",
112
+ "value": 107
113
+ },
114
+ {
115
+ "owner": "Overall",
116
+ "description": "Total Files",
117
+ "value": 6
118
+ }
119
+ ]
120
+ }
@@ -0,0 +1,120 @@
1
+ {
2
+ "errors": [],
3
+ "statistics": [
4
+ {
5
+ "owner": "errorJson",
6
+ "description": "New adapter errors available for use",
7
+ "value": 0
8
+ },
9
+ {
10
+ "owner": "errorJson",
11
+ "description": "Adapter errors no longer available for use",
12
+ "value": 0
13
+ },
14
+ {
15
+ "owner": "errorJson",
16
+ "description": "Adapter errors that have been updated (e.g. recommendation changes)",
17
+ "value": 31
18
+ },
19
+ {
20
+ "owner": "packageJson",
21
+ "description": "Number of production dependencies",
22
+ "value": 15
23
+ },
24
+ {
25
+ "owner": "packageJson",
26
+ "description": "Number of development dependencies",
27
+ "value": 6
28
+ },
29
+ {
30
+ "owner": "packageJson",
31
+ "description": "Number of npm scripts",
32
+ "value": 17
33
+ },
34
+ {
35
+ "owner": "packageJson",
36
+ "description": "Runtime Library dependency",
37
+ "value": "6.1.14"
38
+ },
39
+ {
40
+ "owner": "propertiesSchemaJson",
41
+ "description": "Adapter properties defined in the propertiesSchema file",
42
+ "value": 83
43
+ },
44
+ {
45
+ "owner": "markdown",
46
+ "description": "Number of lines in the README.md",
47
+ "value": 345
48
+ },
49
+ {
50
+ "owner": "markdown",
51
+ "description": "Number of lines in the SUMMARY.md",
52
+ "value": 9
53
+ },
54
+ {
55
+ "owner": "markdown",
56
+ "description": "Number of lines in the PROPERTIES.md",
57
+ "value": 682
58
+ },
59
+ {
60
+ "owner": "markdown",
61
+ "description": "Number of lines in the TROUBLESHOOT.md",
62
+ "value": 57
63
+ },
64
+ {
65
+ "owner": "markdown",
66
+ "description": "Number of lines in the ENHANCE.md",
67
+ "value": 70
68
+ },
69
+ {
70
+ "owner": "markdown",
71
+ "description": "Number of lines in the BROKER.md",
72
+ "value": 70
73
+ },
74
+ {
75
+ "owner": "unitTestJS",
76
+ "description": "Number of lines of code in unit tests",
77
+ "value": 1768
78
+ },
79
+ {
80
+ "owner": "unitTestJS",
81
+ "description": "Number of unit tests",
82
+ "value": 88
83
+ },
84
+ {
85
+ "owner": "integrationTestJS",
86
+ "description": "Number of lines of code in integration tests",
87
+ "value": 700
88
+ },
89
+ {
90
+ "owner": "integrationTestJS",
91
+ "description": "Number of integration tests",
92
+ "value": 19
93
+ },
94
+ {
95
+ "owner": "staticFile",
96
+ "description": "Number of lines of code in adapterBase.js",
97
+ "value": 1527
98
+ },
99
+ {
100
+ "owner": "staticFile",
101
+ "description": "Number of static files added",
102
+ "value": 37
103
+ },
104
+ {
105
+ "owner": "Overall",
106
+ "description": "Total lines of Code",
107
+ "value": 3995
108
+ },
109
+ {
110
+ "owner": "Overall",
111
+ "description": "Total Tests",
112
+ "value": 107
113
+ },
114
+ {
115
+ "owner": "Overall",
116
+ "description": "Total Files",
117
+ "value": 6
118
+ }
119
+ ]
120
+ }
@@ -84,7 +84,8 @@
84
84
  "healthcheck_on_timeout": true,
85
85
  "return_raw": false,
86
86
  "archiving": false,
87
- "return_request": false
87
+ "return_request": false,
88
+ "keep_alive_interval": 0
88
89
  },
89
90
  "proxy": {
90
91
  "enabled": false,
@@ -273,4 +274,4 @@
273
274
  "brokers": [],
274
275
  "logLevel": "none",
275
276
  "timeout": 120000
276
- }
277
+ }
@@ -280,10 +280,10 @@ describe('[unit] MicrosoftOffice365 Adapter Test', () => {
280
280
  assert.notEqual(null, packageDotJson.dependencies);
281
281
  assert.notEqual('', packageDotJson.dependencies);
282
282
  assert.equal('8.17.1', packageDotJson.dependencies.ajv);
283
- assert.equal('1.12.2', packageDotJson.dependencies.axios);
283
+ assert.equal('1.13.5', packageDotJson.dependencies.axios);
284
284
  assert.equal('11.1.0', packageDotJson.dependencies.commander);
285
285
  assert.equal('11.3.0', packageDotJson.dependencies['fs-extra']);
286
- assert.equal('10.8.2', packageDotJson.dependencies.mocha);
286
+ assert.equal('11.3.0', packageDotJson.dependencies.mocha);
287
287
  assert.equal('2.0.1', packageDotJson.dependencies['mocha-param']);
288
288
  assert.equal('0.4.4', packageDotJson.dependencies.ping);
289
289
  assert.equal('1.4.10', packageDotJson.dependencies['readline-sync']);
@@ -19,17 +19,14 @@ function createObjectForFunction(
19
19
  workflow
20
20
  ) {
21
21
  const funcObject = {};
22
- // if the entity path is not set, then the object is not created.
23
- if (entityPath !== undefined) {
24
- funcObject.method_signature = `${funcName}(${funcArgs.join(', ')})`;
25
- funcObject.path = entityPath;
26
- if (description === undefined) {
27
- funcObject.description = '';
28
- funcObject.workflow = 'No';
29
- } else {
30
- funcObject.description = description;
31
- funcObject.workflow = workflow;
32
- }
22
+ funcObject.method_signature = `${funcName}(${funcArgs.join(', ')})`;
23
+ funcObject.path = entityPath !== undefined ? entityPath : '';
24
+ if (description === undefined) {
25
+ funcObject.description = '';
26
+ funcObject.workflow = 'No';
27
+ } else {
28
+ funcObject.description = description;
29
+ funcObject.workflow = workflow;
33
30
  }
34
31
  return funcObject;
35
32
  }
@@ -77,7 +74,8 @@ function readFileUsingLib(filename, descriptionObj, workflowObj, functionList) {
77
74
  // parsing the file to get the function and class declarations.
78
75
  const aFileFuncArgs = acorn.parse(aFile, { ecmaVersion: 2020 });
79
76
 
80
- let callName = 'identifyRequest';
77
+ // Track all method names that can be called (identifyRequest + any proxy methods)
78
+ const allowedCallNames = new Set(['identifyRequest']);
81
79
  // Looping through all the declarations parsed:
82
80
  aFileFuncArgs.body.forEach((e) => {
83
81
  // Getting only the class declaration as it has our required functions.
@@ -103,9 +101,10 @@ function readFileUsingLib(filename, descriptionObj, workflowObj, functionList) {
103
101
  method.value.body.body.forEach((statement) => {
104
102
  recurseCallExpressions(statement, callList);
105
103
  });
104
+ // Find calls to identifyRequest OR any discovered proxy methods
106
105
  const requests = [];
107
106
  for (let i = 0; i < callList.length; i += 1) {
108
- if (callList[i].callee.property && callList[i].callee.property.name === callName) {
107
+ if (callList[i].callee.property && allowedCallNames.has(callList[i].callee.property.name)) {
109
108
  requests.push(callList[i]);
110
109
  }
111
110
  }
@@ -114,34 +113,60 @@ function readFileUsingLib(filename, descriptionObj, workflowObj, functionList) {
114
113
  if (expr.arguments.length < 2) {
115
114
  throw new Error(`Bad inputs in method ${funcName}`);
116
115
  }
117
- const entity = expr.arguments[0].value;
118
- const actionName = expr.arguments[1].value;
119
- if (expr !== undefined && (expr.arguments[0].type !== 'Literal' || expr.arguments[1].type !== 'Literal')) {
120
- const param1 = method.value.params[0];
121
- const param2 = method.value.params[1];
122
- if (param1.type !== 'Identifier' || param2.type !== 'Identifier'
123
- || expr.arguments[0].type !== 'Identifier' || expr.arguments[1].type !== 'Identifier'
124
- || param1.name !== expr.arguments[0].name || param2.name !== expr.arguments[1].name) {
125
- throw new Error(`identifyRequest proxy method ${funcName} unknown format`);
126
- } else if (callName !== 'identifyRequest') {
127
- throw new Error(`MethodDocumentor not yet programmed to handle multiple helper methods: 1) ${callName}, 2) ${funcName}`);
116
+
117
+ const arg0Type = expr.arguments[0].type;
118
+ const arg1Type = expr.arguments[1].type;
119
+
120
+ let entityPath;
121
+
122
+ if (arg0Type === 'Literal' && arg1Type === 'Literal') {
123
+ const entity = expr.arguments[0].value;
124
+ const actionName = expr.arguments[1].value;
125
+ entityPath = getPathFromEntity(entity, actionName);
126
+ } else {
127
+ // Non-standard format: anything that's not both literals
128
+ // Special handling for proxy methods (both args are identifiers matching first 2 params)
129
+ if (arg0Type === 'Identifier' && arg1Type === 'Identifier') {
130
+ const param1 = method.value.params[0];
131
+ const param2 = method.value.params[1];
132
+ const arg0Name = expr.arguments[0].name;
133
+ const arg1Name = expr.arguments[1].name;
134
+
135
+ // Check if this is a valid proxy method
136
+ const isValidProxy = param1 && param2
137
+ && param1.type === 'Identifier' && param2.type === 'Identifier'
138
+ && param1.name === arg0Name && param2.name === arg1Name;
139
+
140
+ // Only process valid proxy methods
141
+ if (isValidProxy) {
142
+ const calledMethod = expr.callee.property.name;
143
+
144
+ // Skip nested proxies (proxies calling other proxies)
145
+ if (calledMethod !== 'identifyRequest') {
146
+ console.log(`Skipping nested proxy method: ${funcName} (calls ${calledMethod})`);
147
+ return;
148
+ }
149
+
150
+ // First-level proxy: calls identifyRequest directly
151
+ // Add this proxy to the set so other methods can call it
152
+ allowedCallNames.add(funcName);
153
+ }
128
154
  }
129
- callName = funcName;
155
+
156
+ // All non-standard formats get documented without path
157
+ entityPath = undefined;
130
158
  }
131
- const entityPath = getPathFromEntity(entity, actionName);
132
159
 
133
160
  // Creating and storing the object for the method.
134
- if (entityPath !== undefined) {
135
- functionList.push(
136
- createObjectForFunction(
137
- funcName,
138
- funcArgs,
139
- entityPath,
140
- descriptionObj[funcName],
141
- workflowObj[funcName]
142
- )
143
- );
144
- }
161
+ functionList.push(
162
+ createObjectForFunction(
163
+ funcName,
164
+ funcArgs,
165
+ entityPath,
166
+ descriptionObj[funcName],
167
+ workflowObj[funcName]
168
+ )
169
+ );
145
170
  }
146
171
  });
147
172
  }