codeapp-js 0.1.1 → 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 (80) hide show
  1. package/codeApp/dist/codeapp.js +317 -74
  2. package/codeApp/dist/index.js +1 -1
  3. package/codeApp/dist/power-apps-data.js +2952 -2531
  4. package/dev files/customConnector.js +98 -0
  5. package/dev files/dataverse.js +22 -7
  6. package/dev files/environmentVar.js +1 -1
  7. package/dev files/office365groups.js +1 -1
  8. package/dev files/office365users.js +1 -1
  9. package/dev files/outlook.js +1 -1
  10. package/dev files/power-apps-data.js +2952 -0
  11. package/dev files/sharepoint.js +1 -1
  12. package/examples/combined demo/dist/codeapp.js +1098 -0
  13. package/examples/combined demo/dist/index.js +470 -515
  14. package/examples/combined demo/dist/power-apps-data.js +3007 -2531
  15. package/examples/dataverse Demo/dist/codeapp.js +1085 -0
  16. package/examples/dataverse Demo/dist/index.js +38 -26
  17. package/examples/dataverse Demo/dist/power-apps-data.js +2912 -2531
  18. package/examples/groups Demo/dist/codeapp.js +1085 -0
  19. package/examples/groups Demo/dist/index.js +113 -113
  20. package/examples/groups Demo/dist/power-apps-data.js +2912 -2531
  21. package/examples/kanban/dist/power-apps-data.js +2953 -2531
  22. package/examples/myProfile/dist/power-apps-data.js +2953 -2531
  23. package/examples/outlook Demo/dist/codeapp.js +1085 -0
  24. package/examples/outlook Demo/dist/index.js +39 -35
  25. package/examples/outlook Demo/dist/power-apps-data.js +2912 -2531
  26. package/examples/planning Poker/dist/power-apps-data.js +2953 -2531
  27. package/examples/sharePoint Demo/dist/codeapp.js +1085 -0
  28. package/examples/sharePoint Demo/dist/index.js +262 -269
  29. package/examples/sharePoint Demo/dist/power-apps-data.js +2912 -2531
  30. package/examples/solution explorer/agent/decision-log.md +27 -0
  31. package/examples/solution explorer/agent/mockup-01-swiss-grid.html +452 -0
  32. package/examples/solution explorer/agent/mockup-02-dark-glass.html +496 -0
  33. package/examples/solution explorer/agent/mockup-03-paper-console.html +510 -0
  34. package/examples/solution explorer/agent/mockup-04-neon-noir.html +546 -0
  35. package/examples/solution explorer/agent/mockup-05-zen-garden.html +534 -0
  36. package/examples/solution explorer/dist/codeapp.js +1098 -0
  37. package/examples/solution explorer/dist/icon-512.png +0 -0
  38. package/examples/solution explorer/dist/index.html +80 -0
  39. package/examples/solution explorer/dist/index.js +735 -0
  40. package/examples/solution explorer/dist/power-apps-data.js +3007 -0
  41. package/examples/solution explorer/dist/styles.css +571 -0
  42. package/examples/solution explorer/power.config.json +151 -0
  43. package/examples/todo/dist/power-apps-data.js +2953 -2531
  44. package/package.json +1 -8
  45. package/.github/instructions/wyattdave.instructions.md +0 -39
  46. package/docs-mockups/atelier/index.html +0 -120
  47. package/docs-mockups/atelier/script.js +0 -23
  48. package/docs-mockups/atelier/styles.css +0 -361
  49. package/docs-mockups/field-guide/index.html +0 -112
  50. package/docs-mockups/field-guide/script.js +0 -20
  51. package/docs-mockups/field-guide/styles.css +0 -272
  52. package/docs-mockups/index.html +0 -80
  53. package/docs-mockups/maker-hub/index.html +0 -178
  54. package/docs-mockups/maker-hub/script.js +0 -20
  55. package/docs-mockups/maker-hub/styles.css +0 -404
  56. package/docs-mockups/script.js +0 -26
  57. package/docs-mockups/signal/index.html +0 -146
  58. package/docs-mockups/signal/script.js +0 -20
  59. package/docs-mockups/signal/styles.css +0 -314
  60. package/docs-mockups/styles.css +0 -287
  61. package/examples/combined demo/dist/dataverse.js +0 -86
  62. package/examples/combined demo/dist/environmentVar.js +0 -55
  63. package/examples/combined demo/dist/office365groups.js +0 -97
  64. package/examples/combined demo/dist/office365users.js +0 -169
  65. package/examples/combined demo/dist/outlook.js +0 -162
  66. package/examples/combined demo/dist/sharepoint.js +0 -339
  67. package/examples/dataverse Demo/dist/dataverse.js +0 -86
  68. package/examples/groups Demo/dist/dataverse.js +0 -86
  69. package/examples/groups Demo/dist/environmentVar.js +0 -55
  70. package/examples/groups Demo/dist/office365groups.js +0 -97
  71. package/examples/groups Demo/dist/office365users.js +0 -169
  72. package/examples/groups Demo/dist/outlook.js +0 -162
  73. package/examples/groups Demo/dist/sharepoint.js +0 -339
  74. package/examples/sharePoint Demo/dist/dataverse.js +0 -94
  75. package/examples/sharePoint Demo/dist/environmentVar.js +0 -55
  76. package/examples/sharePoint Demo/dist/office365groups.js +0 -97
  77. package/examples/sharePoint Demo/dist/office365users.js +0 -169
  78. package/examples/sharePoint Demo/dist/outlook.js +0 -162
  79. package/examples/sharePoint Demo/dist/sharepoint.js +0 -339
  80. 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,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
- const client = getSharedClient();
143
- 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 || {});
144
319
  return unwrapResult(result);
320
+ });
145
321
  }
146
322
 
147
323
  // ── WhoAmI ─────────────────────────────────────────────────────
148
324
  export async function whoAmI() {
149
- const client = getSharedClient();
150
- const result = await client.invokeActionAsync('', 'WhoAmI', {});
151
- var data = unwrapResult(result);
152
- 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
+ });
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 initClient() {
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 execOp(operationName, parameters) {
306
- const client = await initClient();
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 execOp(operationName, parameters);
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 execOp("HttpRequest", {
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 execOp("GetItems", params);
534
+ return execSpOp("GetItems", params);
535
+ });
351
536
  }
352
537
 
353
538
  // ── Get Item ───────────────────────────────────────────────────
354
- export async function getItem(sSiteUrl, sListId, iItemId) {
355
- return execOp("GetItem", {
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 createItem(sSiteUrl, sListId, oFields) {
364
- return execOp("PostItem", {
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 updateItem(sSiteUrl, sListId, iItemId, oChangedFields) {
373
- 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", {
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 deleteItem(sSiteUrl, sListId, iItemId) {
383
- return execOp("DeleteItem", {
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 execOp("GetTables", {
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 execOp("GetDataSetsMetadata", {
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 execOp("CreateFile", {
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 execOp("UpdateFile", {
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 execOp("DeleteFile", {
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 execOp("MoveFile", {
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 execOp("GetFileMetadata", {
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
  // ────────────────────────────────────────────────────────────────────────────
@@ -525,7 +742,7 @@ const OUTLOOK_APIS = {
525
742
  };
526
743
 
527
744
  // ── Initialize SDK client for the Office 365 Outlook connector ──
528
- function initClient() {
745
+ function initOutlookClient() {
529
746
  const dataSourcesInfo = {};
530
747
 
531
748
  DATA_SOURCE_CANDIDATES.forEach((sDataSourceName) => {
@@ -541,7 +758,7 @@ function initClient() {
541
758
  return getClient(dataSourcesInfo);
542
759
  }
543
760
 
544
- function stringifyErrorDetails(oError) {
761
+ function stringifyOutlookError(oError) {
545
762
  if (!oError) return "Operation failed";
546
763
  if (typeof oError === "string") return oError;
547
764
  if (oError instanceof Error) return oError.message || "Operation failed";
@@ -559,11 +776,11 @@ function stringifyErrorDetails(oError) {
559
776
  }
560
777
  }
561
778
 
562
- function unwrapResult(oResult) {
779
+ function unwrapOutlookResult(oResult) {
563
780
  if (oResult && oResult.success === false) {
564
- var sMessage = stringifyErrorDetails(oResult.error);
781
+ var sMessage = stringifyOutlookError(oResult.error);
565
782
  if (oResult.data !== undefined) {
566
- sMessage += " | data: " + stringifyErrorDetails(oResult.data);
783
+ sMessage += " | data: " + stringifyOutlookError(oResult.data);
567
784
  }
568
785
  throw new Error(sMessage);
569
786
  }
@@ -576,8 +793,8 @@ function unwrapResult(oResult) {
576
793
  }
577
794
 
578
795
  // ── Internal: execute a connector operation ────────────────────
579
- async function execOp(operationName, parameters) {
580
- const client = await initClient();
796
+ async function execOutlookOp(operationName, parameters) {
797
+ const client = await initOutlookClient();
581
798
  const aErrors = [];
582
799
 
583
800
  for (let iIndex = 0; iIndex < DATA_SOURCE_CANDIDATES.length; iIndex += 1) {
@@ -592,9 +809,9 @@ async function execOp(operationName, parameters) {
592
809
  },
593
810
  });
594
811
 
595
- return unwrapResult(result);
812
+ return unwrapOutlookResult(result);
596
813
  } catch (oErr) {
597
- const sMessage = stringifyErrorDetails(oErr);
814
+ const sMessage = stringifyOutlookError(oErr);
598
815
  aErrors.push(sDataSourceName + ": " + sMessage);
599
816
 
600
817
  if (sMessage.indexOf("Connection reference not found") === -1) {
@@ -608,14 +825,16 @@ async function execOp(operationName, parameters) {
608
825
 
609
826
  // ── List Emails ────────────────────────────────────────────────
610
827
  export async function listEmails({ folderId = "Inbox", fetchOnlyUnread, searchQuery, top, skip } = {}) {
828
+ return _dbgWrap('listEmails', [{ folderId, fetchOnlyUnread, searchQuery, top, skip }], async function() {
611
829
  void skip;
612
830
 
613
- return execOp("GetEmailsV3", {
831
+ return execOutlookOp("GetEmailsV3", {
614
832
  folderPath: folderId,
615
833
  fetchOnlyUnread,
616
834
  searchQuery,
617
835
  top: top != null ? top : 10,
618
836
  });
837
+ });
619
838
  }
620
839
 
621
840
  // ────────────────────────────────────────────────────────────────────────────
@@ -626,7 +845,7 @@ export async function listEmails({ folderId = "Inbox", fetchOnlyUnread, searchQu
626
845
  const DATA_SOURCE_USERS = "office365users";
627
846
 
628
847
  // ── Initialize SDK client for the Office 365 Users connector ───
629
- function initClient() {
848
+ function initUsersClient() {
630
849
  const dataSourcesInfo = {
631
850
  [DATA_SOURCE_USERS]: {
632
851
  tableId: "",
@@ -698,8 +917,8 @@ function initClient() {
698
917
  }
699
918
 
700
919
  // ── Internal: execute a connector operation ────────────────────
701
- async function execOp(operationName, parameters) {
702
- const client = await initClient();
920
+ async function execUsersOp(operationName, parameters) {
921
+ const client = await initUsersClient();
703
922
  const result = await client.executeAsync({
704
923
  connectorOperation: {
705
924
  tableName: DATA_SOURCE_USERS,
@@ -719,17 +938,21 @@ async function execOp(operationName, parameters) {
719
938
 
720
939
  // ── Call any Office 365 Users operation by name ────────────────
721
940
  export async function callUsersOperation(operationName, parameters = {}) {
722
- return execOp(operationName, parameters);
941
+ return _dbgWrap('callUsersOperation', [operationName, parameters], async function() {
942
+ return execUsersOp(operationName, parameters);
943
+ });
723
944
  }
724
945
 
725
946
  // ── Open HTTP Request ──────────────────────────────────────────
726
- export async function openHttpRequest({ method = "GET", uri, headers, body }) {
727
- 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", {
728
950
  method,
729
951
  uri,
730
952
  headers: headers || {},
731
953
  body: body || "",
732
954
  });
955
+ });
733
956
  }
734
957
 
735
958
  // ═══════════════════════════════════════════════════════════════
@@ -738,14 +961,18 @@ export async function openHttpRequest({ method = "GET", uri, headers, body }) {
738
961
 
739
962
  // ── Get My Profile ─────────────────────────────────────────────
740
963
  export async function getMyProfile() {
741
- return execOp("MyProfile_V2", {});
964
+ return _dbgWrap('getMyProfile', [], async function() {
965
+ return execUsersOp("MyProfile_V2", {});
966
+ });
742
967
  }
743
968
 
744
969
  // ── Get User Profile ───────────────────────────────────────────
745
970
  export async function getUserProfile(userId) {
746
- return execOp("UserProfile_V2", {
971
+ return _dbgWrap('getUserProfile', [userId], async function() {
972
+ return execUsersOp("UserProfile_V2", {
747
973
  id: userId,
748
974
  });
975
+ });
749
976
  }
750
977
 
751
978
  // ═══════════════════════════════════════════════════════════════
@@ -754,16 +981,20 @@ export async function getUserProfile(userId) {
754
981
 
755
982
  // ── Get Manager ────────────────────────────────────────────────
756
983
  export async function getManager(userId) {
757
- return execOp("Manager_V2", {
984
+ return _dbgWrap('getManager', [userId], async function() {
985
+ return execUsersOp("Manager_V2", {
758
986
  id: userId,
759
987
  });
988
+ });
760
989
  }
761
990
 
762
991
  // ── Get Direct Reports ─────────────────────────────────────────
763
992
  export async function getDirectReports(userId) {
764
- return execOp("DirectReports_V2", {
993
+ return _dbgWrap('getDirectReports', [userId], async function() {
994
+ return execUsersOp("DirectReports_V2", {
765
995
  id: userId,
766
996
  });
997
+ });
767
998
  }
768
999
 
769
1000
  // ═══════════════════════════════════════════════════════════════
@@ -772,9 +1003,11 @@ export async function getDirectReports(userId) {
772
1003
 
773
1004
  // ── Get User Photo ─────────────────────────────────────────────
774
1005
  export async function getUserPhoto(userId) {
775
- return execOp("UserPhoto_V2", {
1006
+ return _dbgWrap('getUserPhoto', [userId], async function() {
1007
+ return execUsersOp("UserPhoto_V2", {
776
1008
  id: userId,
777
1009
  });
1010
+ });
778
1011
  }
779
1012
 
780
1013
  // ═══════════════════════════════════════════════════════════════
@@ -783,11 +1016,13 @@ export async function getUserPhoto(userId) {
783
1016
 
784
1017
  // ── Search for Users ───────────────────────────────────────────
785
1018
  export async function searchForUsers({ searchTerm, top, skip } = {}) {
1019
+ return _dbgWrap('searchForUsers', [{ searchTerm, top, skip }], async function() {
786
1020
  const params = {};
787
1021
  if (searchTerm) params.searchTerm = searchTerm;
788
1022
  if (top != null) params.$top = top;
789
1023
  if (skip != null) params.$skip = skip;
790
- return execOp("SearchUser_V2", params);
1024
+ return execUsersOp("SearchUser_V2", params);
1025
+ });
791
1026
  }
792
1027
 
793
1028
  // ────────────────────────────────────────────────────────────────────────────
@@ -799,7 +1034,7 @@ export async function searchForUsers({ searchTerm, top, skip } = {}) {
799
1034
  const DATA_SOURCE_GROUPS = "Office365Groups";
800
1035
 
801
1036
  // ── Initialize SDK client for the Office 365 Groups connector ──
802
- function initClient() {
1037
+ function initGroupsClient() {
803
1038
  const dataSourcesInfo = {
804
1039
  [DATA_SOURCE_GROUPS]: {
805
1040
  tableId: "",
@@ -813,8 +1048,8 @@ function initClient() {
813
1048
  }
814
1049
 
815
1050
  // ── Internal: execute a connector operation ────────────────────
816
- async function execOp(operationName, parameters) {
817
- const client = await initClient();
1051
+ async function execGroupsOp(operationName, parameters) {
1052
+ const client = await initGroupsClient();
818
1053
  return client.executeAsync({
819
1054
  connectorOperation: {
820
1055
  tableName: DATA_SOURCE_GROUPS,
@@ -830,17 +1065,21 @@ async function execOp(operationName, parameters) {
830
1065
 
831
1066
  // ── Call any Office 365 Groups operation by name ───────────────
832
1067
  export async function callGroupsOperation(operationName, parameters = {}) {
833
- return execOp(operationName, parameters);
1068
+ return _dbgWrap('callGroupsOperation', [operationName, parameters], async function() {
1069
+ return execGroupsOp(operationName, parameters);
1070
+ });
834
1071
  }
835
1072
 
836
1073
  // ── Open HTTP Request ──────────────────────────────────────────
837
- export async function openHttpRequest({ method = "GET", uri, headers, body }) {
838
- 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", {
839
1077
  method,
840
1078
  uri,
841
1079
  headers: headers || {},
842
1080
  body: body || "",
843
1081
  });
1082
+ });
844
1083
  }
845
1084
 
846
1085
  // ═══════════════════════════════════════════════════════════════
@@ -849,12 +1088,16 @@ export async function openHttpRequest({ method = "GET", uri, headers, body }) {
849
1088
 
850
1089
  // ── List My Groups ─────────────────────────────────────────────
851
1090
  export async function listMyGroups() {
852
- return execOp("ListOwnedGroups", {});
1091
+ return _dbgWrap('listMyGroups', [], async function() {
1092
+ return execGroupsOp("ListOwnedGroups", {});
1093
+ });
853
1094
  }
854
1095
 
855
1096
  // ── List Members of a Group ────────────────────────────────────
856
1097
  export async function listGroupMembers(groupId) {
857
- return execOp("ListGroupMembers", {
1098
+ return _dbgWrap('listGroupMembers', [groupId], async function() {
1099
+ return execGroupsOp("ListGroupMembers", {
858
1100
  groupId,
859
1101
  });
1102
+ });
860
1103
  }