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.
Files changed (121) hide show
  1. package/codeApp/dist/codeapp.js +552 -78
  2. package/codeApp/dist/power-apps-data.js +2531 -2531
  3. package/dev files/outlook.js +218 -9
  4. package/examples/combined demo/dist/codeapp.js +1098 -0
  5. package/examples/combined demo/dist/index.js +69 -114
  6. package/examples/combined demo/dist/power-apps-data.js +646 -170
  7. package/examples/combined demo/power.config.json +42 -42
  8. package/examples/dataverse Demo/dist/codeapp.js +1085 -0
  9. package/examples/dataverse Demo/dist/index.html +54 -54
  10. package/examples/dataverse Demo/dist/index.js +82 -70
  11. package/examples/dataverse Demo/dist/power-apps-data.js +551 -170
  12. package/examples/dataverse Demo/power.config.json +34 -34
  13. package/examples/dataverse Demo/readme.md +79 -79
  14. package/examples/groups Demo/dist/codeapp.js +1085 -0
  15. package/examples/groups Demo/dist/index.js +27 -27
  16. package/examples/groups Demo/dist/power-apps-data.js +551 -170
  17. package/examples/kanban/dist/dataverse.js +94 -94
  18. package/examples/kanban/dist/environmentVar.js +55 -55
  19. package/examples/kanban/dist/office365groups.js +97 -97
  20. package/examples/kanban/dist/office365users.js +169 -169
  21. package/examples/kanban/dist/outlook.js +162 -162
  22. package/examples/kanban/dist/power-apps-data.js +560 -138
  23. package/examples/kanban/dist/sharepoint.js +339 -339
  24. package/examples/myProfile/dist/index.html +184 -184
  25. package/examples/myProfile/dist/index.js +141 -141
  26. package/examples/myProfile/dist/office365users.js +169 -169
  27. package/examples/myProfile/dist/power-apps-data.js +560 -138
  28. package/examples/myProfile/power.config.json +22 -22
  29. package/examples/myProfile/readme.md +79 -79
  30. package/examples/outlook Demo/dist/codeapp.js +1085 -0
  31. package/examples/outlook Demo/dist/index.html +35 -35
  32. package/examples/outlook Demo/dist/index.js +170 -166
  33. package/examples/outlook Demo/dist/outlook.js +121 -121
  34. package/examples/outlook Demo/dist/power-apps-data.js +551 -170
  35. package/examples/outlook Demo/dist/styles.css +84 -84
  36. package/examples/outlook Demo/readme.md +82 -82
  37. package/examples/outlook Demo2/OutlookDemo_1_0_0_1.zip +0 -0
  38. package/examples/outlook Demo2/agent/decision-log.md +7 -0
  39. package/examples/outlook Demo2/dist/codeapp.js +1334 -0
  40. package/examples/outlook Demo2/dist/icon-512.png +0 -0
  41. package/examples/outlook Demo2/dist/index.html +98 -0
  42. package/examples/outlook Demo2/dist/index.js +346 -0
  43. package/examples/outlook Demo2/dist/power-apps-data.js +3007 -0
  44. package/examples/outlook Demo2/dist/styles.css +639 -0
  45. package/examples/outlook Demo2/power.config.json +23 -0
  46. package/examples/outlook Demo2/src/generated/index.ts +14 -0
  47. package/examples/outlook Demo2/src/generated/models/Office365GroupsModel.ts +363 -0
  48. package/examples/outlook Demo2/src/generated/models/Office365OutlookModel.ts +2046 -0
  49. package/examples/outlook Demo2/src/generated/models/Office365UsersModel.ts +254 -0
  50. package/examples/outlook Demo2/src/generated/services/Office365GroupsService.ts +326 -0
  51. package/examples/outlook Demo2/src/generated/services/Office365OutlookService.ts +2476 -0
  52. package/examples/outlook Demo2/src/generated/services/Office365UsersService.ts +358 -0
  53. package/examples/planning Poker/.vscode/settings.json +4 -4
  54. package/examples/planning Poker/additional files/customizations (tables).xml +6428 -6428
  55. package/examples/planning Poker/additional files/dataverse-tables.json +165 -165
  56. package/examples/planning Poker/additional files/readme.md +122 -122
  57. package/examples/planning Poker/dist/dataverse.js +78 -78
  58. package/examples/planning Poker/dist/index.html +198 -198
  59. package/examples/planning Poker/dist/index.js +954 -954
  60. package/examples/planning Poker/dist/power-apps-data.js +560 -138
  61. package/examples/planning Poker/dist/styles.css +815 -815
  62. package/examples/sharePoint Demo/agent/decision-log.md +5 -5
  63. package/examples/sharePoint Demo/dist/codeapp.js +1085 -0
  64. package/examples/sharePoint Demo/dist/index.js +44 -51
  65. package/examples/sharePoint Demo/dist/power-apps-data.js +551 -170
  66. package/examples/sharePoint Demo/power.config.json +22 -22
  67. package/examples/solution explorer/agent/decision-log.md +27 -0
  68. package/examples/solution explorer/agent/mockup-01-swiss-grid.html +452 -0
  69. package/examples/solution explorer/agent/mockup-02-dark-glass.html +496 -0
  70. package/examples/solution explorer/agent/mockup-03-paper-console.html +510 -0
  71. package/examples/solution explorer/agent/mockup-04-neon-noir.html +546 -0
  72. package/examples/solution explorer/agent/mockup-05-zen-garden.html +534 -0
  73. package/examples/solution explorer/dist/codeapp.js +1098 -0
  74. package/examples/solution explorer/dist/icon-512.png +0 -0
  75. package/examples/solution explorer/dist/index.html +80 -0
  76. package/examples/solution explorer/dist/index.js +735 -0
  77. package/examples/solution explorer/dist/power-apps-data.js +3007 -0
  78. package/examples/solution explorer/dist/styles.css +571 -0
  79. package/examples/solution explorer/power.config.json +151 -0
  80. package/examples/todo/dist/dataverse.js +64 -64
  81. package/examples/todo/dist/index.html +75 -75
  82. package/examples/todo/dist/index.js +8 -8
  83. package/examples/todo/dist/power-apps-data.js +560 -138
  84. package/examples/todo/dist/renderer.js +375 -375
  85. package/examples/todo/dist/styles.css +691 -691
  86. package/examples/todo/power.config.json +34 -34
  87. package/package.json +1 -8
  88. package/docs-mockups/atelier/index.html +0 -120
  89. package/docs-mockups/atelier/script.js +0 -23
  90. package/docs-mockups/atelier/styles.css +0 -361
  91. package/docs-mockups/field-guide/index.html +0 -112
  92. package/docs-mockups/field-guide/script.js +0 -20
  93. package/docs-mockups/field-guide/styles.css +0 -272
  94. package/docs-mockups/index.html +0 -80
  95. package/docs-mockups/maker-hub/index.html +0 -178
  96. package/docs-mockups/maker-hub/script.js +0 -20
  97. package/docs-mockups/maker-hub/styles.css +0 -404
  98. package/docs-mockups/script.js +0 -26
  99. package/docs-mockups/signal/index.html +0 -146
  100. package/docs-mockups/signal/script.js +0 -20
  101. package/docs-mockups/signal/styles.css +0 -314
  102. package/docs-mockups/styles.css +0 -287
  103. package/examples/combined demo/dist/dataverse.js +0 -86
  104. package/examples/combined demo/dist/environmentVar.js +0 -55
  105. package/examples/combined demo/dist/office365groups.js +0 -97
  106. package/examples/combined demo/dist/office365users.js +0 -169
  107. package/examples/combined demo/dist/outlook.js +0 -162
  108. package/examples/combined demo/dist/sharepoint.js +0 -339
  109. package/examples/dataverse Demo/dist/dataverse.js +0 -86
  110. package/examples/groups Demo/dist/dataverse.js +0 -86
  111. package/examples/groups Demo/dist/environmentVar.js +0 -55
  112. package/examples/groups Demo/dist/office365groups.js +0 -97
  113. package/examples/groups Demo/dist/office365users.js +0 -169
  114. package/examples/groups Demo/dist/outlook.js +0 -162
  115. package/examples/groups Demo/dist/sharepoint.js +0 -339
  116. package/examples/sharePoint Demo/dist/dataverse.js +0 -94
  117. package/examples/sharePoint Demo/dist/environmentVar.js +0 -55
  118. package/examples/sharePoint Demo/dist/office365groups.js +0 -97
  119. package/examples/sharePoint Demo/dist/office365users.js +0 -169
  120. package/examples/sharePoint Demo/dist/outlook.js +0 -162
  121. package/examples/sharePoint Demo/dist/sharepoint.js +0 -339
@@ -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
  // ────────────────────────────────────────────────────────────────────────────
@@ -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 initClient() {
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 stringifyErrorDetails(oError) {
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 unwrapResult(oResult) {
874
+ function unwrapOutlookResult(oResult) {
563
875
  if (oResult && oResult.success === false) {
564
- var sMessage = stringifyErrorDetails(oResult.error);
876
+ var sMessage = stringifyOutlookError(oResult.error);
565
877
  if (oResult.data !== undefined) {
566
- sMessage += " | data: " + stringifyErrorDetails(oResult.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 execOp(operationName, parameters) {
580
- const client = await initClient();
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 unwrapResult(result);
907
+ return unwrapOutlookResult(result);
596
908
  } catch (oErr) {
597
- const sMessage = stringifyErrorDetails(oErr);
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
- void skip;
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 initClient() {
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 execOp(operationName, parameters) {
702
- const client = await initClient();
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 execOp(operationName, parameters);
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 openHttpRequest({ method = "GET", uri, headers, body }) {
727
- return execOp("HttpRequest", {
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 execOp("MyProfile_V2", {});
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 execOp("UserProfile_V2", {
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 execOp("Manager_V2", {
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 execOp("DirectReports_V2", {
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 execOp("UserPhoto_V2", {
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 execOp("SearchUser_V2", params);
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 initClient() {
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 execOp(operationName, parameters) {
817
- const client = await initClient();
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 execOp(operationName, parameters);
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 openHttpRequest({ method = "GET", uri, headers, body }) {
838
- return execOp("HttpRequest", {
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 execOp("ListOwnedGroups", {});
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 execOp("ListGroupMembers", {
1329
+ return _dbgWrap('listGroupMembers', [groupId], async function() {
1330
+ return execGroupsOp("ListGroupMembers", {
858
1331
  groupId,
859
1332
  });
1333
+ });
860
1334
  }