codeapp-js 0.1.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/codeApp/dist/codeapp.js +552 -78
- package/codeApp/dist/power-apps-data.js +2531 -2531
- package/dev files/outlook.js +218 -9
- package/examples/combined demo/dist/codeapp.js +1098 -0
- package/examples/combined demo/dist/index.js +69 -114
- package/examples/combined demo/dist/power-apps-data.js +646 -170
- package/examples/combined demo/power.config.json +42 -42
- package/examples/dataverse Demo/dist/codeapp.js +1085 -0
- package/examples/dataverse Demo/dist/index.html +54 -54
- package/examples/dataverse Demo/dist/index.js +82 -70
- package/examples/dataverse Demo/dist/power-apps-data.js +551 -170
- package/examples/dataverse Demo/power.config.json +34 -34
- package/examples/dataverse Demo/readme.md +79 -79
- package/examples/groups Demo/dist/codeapp.js +1085 -0
- package/examples/groups Demo/dist/index.js +27 -27
- package/examples/groups Demo/dist/power-apps-data.js +551 -170
- package/examples/kanban/dist/dataverse.js +94 -94
- package/examples/kanban/dist/environmentVar.js +55 -55
- package/examples/kanban/dist/office365groups.js +97 -97
- package/examples/kanban/dist/office365users.js +169 -169
- package/examples/kanban/dist/outlook.js +162 -162
- package/examples/kanban/dist/power-apps-data.js +560 -138
- package/examples/kanban/dist/sharepoint.js +339 -339
- package/examples/myProfile/dist/index.html +184 -184
- package/examples/myProfile/dist/index.js +141 -141
- package/examples/myProfile/dist/office365users.js +169 -169
- package/examples/myProfile/dist/power-apps-data.js +560 -138
- package/examples/myProfile/power.config.json +22 -22
- package/examples/myProfile/readme.md +79 -79
- package/examples/outlook Demo/dist/codeapp.js +1085 -0
- package/examples/outlook Demo/dist/index.html +35 -35
- package/examples/outlook Demo/dist/index.js +170 -166
- package/examples/outlook Demo/dist/outlook.js +121 -121
- package/examples/outlook Demo/dist/power-apps-data.js +551 -170
- package/examples/outlook Demo/dist/styles.css +84 -84
- package/examples/outlook Demo/readme.md +82 -82
- package/examples/outlook Demo2/OutlookDemo_1_0_0_1.zip +0 -0
- package/examples/outlook Demo2/agent/decision-log.md +7 -0
- package/examples/outlook Demo2/dist/codeapp.js +1334 -0
- package/examples/outlook Demo2/dist/icon-512.png +0 -0
- package/examples/outlook Demo2/dist/index.html +98 -0
- package/examples/outlook Demo2/dist/index.js +346 -0
- package/examples/outlook Demo2/dist/power-apps-data.js +3007 -0
- package/examples/outlook Demo2/dist/styles.css +639 -0
- package/examples/outlook Demo2/power.config.json +23 -0
- package/examples/outlook Demo2/src/generated/index.ts +14 -0
- package/examples/outlook Demo2/src/generated/models/Office365GroupsModel.ts +363 -0
- package/examples/outlook Demo2/src/generated/models/Office365OutlookModel.ts +2046 -0
- package/examples/outlook Demo2/src/generated/models/Office365UsersModel.ts +254 -0
- package/examples/outlook Demo2/src/generated/services/Office365GroupsService.ts +326 -0
- package/examples/outlook Demo2/src/generated/services/Office365OutlookService.ts +2476 -0
- package/examples/outlook Demo2/src/generated/services/Office365UsersService.ts +358 -0
- package/examples/planning Poker/.vscode/settings.json +4 -4
- package/examples/planning Poker/additional files/customizations (tables).xml +6428 -6428
- package/examples/planning Poker/additional files/dataverse-tables.json +165 -165
- package/examples/planning Poker/additional files/readme.md +122 -122
- package/examples/planning Poker/dist/dataverse.js +78 -78
- package/examples/planning Poker/dist/index.html +198 -198
- package/examples/planning Poker/dist/index.js +954 -954
- package/examples/planning Poker/dist/power-apps-data.js +560 -138
- package/examples/planning Poker/dist/styles.css +815 -815
- package/examples/sharePoint Demo/agent/decision-log.md +5 -5
- package/examples/sharePoint Demo/dist/codeapp.js +1085 -0
- package/examples/sharePoint Demo/dist/index.js +44 -51
- package/examples/sharePoint Demo/dist/power-apps-data.js +551 -170
- package/examples/sharePoint Demo/power.config.json +22 -22
- package/examples/solution explorer/agent/decision-log.md +27 -0
- package/examples/solution explorer/agent/mockup-01-swiss-grid.html +452 -0
- package/examples/solution explorer/agent/mockup-02-dark-glass.html +496 -0
- package/examples/solution explorer/agent/mockup-03-paper-console.html +510 -0
- package/examples/solution explorer/agent/mockup-04-neon-noir.html +546 -0
- package/examples/solution explorer/agent/mockup-05-zen-garden.html +534 -0
- package/examples/solution explorer/dist/codeapp.js +1098 -0
- package/examples/solution explorer/dist/icon-512.png +0 -0
- package/examples/solution explorer/dist/index.html +80 -0
- package/examples/solution explorer/dist/index.js +735 -0
- package/examples/solution explorer/dist/power-apps-data.js +3007 -0
- package/examples/solution explorer/dist/styles.css +571 -0
- package/examples/solution explorer/power.config.json +151 -0
- package/examples/todo/dist/dataverse.js +64 -64
- package/examples/todo/dist/index.html +75 -75
- package/examples/todo/dist/index.js +8 -8
- package/examples/todo/dist/power-apps-data.js +560 -138
- package/examples/todo/dist/renderer.js +375 -375
- package/examples/todo/dist/styles.css +691 -691
- package/examples/todo/power.config.json +34 -34
- package/package.json +1 -8
- package/docs-mockups/atelier/index.html +0 -120
- package/docs-mockups/atelier/script.js +0 -23
- package/docs-mockups/atelier/styles.css +0 -361
- package/docs-mockups/field-guide/index.html +0 -112
- package/docs-mockups/field-guide/script.js +0 -20
- package/docs-mockups/field-guide/styles.css +0 -272
- package/docs-mockups/index.html +0 -80
- package/docs-mockups/maker-hub/index.html +0 -178
- package/docs-mockups/maker-hub/script.js +0 -20
- package/docs-mockups/maker-hub/styles.css +0 -404
- package/docs-mockups/script.js +0 -26
- package/docs-mockups/signal/index.html +0 -146
- package/docs-mockups/signal/script.js +0 -20
- package/docs-mockups/signal/styles.css +0 -314
- package/docs-mockups/styles.css +0 -287
- package/examples/combined demo/dist/dataverse.js +0 -86
- package/examples/combined demo/dist/environmentVar.js +0 -55
- package/examples/combined demo/dist/office365groups.js +0 -97
- package/examples/combined demo/dist/office365users.js +0 -169
- package/examples/combined demo/dist/outlook.js +0 -162
- package/examples/combined demo/dist/sharepoint.js +0 -339
- package/examples/dataverse Demo/dist/dataverse.js +0 -86
- package/examples/groups Demo/dist/dataverse.js +0 -86
- package/examples/groups Demo/dist/environmentVar.js +0 -55
- package/examples/groups Demo/dist/office365groups.js +0 -97
- package/examples/groups Demo/dist/office365users.js +0 -169
- package/examples/groups Demo/dist/outlook.js +0 -162
- package/examples/groups Demo/dist/sharepoint.js +0 -339
- package/examples/sharePoint Demo/dist/dataverse.js +0 -94
- package/examples/sharePoint Demo/dist/environmentVar.js +0 -55
- package/examples/sharePoint Demo/dist/office365groups.js +0 -97
- package/examples/sharePoint Demo/dist/office365users.js +0 -169
- package/examples/sharePoint Demo/dist/outlook.js +0 -162
- package/examples/sharePoint Demo/dist/sharepoint.js +0 -339
package/codeApp/dist/codeapp.js
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
import { getClient } from "
|
|
2
|
-
|
|
3
|
-
// ── All Table Definitions ──────────────────────────────────────
|
|
4
|
-
const ALL_DATA_SOURCES = {
|
|
5
|
-
environmentvariabledefinitions: { tableId: "", version: "", primaryKey: "environmentvariabledefinitionid", dataSourceType: "Dataverse", apis: {} },
|
|
6
|
-
environmentvariablevalues: { tableId: "", version: "", primaryKey: "environmentvariablevalueid", dataSourceType: "Dataverse", apis: {} },
|
|
7
|
-
};
|
|
1
|
+
import { getClient, getContext, callActionAsync } from "./power-apps-data.js";
|
|
8
2
|
|
|
9
3
|
// ── Initialize SDK & Client ────────────────────────────────────
|
|
10
4
|
let oSharedClient = null;
|
|
5
|
+
let oInitialDataSources = {};
|
|
6
|
+
|
|
7
|
+
// ── Set initial data sources (call before any API calls) ───────
|
|
8
|
+
export function initDataSources(oSources) {
|
|
9
|
+
return _dbgWrap('initDataSources', [oSources], function() {
|
|
10
|
+
oInitialDataSources = oSources || {};
|
|
11
|
+
oSharedClient = null;
|
|
12
|
+
});
|
|
13
|
+
}
|
|
11
14
|
|
|
12
15
|
function getSharedClient() {
|
|
13
16
|
if (!oSharedClient) {
|
|
14
|
-
oSharedClient = getClient(
|
|
17
|
+
oSharedClient = getClient(Object.assign({}, oInitialDataSources, oDataSources));
|
|
15
18
|
}
|
|
16
19
|
return oSharedClient;
|
|
17
20
|
}
|
|
@@ -25,8 +28,172 @@ function unwrapResult(result) {
|
|
|
25
28
|
return result && "data" in result ? result.data : result;
|
|
26
29
|
}
|
|
27
30
|
|
|
31
|
+
// ── Debugger ───────────────────────────────────────────────────
|
|
32
|
+
let _bDebugActive = false;
|
|
33
|
+
let _aDebugEntries = [];
|
|
34
|
+
let _eDebugPanel = null;
|
|
35
|
+
let _eDebugIcon = null;
|
|
36
|
+
let _eDebugList = null;
|
|
37
|
+
let _iDebugCounter = 0;
|
|
38
|
+
|
|
39
|
+
function _dbgWrap(sName, aArgs, fnBody) {
|
|
40
|
+
if (!_bDebugActive) return fnBody();
|
|
41
|
+
let oEntry = { iId: ++_iDebugCounter, sName: sName, aArgs: _dbgClone(aArgs), iTime: Date.now() };
|
|
42
|
+
_aDebugEntries.unshift(oEntry);
|
|
43
|
+
_dbgRenderEntry(oEntry, true);
|
|
44
|
+
let oResult;
|
|
45
|
+
try {
|
|
46
|
+
oResult = fnBody();
|
|
47
|
+
} catch (oErr) {
|
|
48
|
+
oEntry.oError = oErr && oErr.message ? oErr.message : String(oErr);
|
|
49
|
+
oEntry.iDuration = Date.now() - oEntry.iTime;
|
|
50
|
+
_dbgRenderEntry(oEntry, false);
|
|
51
|
+
throw oErr;
|
|
52
|
+
}
|
|
53
|
+
if (oResult && typeof oResult.then === 'function') {
|
|
54
|
+
return oResult.then(function(oVal) {
|
|
55
|
+
oEntry.oResult = _dbgClone(oVal);
|
|
56
|
+
oEntry.iDuration = Date.now() - oEntry.iTime;
|
|
57
|
+
_dbgRenderEntry(oEntry, false);
|
|
58
|
+
return oVal;
|
|
59
|
+
}, function(oErr) {
|
|
60
|
+
oEntry.oError = oErr && oErr.message ? oErr.message : String(oErr);
|
|
61
|
+
oEntry.iDuration = Date.now() - oEntry.iTime;
|
|
62
|
+
_dbgRenderEntry(oEntry, false);
|
|
63
|
+
throw oErr;
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
oEntry.oResult = _dbgClone(oResult);
|
|
67
|
+
oEntry.iDuration = Date.now() - oEntry.iTime;
|
|
68
|
+
_dbgRenderEntry(oEntry, false);
|
|
69
|
+
return oResult;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function _dbgClone(oVal) {
|
|
73
|
+
try { return JSON.parse(JSON.stringify(oVal)); }
|
|
74
|
+
catch (oErr) { return String(oVal); }
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function _dbgFormatTime(iTimestamp) {
|
|
78
|
+
let oDate = new Date(iTimestamp);
|
|
79
|
+
let sH = String(oDate.getHours()).padStart(2, '0');
|
|
80
|
+
let sM = String(oDate.getMinutes()).padStart(2, '0');
|
|
81
|
+
let sS = String(oDate.getSeconds()).padStart(2, '0');
|
|
82
|
+
let sMs = String(oDate.getMilliseconds()).padStart(3, '0');
|
|
83
|
+
return sH + ':' + sM + ':' + sS + '.' + sMs;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function _dbgEscapeHtml(sStr) {
|
|
87
|
+
if (typeof sStr !== 'string') sStr = String(sStr);
|
|
88
|
+
return sStr.replace(new RegExp('&', 'g'), '&').replace(new RegExp('<', 'g'), '<').replace(new RegExp('>', 'g'), '>');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function _dbgRenderEntry(oEntry, bPending) {
|
|
92
|
+
if (!_eDebugList) return;
|
|
93
|
+
let sId = 'dbg-' + oEntry.iId;
|
|
94
|
+
let eRow = _eDebugList.querySelector('[data-dbg-id="' + sId + '"]');
|
|
95
|
+
if (!eRow) {
|
|
96
|
+
eRow = document.createElement('div');
|
|
97
|
+
eRow.setAttribute('data-dbg-id', sId);
|
|
98
|
+
eRow.style.cssText = 'border-bottom:1px solid #333;padding:6px 8px;font-size:12px;cursor:pointer;';
|
|
99
|
+
_eDebugList.prepend(eRow);
|
|
100
|
+
}
|
|
101
|
+
let sStatus = bPending ? '\u23F3' : (oEntry.oError ? '\u274C' : '\u2705');
|
|
102
|
+
let sDuration = bPending ? '\u2026' : oEntry.iDuration + 'ms';
|
|
103
|
+
eRow.innerHTML = '<div style="display:flex;justify-content:space-between;align-items:center;gap:6px;">'
|
|
104
|
+
+ '<span style="flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;"><strong>' + sStatus + ' ' + _dbgEscapeHtml(oEntry.sName) + '</strong></span>'
|
|
105
|
+
+ '<span style="color:#888;font-size:11px;white-space:nowrap;">' + _dbgFormatTime(oEntry.iTime) + ' | ' + sDuration + '</span>'
|
|
106
|
+
+ '<button class="dbg-copy" style="background:#333;color:#e0e0e0;border:1px solid #555;border-radius:3px;padding:1px 6px;cursor:pointer;font-size:11px;white-space:nowrap;" title="Copy to clipboard">⎘</button>'
|
|
107
|
+
+ '</div>';
|
|
108
|
+
eRow.querySelector('.dbg-copy').onclick = function(e) {
|
|
109
|
+
e.stopPropagation();
|
|
110
|
+
let oData = { name: oEntry.sName, args: oEntry.aArgs, time: _dbgFormatTime(oEntry.iTime) };
|
|
111
|
+
if (oEntry.oError) { oData.error = oEntry.oError; }
|
|
112
|
+
else if (oEntry.oResult !== undefined) { oData.result = oEntry.oResult; }
|
|
113
|
+
if (oEntry.iDuration !== undefined) { oData.duration = oEntry.iDuration + 'ms'; }
|
|
114
|
+
navigator.clipboard.writeText(JSON.stringify(oData, null, 2)).then(function() {
|
|
115
|
+
let eBtn = eRow.querySelector('.dbg-copy');
|
|
116
|
+
eBtn.textContent = '\u2713';
|
|
117
|
+
setTimeout(function() { eBtn.textContent = '\u2398'; }, 1000);
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
eRow.onclick = function() {
|
|
121
|
+
let eDetail = eRow.querySelector('.dbg-detail');
|
|
122
|
+
if (eDetail) { eDetail.remove(); return; }
|
|
123
|
+
eDetail = document.createElement('div');
|
|
124
|
+
eDetail.className = 'dbg-detail';
|
|
125
|
+
eDetail.style.cssText = 'margin-top:4px;padding:4px;background:#1a1a2e;border-radius:4px;font-size:11px;overflow:auto;max-height:300px;';
|
|
126
|
+
let sArgsHtml = '<div style="color:#61dafb;margin-bottom:4px;"><b>Args:</b> <pre style="margin:2px 0;white-space:pre-wrap;word-break:break-all;">' + _dbgEscapeHtml(JSON.stringify(oEntry.aArgs, null, 2)) + '</pre></div>';
|
|
127
|
+
let sResultHtml = '';
|
|
128
|
+
if (oEntry.oError) {
|
|
129
|
+
sResultHtml = '<div style="color:#ff6b6b;"><b>Error:</b> <pre style="margin:2px 0;white-space:pre-wrap;word-break:break-all;">' + _dbgEscapeHtml(oEntry.oError) + '</pre></div>';
|
|
130
|
+
} else if (!bPending) {
|
|
131
|
+
sResultHtml = '<div style="color:#a8e6cf;"><b>Result:</b> <pre style="margin:2px 0;white-space:pre-wrap;word-break:break-all;">' + _dbgEscapeHtml(JSON.stringify(oEntry.oResult, null, 2)) + '</pre></div>';
|
|
132
|
+
}
|
|
133
|
+
eDetail.innerHTML = sArgsHtml + sResultHtml;
|
|
134
|
+
eRow.appendChild(eDetail);
|
|
135
|
+
};
|
|
136
|
+
if (_eDebugIcon) {
|
|
137
|
+
let eBadge = _eDebugIcon.querySelector('.dbg-badge');
|
|
138
|
+
if (eBadge) eBadge.textContent = String(_aDebugEntries.length);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function _dbgInjectUI() {
|
|
143
|
+
_eDebugIcon = document.createElement('div');
|
|
144
|
+
_eDebugIcon.id = 'codeapp-debug-icon';
|
|
145
|
+
_eDebugIcon.innerHTML = '<span style="font-size:18px;">\uD83D\uDC1B</span>'
|
|
146
|
+
+ '<span class="dbg-badge" style="position:absolute;top:-4px;right:-4px;background:#ff6b6b;color:#fff;font-size:10px;border-radius:50%;width:18px;height:18px;display:flex;align-items:center;justify-content:center;">0</span>';
|
|
147
|
+
_eDebugIcon.style.cssText = 'position:fixed;top:10px;right:70px;z-index:999999;width:36px;height:36px;background:#1e1e2e;border:1px solid #444;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 2px 8px rgba(0,0,0,0.4);user-select:none;';
|
|
148
|
+
_eDebugIcon.onclick = function() {
|
|
149
|
+
_eDebugPanel.style.display = _eDebugPanel.style.display === 'none' ? 'flex' : 'none';
|
|
150
|
+
};
|
|
151
|
+
document.body.appendChild(_eDebugIcon);
|
|
152
|
+
|
|
153
|
+
_eDebugPanel = document.createElement('div');
|
|
154
|
+
_eDebugPanel.id = 'codeapp-debug-panel';
|
|
155
|
+
_eDebugPanel.style.cssText = 'position:fixed;top:0;right:0;z-index:999998;width:420px;height:100vh;background:#16161e;color:#e0e0e0;font-family:monospace;display:none;flex-direction:column;box-shadow:-4px 0 16px rgba(0,0,0,0.5);';
|
|
156
|
+
|
|
157
|
+
let eHeader = document.createElement('div');
|
|
158
|
+
eHeader.style.cssText = 'padding:10px 12px;background:#1e1e2e;border-bottom:1px solid #333;display:flex;justify-content:space-between;align-items:center;flex-shrink:0;';
|
|
159
|
+
eHeader.innerHTML = '<span style="font-weight:bold;font-size:14px;">\uD83D\uDC1B codeapp.js Debugger</span>';
|
|
160
|
+
let eClear = document.createElement('button');
|
|
161
|
+
eClear.textContent = 'Clear';
|
|
162
|
+
eClear.style.cssText = 'background:#333;color:#e0e0e0;border:1px solid #555;border-radius:4px;padding:3px 10px;cursor:pointer;font-size:12px;';
|
|
163
|
+
eClear.onclick = function() {
|
|
164
|
+
_aDebugEntries = [];
|
|
165
|
+
_eDebugList.innerHTML = '';
|
|
166
|
+
let eBadge = _eDebugIcon.querySelector('.dbg-badge');
|
|
167
|
+
if (eBadge) eBadge.textContent = '0';
|
|
168
|
+
};
|
|
169
|
+
eHeader.appendChild(eClear);
|
|
170
|
+
_eDebugPanel.appendChild(eHeader);
|
|
171
|
+
|
|
172
|
+
_eDebugList = document.createElement('div');
|
|
173
|
+
_eDebugList.style.cssText = 'flex:1;overflow-y:auto;';
|
|
174
|
+
_eDebugPanel.appendChild(_eDebugList);
|
|
175
|
+
document.body.appendChild(_eDebugPanel);
|
|
176
|
+
|
|
177
|
+
// Render entries logged before UI was ready
|
|
178
|
+
_aDebugEntries.slice().reverse().forEach(function(oEntry) {
|
|
179
|
+
_dbgRenderEntry(oEntry, false);
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export function enableDebugger() {
|
|
184
|
+
console.warn("Debug mode enabled: all API calls will be logged in the debug panel. Call enableDebugger() only in development environments.");
|
|
185
|
+
if (_bDebugActive) return;
|
|
186
|
+
_bDebugActive = true;
|
|
187
|
+
if (document.body) {
|
|
188
|
+
_dbgInjectUI();
|
|
189
|
+
} else {
|
|
190
|
+
document.addEventListener('DOMContentLoaded', _dbgInjectUI);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
28
194
|
// ── Get Environment Variable (single query with expand) ────────
|
|
29
195
|
export async function getEnvironmentVariable(sSchemaName) {
|
|
196
|
+
return _dbgWrap('getEnvironmentVariable', [sSchemaName], async function() {
|
|
30
197
|
let client = getSharedClient();
|
|
31
198
|
|
|
32
199
|
// Try single query: filter values by expanded definition schema name
|
|
@@ -52,6 +219,7 @@ export async function getEnvironmentVariable(sSchemaName) {
|
|
|
52
219
|
throw new Error("Environment variable not found: " + sSchemaName);
|
|
53
220
|
}
|
|
54
221
|
return aDefs[0].defaultvalue || "";
|
|
222
|
+
});
|
|
55
223
|
}
|
|
56
224
|
|
|
57
225
|
// ────────────────────────────────────────────────────────────────────────────
|
|
@@ -63,6 +231,7 @@ let oDataSources = {};
|
|
|
63
231
|
|
|
64
232
|
// ── Register a Dataverse table for use by the library ──────────
|
|
65
233
|
export function registerTable(sTableName, sPrimaryKey) {
|
|
234
|
+
return _dbgWrap('registerTable', [sTableName, sPrimaryKey], function() {
|
|
66
235
|
oDataSources[sTableName] = {
|
|
67
236
|
tableId: '',
|
|
68
237
|
version: '',
|
|
@@ -72,6 +241,7 @@ export function registerTable(sTableName, sPrimaryKey) {
|
|
|
72
241
|
};
|
|
73
242
|
// reset client so it picks up the new table on next call
|
|
74
243
|
oSharedClient = null;
|
|
244
|
+
});
|
|
75
245
|
}
|
|
76
246
|
|
|
77
247
|
// ── Ensure value is an array (accepts array or comma-separated string)
|
|
@@ -82,33 +252,29 @@ function ensureArray(value) {
|
|
|
82
252
|
return value;
|
|
83
253
|
}
|
|
84
254
|
|
|
85
|
-
// ── Unwrap SDK response ────────────────────────────────────────
|
|
86
|
-
function unwrapResult(result) {
|
|
87
|
-
if (result && result.success === false) {
|
|
88
|
-
var sMsg = result.error ? (result.error.message || JSON.stringify(result.error)) : 'Operation failed';
|
|
89
|
-
throw new Error(sMsg);
|
|
90
|
-
}
|
|
91
|
-
return result && 'data' in result ? result.data : result;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
255
|
// ── Create ─────────────────────────────────────────────────────
|
|
95
256
|
export async function createItem(tableName, primaryKey, record) {
|
|
257
|
+
return _dbgWrap('createItem', [tableName, primaryKey, record], async function() {
|
|
96
258
|
const client = getSharedClient();
|
|
97
259
|
const result = await client.createRecordAsync(tableName, record);
|
|
98
260
|
return unwrapResult(result);
|
|
261
|
+
});
|
|
99
262
|
}
|
|
100
263
|
|
|
101
264
|
// ── Read (single) ──────────────────────────────────────────────
|
|
102
265
|
export async function getItem(tableName, primaryKey, id, select) {
|
|
266
|
+
return _dbgWrap('getItem', [tableName, primaryKey, id, select], async function() {
|
|
103
267
|
const client = getSharedClient();
|
|
104
268
|
select = ensureArray(select);
|
|
105
269
|
const options = select ? { select } : undefined;
|
|
106
270
|
const result = await client.retrieveRecordAsync(tableName, id, options);
|
|
107
271
|
return unwrapResult(result);
|
|
272
|
+
});
|
|
108
273
|
}
|
|
109
274
|
|
|
110
275
|
// ── List (multiple) ────────────────────────────────────────────
|
|
111
276
|
export async function listItems(tableName, primaryKey, { filter, select, orderBy, top, skip } = {}) {
|
|
277
|
+
return _dbgWrap('listItems', [tableName, primaryKey, { filter, select, orderBy, top, skip }], async function() {
|
|
112
278
|
const client = getSharedClient();
|
|
113
279
|
select = ensureArray(select);
|
|
114
280
|
orderBy = ensureArray(orderBy);
|
|
@@ -121,35 +287,48 @@ export async function listItems(tableName, primaryKey, { filter, select, orderBy
|
|
|
121
287
|
});
|
|
122
288
|
var unwrapped = unwrapResult(result);
|
|
123
289
|
return { entities: Array.isArray(unwrapped) ? unwrapped : [] };
|
|
290
|
+
});
|
|
124
291
|
}
|
|
125
292
|
|
|
126
293
|
// ── Update ─────────────────────────────────────────────────────
|
|
127
294
|
export async function updateItem(tableName, primaryKey, id, changedFields) {
|
|
295
|
+
return _dbgWrap('updateItem', [tableName, primaryKey, id, changedFields], async function() {
|
|
128
296
|
const client = getSharedClient();
|
|
129
297
|
const result = await client.updateRecordAsync(tableName, id, changedFields);
|
|
130
298
|
return unwrapResult(result);
|
|
299
|
+
});
|
|
131
300
|
}
|
|
132
301
|
|
|
133
302
|
// ── Delete ─────────────────────────────────────────────────────
|
|
134
303
|
export async function deleteItem(tableName, primaryKey, id) {
|
|
304
|
+
return _dbgWrap('deleteItem', [tableName, primaryKey, id], async function() {
|
|
135
305
|
const client = getSharedClient();
|
|
136
306
|
const result = await client.deleteRecordAsync(tableName, id);
|
|
137
307
|
return unwrapResult(result);
|
|
308
|
+
});
|
|
138
309
|
}
|
|
139
310
|
|
|
140
311
|
// ── Unbound Action ─────────────────────────────────────────────
|
|
312
|
+
// Calls an unbound Dataverse action by POSTing to the action endpoint.
|
|
313
|
+
// Do NOT add action names to power.config.json dataSources — they are
|
|
314
|
+
// not entities and will cause deploy errors.
|
|
141
315
|
export async function callUnboundAction(tableName, primaryKey, actionName, params) {
|
|
142
|
-
|
|
143
|
-
|
|
316
|
+
return _dbgWrap('callUnboundAction', [tableName, primaryKey, actionName, params], async function() {
|
|
317
|
+
var oAllSources = Object.assign({}, oInitialDataSources, oDataSources);
|
|
318
|
+
var result = await callActionAsync(oAllSources, actionName, params || {});
|
|
144
319
|
return unwrapResult(result);
|
|
320
|
+
});
|
|
145
321
|
}
|
|
146
322
|
|
|
147
323
|
// ── WhoAmI ─────────────────────────────────────────────────────
|
|
148
324
|
export async function whoAmI() {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
var
|
|
152
|
-
|
|
325
|
+
return _dbgWrap('whoAmI', [], async function() {
|
|
326
|
+
var oCtx = await getContext();
|
|
327
|
+
var sId = oCtx.UserId || oCtx.userId || oCtx.systemuserid;
|
|
328
|
+
if (sId) return sId;
|
|
329
|
+
if (oCtx.userSettings && oCtx.userSettings.userId) return oCtx.userSettings.userId;
|
|
330
|
+
return oCtx;
|
|
331
|
+
});
|
|
153
332
|
}
|
|
154
333
|
|
|
155
334
|
// ────────────────────────────────────────────────────────────────────────────
|
|
@@ -160,7 +339,7 @@ export async function whoAmI() {
|
|
|
160
339
|
const DATA_SOURCE_SP = "sharepointonline";
|
|
161
340
|
|
|
162
341
|
// ── Initialize SDK client for the SharePoint connector ─────────
|
|
163
|
-
function
|
|
342
|
+
function initSpClient() {
|
|
164
343
|
const dataSourcesInfo = {
|
|
165
344
|
[DATA_SOURCE_SP]: {
|
|
166
345
|
tableId: "",
|
|
@@ -302,8 +481,8 @@ function initClient() {
|
|
|
302
481
|
}
|
|
303
482
|
|
|
304
483
|
// ── Internal: execute a connector operation ────────────────────
|
|
305
|
-
async function
|
|
306
|
-
const client = await
|
|
484
|
+
async function execSpOp(operationName, parameters) {
|
|
485
|
+
const client = await initSpClient();
|
|
307
486
|
const result = await client.executeAsync({
|
|
308
487
|
connectorOperation: {
|
|
309
488
|
tableName: DATA_SOURCE_SP,
|
|
@@ -323,17 +502,21 @@ async function execOp(operationName, parameters) {
|
|
|
323
502
|
|
|
324
503
|
// ── Call any SharePoint connector operation by name ─────────────
|
|
325
504
|
export async function callSharePointOperation(operationName, parameters = {}) {
|
|
326
|
-
return
|
|
505
|
+
return _dbgWrap('callSharePointOperation', [operationName, parameters], async function() {
|
|
506
|
+
return execSpOp(operationName, parameters);
|
|
507
|
+
});
|
|
327
508
|
}
|
|
328
509
|
|
|
329
510
|
// ── Send HTTP Request (for list-name-based operations) ─────────
|
|
330
511
|
export async function sendHttpRequest({ method = "GET", uri, headers, body }) {
|
|
331
|
-
return
|
|
512
|
+
return _dbgWrap('sendHttpRequest', [{ method, uri, headers, body }], async function() {
|
|
513
|
+
return execSpOp("HttpRequest", {
|
|
332
514
|
method,
|
|
333
515
|
uri,
|
|
334
516
|
headers: headers || {},
|
|
335
517
|
body: body || "",
|
|
336
518
|
});
|
|
519
|
+
});
|
|
337
520
|
}
|
|
338
521
|
|
|
339
522
|
// ═══════════════════════════════════════════════════════════════
|
|
@@ -342,49 +525,59 @@ export async function sendHttpRequest({ method = "GET", uri, headers, body }) {
|
|
|
342
525
|
|
|
343
526
|
// ── Get Items ──────────────────────────────────────────────────
|
|
344
527
|
export async function getItems(sSiteUrl, sListId, { filter, orderBy, top, skip } = {}) {
|
|
528
|
+
return _dbgWrap('getItems', [sSiteUrl, sListId, { filter, orderBy, top, skip }], async function() {
|
|
345
529
|
let params = { siteUrl: encodeURIComponent(sSiteUrl), table: sListId };
|
|
346
530
|
if (filter) params.$filter = filter;
|
|
347
531
|
if (orderBy) params.$orderby = orderBy;
|
|
348
532
|
if (top != null) params.$top = top;
|
|
349
533
|
if (skip != null) params.$skip = skip;
|
|
350
|
-
return
|
|
534
|
+
return execSpOp("GetItems", params);
|
|
535
|
+
});
|
|
351
536
|
}
|
|
352
537
|
|
|
353
538
|
// ── Get Item ───────────────────────────────────────────────────
|
|
354
|
-
export async function
|
|
355
|
-
return
|
|
539
|
+
export async function getSpItem(sSiteUrl, sListId, iItemId) {
|
|
540
|
+
return _dbgWrap('getSpItem', [sSiteUrl, sListId, iItemId], async function() {
|
|
541
|
+
return execSpOp("GetItem", {
|
|
356
542
|
siteUrl: encodeURIComponent(sSiteUrl),
|
|
357
543
|
table: sListId,
|
|
358
544
|
id: iItemId,
|
|
359
545
|
});
|
|
546
|
+
});
|
|
360
547
|
}
|
|
361
548
|
|
|
362
549
|
// ── Create Item ────────────────────────────────────────────────
|
|
363
|
-
export async function
|
|
364
|
-
return
|
|
550
|
+
export async function createSpItem(sSiteUrl, sListId, oFields) {
|
|
551
|
+
return _dbgWrap('createSpItem', [sSiteUrl, sListId, oFields], async function() {
|
|
552
|
+
return execSpOp("PostItem", {
|
|
365
553
|
siteUrl: encodeURIComponent(sSiteUrl),
|
|
366
554
|
table: sListId,
|
|
367
555
|
item: oFields,
|
|
368
556
|
});
|
|
557
|
+
});
|
|
369
558
|
}
|
|
370
559
|
|
|
371
560
|
// ── Update Item ────────────────────────────────────────────────
|
|
372
|
-
export async function
|
|
373
|
-
return
|
|
561
|
+
export async function updateSpItem(sSiteUrl, sListId, iItemId, oChangedFields) {
|
|
562
|
+
return _dbgWrap('updateSpItem', [sSiteUrl, sListId, iItemId, oChangedFields], async function() {
|
|
563
|
+
return execSpOp("PatchItem", {
|
|
374
564
|
siteUrl: encodeURIComponent(sSiteUrl),
|
|
375
565
|
table: sListId,
|
|
376
566
|
id: iItemId,
|
|
377
567
|
item: oChangedFields,
|
|
378
568
|
});
|
|
569
|
+
});
|
|
379
570
|
}
|
|
380
571
|
|
|
381
572
|
// ── Delete Item ────────────────────────────────────────────────
|
|
382
|
-
export async function
|
|
383
|
-
return
|
|
573
|
+
export async function deleteSpItem(sSiteUrl, sListId, iItemId) {
|
|
574
|
+
return _dbgWrap('deleteSpItem', [sSiteUrl, sListId, iItemId], async function() {
|
|
575
|
+
return execSpOp("DeleteItem", {
|
|
384
576
|
siteUrl: encodeURIComponent(sSiteUrl),
|
|
385
577
|
table: sListId,
|
|
386
578
|
id: iItemId,
|
|
387
579
|
});
|
|
580
|
+
});
|
|
388
581
|
}
|
|
389
582
|
|
|
390
583
|
// ═══════════════════════════════════════════════════════════════
|
|
@@ -393,6 +586,7 @@ export async function deleteItem(sSiteUrl, sListId, iItemId) {
|
|
|
393
586
|
|
|
394
587
|
// ── Get Items by List Name ─────────────────────────────────────
|
|
395
588
|
export async function getItemsByName(sSiteUrl, sListName, { filter, orderBy, top, skip } = {}) {
|
|
589
|
+
return _dbgWrap('getItemsByName', [sSiteUrl, sListName, { filter, orderBy, top, skip }], async function() {
|
|
396
590
|
let sUri = sSiteUrl + "/_api/web/lists/getbytitle('" + sListName + "')/items";
|
|
397
591
|
let aQuery = [];
|
|
398
592
|
if (filter) aQuery.push("$filter=" + filter);
|
|
@@ -401,30 +595,39 @@ export async function getItemsByName(sSiteUrl, sListName, { filter, orderBy, top
|
|
|
401
595
|
if (skip != null) aQuery.push("$skip=" + skip);
|
|
402
596
|
if (aQuery.length > 0) sUri = sUri + "?" + aQuery.join("&");
|
|
403
597
|
return sendHttpRequest({ method: "GET", uri: sUri, headers: { Accept: "application/json;odata=nometadata" } });
|
|
598
|
+
});
|
|
404
599
|
}
|
|
405
600
|
|
|
406
601
|
// ── Get Item by List Name ──────────────────────────────────────
|
|
407
602
|
export async function getItemByName(sSiteUrl, sListName, iItemId) {
|
|
603
|
+
return _dbgWrap('getItemByName', [sSiteUrl, sListName, iItemId], async function() {
|
|
408
604
|
let sUri = sSiteUrl + "/_api/web/lists/getbytitle('" + sListName + "')/items(" + iItemId + ")";
|
|
409
605
|
return sendHttpRequest({ method: "GET", uri: sUri, headers: { Accept: "application/json;odata=nometadata" } });
|
|
606
|
+
});
|
|
410
607
|
}
|
|
411
608
|
|
|
412
609
|
// ── Create Item by List Name ───────────────────────────────────
|
|
413
610
|
export async function createItemByName(sSiteUrl, sListName, oFields) {
|
|
611
|
+
return _dbgWrap('createItemByName', [sSiteUrl, sListName, oFields], async function() {
|
|
414
612
|
let sUri = sSiteUrl + "/_api/web/lists/getbytitle('" + sListName + "')/items";
|
|
415
613
|
return sendHttpRequest({ method: "POST", uri: sUri, headers: { Accept: "application/json;odata=nometadata", "Content-Type": "application/json;odata=nometadata" }, body: JSON.stringify(oFields) });
|
|
614
|
+
});
|
|
416
615
|
}
|
|
417
616
|
|
|
418
617
|
// ── Update Item by List Name ───────────────────────────────────
|
|
419
618
|
export async function updateItemByName(sSiteUrl, sListName, iItemId, oChangedFields) {
|
|
619
|
+
return _dbgWrap('updateItemByName', [sSiteUrl, sListName, iItemId, oChangedFields], async function() {
|
|
420
620
|
let sUri = sSiteUrl + "/_api/web/lists/getbytitle('" + sListName + "')/items(" + iItemId + ")";
|
|
421
621
|
return sendHttpRequest({ method: "PATCH", uri: sUri, headers: { Accept: "application/json;odata=nometadata", "Content-Type": "application/json;odata=nometadata", "If-Match": "*" }, body: JSON.stringify(oChangedFields) });
|
|
622
|
+
});
|
|
422
623
|
}
|
|
423
624
|
|
|
424
625
|
// ── Delete Item by List Name ───────────────────────────────────
|
|
425
626
|
export async function deleteItemByName(sSiteUrl, sListName, iItemId) {
|
|
627
|
+
return _dbgWrap('deleteItemByName', [sSiteUrl, sListName, iItemId], async function() {
|
|
426
628
|
let sUri = sSiteUrl + "/_api/web/lists/getbytitle('" + sListName + "')/items(" + iItemId + ")";
|
|
427
629
|
return sendHttpRequest({ method: "DELETE", uri: sUri, headers: { Accept: "application/json;odata=nometadata", "If-Match": "*" } });
|
|
630
|
+
});
|
|
428
631
|
}
|
|
429
632
|
|
|
430
633
|
// ═══════════════════════════════════════════════════════════════
|
|
@@ -433,16 +636,20 @@ export async function deleteItemByName(sSiteUrl, sListName, iItemId) {
|
|
|
433
636
|
|
|
434
637
|
// ── List Tables (Lists) ────────────────────────────────────────
|
|
435
638
|
export async function listTables(sSiteUrl) {
|
|
436
|
-
return
|
|
639
|
+
return _dbgWrap('listTables', [sSiteUrl], async function() {
|
|
640
|
+
return execSpOp("GetTables", {
|
|
437
641
|
siteUrl: encodeURIComponent(sSiteUrl),
|
|
438
642
|
});
|
|
643
|
+
});
|
|
439
644
|
}
|
|
440
645
|
|
|
441
646
|
// ── List Library (Document Libraries) ──────────────────────────
|
|
442
647
|
export async function listLibrary(sSiteUrl) {
|
|
443
|
-
return
|
|
648
|
+
return _dbgWrap('listLibrary', [sSiteUrl], async function() {
|
|
649
|
+
return execSpOp("GetDataSetsMetadata", {
|
|
444
650
|
siteUrl: encodeURIComponent(sSiteUrl),
|
|
445
651
|
});
|
|
652
|
+
});
|
|
446
653
|
}
|
|
447
654
|
|
|
448
655
|
// ═══════════════════════════════════════════════════════════════
|
|
@@ -451,47 +658,57 @@ export async function listLibrary(sSiteUrl) {
|
|
|
451
658
|
|
|
452
659
|
// ── Create File ────────────────────────────────────────────────
|
|
453
660
|
export async function createFile(sSiteUrl, sLibraryName, sFileName, fileContent) {
|
|
454
|
-
return
|
|
661
|
+
return _dbgWrap('createFile', [sSiteUrl, sLibraryName, sFileName, fileContent], async function() {
|
|
662
|
+
return execSpOp("CreateFile", {
|
|
455
663
|
siteUrl: encodeURIComponent(sSiteUrl),
|
|
456
664
|
folderPath: sLibraryName,
|
|
457
665
|
name: sFileName,
|
|
458
666
|
body: fileContent,
|
|
459
667
|
});
|
|
668
|
+
});
|
|
460
669
|
}
|
|
461
670
|
|
|
462
671
|
// ── Update File ────────────────────────────────────────────────
|
|
463
672
|
export async function updateFile(sSiteUrl, sFileId, fileContent) {
|
|
464
|
-
return
|
|
673
|
+
return _dbgWrap('updateFile', [sSiteUrl, sFileId, fileContent], async function() {
|
|
674
|
+
return execSpOp("UpdateFile", {
|
|
465
675
|
siteUrl: encodeURIComponent(sSiteUrl),
|
|
466
676
|
id: sFileId,
|
|
467
677
|
body: fileContent,
|
|
468
678
|
});
|
|
679
|
+
});
|
|
469
680
|
}
|
|
470
681
|
|
|
471
682
|
// ── Delete File ────────────────────────────────────────────────
|
|
472
683
|
export async function deleteFile(sSiteUrl, sFileId) {
|
|
473
|
-
return
|
|
684
|
+
return _dbgWrap('deleteFile', [sSiteUrl, sFileId], async function() {
|
|
685
|
+
return execSpOp("DeleteFile", {
|
|
474
686
|
siteUrl: encodeURIComponent(sSiteUrl),
|
|
475
687
|
id: sFileId,
|
|
476
688
|
});
|
|
689
|
+
});
|
|
477
690
|
}
|
|
478
691
|
|
|
479
692
|
// ── Move File ──────────────────────────────────────────────────
|
|
480
693
|
export async function moveFile(sSiteUrl, sSourceFileId, sDestinationFolderPath, sNewFileName) {
|
|
481
|
-
return
|
|
694
|
+
return _dbgWrap('moveFile', [sSiteUrl, sSourceFileId, sDestinationFolderPath, sNewFileName], async function() {
|
|
695
|
+
return execSpOp("MoveFile", {
|
|
482
696
|
siteUrl: encodeURIComponent(sSiteUrl),
|
|
483
697
|
id: sSourceFileId,
|
|
484
698
|
destinationFolderPath: sDestinationFolderPath,
|
|
485
699
|
newFileName: sNewFileName || "",
|
|
486
700
|
});
|
|
701
|
+
});
|
|
487
702
|
}
|
|
488
703
|
|
|
489
704
|
// ── Get File Metadata ──────────────────────────────────────────
|
|
490
705
|
export async function getFileMetadata(sSiteUrl, sFileId) {
|
|
491
|
-
return
|
|
706
|
+
return _dbgWrap('getFileMetadata', [sSiteUrl, sFileId], async function() {
|
|
707
|
+
return execSpOp("GetFileMetadata", {
|
|
492
708
|
siteUrl: encodeURIComponent(sSiteUrl),
|
|
493
709
|
id: sFileId,
|
|
494
710
|
});
|
|
711
|
+
});
|
|
495
712
|
}
|
|
496
713
|
|
|
497
714
|
// ────────────────────────────────────────────────────────────────────────────
|
|
@@ -501,6 +718,7 @@ export async function getFileMetadata(sSiteUrl, sFileId) {
|
|
|
501
718
|
// ── Data source name (must match connectionReferences in power.config.json) ──
|
|
502
719
|
const DATA_SOURCE_CANDIDATES = ["office365outlook", "Office365Outlook", "office365"];
|
|
503
720
|
const OUTLOOK_APIS = {
|
|
721
|
+
// ── Email operations ──
|
|
504
722
|
GetEmailsV3: {
|
|
505
723
|
path: "/{connectionId}/v3/Mail",
|
|
506
724
|
method: "GET",
|
|
@@ -522,10 +740,104 @@ const OUTLOOK_APIS = {
|
|
|
522
740
|
{ name: "top", in: "query", required: false },
|
|
523
741
|
],
|
|
524
742
|
},
|
|
743
|
+
SendEmailV2: {
|
|
744
|
+
path: "/{connectionId}/v2/Mail",
|
|
745
|
+
method: "POST",
|
|
746
|
+
parameters: [
|
|
747
|
+
{ name: "connectionId", in: "path", required: true },
|
|
748
|
+
{ name: "emailMessage", in: "body", required: true },
|
|
749
|
+
],
|
|
750
|
+
},
|
|
751
|
+
ForwardEmail: {
|
|
752
|
+
path: "/{connectionId}/codeless/api/v2.0/me/messages/{message_id}/forward",
|
|
753
|
+
method: "POST",
|
|
754
|
+
parameters: [
|
|
755
|
+
{ name: "connectionId", in: "path", required: true },
|
|
756
|
+
{ name: "message_id", in: "path", required: true },
|
|
757
|
+
{ name: "body", in: "body", required: true },
|
|
758
|
+
],
|
|
759
|
+
},
|
|
760
|
+
ReplyToV3: {
|
|
761
|
+
path: "/{connectionId}/v3/Mail/ReplyTo/{messageId}",
|
|
762
|
+
method: "POST",
|
|
763
|
+
parameters: [
|
|
764
|
+
{ name: "connectionId", in: "path", required: true },
|
|
765
|
+
{ name: "messageId", in: "path", required: true },
|
|
766
|
+
{ name: "replyParameters", in: "body", required: true },
|
|
767
|
+
{ name: "mailboxAddress", in: "query", required: false },
|
|
768
|
+
],
|
|
769
|
+
},
|
|
770
|
+
MoveV2: {
|
|
771
|
+
path: "/{connectionId}/v2/Mail/Move/{messageId}",
|
|
772
|
+
method: "POST",
|
|
773
|
+
parameters: [
|
|
774
|
+
{ name: "connectionId", in: "path", required: true },
|
|
775
|
+
{ name: "messageId", in: "path", required: true },
|
|
776
|
+
{ name: "folderPath", in: "query", required: true },
|
|
777
|
+
{ name: "mailboxAddress", in: "query", required: false },
|
|
778
|
+
],
|
|
779
|
+
},
|
|
780
|
+
DeleteEmail: {
|
|
781
|
+
path: "/{connectionId}/Mail/{messageId}",
|
|
782
|
+
method: "DELETE",
|
|
783
|
+
parameters: [
|
|
784
|
+
{ name: "connectionId", in: "path", required: true },
|
|
785
|
+
{ name: "messageId", in: "path", required: true },
|
|
786
|
+
],
|
|
787
|
+
},
|
|
788
|
+
SharedMailboxSendEmailV2: {
|
|
789
|
+
path: "/{connectionId}/v2/SharedMailbox/Mail",
|
|
790
|
+
method: "POST",
|
|
791
|
+
parameters: [
|
|
792
|
+
{ name: "connectionId", in: "path", required: true },
|
|
793
|
+
{ name: "emailMessage", in: "body", required: true },
|
|
794
|
+
],
|
|
795
|
+
},
|
|
796
|
+
// ── Calendar operations ──
|
|
797
|
+
V4CalendarGetItems: {
|
|
798
|
+
path: "/{connectionId}/datasets/calendars/v4/tables/{table}/items",
|
|
799
|
+
method: "GET",
|
|
800
|
+
parameters: [
|
|
801
|
+
{ name: "connectionId", in: "path", required: true },
|
|
802
|
+
{ name: "table", in: "path", required: true },
|
|
803
|
+
{ name: "$filter", in: "query", required: false },
|
|
804
|
+
{ name: "$orderby", in: "query", required: false },
|
|
805
|
+
{ name: "$top", in: "query", required: false },
|
|
806
|
+
{ name: "$skip", in: "query", required: false },
|
|
807
|
+
],
|
|
808
|
+
},
|
|
809
|
+
V4CalendarPostItem: {
|
|
810
|
+
path: "/{connectionId}/datasets/calendars/v4/tables/{table}/items",
|
|
811
|
+
method: "POST",
|
|
812
|
+
parameters: [
|
|
813
|
+
{ name: "connectionId", in: "path", required: true },
|
|
814
|
+
{ name: "table", in: "path", required: true },
|
|
815
|
+
{ name: "item", in: "body", required: true },
|
|
816
|
+
],
|
|
817
|
+
},
|
|
818
|
+
V4CalendarPatchItem: {
|
|
819
|
+
path: "/{connectionId}/datasets/calendars/v4/tables/{table}/items/{id}",
|
|
820
|
+
method: "PATCH",
|
|
821
|
+
parameters: [
|
|
822
|
+
{ name: "connectionId", in: "path", required: true },
|
|
823
|
+
{ name: "table", in: "path", required: true },
|
|
824
|
+
{ name: "id", in: "path", required: true },
|
|
825
|
+
{ name: "item", in: "body", required: true },
|
|
826
|
+
],
|
|
827
|
+
},
|
|
828
|
+
CalendarDeleteItem: {
|
|
829
|
+
path: "/{connectionId}/datasets/calendars/tables/{table}/items/{id}",
|
|
830
|
+
method: "DELETE",
|
|
831
|
+
parameters: [
|
|
832
|
+
{ name: "connectionId", in: "path", required: true },
|
|
833
|
+
{ name: "table", in: "path", required: true },
|
|
834
|
+
{ name: "id", in: "path", required: true },
|
|
835
|
+
],
|
|
836
|
+
},
|
|
525
837
|
};
|
|
526
838
|
|
|
527
839
|
// ── Initialize SDK client for the Office 365 Outlook connector ──
|
|
528
|
-
function
|
|
840
|
+
function initOutlookClient() {
|
|
529
841
|
const dataSourcesInfo = {};
|
|
530
842
|
|
|
531
843
|
DATA_SOURCE_CANDIDATES.forEach((sDataSourceName) => {
|
|
@@ -541,7 +853,7 @@ function initClient() {
|
|
|
541
853
|
return getClient(dataSourcesInfo);
|
|
542
854
|
}
|
|
543
855
|
|
|
544
|
-
function
|
|
856
|
+
function stringifyOutlookError(oError) {
|
|
545
857
|
if (!oError) return "Operation failed";
|
|
546
858
|
if (typeof oError === "string") return oError;
|
|
547
859
|
if (oError instanceof Error) return oError.message || "Operation failed";
|
|
@@ -559,11 +871,11 @@ function stringifyErrorDetails(oError) {
|
|
|
559
871
|
}
|
|
560
872
|
}
|
|
561
873
|
|
|
562
|
-
function
|
|
874
|
+
function unwrapOutlookResult(oResult) {
|
|
563
875
|
if (oResult && oResult.success === false) {
|
|
564
|
-
var sMessage =
|
|
876
|
+
var sMessage = stringifyOutlookError(oResult.error);
|
|
565
877
|
if (oResult.data !== undefined) {
|
|
566
|
-
sMessage += " | data: " +
|
|
878
|
+
sMessage += " | data: " + stringifyOutlookError(oResult.data);
|
|
567
879
|
}
|
|
568
880
|
throw new Error(sMessage);
|
|
569
881
|
}
|
|
@@ -576,8 +888,8 @@ function unwrapResult(oResult) {
|
|
|
576
888
|
}
|
|
577
889
|
|
|
578
890
|
// ── Internal: execute a connector operation ────────────────────
|
|
579
|
-
async function
|
|
580
|
-
const client = await
|
|
891
|
+
async function execOutlookOp(operationName, parameters) {
|
|
892
|
+
const client = await initOutlookClient();
|
|
581
893
|
const aErrors = [];
|
|
582
894
|
|
|
583
895
|
for (let iIndex = 0; iIndex < DATA_SOURCE_CANDIDATES.length; iIndex += 1) {
|
|
@@ -592,9 +904,9 @@ async function execOp(operationName, parameters) {
|
|
|
592
904
|
},
|
|
593
905
|
});
|
|
594
906
|
|
|
595
|
-
return
|
|
907
|
+
return unwrapOutlookResult(result);
|
|
596
908
|
} catch (oErr) {
|
|
597
|
-
const sMessage =
|
|
909
|
+
const sMessage = stringifyOutlookError(oErr);
|
|
598
910
|
aErrors.push(sDataSourceName + ": " + sMessage);
|
|
599
911
|
|
|
600
912
|
if (sMessage.indexOf("Connection reference not found") === -1) {
|
|
@@ -606,15 +918,153 @@ async function execOp(operationName, parameters) {
|
|
|
606
918
|
throw new Error("No Outlook connection reference matched. Tried: " + aErrors.join(" || "));
|
|
607
919
|
}
|
|
608
920
|
|
|
921
|
+
// ── Generic: call any Outlook connector operation ──────────────
|
|
922
|
+
export async function callOutlookOperation(sOperationName, oParameters) {
|
|
923
|
+
return _dbgWrap('callOutlookOperation', [sOperationName, oParameters], async function() {
|
|
924
|
+
return execOutlookOp(sOperationName, oParameters);
|
|
925
|
+
});
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
// ── Send Email ─────────────────────────────────────────────────
|
|
929
|
+
export async function sendEmail({ to, cc, bcc, subject, body, isHtml, importance, attachments } = {}) {
|
|
930
|
+
return _dbgWrap('sendEmail', [{ to, cc, bcc, subject, body, isHtml, importance, attachments }], async function() {
|
|
931
|
+
var oMessage = {
|
|
932
|
+
To: to,
|
|
933
|
+
Subject: subject,
|
|
934
|
+
Body: body,
|
|
935
|
+
};
|
|
936
|
+
if (cc) oMessage.Cc = cc;
|
|
937
|
+
if (bcc) oMessage.Bcc = bcc;
|
|
938
|
+
if (importance) oMessage.Importance = importance;
|
|
939
|
+
if (attachments) oMessage.Attachments = attachments;
|
|
940
|
+
if (isHtml === false) oMessage.IsHtml = false;
|
|
941
|
+
|
|
942
|
+
return execOutlookOp("SendEmailV2", { emailMessage: oMessage });
|
|
943
|
+
});
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
// ── Forward Email ──────────────────────────────────────────────
|
|
947
|
+
export async function forwardEmail(sMessageId, { to, comment } = {}) {
|
|
948
|
+
return _dbgWrap('forwardEmail', [sMessageId, { to, comment }], async function() {
|
|
949
|
+
return execOutlookOp("ForwardEmail", {
|
|
950
|
+
message_id: sMessageId,
|
|
951
|
+
body: { ToRecipients: to, Comment: comment },
|
|
952
|
+
});
|
|
953
|
+
});
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
// ── Reply to Email ─────────────────────────────────────────────
|
|
957
|
+
export async function replyToEmail(sMessageId, { comment, replyAll } = {}) {
|
|
958
|
+
return _dbgWrap('replyToEmail', [sMessageId, { comment, replyAll }], async function() {
|
|
959
|
+
return execOutlookOp("ReplyToV3", {
|
|
960
|
+
messageId: sMessageId,
|
|
961
|
+
replyParameters: { Body: comment, ReplyAll: replyAll === true },
|
|
962
|
+
});
|
|
963
|
+
});
|
|
964
|
+
}
|
|
965
|
+
|
|
609
966
|
// ── List Emails ────────────────────────────────────────────────
|
|
610
967
|
export async function listEmails({ folderId = "Inbox", fetchOnlyUnread, searchQuery, top, skip } = {}) {
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
return execOp("GetEmailsV3", {
|
|
968
|
+
return _dbgWrap('listEmails', [{ folderId, fetchOnlyUnread, searchQuery, top, skip }], async function() {
|
|
969
|
+
return execOutlookOp("GetEmailsV3", {
|
|
614
970
|
folderPath: folderId,
|
|
615
|
-
fetchOnlyUnread,
|
|
616
|
-
searchQuery,
|
|
971
|
+
fetchOnlyUnread: fetchOnlyUnread,
|
|
972
|
+
searchQuery: searchQuery,
|
|
617
973
|
top: top != null ? top : 10,
|
|
974
|
+
skip: skip,
|
|
975
|
+
});
|
|
976
|
+
});
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
// ── Send from Shared Mailbox ───────────────────────────────────
|
|
980
|
+
export async function sendFromSharedMailbox(sSharedMailbox, { to, cc, bcc, subject, body, importance, attachments } = {}) {
|
|
981
|
+
return _dbgWrap('sendFromSharedMailbox', [sSharedMailbox, { to, cc, bcc, subject, body, importance, attachments }], async function() {
|
|
982
|
+
var oMessage = {
|
|
983
|
+
MailboxAddress: sSharedMailbox,
|
|
984
|
+
To: to,
|
|
985
|
+
Subject: subject,
|
|
986
|
+
Body: body,
|
|
987
|
+
};
|
|
988
|
+
if (cc) oMessage.Cc = cc;
|
|
989
|
+
if (bcc) oMessage.Bcc = bcc;
|
|
990
|
+
if (importance) oMessage.Importance = importance;
|
|
991
|
+
if (attachments) oMessage.Attachments = attachments;
|
|
992
|
+
|
|
993
|
+
return execOutlookOp("SharedMailboxSendEmailV2", { emailMessage: oMessage });
|
|
994
|
+
});
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
// ── Move Email ─────────────────────────────────────────────────
|
|
998
|
+
export async function moveEmail(sMessageId, sDestinationFolderId) {
|
|
999
|
+
return _dbgWrap('moveEmail', [sMessageId, sDestinationFolderId], async function() {
|
|
1000
|
+
return execOutlookOp("MoveV2", {
|
|
1001
|
+
messageId: sMessageId,
|
|
1002
|
+
folderPath: sDestinationFolderId,
|
|
1003
|
+
});
|
|
1004
|
+
});
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
// ── Delete Email ───────────────────────────────────────────────
|
|
1008
|
+
export async function deleteEmail(sMessageId) {
|
|
1009
|
+
return _dbgWrap('deleteEmail', [sMessageId], async function() {
|
|
1010
|
+
return execOutlookOp("DeleteEmail", { messageId: sMessageId });
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
// ── Create Event ───────────────────────────────────────────────
|
|
1015
|
+
export async function createEvent({ subject, start, end, attendees, body, location, importance, isAllDay, timeZone, calendarId } = {}) {
|
|
1016
|
+
return _dbgWrap('createEvent', [{ subject, start, end, attendees, body, location, importance, isAllDay, timeZone, calendarId }], async function() {
|
|
1017
|
+
var sAttendees = Array.isArray(attendees) ? attendees.join(";") : attendees;
|
|
1018
|
+
var oItem = {
|
|
1019
|
+
subject: subject,
|
|
1020
|
+
start: start,
|
|
1021
|
+
end: end,
|
|
1022
|
+
timeZone: timeZone || "",
|
|
1023
|
+
};
|
|
1024
|
+
if (sAttendees) oItem.requiredAttendees = sAttendees;
|
|
1025
|
+
if (body) oItem.body = body;
|
|
1026
|
+
if (location) oItem.location = location;
|
|
1027
|
+
if (importance) oItem.importance = importance;
|
|
1028
|
+
if (isAllDay) oItem.isAllDay = true;
|
|
1029
|
+
|
|
1030
|
+
return execOutlookOp("V4CalendarPostItem", {
|
|
1031
|
+
table: calendarId || "Calendar",
|
|
1032
|
+
item: oItem,
|
|
1033
|
+
});
|
|
1034
|
+
});
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
// ── List Events ────────────────────────────────────────────────
|
|
1038
|
+
export async function listEvents({ calendarId = "Calendar", filter, orderBy, top, skip } = {}) {
|
|
1039
|
+
return _dbgWrap('listEvents', [{ calendarId, filter, orderBy, top, skip }], async function() {
|
|
1040
|
+
return execOutlookOp("V4CalendarGetItems", {
|
|
1041
|
+
table: calendarId,
|
|
1042
|
+
$filter: filter,
|
|
1043
|
+
$orderby: orderBy,
|
|
1044
|
+
$top: top,
|
|
1045
|
+
$skip: skip,
|
|
1046
|
+
});
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
// ── Edit Event ─────────────────────────────────────────────────
|
|
1051
|
+
export async function editEvent(sEventId, oChangedFields, sCalendarId) {
|
|
1052
|
+
return _dbgWrap('editEvent', [sEventId, oChangedFields, sCalendarId], async function() {
|
|
1053
|
+
return execOutlookOp("V4CalendarPatchItem", {
|
|
1054
|
+
table: sCalendarId || "Calendar",
|
|
1055
|
+
id: sEventId,
|
|
1056
|
+
item: oChangedFields,
|
|
1057
|
+
});
|
|
1058
|
+
});
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
// ── Delete Event ───────────────────────────────────────────────
|
|
1062
|
+
export async function deleteEvent(sEventId, sCalendarId) {
|
|
1063
|
+
return _dbgWrap('deleteEvent', [sEventId, sCalendarId], async function() {
|
|
1064
|
+
return execOutlookOp("CalendarDeleteItem", {
|
|
1065
|
+
table: sCalendarId || "Calendar",
|
|
1066
|
+
id: sEventId,
|
|
1067
|
+
});
|
|
618
1068
|
});
|
|
619
1069
|
}
|
|
620
1070
|
|
|
@@ -626,7 +1076,7 @@ export async function listEmails({ folderId = "Inbox", fetchOnlyUnread, searchQu
|
|
|
626
1076
|
const DATA_SOURCE_USERS = "office365users";
|
|
627
1077
|
|
|
628
1078
|
// ── Initialize SDK client for the Office 365 Users connector ───
|
|
629
|
-
function
|
|
1079
|
+
function initUsersClient() {
|
|
630
1080
|
const dataSourcesInfo = {
|
|
631
1081
|
[DATA_SOURCE_USERS]: {
|
|
632
1082
|
tableId: "",
|
|
@@ -698,8 +1148,8 @@ function initClient() {
|
|
|
698
1148
|
}
|
|
699
1149
|
|
|
700
1150
|
// ── Internal: execute a connector operation ────────────────────
|
|
701
|
-
async function
|
|
702
|
-
const client = await
|
|
1151
|
+
async function execUsersOp(operationName, parameters) {
|
|
1152
|
+
const client = await initUsersClient();
|
|
703
1153
|
const result = await client.executeAsync({
|
|
704
1154
|
connectorOperation: {
|
|
705
1155
|
tableName: DATA_SOURCE_USERS,
|
|
@@ -719,17 +1169,21 @@ async function execOp(operationName, parameters) {
|
|
|
719
1169
|
|
|
720
1170
|
// ── Call any Office 365 Users operation by name ────────────────
|
|
721
1171
|
export async function callUsersOperation(operationName, parameters = {}) {
|
|
722
|
-
return
|
|
1172
|
+
return _dbgWrap('callUsersOperation', [operationName, parameters], async function() {
|
|
1173
|
+
return execUsersOp(operationName, parameters);
|
|
1174
|
+
});
|
|
723
1175
|
}
|
|
724
1176
|
|
|
725
1177
|
// ── Open HTTP Request ──────────────────────────────────────────
|
|
726
|
-
export async function
|
|
727
|
-
return
|
|
1178
|
+
export async function openUsersHttpRequest({ method = "GET", uri, headers, body }) {
|
|
1179
|
+
return _dbgWrap('openUsersHttpRequest', [{ method, uri, headers, body }], async function() {
|
|
1180
|
+
return execUsersOp("HttpRequest", {
|
|
728
1181
|
method,
|
|
729
1182
|
uri,
|
|
730
1183
|
headers: headers || {},
|
|
731
1184
|
body: body || "",
|
|
732
1185
|
});
|
|
1186
|
+
});
|
|
733
1187
|
}
|
|
734
1188
|
|
|
735
1189
|
// ═══════════════════════════════════════════════════════════════
|
|
@@ -738,14 +1192,18 @@ export async function openHttpRequest({ method = "GET", uri, headers, body }) {
|
|
|
738
1192
|
|
|
739
1193
|
// ── Get My Profile ─────────────────────────────────────────────
|
|
740
1194
|
export async function getMyProfile() {
|
|
741
|
-
return
|
|
1195
|
+
return _dbgWrap('getMyProfile', [], async function() {
|
|
1196
|
+
return execUsersOp("MyProfile_V2", {});
|
|
1197
|
+
});
|
|
742
1198
|
}
|
|
743
1199
|
|
|
744
1200
|
// ── Get User Profile ───────────────────────────────────────────
|
|
745
1201
|
export async function getUserProfile(userId) {
|
|
746
|
-
return
|
|
1202
|
+
return _dbgWrap('getUserProfile', [userId], async function() {
|
|
1203
|
+
return execUsersOp("UserProfile_V2", {
|
|
747
1204
|
id: userId,
|
|
748
1205
|
});
|
|
1206
|
+
});
|
|
749
1207
|
}
|
|
750
1208
|
|
|
751
1209
|
// ═══════════════════════════════════════════════════════════════
|
|
@@ -754,16 +1212,20 @@ export async function getUserProfile(userId) {
|
|
|
754
1212
|
|
|
755
1213
|
// ── Get Manager ────────────────────────────────────────────────
|
|
756
1214
|
export async function getManager(userId) {
|
|
757
|
-
return
|
|
1215
|
+
return _dbgWrap('getManager', [userId], async function() {
|
|
1216
|
+
return execUsersOp("Manager_V2", {
|
|
758
1217
|
id: userId,
|
|
759
1218
|
});
|
|
1219
|
+
});
|
|
760
1220
|
}
|
|
761
1221
|
|
|
762
1222
|
// ── Get Direct Reports ─────────────────────────────────────────
|
|
763
1223
|
export async function getDirectReports(userId) {
|
|
764
|
-
return
|
|
1224
|
+
return _dbgWrap('getDirectReports', [userId], async function() {
|
|
1225
|
+
return execUsersOp("DirectReports_V2", {
|
|
765
1226
|
id: userId,
|
|
766
1227
|
});
|
|
1228
|
+
});
|
|
767
1229
|
}
|
|
768
1230
|
|
|
769
1231
|
// ═══════════════════════════════════════════════════════════════
|
|
@@ -772,9 +1234,11 @@ export async function getDirectReports(userId) {
|
|
|
772
1234
|
|
|
773
1235
|
// ── Get User Photo ─────────────────────────────────────────────
|
|
774
1236
|
export async function getUserPhoto(userId) {
|
|
775
|
-
return
|
|
1237
|
+
return _dbgWrap('getUserPhoto', [userId], async function() {
|
|
1238
|
+
return execUsersOp("UserPhoto_V2", {
|
|
776
1239
|
id: userId,
|
|
777
1240
|
});
|
|
1241
|
+
});
|
|
778
1242
|
}
|
|
779
1243
|
|
|
780
1244
|
// ═══════════════════════════════════════════════════════════════
|
|
@@ -783,11 +1247,13 @@ export async function getUserPhoto(userId) {
|
|
|
783
1247
|
|
|
784
1248
|
// ── Search for Users ───────────────────────────────────────────
|
|
785
1249
|
export async function searchForUsers({ searchTerm, top, skip } = {}) {
|
|
1250
|
+
return _dbgWrap('searchForUsers', [{ searchTerm, top, skip }], async function() {
|
|
786
1251
|
const params = {};
|
|
787
1252
|
if (searchTerm) params.searchTerm = searchTerm;
|
|
788
1253
|
if (top != null) params.$top = top;
|
|
789
1254
|
if (skip != null) params.$skip = skip;
|
|
790
|
-
return
|
|
1255
|
+
return execUsersOp("SearchUser_V2", params);
|
|
1256
|
+
});
|
|
791
1257
|
}
|
|
792
1258
|
|
|
793
1259
|
// ────────────────────────────────────────────────────────────────────────────
|
|
@@ -799,7 +1265,7 @@ export async function searchForUsers({ searchTerm, top, skip } = {}) {
|
|
|
799
1265
|
const DATA_SOURCE_GROUPS = "Office365Groups";
|
|
800
1266
|
|
|
801
1267
|
// ── Initialize SDK client for the Office 365 Groups connector ──
|
|
802
|
-
function
|
|
1268
|
+
function initGroupsClient() {
|
|
803
1269
|
const dataSourcesInfo = {
|
|
804
1270
|
[DATA_SOURCE_GROUPS]: {
|
|
805
1271
|
tableId: "",
|
|
@@ -813,8 +1279,8 @@ function initClient() {
|
|
|
813
1279
|
}
|
|
814
1280
|
|
|
815
1281
|
// ── Internal: execute a connector operation ────────────────────
|
|
816
|
-
async function
|
|
817
|
-
const client = await
|
|
1282
|
+
async function execGroupsOp(operationName, parameters) {
|
|
1283
|
+
const client = await initGroupsClient();
|
|
818
1284
|
return client.executeAsync({
|
|
819
1285
|
connectorOperation: {
|
|
820
1286
|
tableName: DATA_SOURCE_GROUPS,
|
|
@@ -830,17 +1296,21 @@ async function execOp(operationName, parameters) {
|
|
|
830
1296
|
|
|
831
1297
|
// ── Call any Office 365 Groups operation by name ───────────────
|
|
832
1298
|
export async function callGroupsOperation(operationName, parameters = {}) {
|
|
833
|
-
return
|
|
1299
|
+
return _dbgWrap('callGroupsOperation', [operationName, parameters], async function() {
|
|
1300
|
+
return execGroupsOp(operationName, parameters);
|
|
1301
|
+
});
|
|
834
1302
|
}
|
|
835
1303
|
|
|
836
1304
|
// ── Open HTTP Request ──────────────────────────────────────────
|
|
837
|
-
export async function
|
|
838
|
-
return
|
|
1305
|
+
export async function openGroupsHttpRequest({ method = "GET", uri, headers, body }) {
|
|
1306
|
+
return _dbgWrap('openGroupsHttpRequest', [{ method, uri, headers, body }], async function() {
|
|
1307
|
+
return execGroupsOp("HttpRequest", {
|
|
839
1308
|
method,
|
|
840
1309
|
uri,
|
|
841
1310
|
headers: headers || {},
|
|
842
1311
|
body: body || "",
|
|
843
1312
|
});
|
|
1313
|
+
});
|
|
844
1314
|
}
|
|
845
1315
|
|
|
846
1316
|
// ═══════════════════════════════════════════════════════════════
|
|
@@ -849,12 +1319,16 @@ export async function openHttpRequest({ method = "GET", uri, headers, body }) {
|
|
|
849
1319
|
|
|
850
1320
|
// ── List My Groups ─────────────────────────────────────────────
|
|
851
1321
|
export async function listMyGroups() {
|
|
852
|
-
return
|
|
1322
|
+
return _dbgWrap('listMyGroups', [], async function() {
|
|
1323
|
+
return execGroupsOp("ListOwnedGroups", {});
|
|
1324
|
+
});
|
|
853
1325
|
}
|
|
854
1326
|
|
|
855
1327
|
// ── List Members of a Group ────────────────────────────────────
|
|
856
1328
|
export async function listGroupMembers(groupId) {
|
|
857
|
-
return
|
|
1329
|
+
return _dbgWrap('listGroupMembers', [groupId], async function() {
|
|
1330
|
+
return execGroupsOp("ListGroupMembers", {
|
|
858
1331
|
groupId,
|
|
859
1332
|
});
|
|
1333
|
+
});
|
|
860
1334
|
}
|