codeapp-js 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/codeApp/dist/codeapp.js +326 -72
  2. package/codeApp/dist/icon-512.png +0 -0
  3. package/codeApp/dist/index.html +1 -0
  4. package/codeApp/dist/index.js +1 -1
  5. package/codeApp/dist/power-apps-data.js +2952 -2531
  6. package/codeApp/power.config.json +1 -1
  7. package/dev files/customConnector.js +98 -0
  8. package/dev files/dataverse.js +33 -7
  9. package/dev files/environmentVar.js +1 -1
  10. package/dev files/office365groups.js +1 -1
  11. package/dev files/office365users.js +1 -1
  12. package/dev files/outlook.js +1 -1
  13. package/dev files/power-apps-data.js +2952 -0
  14. package/dev files/sharepoint.js +1 -1
  15. package/examples/combined demo/dist/codeapp.js +1098 -0
  16. package/examples/combined demo/dist/index.js +470 -515
  17. package/examples/combined demo/dist/power-apps-data.js +3007 -2531
  18. package/examples/dataverse Demo/dist/codeapp.js +1085 -0
  19. package/examples/dataverse Demo/dist/index.js +38 -26
  20. package/examples/dataverse Demo/dist/power-apps-data.js +2912 -2531
  21. package/examples/groups Demo/dist/codeapp.js +1085 -0
  22. package/examples/groups Demo/dist/index.js +113 -113
  23. package/examples/groups Demo/dist/power-apps-data.js +2912 -2531
  24. package/examples/groups Demo/power.config.json +3 -2
  25. package/examples/kanban/dist/power-apps-data.js +2953 -2531
  26. package/examples/myProfile/dist/power-apps-data.js +2953 -2531
  27. package/examples/outlook Demo/dist/codeapp.js +1085 -0
  28. package/examples/outlook Demo/dist/index.js +39 -35
  29. package/examples/outlook Demo/dist/power-apps-data.js +2912 -2531
  30. package/examples/planning Poker/dist/power-apps-data.js +2953 -2531
  31. package/examples/sharePoint Demo/dist/codeapp.js +1085 -0
  32. package/examples/sharePoint Demo/dist/index.js +262 -269
  33. package/examples/sharePoint Demo/dist/power-apps-data.js +2912 -2531
  34. package/examples/solution explorer/agent/decision-log.md +27 -0
  35. package/examples/solution explorer/agent/mockup-01-swiss-grid.html +452 -0
  36. package/examples/solution explorer/agent/mockup-02-dark-glass.html +496 -0
  37. package/examples/solution explorer/agent/mockup-03-paper-console.html +510 -0
  38. package/examples/solution explorer/agent/mockup-04-neon-noir.html +546 -0
  39. package/examples/solution explorer/agent/mockup-05-zen-garden.html +534 -0
  40. package/examples/solution explorer/dist/codeapp.js +1098 -0
  41. package/examples/solution explorer/dist/icon-512.png +0 -0
  42. package/examples/solution explorer/dist/index.html +80 -0
  43. package/examples/solution explorer/dist/index.js +735 -0
  44. package/examples/solution explorer/dist/power-apps-data.js +3007 -0
  45. package/examples/solution explorer/dist/styles.css +571 -0
  46. package/examples/solution explorer/power.config.json +151 -0
  47. package/examples/todo/dist/power-apps-data.js +2953 -2531
  48. package/package.json +1 -8
  49. package/.github/instructions/wyattdave.instructions.md +0 -39
  50. package/examples/combined demo/dist/dataverse.js +0 -86
  51. package/examples/combined demo/dist/environmentVar.js +0 -55
  52. package/examples/combined demo/dist/office365groups.js +0 -97
  53. package/examples/combined demo/dist/office365users.js +0 -169
  54. package/examples/combined demo/dist/outlook.js +0 -162
  55. package/examples/combined demo/dist/sharepoint.js +0 -339
  56. package/examples/dataverse Demo/dist/dataverse.js +0 -86
  57. package/examples/groups Demo/dist/dataverse.js +0 -86
  58. package/examples/groups Demo/dist/environmentVar.js +0 -55
  59. package/examples/groups Demo/dist/office365groups.js +0 -97
  60. package/examples/groups Demo/dist/office365users.js +0 -169
  61. package/examples/groups Demo/dist/outlook.js +0 -162
  62. package/examples/groups Demo/dist/sharepoint.js +0 -339
  63. package/examples/sharePoint Demo/dist/dataverse.js +0 -94
  64. package/examples/sharePoint Demo/dist/environmentVar.js +0 -55
  65. package/examples/sharePoint Demo/dist/office365groups.js +0 -97
  66. package/examples/sharePoint Demo/dist/office365users.js +0 -169
  67. package/examples/sharePoint Demo/dist/outlook.js +0 -162
  68. package/examples/sharePoint Demo/dist/sharepoint.js +0 -339
  69. package/scripts/build-power-sdk.mjs +0 -69
@@ -1,17 +1,20 @@
1
- import { getClient } from "@microsoft/power-apps/data";
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(ALL_DATA_SOURCES);
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'), '&amp;').replace(new RegExp('<', 'g'), '&lt;').replace(new RegExp('>', 'g'), '&gt;');
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,35 +241,43 @@ 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
- // ── Unwrap SDK response ────────────────────────────────────────
78
- function unwrapResult(result) {
79
- if (result && result.success === false) {
80
- var sMsg = result.error ? (result.error.message || JSON.stringify(result.error)) : 'Operation failed';
81
- throw new Error(sMsg);
82
- }
83
- return result && 'data' in result ? result.data : result;
247
+ // ── Ensure value is an array (accepts array or comma-separated string)
248
+ function ensureArray(value) {
249
+ if (!value) return value;
250
+ if (Array.isArray(value)) return value;
251
+ if (typeof value === 'string') return value.split(',').map(function (s) { return s.trim(); });
252
+ return value;
84
253
  }
85
254
 
86
255
  // ── Create ─────────────────────────────────────────────────────
87
256
  export async function createItem(tableName, primaryKey, record) {
257
+ return _dbgWrap('createItem', [tableName, primaryKey, record], async function() {
88
258
  const client = getSharedClient();
89
259
  const result = await client.createRecordAsync(tableName, record);
90
260
  return unwrapResult(result);
261
+ });
91
262
  }
92
263
 
93
264
  // ── Read (single) ──────────────────────────────────────────────
94
265
  export async function getItem(tableName, primaryKey, id, select) {
266
+ return _dbgWrap('getItem', [tableName, primaryKey, id, select], async function() {
95
267
  const client = getSharedClient();
268
+ select = ensureArray(select);
96
269
  const options = select ? { select } : undefined;
97
270
  const result = await client.retrieveRecordAsync(tableName, id, options);
98
271
  return unwrapResult(result);
272
+ });
99
273
  }
100
274
 
101
275
  // ── List (multiple) ────────────────────────────────────────────
102
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() {
103
278
  const client = getSharedClient();
279
+ select = ensureArray(select);
280
+ orderBy = ensureArray(orderBy);
104
281
  const result = await client.retrieveMultipleRecordsAsync(tableName, {
105
282
  filter,
106
283
  select,
@@ -110,35 +287,48 @@ export async function listItems(tableName, primaryKey, { filter, select, orderBy
110
287
  });
111
288
  var unwrapped = unwrapResult(result);
112
289
  return { entities: Array.isArray(unwrapped) ? unwrapped : [] };
290
+ });
113
291
  }
114
292
 
115
293
  // ── Update ─────────────────────────────────────────────────────
116
294
  export async function updateItem(tableName, primaryKey, id, changedFields) {
295
+ return _dbgWrap('updateItem', [tableName, primaryKey, id, changedFields], async function() {
117
296
  const client = getSharedClient();
118
297
  const result = await client.updateRecordAsync(tableName, id, changedFields);
119
298
  return unwrapResult(result);
299
+ });
120
300
  }
121
301
 
122
302
  // ── Delete ─────────────────────────────────────────────────────
123
303
  export async function deleteItem(tableName, primaryKey, id) {
304
+ return _dbgWrap('deleteItem', [tableName, primaryKey, id], async function() {
124
305
  const client = getSharedClient();
125
306
  const result = await client.deleteRecordAsync(tableName, id);
126
307
  return unwrapResult(result);
308
+ });
127
309
  }
128
310
 
129
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.
130
315
  export async function callUnboundAction(tableName, primaryKey, actionName, params) {
131
- const client = getSharedClient();
132
- const result = await client.invokeActionAsync(tableName, actionName, params);
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 || {});
133
319
  return unwrapResult(result);
320
+ });
134
321
  }
135
322
 
136
323
  // ── WhoAmI ─────────────────────────────────────────────────────
137
324
  export async function whoAmI() {
138
- const client = getSharedClient();
139
- const result = await client.invokeActionAsync('', 'WhoAmI', {});
140
- var data = unwrapResult(result);
141
- return data.UserId || data.userid || data.systemuserid || data;
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
+ });
142
332
  }
143
333
 
144
334
  // ────────────────────────────────────────────────────────────────────────────
@@ -149,7 +339,7 @@ export async function whoAmI() {
149
339
  const DATA_SOURCE_SP = "sharepointonline";
150
340
 
151
341
  // ── Initialize SDK client for the SharePoint connector ─────────
152
- function initClient() {
342
+ function initSpClient() {
153
343
  const dataSourcesInfo = {
154
344
  [DATA_SOURCE_SP]: {
155
345
  tableId: "",
@@ -291,8 +481,8 @@ function initClient() {
291
481
  }
292
482
 
293
483
  // ── Internal: execute a connector operation ────────────────────
294
- async function execOp(operationName, parameters) {
295
- const client = await initClient();
484
+ async function execSpOp(operationName, parameters) {
485
+ const client = await initSpClient();
296
486
  const result = await client.executeAsync({
297
487
  connectorOperation: {
298
488
  tableName: DATA_SOURCE_SP,
@@ -312,17 +502,21 @@ async function execOp(operationName, parameters) {
312
502
 
313
503
  // ── Call any SharePoint connector operation by name ─────────────
314
504
  export async function callSharePointOperation(operationName, parameters = {}) {
315
- return execOp(operationName, parameters);
505
+ return _dbgWrap('callSharePointOperation', [operationName, parameters], async function() {
506
+ return execSpOp(operationName, parameters);
507
+ });
316
508
  }
317
509
 
318
510
  // ── Send HTTP Request (for list-name-based operations) ─────────
319
511
  export async function sendHttpRequest({ method = "GET", uri, headers, body }) {
320
- return execOp("HttpRequest", {
512
+ return _dbgWrap('sendHttpRequest', [{ method, uri, headers, body }], async function() {
513
+ return execSpOp("HttpRequest", {
321
514
  method,
322
515
  uri,
323
516
  headers: headers || {},
324
517
  body: body || "",
325
518
  });
519
+ });
326
520
  }
327
521
 
328
522
  // ═══════════════════════════════════════════════════════════════
@@ -331,49 +525,59 @@ export async function sendHttpRequest({ method = "GET", uri, headers, body }) {
331
525
 
332
526
  // ── Get Items ──────────────────────────────────────────────────
333
527
  export async function getItems(sSiteUrl, sListId, { filter, orderBy, top, skip } = {}) {
528
+ return _dbgWrap('getItems', [sSiteUrl, sListId, { filter, orderBy, top, skip }], async function() {
334
529
  let params = { siteUrl: encodeURIComponent(sSiteUrl), table: sListId };
335
530
  if (filter) params.$filter = filter;
336
531
  if (orderBy) params.$orderby = orderBy;
337
532
  if (top != null) params.$top = top;
338
533
  if (skip != null) params.$skip = skip;
339
- return execOp("GetItems", params);
534
+ return execSpOp("GetItems", params);
535
+ });
340
536
  }
341
537
 
342
538
  // ── Get Item ───────────────────────────────────────────────────
343
- export async function getItem(sSiteUrl, sListId, iItemId) {
344
- return execOp("GetItem", {
539
+ export async function getSpItem(sSiteUrl, sListId, iItemId) {
540
+ return _dbgWrap('getSpItem', [sSiteUrl, sListId, iItemId], async function() {
541
+ return execSpOp("GetItem", {
345
542
  siteUrl: encodeURIComponent(sSiteUrl),
346
543
  table: sListId,
347
544
  id: iItemId,
348
545
  });
546
+ });
349
547
  }
350
548
 
351
549
  // ── Create Item ────────────────────────────────────────────────
352
- export async function createItem(sSiteUrl, sListId, oFields) {
353
- return execOp("PostItem", {
550
+ export async function createSpItem(sSiteUrl, sListId, oFields) {
551
+ return _dbgWrap('createSpItem', [sSiteUrl, sListId, oFields], async function() {
552
+ return execSpOp("PostItem", {
354
553
  siteUrl: encodeURIComponent(sSiteUrl),
355
554
  table: sListId,
356
555
  item: oFields,
357
556
  });
557
+ });
358
558
  }
359
559
 
360
560
  // ── Update Item ────────────────────────────────────────────────
361
- export async function updateItem(sSiteUrl, sListId, iItemId, oChangedFields) {
362
- return execOp("PatchItem", {
561
+ export async function updateSpItem(sSiteUrl, sListId, iItemId, oChangedFields) {
562
+ return _dbgWrap('updateSpItem', [sSiteUrl, sListId, iItemId, oChangedFields], async function() {
563
+ return execSpOp("PatchItem", {
363
564
  siteUrl: encodeURIComponent(sSiteUrl),
364
565
  table: sListId,
365
566
  id: iItemId,
366
567
  item: oChangedFields,
367
568
  });
569
+ });
368
570
  }
369
571
 
370
572
  // ── Delete Item ────────────────────────────────────────────────
371
- export async function deleteItem(sSiteUrl, sListId, iItemId) {
372
- return execOp("DeleteItem", {
573
+ export async function deleteSpItem(sSiteUrl, sListId, iItemId) {
574
+ return _dbgWrap('deleteSpItem', [sSiteUrl, sListId, iItemId], async function() {
575
+ return execSpOp("DeleteItem", {
373
576
  siteUrl: encodeURIComponent(sSiteUrl),
374
577
  table: sListId,
375
578
  id: iItemId,
376
579
  });
580
+ });
377
581
  }
378
582
 
379
583
  // ═══════════════════════════════════════════════════════════════
@@ -382,6 +586,7 @@ export async function deleteItem(sSiteUrl, sListId, iItemId) {
382
586
 
383
587
  // ── Get Items by List Name ─────────────────────────────────────
384
588
  export async function getItemsByName(sSiteUrl, sListName, { filter, orderBy, top, skip } = {}) {
589
+ return _dbgWrap('getItemsByName', [sSiteUrl, sListName, { filter, orderBy, top, skip }], async function() {
385
590
  let sUri = sSiteUrl + "/_api/web/lists/getbytitle('" + sListName + "')/items";
386
591
  let aQuery = [];
387
592
  if (filter) aQuery.push("$filter=" + filter);
@@ -390,30 +595,39 @@ export async function getItemsByName(sSiteUrl, sListName, { filter, orderBy, top
390
595
  if (skip != null) aQuery.push("$skip=" + skip);
391
596
  if (aQuery.length > 0) sUri = sUri + "?" + aQuery.join("&");
392
597
  return sendHttpRequest({ method: "GET", uri: sUri, headers: { Accept: "application/json;odata=nometadata" } });
598
+ });
393
599
  }
394
600
 
395
601
  // ── Get Item by List Name ──────────────────────────────────────
396
602
  export async function getItemByName(sSiteUrl, sListName, iItemId) {
603
+ return _dbgWrap('getItemByName', [sSiteUrl, sListName, iItemId], async function() {
397
604
  let sUri = sSiteUrl + "/_api/web/lists/getbytitle('" + sListName + "')/items(" + iItemId + ")";
398
605
  return sendHttpRequest({ method: "GET", uri: sUri, headers: { Accept: "application/json;odata=nometadata" } });
606
+ });
399
607
  }
400
608
 
401
609
  // ── Create Item by List Name ───────────────────────────────────
402
610
  export async function createItemByName(sSiteUrl, sListName, oFields) {
611
+ return _dbgWrap('createItemByName', [sSiteUrl, sListName, oFields], async function() {
403
612
  let sUri = sSiteUrl + "/_api/web/lists/getbytitle('" + sListName + "')/items";
404
613
  return sendHttpRequest({ method: "POST", uri: sUri, headers: { Accept: "application/json;odata=nometadata", "Content-Type": "application/json;odata=nometadata" }, body: JSON.stringify(oFields) });
614
+ });
405
615
  }
406
616
 
407
617
  // ── Update Item by List Name ───────────────────────────────────
408
618
  export async function updateItemByName(sSiteUrl, sListName, iItemId, oChangedFields) {
619
+ return _dbgWrap('updateItemByName', [sSiteUrl, sListName, iItemId, oChangedFields], async function() {
409
620
  let sUri = sSiteUrl + "/_api/web/lists/getbytitle('" + sListName + "')/items(" + iItemId + ")";
410
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
+ });
411
623
  }
412
624
 
413
625
  // ── Delete Item by List Name ───────────────────────────────────
414
626
  export async function deleteItemByName(sSiteUrl, sListName, iItemId) {
627
+ return _dbgWrap('deleteItemByName', [sSiteUrl, sListName, iItemId], async function() {
415
628
  let sUri = sSiteUrl + "/_api/web/lists/getbytitle('" + sListName + "')/items(" + iItemId + ")";
416
629
  return sendHttpRequest({ method: "DELETE", uri: sUri, headers: { Accept: "application/json;odata=nometadata", "If-Match": "*" } });
630
+ });
417
631
  }
418
632
 
419
633
  // ═══════════════════════════════════════════════════════════════
@@ -422,16 +636,20 @@ export async function deleteItemByName(sSiteUrl, sListName, iItemId) {
422
636
 
423
637
  // ── List Tables (Lists) ────────────────────────────────────────
424
638
  export async function listTables(sSiteUrl) {
425
- return execOp("GetTables", {
639
+ return _dbgWrap('listTables', [sSiteUrl], async function() {
640
+ return execSpOp("GetTables", {
426
641
  siteUrl: encodeURIComponent(sSiteUrl),
427
642
  });
643
+ });
428
644
  }
429
645
 
430
646
  // ── List Library (Document Libraries) ──────────────────────────
431
647
  export async function listLibrary(sSiteUrl) {
432
- return execOp("GetDataSetsMetadata", {
648
+ return _dbgWrap('listLibrary', [sSiteUrl], async function() {
649
+ return execSpOp("GetDataSetsMetadata", {
433
650
  siteUrl: encodeURIComponent(sSiteUrl),
434
651
  });
652
+ });
435
653
  }
436
654
 
437
655
  // ═══════════════════════════════════════════════════════════════
@@ -440,47 +658,57 @@ export async function listLibrary(sSiteUrl) {
440
658
 
441
659
  // ── Create File ────────────────────────────────────────────────
442
660
  export async function createFile(sSiteUrl, sLibraryName, sFileName, fileContent) {
443
- return execOp("CreateFile", {
661
+ return _dbgWrap('createFile', [sSiteUrl, sLibraryName, sFileName, fileContent], async function() {
662
+ return execSpOp("CreateFile", {
444
663
  siteUrl: encodeURIComponent(sSiteUrl),
445
664
  folderPath: sLibraryName,
446
665
  name: sFileName,
447
666
  body: fileContent,
448
667
  });
668
+ });
449
669
  }
450
670
 
451
671
  // ── Update File ────────────────────────────────────────────────
452
672
  export async function updateFile(sSiteUrl, sFileId, fileContent) {
453
- return execOp("UpdateFile", {
673
+ return _dbgWrap('updateFile', [sSiteUrl, sFileId, fileContent], async function() {
674
+ return execSpOp("UpdateFile", {
454
675
  siteUrl: encodeURIComponent(sSiteUrl),
455
676
  id: sFileId,
456
677
  body: fileContent,
457
678
  });
679
+ });
458
680
  }
459
681
 
460
682
  // ── Delete File ────────────────────────────────────────────────
461
683
  export async function deleteFile(sSiteUrl, sFileId) {
462
- return execOp("DeleteFile", {
684
+ return _dbgWrap('deleteFile', [sSiteUrl, sFileId], async function() {
685
+ return execSpOp("DeleteFile", {
463
686
  siteUrl: encodeURIComponent(sSiteUrl),
464
687
  id: sFileId,
465
688
  });
689
+ });
466
690
  }
467
691
 
468
692
  // ── Move File ──────────────────────────────────────────────────
469
693
  export async function moveFile(sSiteUrl, sSourceFileId, sDestinationFolderPath, sNewFileName) {
470
- return execOp("MoveFile", {
694
+ return _dbgWrap('moveFile', [sSiteUrl, sSourceFileId, sDestinationFolderPath, sNewFileName], async function() {
695
+ return execSpOp("MoveFile", {
471
696
  siteUrl: encodeURIComponent(sSiteUrl),
472
697
  id: sSourceFileId,
473
698
  destinationFolderPath: sDestinationFolderPath,
474
699
  newFileName: sNewFileName || "",
475
700
  });
701
+ });
476
702
  }
477
703
 
478
704
  // ── Get File Metadata ──────────────────────────────────────────
479
705
  export async function getFileMetadata(sSiteUrl, sFileId) {
480
- return execOp("GetFileMetadata", {
706
+ return _dbgWrap('getFileMetadata', [sSiteUrl, sFileId], async function() {
707
+ return execSpOp("GetFileMetadata", {
481
708
  siteUrl: encodeURIComponent(sSiteUrl),
482
709
  id: sFileId,
483
710
  });
711
+ });
484
712
  }
485
713
 
486
714
  // ────────────────────────────────────────────────────────────────────────────
@@ -514,7 +742,7 @@ const OUTLOOK_APIS = {
514
742
  };
515
743
 
516
744
  // ── Initialize SDK client for the Office 365 Outlook connector ──
517
- function initClient() {
745
+ function initOutlookClient() {
518
746
  const dataSourcesInfo = {};
519
747
 
520
748
  DATA_SOURCE_CANDIDATES.forEach((sDataSourceName) => {
@@ -530,7 +758,7 @@ function initClient() {
530
758
  return getClient(dataSourcesInfo);
531
759
  }
532
760
 
533
- function stringifyErrorDetails(oError) {
761
+ function stringifyOutlookError(oError) {
534
762
  if (!oError) return "Operation failed";
535
763
  if (typeof oError === "string") return oError;
536
764
  if (oError instanceof Error) return oError.message || "Operation failed";
@@ -548,11 +776,11 @@ function stringifyErrorDetails(oError) {
548
776
  }
549
777
  }
550
778
 
551
- function unwrapResult(oResult) {
779
+ function unwrapOutlookResult(oResult) {
552
780
  if (oResult && oResult.success === false) {
553
- var sMessage = stringifyErrorDetails(oResult.error);
781
+ var sMessage = stringifyOutlookError(oResult.error);
554
782
  if (oResult.data !== undefined) {
555
- sMessage += " | data: " + stringifyErrorDetails(oResult.data);
783
+ sMessage += " | data: " + stringifyOutlookError(oResult.data);
556
784
  }
557
785
  throw new Error(sMessage);
558
786
  }
@@ -565,8 +793,8 @@ function unwrapResult(oResult) {
565
793
  }
566
794
 
567
795
  // ── Internal: execute a connector operation ────────────────────
568
- async function execOp(operationName, parameters) {
569
- const client = await initClient();
796
+ async function execOutlookOp(operationName, parameters) {
797
+ const client = await initOutlookClient();
570
798
  const aErrors = [];
571
799
 
572
800
  for (let iIndex = 0; iIndex < DATA_SOURCE_CANDIDATES.length; iIndex += 1) {
@@ -581,9 +809,9 @@ async function execOp(operationName, parameters) {
581
809
  },
582
810
  });
583
811
 
584
- return unwrapResult(result);
812
+ return unwrapOutlookResult(result);
585
813
  } catch (oErr) {
586
- const sMessage = stringifyErrorDetails(oErr);
814
+ const sMessage = stringifyOutlookError(oErr);
587
815
  aErrors.push(sDataSourceName + ": " + sMessage);
588
816
 
589
817
  if (sMessage.indexOf("Connection reference not found") === -1) {
@@ -597,14 +825,16 @@ async function execOp(operationName, parameters) {
597
825
 
598
826
  // ── List Emails ────────────────────────────────────────────────
599
827
  export async function listEmails({ folderId = "Inbox", fetchOnlyUnread, searchQuery, top, skip } = {}) {
828
+ return _dbgWrap('listEmails', [{ folderId, fetchOnlyUnread, searchQuery, top, skip }], async function() {
600
829
  void skip;
601
830
 
602
- return execOp("GetEmailsV3", {
831
+ return execOutlookOp("GetEmailsV3", {
603
832
  folderPath: folderId,
604
833
  fetchOnlyUnread,
605
834
  searchQuery,
606
835
  top: top != null ? top : 10,
607
836
  });
837
+ });
608
838
  }
609
839
 
610
840
  // ────────────────────────────────────────────────────────────────────────────
@@ -615,7 +845,7 @@ export async function listEmails({ folderId = "Inbox", fetchOnlyUnread, searchQu
615
845
  const DATA_SOURCE_USERS = "office365users";
616
846
 
617
847
  // ── Initialize SDK client for the Office 365 Users connector ───
618
- function initClient() {
848
+ function initUsersClient() {
619
849
  const dataSourcesInfo = {
620
850
  [DATA_SOURCE_USERS]: {
621
851
  tableId: "",
@@ -687,8 +917,8 @@ function initClient() {
687
917
  }
688
918
 
689
919
  // ── Internal: execute a connector operation ────────────────────
690
- async function execOp(operationName, parameters) {
691
- const client = await initClient();
920
+ async function execUsersOp(operationName, parameters) {
921
+ const client = await initUsersClient();
692
922
  const result = await client.executeAsync({
693
923
  connectorOperation: {
694
924
  tableName: DATA_SOURCE_USERS,
@@ -708,17 +938,21 @@ async function execOp(operationName, parameters) {
708
938
 
709
939
  // ── Call any Office 365 Users operation by name ────────────────
710
940
  export async function callUsersOperation(operationName, parameters = {}) {
711
- return execOp(operationName, parameters);
941
+ return _dbgWrap('callUsersOperation', [operationName, parameters], async function() {
942
+ return execUsersOp(operationName, parameters);
943
+ });
712
944
  }
713
945
 
714
946
  // ── Open HTTP Request ──────────────────────────────────────────
715
- export async function openHttpRequest({ method = "GET", uri, headers, body }) {
716
- return execOp("HttpRequest", {
947
+ export async function openUsersHttpRequest({ method = "GET", uri, headers, body }) {
948
+ return _dbgWrap('openUsersHttpRequest', [{ method, uri, headers, body }], async function() {
949
+ return execUsersOp("HttpRequest", {
717
950
  method,
718
951
  uri,
719
952
  headers: headers || {},
720
953
  body: body || "",
721
954
  });
955
+ });
722
956
  }
723
957
 
724
958
  // ═══════════════════════════════════════════════════════════════
@@ -727,14 +961,18 @@ export async function openHttpRequest({ method = "GET", uri, headers, body }) {
727
961
 
728
962
  // ── Get My Profile ─────────────────────────────────────────────
729
963
  export async function getMyProfile() {
730
- return execOp("MyProfile_V2", {});
964
+ return _dbgWrap('getMyProfile', [], async function() {
965
+ return execUsersOp("MyProfile_V2", {});
966
+ });
731
967
  }
732
968
 
733
969
  // ── Get User Profile ───────────────────────────────────────────
734
970
  export async function getUserProfile(userId) {
735
- return execOp("UserProfile_V2", {
971
+ return _dbgWrap('getUserProfile', [userId], async function() {
972
+ return execUsersOp("UserProfile_V2", {
736
973
  id: userId,
737
974
  });
975
+ });
738
976
  }
739
977
 
740
978
  // ═══════════════════════════════════════════════════════════════
@@ -743,16 +981,20 @@ export async function getUserProfile(userId) {
743
981
 
744
982
  // ── Get Manager ────────────────────────────────────────────────
745
983
  export async function getManager(userId) {
746
- return execOp("Manager_V2", {
984
+ return _dbgWrap('getManager', [userId], async function() {
985
+ return execUsersOp("Manager_V2", {
747
986
  id: userId,
748
987
  });
988
+ });
749
989
  }
750
990
 
751
991
  // ── Get Direct Reports ─────────────────────────────────────────
752
992
  export async function getDirectReports(userId) {
753
- return execOp("DirectReports_V2", {
993
+ return _dbgWrap('getDirectReports', [userId], async function() {
994
+ return execUsersOp("DirectReports_V2", {
754
995
  id: userId,
755
996
  });
997
+ });
756
998
  }
757
999
 
758
1000
  // ═══════════════════════════════════════════════════════════════
@@ -761,9 +1003,11 @@ export async function getDirectReports(userId) {
761
1003
 
762
1004
  // ── Get User Photo ─────────────────────────────────────────────
763
1005
  export async function getUserPhoto(userId) {
764
- return execOp("UserPhoto_V2", {
1006
+ return _dbgWrap('getUserPhoto', [userId], async function() {
1007
+ return execUsersOp("UserPhoto_V2", {
765
1008
  id: userId,
766
1009
  });
1010
+ });
767
1011
  }
768
1012
 
769
1013
  // ═══════════════════════════════════════════════════════════════
@@ -772,11 +1016,13 @@ export async function getUserPhoto(userId) {
772
1016
 
773
1017
  // ── Search for Users ───────────────────────────────────────────
774
1018
  export async function searchForUsers({ searchTerm, top, skip } = {}) {
1019
+ return _dbgWrap('searchForUsers', [{ searchTerm, top, skip }], async function() {
775
1020
  const params = {};
776
1021
  if (searchTerm) params.searchTerm = searchTerm;
777
1022
  if (top != null) params.$top = top;
778
1023
  if (skip != null) params.$skip = skip;
779
- return execOp("SearchUser_V2", params);
1024
+ return execUsersOp("SearchUser_V2", params);
1025
+ });
780
1026
  }
781
1027
 
782
1028
  // ────────────────────────────────────────────────────────────────────────────
@@ -788,7 +1034,7 @@ export async function searchForUsers({ searchTerm, top, skip } = {}) {
788
1034
  const DATA_SOURCE_GROUPS = "Office365Groups";
789
1035
 
790
1036
  // ── Initialize SDK client for the Office 365 Groups connector ──
791
- function initClient() {
1037
+ function initGroupsClient() {
792
1038
  const dataSourcesInfo = {
793
1039
  [DATA_SOURCE_GROUPS]: {
794
1040
  tableId: "",
@@ -802,8 +1048,8 @@ function initClient() {
802
1048
  }
803
1049
 
804
1050
  // ── Internal: execute a connector operation ────────────────────
805
- async function execOp(operationName, parameters) {
806
- const client = await initClient();
1051
+ async function execGroupsOp(operationName, parameters) {
1052
+ const client = await initGroupsClient();
807
1053
  return client.executeAsync({
808
1054
  connectorOperation: {
809
1055
  tableName: DATA_SOURCE_GROUPS,
@@ -819,17 +1065,21 @@ async function execOp(operationName, parameters) {
819
1065
 
820
1066
  // ── Call any Office 365 Groups operation by name ───────────────
821
1067
  export async function callGroupsOperation(operationName, parameters = {}) {
822
- return execOp(operationName, parameters);
1068
+ return _dbgWrap('callGroupsOperation', [operationName, parameters], async function() {
1069
+ return execGroupsOp(operationName, parameters);
1070
+ });
823
1071
  }
824
1072
 
825
1073
  // ── Open HTTP Request ──────────────────────────────────────────
826
- export async function openHttpRequest({ method = "GET", uri, headers, body }) {
827
- return execOp("HttpRequest", {
1074
+ export async function openGroupsHttpRequest({ method = "GET", uri, headers, body }) {
1075
+ return _dbgWrap('openGroupsHttpRequest', [{ method, uri, headers, body }], async function() {
1076
+ return execGroupsOp("HttpRequest", {
828
1077
  method,
829
1078
  uri,
830
1079
  headers: headers || {},
831
1080
  body: body || "",
832
1081
  });
1082
+ });
833
1083
  }
834
1084
 
835
1085
  // ═══════════════════════════════════════════════════════════════
@@ -838,12 +1088,16 @@ export async function openHttpRequest({ method = "GET", uri, headers, body }) {
838
1088
 
839
1089
  // ── List My Groups ─────────────────────────────────────────────
840
1090
  export async function listMyGroups() {
841
- return execOp("ListOwnedGroups", {});
1091
+ return _dbgWrap('listMyGroups', [], async function() {
1092
+ return execGroupsOp("ListOwnedGroups", {});
1093
+ });
842
1094
  }
843
1095
 
844
1096
  // ── List Members of a Group ────────────────────────────────────
845
1097
  export async function listGroupMembers(groupId) {
846
- return execOp("ListGroupMembers", {
1098
+ return _dbgWrap('listGroupMembers', [groupId], async function() {
1099
+ return execGroupsOp("ListGroupMembers", {
847
1100
  groupId,
848
1101
  });
1102
+ });
849
1103
  }