codeapp-js 0.3.0 → 1.0.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 (158) hide show
  1. package/AI/codeapp.agent.md +105 -0
  2. package/AI/skills/connections/SKILL.md +47 -0
  3. package/AI/skills/dataverse/SKILL.md +99 -0
  4. package/AI/skills/environment-variables/SKILL.md +89 -0
  5. package/AI/skills/frontend-design/SKILL.md +34 -0
  6. package/AI/skills/jira/SKILL.md +81 -0
  7. package/AI/skills/office365-groups/SKILL.md +61 -0
  8. package/AI/skills/office365-outlook/SKILL.md +52 -0
  9. package/AI/skills/office365-users/SKILL.md +78 -0
  10. package/AI/skills/sharepoint/SKILL.md +77 -0
  11. package/AI/skills/sql/SKILL.md +85 -0
  12. package/AI/skills/start/SKILL.md +46 -0
  13. package/AI/skills/teams/SKILL.md +55 -0
  14. package/{examples/combined demo/.power/schemas/office365groups/office365groups.Schema.json → codeApp/.power/schemas/office365groups/office365groups.Schema.json} +2203 -2203
  15. package/codeApp/dist/codeapp.js +95 -1792
  16. package/codeApp/dist/connectors/azureKeyvault.js +459 -0
  17. package/codeApp/dist/connectors/jira.js +1247 -0
  18. package/codeApp/dist/connectors/office365groups.js +642 -0
  19. package/codeApp/dist/connectors/office365users.js +513 -0
  20. package/codeApp/dist/connectors/outlook.js +1393 -0
  21. package/codeApp/dist/connectors/sharepoint.js +466 -0
  22. package/codeApp/dist/connectors/sql.js +149 -0
  23. package/codeApp/dist/connectors/teams.js +280 -0
  24. package/codeApp/dist/power-apps-data.js +16 -2
  25. package/examples/{kanban → apps/kanban}/dist/dataverse.js +94 -94
  26. package/examples/{kanban → apps/kanban}/dist/environmentVar.js +55 -55
  27. package/examples/{kanban → apps/kanban}/dist/index.css +605 -605
  28. package/examples/{kanban → apps/kanban}/dist/index.html +21 -21
  29. package/examples/{kanban → apps/kanban}/dist/index.js +860 -860
  30. package/examples/{kanban → apps/kanban}/dist/office365groups.js +97 -97
  31. package/examples/apps/kanban/dist/office365users.js +451 -0
  32. package/examples/{kanban → apps/kanban}/dist/outlook.js +162 -162
  33. package/examples/{planning Poker/dist/power-apps-data.js → apps/kanban/dist/power-apps-data.js} +2953 -2953
  34. package/examples/{kanban → apps/kanban}/dist/sharepoint.js +435 -339
  35. package/examples/{kanban → apps/kanban}/power.config.json +35 -35
  36. package/examples/{planning Poker → apps/planning Poker}/additional files/customizations (tables).xml +6428 -6428
  37. package/examples/{planning Poker → apps/planning Poker}/additional files/dataverse-tables.json +165 -165
  38. package/examples/{planning Poker → apps/planning Poker}/additional files/readme.md +122 -122
  39. package/examples/{planning Poker → apps/planning Poker}/dist/dataverse.js +78 -78
  40. package/examples/{planning Poker → apps/planning Poker}/dist/index.html +198 -198
  41. package/examples/{planning Poker → apps/planning Poker}/dist/index.js +954 -954
  42. package/examples/{todo/dist/power-apps-data.js → apps/planning Poker/dist/power-apps-data.js } +2953 -2953
  43. package/examples/{planning Poker → apps/planning Poker}/dist/styles.css +815 -815
  44. package/examples/{planning Poker → apps/planning Poker}/power.config.json +50 -50
  45. package/examples/{outlook Demo2 → apps/solution explorer}/dist/codeapp.js +9 -245
  46. package/examples/apps/solution explorer/dist/index.html +80 -0
  47. package/examples/apps/solution explorer/dist/index.js +735 -0
  48. package/examples/apps/solution explorer/dist/styles.css +571 -0
  49. package/examples/apps/solution explorer/power.config.json +151 -0
  50. package/examples/{todo → apps/todo}/dist/dataverse.js +64 -64
  51. package/examples/{todo → apps/todo}/dist/index.html +75 -75
  52. package/examples/{todo → apps/todo}/dist/index.js +8 -8
  53. package/examples/{kanban → apps/todo}/dist/power-apps-data.js +2953 -2953
  54. package/examples/{todo → apps/todo}/dist/renderer.js +375 -375
  55. package/examples/{todo → apps/todo}/dist/styles.css +691 -691
  56. package/examples/{todo → apps/todo}/power.config.json +34 -34
  57. package/examples/combined demo/.power/schemas/appschemas/dataSourcesInfo.ts +6275 -7830
  58. package/examples/combined demo/.power/schemas/jira/jira.Schema.json +6903 -0
  59. package/examples/combined demo/.power/schemas/keyvault/keyvault.Schema.json +1600 -0
  60. package/examples/combined demo/.power/schemas/teams/teams.Schema.json +11112 -0
  61. package/examples/combined demo/dist/codeapp.js +394 -1098
  62. package/examples/{outlook Demo2/OutlookDemo_1_0_0_1.zip → combined demo/dist/icon-512.png} +0 -0
  63. package/examples/combined demo/dist/index.html +29 -511
  64. package/examples/combined demo/dist/index.js +490 -470
  65. package/examples/combined demo/dist/office365users.js +513 -0
  66. package/examples/combined demo/dist/outlook.js +1393 -0
  67. package/examples/combined demo/dist/power-apps-data.js +3079 -3006
  68. package/examples/combined demo/dist/styles.css +483 -0
  69. package/examples/combined demo/power.config.json +33 -42
  70. package/examples/combined demo/src/generated/index.ts +12 -14
  71. package/examples/combined demo/src/generated/models/AzureKeyVaultModel.ts +107 -0
  72. package/examples/combined demo/src/generated/models/JiraModel.ts +501 -0
  73. package/examples/combined demo/src/generated/services/AzureKeyVaultService.ts +257 -0
  74. package/examples/combined demo/src/generated/services/JiraService.ts +1124 -0
  75. package/examples/dataverse Demo/dist/codeapp.js +394 -1085
  76. package/examples/dataverse Demo/dist/icon-512.png +0 -0
  77. package/examples/dataverse Demo/dist/index.html +146 -54
  78. package/examples/dataverse Demo/dist/index.js +693 -83
  79. package/examples/dataverse Demo/dist/power-apps-data.js +3079 -2911
  80. package/examples/dataverse Demo/dist/styles.css +528 -0
  81. package/examples/dataverse Demo/power.config.json +41 -35
  82. package/examples/dataverse Demo/readme.md +79 -79
  83. package/examples/groups Demo/dist/codeapp.js +394 -1085
  84. package/examples/groups Demo/dist/icon-512.png +0 -0
  85. package/examples/groups Demo/dist/index.html +21 -25
  86. package/examples/groups Demo/dist/index.js +304 -113
  87. package/examples/groups Demo/dist/office365groups.js +642 -0
  88. package/examples/groups Demo/dist/power-apps-data.js +3079 -2911
  89. package/examples/groups Demo/dist/styles.css +509 -0
  90. package/examples/groups Demo/power.config.json +25 -25
  91. package/examples/myProfile/dist/codeapp.js +398 -0
  92. package/examples/myProfile/dist/index.html +21 -184
  93. package/examples/myProfile/dist/index.js +324 -141
  94. package/examples/myProfile/dist/office365users.js +517 -169
  95. package/examples/myProfile/dist/power-apps-data.js +3080 -2953
  96. package/examples/myProfile/dist/styles.css +458 -0
  97. package/examples/myProfile/power.config.json +24 -23
  98. package/examples/outlook Demo/dist/codeapp.js +394 -1085
  99. package/examples/outlook Demo/dist/index.html +150 -35
  100. package/examples/outlook Demo/dist/index.js +516 -170
  101. package/examples/outlook Demo/dist/outlook.js +1393 -121
  102. package/examples/outlook Demo/dist/power-apps-data.js +3079 -2911
  103. package/examples/outlook Demo/dist/styles.css +408 -84
  104. package/examples/outlook Demo/power.config.json +24 -23
  105. package/examples/outlook Demo/readme.md +92 -82
  106. package/examples/sharePoint Demo/dist/codeapp.js +394 -1085
  107. package/examples/sharePoint Demo/dist/icon-512.png +0 -0
  108. package/examples/sharePoint Demo/dist/index.html +22 -255
  109. package/examples/sharePoint Demo/dist/index.js +899 -262
  110. package/examples/sharePoint Demo/dist/power-apps-data.js +3079 -2911
  111. package/{dev files → examples/sharePoint Demo/dist}/sharepoint.js +239 -112
  112. package/examples/sharePoint Demo/dist/styles.css +587 -0
  113. package/examples/sharePoint Demo/power.config.json +23 -22
  114. package/package.json +1 -1
  115. package/readme.md +465 -76
  116. package/.vscode/settings.json +0 -6
  117. package/dev files/customConnector.js +0 -98
  118. package/dev files/dataverse.js +0 -120
  119. package/dev files/environmentVar.js +0 -55
  120. package/dev files/office365groups.js +0 -65
  121. package/dev files/office365users.js +0 -169
  122. package/dev files/outlook.js +0 -330
  123. package/dev files/power-apps-data.js +0 -2952
  124. package/examples/combined demo/.power/schemas/office365/office365.Schema.json +0 -21098
  125. package/examples/combined demo/.power/schemas/office365users/office365users.Schema.json +0 -2094
  126. package/examples/kanban/agent/decision-log.md +0 -9
  127. package/examples/kanban/agent/mockup-01-editorial-glass.html +0 -159
  128. package/examples/kanban/agent/mockup-02-dark-rail.html +0 -147
  129. package/examples/kanban/agent/mockup-03-paper-grid.html +0 -114
  130. package/examples/kanban/agent/mockup-04-neon-minimal.html +0 -141
  131. package/examples/kanban/agent/mockup-05-mono-architect.html +0 -119
  132. package/examples/kanban/dist/office365users.js +0 -169
  133. package/examples/kanban/src/generated/index.ts +0 -14
  134. package/examples/kanban/src/generated/models/Office365GroupsModel.ts +0 -363
  135. package/examples/kanban/src/generated/models/Office365OutlookModel.ts +0 -2046
  136. package/examples/kanban/src/generated/models/Office365UsersModel.ts +0 -254
  137. package/examples/kanban/src/generated/services/Office365GroupsService.ts +0 -326
  138. package/examples/kanban/src/generated/services/Office365OutlookService.ts +0 -2476
  139. package/examples/kanban/src/generated/services/Office365UsersService.ts +0 -358
  140. package/examples/outlook Demo2/agent/decision-log.md +0 -7
  141. package/examples/outlook Demo2/dist/index.html +0 -98
  142. package/examples/outlook Demo2/dist/index.js +0 -272
  143. package/examples/outlook Demo2/dist/styles.css +0 -639
  144. package/examples/outlook Demo2/power.config.json +0 -23
  145. package/examples/planning Poker/.vscode/settings.json +0 -5
  146. package/examples/sharePoint Demo/agent/decision-log.md +0 -17
  147. /package/examples/{outlook Demo2 → apps/kanban}/src/generated/index.ts +0 -0
  148. /package/examples/{outlook Demo2 → apps/kanban}/src/generated/models/Office365GroupsModel.ts +0 -0
  149. /package/examples/{outlook Demo2 → apps/kanban}/src/generated/models/Office365OutlookModel.ts +0 -0
  150. /package/examples/{outlook Demo2 → apps/kanban}/src/generated/models/Office365UsersModel.ts +0 -0
  151. /package/examples/{outlook Demo2 → apps/kanban}/src/generated/services/Office365GroupsService.ts +0 -0
  152. /package/examples/{outlook Demo2 → apps/kanban}/src/generated/services/Office365OutlookService.ts +0 -0
  153. /package/examples/{outlook Demo2 → apps/kanban}/src/generated/services/Office365UsersService.ts +0 -0
  154. /package/examples/{planning Poker → apps/planning Poker}/additional files/AgilePoker_1_0_0_1.zip +0 -0
  155. /package/examples/{planning Poker → apps/planning Poker}/additional files/PokerTables_1_0_0_1.zip +0 -0
  156. /package/examples/{outlook Demo2 → apps/solution explorer}/dist/icon-512.png +0 -0
  157. /package/examples/{outlook Demo2 → apps/solution explorer}/dist/power-apps-data.js +0 -0
  158. /package/examples/{todo → apps/todo}/dist/icon192.png +0 -0
@@ -1,2952 +0,0 @@
1
- /* power-apps-data.js - Standalone Power Apps SDK for Code Apps
2
- Converted from @microsoft/power-apps v1.0.4
3
- Zero dependencies - all code is self-contained */
4
- var __defProp = Object.defineProperty;
5
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
7
-
8
- var DefaultPowerAppsBridge = class {
9
- constructor() {
10
- __publicField(this, "_antiCSRFToken");
11
- __publicField(this, "_callbacks", {});
12
- __publicField(this, "_currentCallbackId", 0);
13
- __publicField(this, "_instanceId", Date.now().toString());
14
- __publicField(this, "_messageChannel", new window.MessageChannel());
15
- __publicField(this, "_postMessageQueue", []);
16
- __publicField(this, "_postMessageSource");
17
- __publicField(this, "_handleMessageEvent", (messageEvent) => {
18
- const message = messageEvent.data;
19
- if (message && typeof message.isPluginCall === "boolean") {
20
- if (message.isPluginCall) {
21
- const callbackId = message.callbackId;
22
- const status = message.status;
23
- const args = message.args;
24
- const keepCallback = message.keepCallback;
25
- try {
26
- const callback = this._callbacks[callbackId];
27
- if (keepCallback) {
28
- if (callback && callback.onUpdate) {
29
- callback.onUpdate(message.args?.[0]);
30
- }
31
- } else {
32
- if (callback) {
33
- if (status === 1) {
34
- callback.resolve(args[0]);
35
- } else if (status !== 0) {
36
- callback.reject(args);
37
- }
38
- }
39
- if (!keepCallback) {
40
- delete this._callbacks[callbackId];
41
- }
42
- }
43
- } catch (error) {
44
- console.error(error);
45
- }
46
- }
47
- } else if (message && message.messageType === "initCommunication") {
48
- this._antiCSRFToken = message.antiCSRFToken;
49
- this._postMessageSource = this._messageChannel.port1;
50
- if (this._postMessageSource) {
51
- for (let i = 0; i < this._postMessageQueue.length; i++) {
52
- this._postMessageQueue[i].antiCSRFToken = this._antiCSRFToken;
53
- this._postMessageSource.postMessage(this._postMessageQueue[i]);
54
- }
55
- }
56
- }
57
- });
58
- }
59
- async initialize() {
60
- this._messageChannel.port1.onmessage = this._handleMessageEvent;
61
- window.parent.postMessage({
62
- messageType: "initCommunicationWithPort",
63
- instanceId: this._instanceId
64
- }, "*", [this._messageChannel.port2]);
65
- }
66
- async executePluginAsync(pluginName, pluginAction, params = [], onUpdate) {
67
- return new Promise((resolve, reject) => {
68
- const callbackId = this._getCallbackId(pluginName);
69
- this._callbacks[callbackId] = { resolve, reject, onUpdate };
70
- this._sendMessage({
71
- isPluginCall: true,
72
- callbackId,
73
- service: pluginName,
74
- action: pluginAction,
75
- actionArgs: params,
76
- antiCSRFToken: this._antiCSRFToken
77
- });
78
- });
79
- }
80
- _sendMessage(message) {
81
- if (!this._postMessageSource) {
82
- this._postMessageQueue.push(message);
83
- } else {
84
- this._postMessageSource.postMessage(message);
85
- }
86
- }
87
- _getCallbackId(pluginName) {
88
- return "instanceId=" + this._instanceId + "_" + pluginName + this._currentCallbackId++;
89
- }
90
- };
91
-
92
- var bridgePromise;
93
- async function executePluginAsync(pluginName, pluginAction, params = [], update) {
94
- const powerAppsBridge = await getBridge();
95
- return powerAppsBridge.executePluginAsync(pluginName, pluginAction, params, update);
96
- }
97
- async function getBridge() {
98
- if (!bridgePromise) {
99
- bridgePromise = new Promise(async (resolve, reject) => {
100
- try {
101
- const bridge = window && window.powerAppsBridge ? window.powerAppsBridge : new DefaultPowerAppsBridge();
102
- await bridge.initialize();
103
- resolve(bridge);
104
- } catch (error) {
105
- reject(error);
106
- }
107
- });
108
- }
109
- return bridgePromise;
110
- }
111
-
112
- var context;
113
- async function getContext() {
114
- if (context) {
115
- return context;
116
- }
117
- context = await executePluginAsync("AppLifecycle", "getContext");
118
- return context;
119
- }
120
-
121
- var IncompatibleMessageReceiver = class {
122
- constructor(versionInfo, incompatibilityDescription) {
123
- __publicField(this, "versionInfo");
124
- __publicField(this, "incompatibilityDescription");
125
- __publicField(this, "isCompatible", false);
126
- this.versionInfo = versionInfo;
127
- this.incompatibilityDescription = incompatibilityDescription;
128
- }
129
- };
130
-
131
- var SendMessageOperation = class {
132
- constructor(resultPromise, sendUpdate) {
133
- __publicField(this, "resultPromise");
134
- __publicField(this, "sendUpdate");
135
- /**
136
- * When completed is false onMessageReceived and sendUpdate will be visible.
137
- * When completed is true then these are hidden.
138
- */
139
- __publicField(this, "completed", false);
140
- __publicField(this, "onMessageReceived");
141
- this.resultPromise = resultPromise;
142
- this.sendUpdate = sendUpdate;
143
- }
144
- };
145
-
146
- var CompatibleMessageReceiver = class {
147
- constructor(_receiverName, versionInfo) {
148
- __publicField(this, "_receiverName");
149
- __publicField(this, "versionInfo");
150
- __publicField(this, "isCompatible", true);
151
- this._receiverName = _receiverName;
152
- this.versionInfo = versionInfo;
153
- }
154
- async sendMessage(message, onMessageReceived) {
155
- let resolveOperationPromise;
156
- let rejectOperationPromise;
157
- const operationPromise = new Promise((resolve, reject) => {
158
- resolveOperationPromise = resolve;
159
- rejectOperationPromise = reject;
160
- });
161
- const correlationId = crypto.randomUUID();
162
- const handleMessage = (compatibleReceiverMessage) => {
163
- try {
164
- if (sendMessageOperation.completed) {
165
- return;
166
- }
167
- if (compatibleReceiverMessage) {
168
- if (compatibleReceiverMessage.isUpdate) {
169
- if (sendMessageOperation.onMessageReceived) {
170
- try {
171
- sendMessageOperation.onMessageReceived(compatibleReceiverMessage.message);
172
- } catch (error) {
173
- sendMessageOperation.completed = true;
174
- rejectOperationPromise(error);
175
- }
176
- } else {
177
- sendMessageOperation.completed = true;
178
- rejectOperationPromise(new Error(`Native receiver expected a message handler, but no handler was supplied. Message: ${compatibleReceiverMessage.message}`));
179
- }
180
- } else {
181
- sendMessageOperation.completed = true;
182
- resolveOperationPromise(compatibleReceiverMessage.message);
183
- }
184
- return;
185
- }
186
- } catch {
187
- }
188
- sendMessageOperation.completed = true;
189
- resolveOperationPromise(compatibleReceiverMessage.message);
190
- };
191
- const handleError = (error) => {
192
- sendMessageOperation.completed = true;
193
- rejectOperationPromise(error);
194
- };
195
- const sendUpdate = (updateMessage) => {
196
- if (sendMessageOperation.completed) {
197
- throw new Error("Tried to send update for completed operation.");
198
- }
199
- executePluginAsync("SendMessagePlugin", "sendMessage", [
200
- this._receiverName,
201
- updateMessage,
202
- correlationId
203
- ]);
204
- };
205
- const sendMessageOperation = new SendMessageOperation(operationPromise, sendUpdate);
206
- sendMessageOperation.onMessageReceived = onMessageReceived;
207
- try {
208
- await executePluginAsync("SendMessagePlugin", "sendMessage", [this._receiverName, message, correlationId], (response) => {
209
- handleMessage(response);
210
- });
211
- } catch (error) {
212
- handleError(error);
213
- }
214
- return sendMessageOperation;
215
- }
216
- };
217
-
218
- var SendMessage = class _SendMessage {
219
- static createInstanceAsync() {
220
- return Promise.resolve(new _SendMessage());
221
- }
222
- async getMessageReceiverAsync(receiverName, isCompatibleChecker) {
223
- const versionInfo = await this._getVersionInfo(receiverName);
224
- if (versionInfo) {
225
- const compatibilityCheckerResult = isCompatibleChecker(versionInfo);
226
- if (compatibilityCheckerResult.isCompatible === false) {
227
- return new IncompatibleMessageReceiver(versionInfo, compatibilityCheckerResult.incompatibilityDescription || "");
228
- } else {
229
- return new CompatibleMessageReceiver(receiverName, versionInfo);
230
- }
231
- } else {
232
- return new IncompatibleMessageReceiver(void 0, `No receiver ${receiverName} registered.`);
233
- }
234
- }
235
- async _getVersionInfo(receiverName) {
236
- const result = await executePluginAsync("SendMessagePlugin", "getVersionInfo", [receiverName]);
237
- return result;
238
- }
239
- };
240
-
241
- var loggerInstance;
242
- async function initializeLogger(logger) {
243
- loggerInstance = logger;
244
- const sendMessagePlugin = await SendMessage.createInstanceAsync();
245
- const receiver = await sendMessagePlugin.getMessageReceiverAsync("PowerApps.AppMonitorReceiver", (versionInfo) => {
246
- let isCompatible = false;
247
- if (versionInfo === "1.0.0") {
248
- isCompatible = true;
249
- }
250
- return { isCompatible };
251
- });
252
- if (receiver.isCompatible) {
253
- await receiver.sendMessage("initialize", (message) => {
254
- const parsedMessage = JSON.parse(message);
255
- if (parsedMessage.metrics) {
256
- for (const metric of parsedMessage.metrics) {
257
- loggerInstance.logMetric?.(metric);
258
- }
259
- }
260
- });
261
- }
262
- }
263
-
264
- function getAppLoadedPerformanceData() {
265
- const performanceApi = new PerformanceApi();
266
- const perfData = {
267
- appTimeOrigin: performanceApi.timeOrigin
268
- };
269
- const navigationTimingEntries = performanceApi.getEntriesByType("navigation");
270
- const navigationTiming = navigationTimingEntries[0];
271
- if (navigationTiming) {
272
- perfData.appNavigateType = navigationTiming.type;
273
- perfData.appNavigationStart = navigationTiming.startTime;
274
- perfData.appNavigationDuration = navigationTiming.duration;
275
- perfData.appEncodedBodySize = navigationTiming.encodedBodySize;
276
- perfData.appNextHopProtocol = navigationTiming.nextHopProtocol;
277
- perfData.appDomainLookupStart = navigationTiming.domainLookupStart;
278
- perfData.appDomainLookupEnd = navigationTiming.domainLookupEnd;
279
- perfData.appConnectStart = navigationTiming.connectStart;
280
- perfData.appConnectEnd = navigationTiming.connectEnd;
281
- perfData.appSecureConnectionStart = navigationTiming.secureConnectionStart;
282
- perfData.appFetchStart = navigationTiming.fetchStart;
283
- perfData.appRequestStart = navigationTiming.requestStart;
284
- perfData.appResponseStart = navigationTiming.responseStart;
285
- perfData.appResponseEnd = navigationTiming.responseEnd;
286
- perfData.appLoadEventEnd = navigationTiming.loadEventEnd;
287
- perfData.appDomInteractive = navigationTiming.domInteractive;
288
- perfData.appDomContentLoadedEventStart = navigationTiming.domContentLoadedEventStart;
289
- }
290
- return perfData;
291
- }
292
- var PerformanceApi = class {
293
- constructor(targetWindow = window) {
294
- __publicField(this, "_performance");
295
- this._performance = targetWindow.performance;
296
- }
297
- get timeOrigin() {
298
- return this._performance?.timeOrigin;
299
- }
300
- getEntriesByType(type) {
301
- if (!this._performance?.getEntriesByType) {
302
- return [];
303
- }
304
- return this._performance.getEntriesByType(type);
305
- }
306
- };
307
-
308
- executePluginAsync("AppLifecycle", "notifyAppSdkLoaded", [getAppLoadedPerformanceData()]);
309
-
310
- function setConfig(config) {
311
- if (config.logger) {
312
- initializeLogger(config.logger);
313
- }
314
- }
315
-
316
- var HttpMethod;
317
- (function(HttpMethod2) {
318
- HttpMethod2["GET"] = "GET";
319
- HttpMethod2["POST"] = "POST";
320
- HttpMethod2["PUT"] = "PUT";
321
- HttpMethod2["DELETE"] = "DELETE";
322
- HttpMethod2["PATCH"] = "PATCH";
323
- })(HttpMethod || (HttpMethod = {}));
324
- var DataSources;
325
- (function(DataSources2) {
326
- DataSources2["Dataverse"] = "Dataverse";
327
- DataSources2["Connector"] = "Connector";
328
- })(DataSources || (DataSources = {}));
329
-
330
- var ErrorCodes;
331
- (function(ErrorCodes2) {
332
- ErrorCodes2["InitializationFailed"] = "PDR_INIT_FAILED";
333
- ErrorCodes2["InvalidXrmInfo"] = "INVALID_XRM_INFO";
334
- ErrorCodes2["OperationsNotInitialized"] = "OPS_NOT_INITIALIZED";
335
- ErrorCodes2["InvalidOperationExecutor"] = "INVALID_OPERATION_EXECUTOR";
336
- ErrorCodes2["DataSourceNotFound"] = "CONNECTION_NOT_FOUND";
337
- ErrorCodes2["DuplicateDataSource"] = "DUPLICATE_DATA_SOURCE";
338
- ErrorCodes2["InitializationError"] = "RDSS_INIT_ERROR";
339
- ErrorCodes2["InvalidDataSource"] = "INVALID_DATA_SOURCE";
340
- ErrorCodes2["DataSourcesInfoNotFound"] = "DATA_SOURCES_INFO_NOT_FOUND";
341
- ErrorCodes2["DataClientInitFailed"] = "DATA_CLIENT_INIT_FAILED";
342
- ErrorCodes2["DataClientNotInitialized"] = "DATA_CLIENT_NOT_INITIALIZED";
343
- ErrorCodes2["MetadataClientInitFailed"] = "METADATA_CLIENT_INIT_FAILED";
344
- ErrorCodes2["MetadataClientNotInitialized"] = "METADATA_CLIENT_NOT_INITIALIZED";
345
- ErrorCodes2["ClientProviderNotAvailable"] = "CLIENT_PROVIDER_NOT_AVAILABLE";
346
- ErrorCodes2["ConnectionReferenceNotFound"] = "CONNECTION_REFERENCE_NOT_FOUND";
347
- ErrorCodes2["DataClientNotAvailable"] = "DATA_CLIENT_NOT_AVAILABLE";
348
- ErrorCodes2["DataSourceServiceNotAvailable"] = "DATA_SOURCE_SERVICE_NOT_AVAILABLE";
349
- ErrorCodes2["MetadataClientNotAvailable"] = "METADATA_CLIENT_NOT_AVAILABLE";
350
- ErrorCodes2["ConnectionConfigFetchFailed"] = "CONNECTION_CONFIG_FETCH_FAILED";
351
- ErrorCodes2["DataSourceConfigFetchFailed"] = "DATA_SOURCE_CONFIG_FETCH_FAILED";
352
- ErrorCodes2["InvalidMetadataResponse"] = "INVALID_METADATA_RESPONSE";
353
- ErrorCodes2["TokenAcquisitionFailed"] = "TOKEN_ACQUISITION_FAILED";
354
- })(ErrorCodes || (ErrorCodes = {}));
355
-
356
- var UnknownErrorMessage = "An unknown error occurred";
357
- var ErrorMessages = {
358
- // PowerDataRuntime specific errors
359
- [ErrorCodes.InitializationFailed]: "Failed to initialize PowerDataRuntime",
360
- [ErrorCodes.InvalidXrmInfo]: "Xrm info is required",
361
- [ErrorCodes.OperationsNotInitialized]: "PowerDataRuntime is not initialized",
362
- // RuntimeDataSourceService specific errors
363
- [ErrorCodes.DataSourceNotFound]: "Data source not found",
364
- [ErrorCodes.DuplicateDataSource]: "Duplicate data source",
365
- [ErrorCodes.InitializationError]: "Failed to initialize RuntimeDataSourceService",
366
- [ErrorCodes.InvalidDataSource]: "Invalid data source",
367
- // PowerDataSourcesInfoProvider specific errors
368
- [ErrorCodes.DataSourcesInfoNotFound]: "DataSourcesInfo must be provided to initialize the singleton instance.",
369
- // DataClientProvider specific errors
370
- [ErrorCodes.DataClientInitFailed]: "Failed to initialize PowerDataClient",
371
- [ErrorCodes.DataClientNotInitialized]: "PowerDataClient is not initialized",
372
- [ErrorCodes.MetadataClientInitFailed]: "Failed to initialize PowerMetadataClient",
373
- [ErrorCodes.MetadataClientNotInitialized]: "PowerMetadataClient is not initialized",
374
- // DataOperation specific errors
375
- [ErrorCodes.ClientProviderNotAvailable]: "Client provider is not available",
376
- [ErrorCodes.ConnectionReferenceNotFound]: "Connection reference not found",
377
- [ErrorCodes.DataClientNotAvailable]: "PowerDataClient is not available",
378
- [ErrorCodes.DataSourceServiceNotAvailable]: "Data source service is not available",
379
- [ErrorCodes.MetadataClientNotAvailable]: "PowerMetadataClient is not available",
380
- // MetadataClient specific errors
381
- [ErrorCodes.ConnectionConfigFetchFailed]: "Failed to fetch connection configurations",
382
- [ErrorCodes.DataSourceConfigFetchFailed]: "Failed to fetch data source configurations",
383
- [ErrorCodes.InvalidMetadataResponse]: "Invalid metadata response format",
384
- // RuntimeDataClient specific errors
385
- [ErrorCodes.TokenAcquisitionFailed]: "Failed to acquire access token"
386
- };
387
- var DataOperationErrorMessages;
388
- (function(DataOperationErrorMessages2) {
389
- DataOperationErrorMessages2["CreateFailed"] = "Create operation failure";
390
- DataOperationErrorMessages2["DeleteFailed"] = "Delete operation failure";
391
- DataOperationErrorMessages2["ExecuteFailed"] = "Execute operation failure";
392
- DataOperationErrorMessages2["InvalidOperationParameters"] = "Invalid operation parameters";
393
- DataOperationErrorMessages2["InvalidRequest"] = "Invalid request";
394
- DataOperationErrorMessages2["InvalidResponse"] = "Invalid response format";
395
- DataOperationErrorMessages2["MissingConnectorOperation"] = "Connector operation is required";
396
- DataOperationErrorMessages2["MissingDataverseRequest"] = "Dataverse request is required";
397
- DataOperationErrorMessages2["MissingOperationName"] = "Operation name is required";
398
- DataOperationErrorMessages2["MissingRequestBody"] = "Request body is required";
399
- DataOperationErrorMessages2["RetrieveFailed"] = "Retrieve operation failure";
400
- DataOperationErrorMessages2["RetrieveMultipleFailed"] = "Retrieve multiple records operation failure";
401
- DataOperationErrorMessages2["UpdateFailed"] = "Update operation failure";
402
- })(DataOperationErrorMessages || (DataOperationErrorMessages = {}));
403
-
404
- function isOperationResult(result) {
405
- return result?.success !== void 0;
406
- }
407
-
408
- var ServiceName = "PublishedAppTelemetry";
409
- var TelemetryActionNames;
410
- (function(TelemetryActionNames2) {
411
- TelemetryActionNames2["trackEvent"] = "trackEvent";
412
- TelemetryActionNames2["trackException"] = "trackException";
413
- TelemetryActionNames2["trackMetric"] = "trackMetric";
414
- TelemetryActionNames2["startScenario"] = "startScenario";
415
- TelemetryActionNames2["endScenario"] = "endScenario";
416
- TelemetryActionNames2["setDefaultProperties"] = "setDefaultProperties";
417
- })(TelemetryActionNames || (TelemetryActionNames = {}));
418
- var _Log = class _Log {
419
- constructor(_powerOperationExecutor) {
420
- __publicField(this, "_powerOperationExecutor");
421
- this._powerOperationExecutor = _powerOperationExecutor;
422
- }
423
- static createInstance(powerOperationExecutor) {
424
- if (!_Log._instance) {
425
- _Log._instance = new _Log(powerOperationExecutor);
426
- } else {
427
- _Log.trackEvent("TelemetryLogger", {
428
- message: "Attempted to create an instance when instance is already created."
429
- });
430
- }
431
- return _Log._instance;
432
- }
433
- // Since powerDataRuntime can be reset, we need to be able to reset the instance of Log as well.
434
- static resetInstance() {
435
- _Log._instance = null;
436
- }
437
- static async _sendMessage(actionName, ...args) {
438
- try {
439
- const instance = _Log._getInstance();
440
- const result = await instance._powerOperationExecutor.execute(ServiceName, actionName, args);
441
- if (!result.success) {
442
- console.error({
443
- message: `PowerDataRuntime.TelemetryLogger: Failed to send telemetry message.`,
444
- error: result.error,
445
- telemetryArgs: args
446
- });
447
- }
448
- } catch (error) {
449
- console.error({
450
- message: `PowerDataRuntime.TelemetryLogger: Failed to send telemetry message.`,
451
- error,
452
- telemetryArgs: args
453
- });
454
- }
455
- }
456
- static trackEvent(eventName, eventData) {
457
- const serializedData = eventData ? _Log._serializeErrors(eventData) : eventData;
458
- return _Log._sendMessage(TelemetryActionNames.trackEvent, `PowerDataRuntime.${eventName}`, serializedData);
459
- }
460
- static trackException(exception) {
461
- return _Log._sendMessage(TelemetryActionNames.trackException, exception);
462
- }
463
- static trackMetric(metricName, value) {
464
- return _Log._sendMessage(TelemetryActionNames.trackMetric, `PowerDataRuntime.${metricName}`, value);
465
- }
466
- static startScenario(scenarioName) {
467
- return _Log._sendMessage(TelemetryActionNames.startScenario, `PowerDataRuntime.${scenarioName}`);
468
- }
469
- static endScenario(scenarioName) {
470
- return _Log._sendMessage(TelemetryActionNames.endScenario, `PowerDataRuntime.${scenarioName}`);
471
- }
472
- static setDefaultProperties(properties) {
473
- return _Log._sendMessage(TelemetryActionNames.setDefaultProperties, properties);
474
- }
475
- static _getInstance() {
476
- if (!_Log._instance) {
477
- throw new Error("PowerDataRuntime.TelemetryLogger: Attempted to log telemetry prior to instantiation.");
478
- }
479
- return _Log._instance;
480
- }
481
- /**
482
- * Recursively serializes Error objects in an object to prevent empty object serialization
483
- * when passed through postMessage's structured clone algorithm.
484
- * @param obj - The object to process
485
- * @returns A new object with Error instances replaced by serializable objects
486
- */
487
- static _serializeErrors(obj) {
488
- if (obj === null || obj === void 0) {
489
- return obj;
490
- }
491
- if (obj instanceof Error) {
492
- return {
493
- errorMessage: obj.message,
494
- errorStack: obj.stack,
495
- errorType: obj.name
496
- };
497
- }
498
- if (Array.isArray(obj)) {
499
- return obj.map((item) => _Log._serializeErrors(item));
500
- }
501
- if (typeof obj === "object" && obj !== null && Object.getPrototypeOf(obj) === Object.prototype) {
502
- const serialized = {};
503
- for (const key in obj) {
504
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
505
- serialized[key] = _Log._serializeErrors(obj[key]);
506
- }
507
- }
508
- return serialized;
509
- }
510
- return obj;
511
- }
512
- };
513
- __publicField(_Log, "_instance", null);
514
- var Log = _Log;
515
-
516
- var PowerDataRuntimeError = class extends Error {
517
- /**
518
- * Creates an instance of PowerDataRuntimeError.
519
- * @param code - The error code associated with the error.
520
- * @param additionalInfo - Optional additional information to include in the error message.
521
- * @param messageOverride - Optional override for the default error message.
522
- */
523
- constructor(code, additionalInfo, messageOverride) {
524
- let message = messageOverride || ErrorMessages[code] || UnknownErrorMessage;
525
- if (additionalInfo) {
526
- message += `: ${additionalInfo}`;
527
- }
528
- super(message);
529
- __publicField(this, "code");
530
- this.code = code;
531
- this.name = "PowerDataRuntimeError";
532
- Log.trackException(this);
533
- }
534
- };
535
-
536
- var HeaderNames;
537
- (function(HeaderNames2) {
538
- HeaderNames2["RequestId"] = "x-ms-client-request-id";
539
- })(HeaderNames || (HeaderNames = {}));
540
- var DataverseOperationName;
541
- (function(DataverseOperationName2) {
542
- DataverseOperationName2["CreateRecord"] = "dataverseDataOperation.createRecordAsync";
543
- DataverseOperationName2["UpdateRecord"] = "dataverseDataOperation.updateRecordAsync";
544
- DataverseOperationName2["DeleteRecord"] = "dataverseDataOperation.deleteRecordAsync";
545
- DataverseOperationName2["RetrieveRecord"] = "dataverseDataOperation.retrieveRecordAsync";
546
- DataverseOperationName2["RetrieveMultipleRecords"] = "dataverseDataOperation.retrieveMultipleRecordsAsync";
547
- })(DataverseOperationName || (DataverseOperationName = {}));
548
- var ConnectorOperationName;
549
- (function(ConnectorOperationName2) {
550
- ConnectorOperationName2["CreateRecord"] = "connectorDataOperation.createRecordAsync";
551
- ConnectorOperationName2["UpdateRecord"] = "connectorDataOperation.updateRecordAsync";
552
- ConnectorOperationName2["DeleteRecord"] = "connectorDataOperation.deleteRecordAsync";
553
- ConnectorOperationName2["RetrieveRecord"] = "connectorDataOperation.retrieveRecordAsync";
554
- ConnectorOperationName2["RetrieveMultipleRecords"] = "connectorDataOperation.retrieveMultipleRecordsAsync";
555
- })(ConnectorOperationName || (ConnectorOperationName = {}));
556
-
557
- function getErrorMessage(error) {
558
- if (typeof error === "string") {
559
- return error;
560
- }
561
- if (error instanceof Error || error instanceof PowerDataRuntimeError) {
562
- return error.message || UnknownErrorMessage;
563
- }
564
- if (isOperationResult(error)) {
565
- return error.error?.message || UnknownErrorMessage;
566
- }
567
- if (typeof error === "object") {
568
- return JSON.stringify(error);
569
- }
570
- return UnknownErrorMessage;
571
- }
572
- function createErrorResponse(error, friendlyMessage) {
573
- const message = getErrorMessage(error);
574
- let data;
575
- if (isOperationResult(error)) {
576
- data = error.data;
577
- }
578
- const errorData = new Error(`${friendlyMessage}: ${message}`);
579
- if (error instanceof Error) {
580
- errorData.stack = error.stack;
581
- }
582
- return {
583
- success: false,
584
- error: errorData,
585
- data
586
- };
587
- }
588
- function parseHttpPluginError(error) {
589
- let message = UnknownErrorMessage;
590
- let response;
591
- if (Array.isArray(error)) {
592
- if (Array.isArray(error[0])) {
593
- message = error[0][0] || UnknownErrorMessage;
594
- response = error[0][2];
595
- }
596
- }
597
- const status = response?.status;
598
- const requestId = response?.headers?.[HeaderNames.RequestId];
599
- return {
600
- message,
601
- status,
602
- requestId
603
- };
604
- }
605
-
606
- var DefaultDataOperationOrchestrator = class {
607
- // Static identifiers for services and actions
608
- // Used to identify specific services and actions within the PowerApps environment
609
- constructor(_dataverseOperation, _connectorOperation, _connectionsService) {
610
- __publicField(this, "_dataverseOperation");
611
- __publicField(this, "_connectorOperation");
612
- __publicField(this, "_connectionsService");
613
- this._dataverseOperation = _dataverseOperation;
614
- this._connectorOperation = _connectorOperation;
615
- this._connectionsService = _connectionsService;
616
- }
617
- /**
618
- * Creates a new record in the specified data source.
619
- * @param tableName - The name of the table.
620
- * @param data - The record data to create.
621
- * @returns A promise that resolves to the operation result.
622
- * @throws DataOperationError if the operation fails.
623
- */
624
- async createRecordAsync(tableName, data) {
625
- try {
626
- this._validateParams({ tableName, data });
627
- const executor = await this._getExecutor(tableName);
628
- return await executor.createRecordAsync(tableName, data);
629
- } catch (error) {
630
- return createErrorResponse(error, "Create record operation failed");
631
- }
632
- }
633
- /**
634
- * Updates an existing record in the specified data source.
635
- * @param tableName - The name of the table.
636
- * @param id - The ID of the record to update.
637
- * @param data - The updated record data.
638
- * @returns A promise that resolves to the operation result.
639
- * @throws DataOperationError if the operation fails.
640
- */
641
- async updateRecordAsync(tableName, id, data) {
642
- try {
643
- this._validateParams({ tableName, id, data });
644
- const executor = await this._getExecutor(tableName);
645
- return await executor.updateRecordAsync(tableName, id, data);
646
- } catch (error) {
647
- return createErrorResponse(error, "Update record operation failed");
648
- }
649
- }
650
- /**
651
- * Deletes a record from the specified data source.
652
- * @param tableName - The name of the table.
653
- * @param id - The ID of the record to delete.
654
- * @returns A promise that resolves to the operation result.
655
- * @throws DataOperationError if the operation fails.
656
- */
657
- async deleteRecordAsync(tableName, id) {
658
- try {
659
- this._validateParams({ tableName, id });
660
- const executor = await this._getExecutor(tableName);
661
- return await executor.deleteRecordAsync(tableName, id);
662
- } catch (error) {
663
- return createErrorResponse(error, "Delete record operation failed");
664
- }
665
- }
666
- /**
667
- * Retrieves a record from the specified data source.
668
- * @param tableName - The name of the table.
669
- * @param id - The ID of the record to retrieve.
670
- * @param options - Optional operation options.
671
- * @returns A promise that resolves to the operation result.
672
- * @throws DataOperationError if the operation fails.
673
- */
674
- async retrieveRecordAsync(tableName, id, options) {
675
- try {
676
- this._validateParams({ tableName, id });
677
- const executor = await this._getExecutor(tableName);
678
- this._validateOptions(options);
679
- return await executor.retrieveRecordAsync(tableName, id, options);
680
- } catch (error) {
681
- return createErrorResponse(error, "Retrieve record operation failed");
682
- }
683
- }
684
- /**
685
- * Retrieves multiple records from the specified data source.
686
- * @param tableName - The name of the table.
687
- * @param options - Optional operation options.
688
- * @returns A promise that resolves to the operation result.
689
- * @throws DataOperationError if the operation fails.
690
- */
691
- async retrieveMultipleRecordsAsync(tableName, options) {
692
- try {
693
- this._validateParams({ tableName });
694
- const executor = await this._getExecutor(tableName);
695
- this._validateOptions(options);
696
- return await executor.retrieveMultipleRecordsAsync(tableName, options);
697
- } catch (error) {
698
- return createErrorResponse(error, "Retrieve multiple records operation failed");
699
- }
700
- }
701
- /**
702
- * Executes a data operation on the specified data source.
703
- * @param operation - The operation to execute
704
- * @returns A promise that resolves to the operation result.
705
- * @throws DataOperationError if the operation fails.
706
- */
707
- async executeAsync(operation) {
708
- try {
709
- this._validateParams({ operation });
710
- const executor = await this._getExecutor("", operation.connectorOperation ? DataSources.Connector : DataSources.Dataverse);
711
- return await executor.executeAsync(operation);
712
- } catch (error) {
713
- return createErrorResponse(error, "Execute operation failed");
714
- }
715
- }
716
- /**
717
- * Retrieves the appropriate executor based on the data source.
718
- * @param dataSource - The data source to retrieve the executor for.
719
- * @returns The corresponding executor instance.
720
- * @throws DataOperationError if the data source is invalid.
721
- * // TODO: Add Dataverse support
722
- */
723
- async _getExecutor(tableName, dataSource) {
724
- const dataOperationExecutorOverride = getDataOperationExecutor();
725
- if (dataOperationExecutorOverride) {
726
- return dataOperationExecutorOverride;
727
- }
728
- const dataSourceType = dataSource || (await this._connectionsService.getDataSource(tableName)).dataSourceType;
729
- switch (dataSourceType) {
730
- case DataSources.Dataverse:
731
- return this._dataverseOperation;
732
- case DataSources.Connector:
733
- return this._connectorOperation;
734
- default:
735
- return this._connectorOperation;
736
- }
737
- }
738
- /**
739
- * Validates the input parameters for data operations.
740
- * @param params - The parameters to validate.
741
- * @throws DataOperationError if validation fails.
742
- */
743
- _validateParams(params) {
744
- for (const [key, value] of Object.entries(params)) {
745
- if (!value) {
746
- throw new Error(`${DataOperationErrorMessages.InvalidOperationParameters}: ${key} is required`);
747
- }
748
- }
749
- }
750
- /**
751
- * Validates the operation options.
752
- * @param options - The operation options to validate.
753
- * @throws Error if validation fails.
754
- */
755
- _validateOptions(options) {
756
- if (!options) {
757
- return;
758
- }
759
- if (options.maxPageSize && typeof options.maxPageSize !== "number") {
760
- throw new Error(`${DataOperationErrorMessages.InvalidOperationParameters}: maxPageSize must be a number`);
761
- }
762
- if (options.select) {
763
- if (!Array.isArray(options.select)) {
764
- throw new Error(`${DataOperationErrorMessages.InvalidOperationParameters}: select must be an array of strings`);
765
- }
766
- if (options.select.some((s) => typeof s !== "string" || s.trim() === "")) {
767
- throw new Error(`${DataOperationErrorMessages.InvalidOperationParameters}: select must contain only non-empty strings`);
768
- }
769
- }
770
- if (options.filter && typeof options.filter !== "string") {
771
- throw new Error(`${DataOperationErrorMessages.InvalidOperationParameters}: filter must be a string`);
772
- }
773
- if (options.orderBy) {
774
- if (!Array.isArray(options.orderBy)) {
775
- throw new Error(`${DataOperationErrorMessages.InvalidOperationParameters}: orderBy must be an array of strings`);
776
- }
777
- if (options.orderBy.some((s) => typeof s !== "string" || s.trim() === "")) {
778
- throw new Error(`${DataOperationErrorMessages.InvalidOperationParameters}: orderBy must contain only non-empty strings`);
779
- }
780
- }
781
- if (options.top && typeof options.top !== "number") {
782
- throw new Error(`${DataOperationErrorMessages.InvalidOperationParameters}: top must be a number`);
783
- }
784
- if (options.skip && typeof options.skip !== "number") {
785
- throw new Error(`${DataOperationErrorMessages.InvalidOperationParameters}: skip must be a number`);
786
- }
787
- if (options.count && typeof options.count !== "boolean") {
788
- throw new Error(`${DataOperationErrorMessages.InvalidOperationParameters}: count must be a boolean`);
789
- }
790
- }
791
- };
792
-
793
- var RuntimeMetadataOperations = class {
794
- // Static identifiers for services and actions
795
- // Used to identify specific services and actions within the PowerApps environment
796
- constructor(_clientProvider) {
797
- __publicField(this, "_clientProvider");
798
- this._clientProvider = _clientProvider;
799
- }
800
- async getConnections(context2) {
801
- const client = await this._clientProvider.getMetadataClientAsync();
802
- const response = await client.getAppConnectionConfigsAsync(context2);
803
- return {
804
- success: response.success,
805
- data: response.data ? [response.data] : [],
806
- error: response.error
807
- };
808
- }
809
- async getConnectionApis(_connectionId, context2) {
810
- const client = await this._clientProvider.getMetadataClientAsync();
811
- const response = await client.getAppDataSourceConfigsAsync(context2);
812
- return {
813
- success: response.success,
814
- data: response.data ? [response.data] : [],
815
- error: response.error
816
- };
817
- }
818
- };
819
-
820
- function arrayBufferToBase64(buffer) {
821
- return window.btoa(convertArrayBufferToString(buffer));
822
- }
823
- function convertArrayBufferToString(buf) {
824
- if (buf.byteLength <= 65535) {
825
- return String.fromCharCode(...new Uint8Array(buf));
826
- }
827
- let binary = "";
828
- for (let i = 0, bytes = new Uint8Array(buf); i < bytes.byteLength; i++) {
829
- binary += String.fromCharCode(bytes[i]);
830
- }
831
- return binary;
832
- }
833
- function strictEncode(str) {
834
- return encodeURIComponent(str).replace(/\(/g, "%28").replace(/\)/g, "%29");
835
- }
836
- function extractDataverseUrlParts(url) {
837
- const baseUrlMatch = url.match(/^(https?:\/\/[^/]+\/api\/data\/v9\.0)/);
838
- const baseUrl = baseUrlMatch ? baseUrlMatch[1] : "";
839
- const pathMatch = url.match(/\/api\/data\/v9\.0\/(.+)$/);
840
- const encodedPath = pathMatch ? strictEncode(pathMatch[1]) : "";
841
- return { baseUrl, encodedPath };
842
- }
843
-
844
- var _RuntimeDataClient = class _RuntimeDataClient {
845
- // Constructor for RuntimeDataClient
846
- // Accepts an IPowerOperationExecutor instance for executing operations
847
- constructor(_powerOperationExecutor) {
848
- __publicField(this, "_powerOperationExecutor");
849
- this._powerOperationExecutor = _powerOperationExecutor;
850
- }
851
- /**
852
- * Creates a new instance of RuntimeDataClient
853
- */
854
- static createInstanceAsync(powerOperationExecutor) {
855
- return Promise.resolve(new _RuntimeDataClient(powerOperationExecutor));
856
- }
857
- /**
858
- * Creates data using POST method
859
- * @param url - The URL for the request
860
- * @param apiId - The API ID for authentication
861
- * @param tableName - The name of the table to access
862
- * @param body - The request body for the POST method
863
- * @param operationName - Optional operation name for telemetry
864
- * @return Promise resolving to the response data
865
- * @throws Error if the request fails or the response is invalid
866
- * @throws Error if the request body is invalid
867
- */
868
- async createDataAsync(url, apiId, tableName, body, context2) {
869
- try {
870
- if (!body) {
871
- throw new Error(`${DataOperationErrorMessages.InvalidRequest}: ${DataOperationErrorMessages.MissingRequestBody}`);
872
- }
873
- const config = {
874
- url,
875
- method: HttpMethod.POST,
876
- apiId,
877
- tableName,
878
- body: JSON.stringify(body)
879
- };
880
- context2 = this._ensureContext(context2, "runtimeDataClient.createDataAsync");
881
- return await this._executeRequest(config, context2);
882
- } catch (error) {
883
- if (isOperationResult(error)) {
884
- return error;
885
- } else {
886
- return createErrorResponse(error, DataOperationErrorMessages.CreateFailed);
887
- }
888
- }
889
- }
890
- /**
891
- * Updates data using PATCH method
892
- * @param url - The URL for the request
893
- * @param apiId - The API ID for authentication
894
- * @param tableName - The name of the table to access
895
- * @param body - The request body for the PATCH method
896
- * @param operationName - Optional operation name for telemetry
897
- * @return Promise resolving to the response data
898
- * @throws Error if the request fails or the response is invalid
899
- * @throws Error if the request body is invalid
900
- */
901
- async updateDataAsync(url, apiId, tableName, body, context2) {
902
- try {
903
- if (!body) {
904
- throw new Error(`${DataOperationErrorMessages.InvalidRequest}: ${DataOperationErrorMessages.MissingRequestBody}`);
905
- }
906
- const config = {
907
- url,
908
- method: HttpMethod.PATCH,
909
- apiId,
910
- tableName,
911
- body: JSON.stringify(body)
912
- };
913
- context2 = this._ensureContext(context2, "runtimeDataClient.updateDataAsync");
914
- return await this._executeRequest(config, context2);
915
- } catch (error) {
916
- if (isOperationResult(error)) {
917
- return error;
918
- } else {
919
- return createErrorResponse(error, DataOperationErrorMessages.UpdateFailed);
920
- }
921
- }
922
- }
923
- /**
924
- * Deletes data using DELETE method
925
- * @param url - The URL for the request
926
- * @param connectionApi - The API ID for authentication
927
- * @param serviceNamespace - The name of the service namespace
928
- * @param operationName - Optional operation name for telemetry
929
- * @return Promise resolving to the response data
930
- * @throws Error if the request fails or the response is invalid
931
- */
932
- async deleteDataAsync(url, connectionApi, serviceNamespace, context2) {
933
- try {
934
- const config = {
935
- url,
936
- method: HttpMethod.DELETE,
937
- apiId: connectionApi,
938
- tableName: serviceNamespace
939
- };
940
- context2 = this._ensureContext(context2, "runtimeDataClient.deleteDataAsync");
941
- return await this._executeRequest(config, context2);
942
- } catch (error) {
943
- if (isOperationResult(error)) {
944
- return error;
945
- } else {
946
- return createErrorResponse(error, DataOperationErrorMessages.DeleteFailed);
947
- }
948
- }
949
- }
950
- /**
951
- * Retrieves data using GET or POST method
952
- * @param url - The URL for the request
953
- * @param apiId - The API ID for authentication
954
- * @param tableName - The name of the table to access
955
- * @param method - The HTTP method
956
- * @param body - Optional request body for POST method
957
- * @param context - Optional operation context
958
- * @param operationName - Optional operation name for telemetry
959
- * @return Promise resolving to the response data
960
- * @throws Error if the request fails or the response is invalid
961
- */
962
- async retrieveDataAsync(url, apiId, tableName, method, headers, body, context2) {
963
- try {
964
- const config = {
965
- url,
966
- method,
967
- apiId,
968
- tableName,
969
- headers,
970
- body: body ? typeof body === "string" ? body : JSON.stringify(body) : void 0
971
- };
972
- context2 = this._ensureContext(context2, "runtimeDataClient.retrieveDataAsync");
973
- return await this._executeRequest(config, context2);
974
- } catch (error) {
975
- if (isOperationResult(error)) {
976
- return error;
977
- } else {
978
- return createErrorResponse(error, DataOperationErrorMessages.RetrieveFailed);
979
- }
980
- }
981
- }
982
- /**
983
- * Gets an access token for the specified API.
984
- * If the API is Dataverse, retrieves a dynamic resource token; otherwise, retrieves a standard appservice API token.
985
- * @param apiId - The API ID for authentication
986
- * @param datasetName - Optional dataset name for Dataverse
987
- * @returns Promise resolving to the access token
988
- * @throws Error if token acquisition fails
989
- */
990
- async _getAccessToken(apiId, datasetName) {
991
- try {
992
- let result;
993
- if (apiId === DataSources.Dataverse) {
994
- result = await this._powerOperationExecutor.execute(_RuntimeDataClient.SERVICES.identityService, _RuntimeDataClient.ACTIONS.getDynamicToken, [datasetName]);
995
- } else {
996
- result = await this._powerOperationExecutor.execute(_RuntimeDataClient.SERVICES.identityService, _RuntimeDataClient.ACTIONS.getToken, [apiId]);
997
- }
998
- return result.data;
999
- } catch (error) {
1000
- throw new PowerDataRuntimeError(ErrorCodes.TokenAcquisitionFailed, getErrorMessage(error));
1001
- }
1002
- }
1003
- // Merge Prefer headers for Dataverse batch payloads
1004
- _mergePreferHeaders(configHeaders, method) {
1005
- let preferHeader = "";
1006
- if (configHeaders?.Prefer) {
1007
- preferHeader += configHeaders.Prefer;
1008
- }
1009
- if (method === HttpMethod.POST || method === HttpMethod.PATCH) {
1010
- const defaultPrefer = "return=representation,odata.include-annotations=*";
1011
- if (preferHeader) {
1012
- if (!preferHeader.includes("return=representation")) {
1013
- preferHeader += (preferHeader ? "," : "") + defaultPrefer;
1014
- }
1015
- } else {
1016
- preferHeader = defaultPrefer;
1017
- }
1018
- }
1019
- return preferHeader;
1020
- }
1021
- /**
1022
- * Creates headers for the HTTP request.
1023
- * Combines default headers with any custom headers provided in the config.
1024
- * Custom headers are optional and take precedence over default headers.
1025
- * @param token - The access token for authentication
1026
- * @param config - The HTTP request configuration
1027
- * @return The headers for the request
1028
- * @throws Error if header creation fails
1029
- */
1030
- _createHeaders(token, config, context2) {
1031
- const baseHeaders = {
1032
- Accept: "application/json",
1033
- "x-ms-protocol-semantics": "cdp",
1034
- ServiceNamespace: config.tableName,
1035
- Authorization: `paauth ${token}`,
1036
- "x-ms-pa-client-custom-headers-options": '{"addCustomHeaders":true}',
1037
- "x-ms-enable-selects": "true",
1038
- "x-ms-pa-client-telemetry-options": `paclient-telemetry {"operationName":"${context2?.operationName ?? "runtimeDataClient.executeRequest"}"}`,
1039
- "x-ms-pa-client-telemetry-additional-data": `{"apiId":"${config.apiId}"}`
1040
- };
1041
- if (config.apiId === DataSources.Dataverse) {
1042
- baseHeaders["x-ms-protocol-semantics"] = DataSources.Dataverse;
1043
- baseHeaders.Authorization = `dynamicauth ${token}`;
1044
- const { baseUrl, encodedPath } = extractDataverseUrlParts(config.url);
1045
- const batchId = context2?.batchId || "";
1046
- const preferHeader = this._mergePreferHeaders(config.headers, config.method);
1047
- baseHeaders.BatchInfo = JSON.stringify({
1048
- baseUrl,
1049
- encodedPath,
1050
- headers: {
1051
- Accept: "application/json",
1052
- ...preferHeader ? { Prefer: preferHeader } : {},
1053
- ...config.method === HttpMethod.POST || config.method === HttpMethod.PATCH ? { "Content-Type": "application/json" } : {}
1054
- },
1055
- batchId
1056
- });
1057
- }
1058
- if (config.headers) {
1059
- return { ...baseHeaders, ...config.headers };
1060
- }
1061
- return baseHeaders;
1062
- }
1063
- /**
1064
- * Executes an HTTP request with the given configuration
1065
- * @param config - The HTTP request configuration
1066
- * @param context - Optional operation context
1067
- * @return Promise resolving to the response data
1068
- * @throws Error if the request fails or the response is invalid
1069
- * @throws Error if the response content type is invalid
1070
- */
1071
- async _executeRequest(config, context2) {
1072
- const token = await this._getAccessToken(config.apiId, context2?.datasetName);
1073
- const headers = this._createHeaders(token, config, context2);
1074
- const requestBody = config.body ? new Blob([config.body], { type: "application/json" }) : "";
1075
- let result;
1076
- try {
1077
- result = await this._powerOperationExecutor.execute(_RuntimeDataClient.SERVICES.dataClient, _RuntimeDataClient.ACTIONS.sendHttp, [
1078
- {
1079
- url: config.url,
1080
- method: config.method,
1081
- requestSource: _RuntimeDataClient.REQUEST_SOURCE,
1082
- allowSessionStorage: true,
1083
- returnDirectResponse: true,
1084
- headers
1085
- },
1086
- requestBody,
1087
- "arraybuffer"
1088
- ]);
1089
- } catch (error) {
1090
- return {
1091
- success: false,
1092
- error: parseHttpPluginError(error),
1093
- data: void 0
1094
- };
1095
- }
1096
- const responseData = result.data;
1097
- const responseHeaders = responseData[0].headers;
1098
- const contentType = responseHeaders["Content-Type"];
1099
- if (!contentType) {
1100
- return {
1101
- success: true,
1102
- data: void 0
1103
- };
1104
- } else if (contentType.indexOf("application/json") !== -1) {
1105
- const data = result.data[1];
1106
- let text = this._decodeArrayBuffer(data);
1107
- if (!text) {
1108
- text = "{}";
1109
- }
1110
- const parsedResult = JSON.parse(text);
1111
- if (context2?.isDataVerseOperation || this._isDataverseCall(config.url)) {
1112
- return {
1113
- success: true,
1114
- data: parsedResult
1115
- };
1116
- } else if (!context2?.isExecuteAsync && "value" in parsedResult && Array.isArray(parsedResult.value)) {
1117
- return {
1118
- success: true,
1119
- data: parsedResult.value,
1120
- count: parsedResult["@odata.count"]
1121
- };
1122
- } else {
1123
- return {
1124
- success: true,
1125
- data: parsedResult
1126
- };
1127
- }
1128
- } else if (contentType.indexOf("image/") !== -1) {
1129
- const buffer = result.data[1];
1130
- if (buffer instanceof ArrayBuffer) {
1131
- const value = arrayBufferToBase64(buffer);
1132
- return {
1133
- success: true,
1134
- data: value
1135
- };
1136
- }
1137
- return {
1138
- success: true,
1139
- data: buffer
1140
- };
1141
- } else {
1142
- const buffer = result.data[1];
1143
- if (buffer instanceof ArrayBuffer) {
1144
- const value = convertArrayBufferToString(buffer);
1145
- const status = responseData[0].status;
1146
- const responseType = context2?.responseInfo?.[status];
1147
- if (responseType) {
1148
- let parsedValue;
1149
- try {
1150
- parsedValue = JSON.parse(value);
1151
- } catch (err) {
1152
- return {
1153
- success: false,
1154
- data: void 0,
1155
- error: new Error(DataOperationErrorMessages.InvalidResponse)
1156
- };
1157
- }
1158
- if (responseType.type === "array" && !Array.isArray(parsedValue)) {
1159
- return {
1160
- success: false,
1161
- data: void 0,
1162
- error: new Error(DataOperationErrorMessages.InvalidResponse)
1163
- };
1164
- }
1165
- if (responseType.type === "object" && (typeof parsedValue !== "object" || Array.isArray(parsedValue) || parsedValue === null)) {
1166
- return {
1167
- success: false,
1168
- data: void 0,
1169
- error: new Error(DataOperationErrorMessages.InvalidResponse)
1170
- };
1171
- }
1172
- return {
1173
- success: true,
1174
- data: parsedValue
1175
- };
1176
- } else {
1177
- return {
1178
- success: true,
1179
- data: value
1180
- };
1181
- }
1182
- }
1183
- return {
1184
- success: false,
1185
- data: responseData,
1186
- error: new Error(DataOperationErrorMessages.InvalidResponse)
1187
- };
1188
- }
1189
- }
1190
- _ensureContext(context2, defaultOperationName) {
1191
- if (!context2) {
1192
- context2 = {};
1193
- }
1194
- if (!context2.operationName) {
1195
- context2.operationName = defaultOperationName;
1196
- }
1197
- return context2;
1198
- }
1199
- /**
1200
- * Checks if the given URL is a Dataverse API call
1201
- * @param url - The URL to check
1202
- * @returns True if the URL is a Dataverse API call, false otherwise
1203
- */
1204
- _isDataverseCall(url) {
1205
- if (!url) {
1206
- return false;
1207
- }
1208
- const urlLower = decodeURIComponent(url).toLowerCase();
1209
- return urlLower.includes("/api/data/") && !urlLower.includes("/apim");
1210
- }
1211
- /**
1212
- * Decodes ArrayBuffer to string, handling both browser and Node.js environments
1213
- * @param buffer - The ArrayBuffer to decode
1214
- * @returns The decoded string
1215
- */
1216
- _decodeArrayBuffer(buffer) {
1217
- if (typeof TextDecoder !== "undefined") {
1218
- return new TextDecoder().decode(buffer);
1219
- }
1220
- const uint8Array = new Uint8Array(buffer);
1221
- const results = [];
1222
- const chunkSize = 8192;
1223
- for (let i = 0; i < uint8Array.length; i += chunkSize) {
1224
- const chunk = uint8Array.subarray(i, Math.min(i + chunkSize, uint8Array.length));
1225
- results.push(String.fromCharCode.apply(null, Array.from(chunk)));
1226
- }
1227
- try {
1228
- return results.join("");
1229
- } catch {
1230
- return results.join("");
1231
- }
1232
- }
1233
- };
1234
- // Static identifiers for services
1235
- // Used to identify specific services within the PowerApps environment
1236
- __publicField(_RuntimeDataClient, "SERVICES", {
1237
- dataClient: "AppHttpClientPlugin",
1238
- identityService: "AppIdentityServicePlugin"
1239
- });
1240
- // Static identifiers for service actions
1241
- // Used to identify specific actions within the service
1242
- // These actions are used to send HTTP requests and get access tokens
1243
- __publicField(_RuntimeDataClient, "ACTIONS", {
1244
- sendHttp: "sendHttpAsync",
1245
- getToken: "getAppAccessTokenAsync",
1246
- getDynamicToken: "getAppDynamicResourceAccessTokenAsync"
1247
- });
1248
- // Request source identifier for telemetry
1249
- // Used to identify the source of the request in telemetry data
1250
- __publicField(_RuntimeDataClient, "REQUEST_SOURCE", "PublishedApp");
1251
- var RuntimeDataClient = _RuntimeDataClient;
1252
-
1253
- var _RuntimeMetadataClient = class _RuntimeMetadataClient {
1254
- // Private member for the PowerOperationExecutor
1255
- // The PowerOperationExecutor is used to execute operations on the clients
1256
- constructor(_powerOperationExecutor) {
1257
- __publicField(this, "_powerOperationExecutor");
1258
- this._powerOperationExecutor = _powerOperationExecutor;
1259
- }
1260
- /**
1261
- * Creates a new instance of RuntimeMetadataClient
1262
- * @param powerOperationExecutor - The powerOperationExecutor instance
1263
- * @returns Promise resolving to IRuntimeMetadataClient
1264
- */
1265
- static createInstanceAsync(powerOperationExecutor) {
1266
- return Promise.resolve(new _RuntimeMetadataClient(powerOperationExecutor));
1267
- }
1268
- /**
1269
- * Fetches app connection configurations
1270
- * @returns Promise resolving to connection reference details
1271
- * @throws Error if the operation fails
1272
- */
1273
- async getAppConnectionConfigsAsync() {
1274
- try {
1275
- const config = {
1276
- service: _RuntimeMetadataClient.SERVICES.powerAppsClient,
1277
- action: _RuntimeMetadataClient.ACTIONS.getConnectionConfigs,
1278
- params: []
1279
- };
1280
- const result = await this._executeOperation(config);
1281
- return { success: true, data: result };
1282
- } catch (error) {
1283
- throw new PowerDataRuntimeError(ErrorCodes.ConnectionConfigFetchFailed, getErrorMessage(error));
1284
- }
1285
- }
1286
- /**
1287
- * Fetches app data source configurations
1288
- * @returns Promise resolving to connection reference details
1289
- * @throws Error if the operation fails
1290
- */
1291
- async getAppDataSourceConfigsAsync() {
1292
- try {
1293
- const config = {
1294
- service: _RuntimeMetadataClient.SERVICES.powerAppsClient,
1295
- action: _RuntimeMetadataClient.ACTIONS.getDataSourceConfigs,
1296
- params: []
1297
- };
1298
- const result = await this._executeOperation(config);
1299
- return { success: true, data: result };
1300
- } catch (error) {
1301
- throw new PowerDataRuntimeError(ErrorCodes.DataSourceConfigFetchFailed, getErrorMessage(error));
1302
- }
1303
- }
1304
- /**
1305
- * Executes a metadata operation with the given configuration
1306
- * @param config - The operation configuration
1307
- * @returns Promise resolving to the operation result
1308
- * @throws Error if the operation fails
1309
- */
1310
- async _executeOperation(config) {
1311
- try {
1312
- const result = await this._powerOperationExecutor.execute(config.service, config.action, config.params || []);
1313
- const lowerCaseResult = Object.keys(result.data).reduce((acc, key) => {
1314
- acc[key.toLowerCase()] = (result.data ?? {})[key];
1315
- return acc;
1316
- }, {});
1317
- return lowerCaseResult;
1318
- } catch {
1319
- throw new PowerDataRuntimeError(ErrorCodes.InvalidMetadataResponse);
1320
- }
1321
- }
1322
- };
1323
- // Static identifiers for services and actions
1324
- // Used to identify specific services and actions within the PowerApps environment
1325
- // These identifiers are used to execute operations through the PowerOperationExecutor
1326
- // The services provide the functionality for the operations
1327
- __publicField(_RuntimeMetadataClient, "SERVICES", {
1328
- powerAppsClient: "AppPowerAppsClientPlugin"
1329
- });
1330
- // The actions define the specific operations to be performed
1331
- __publicField(_RuntimeMetadataClient, "ACTIONS", {
1332
- getConnectionConfigs: "loadAppConnectionsAsync_v2",
1333
- getDataSourceConfigs: "getAppCdsDataSourceConfigsAsync"
1334
- });
1335
- var RuntimeMetadataClient = _RuntimeMetadataClient;
1336
-
1337
- var RuntimeClientProvider = class {
1338
- // Constructor for RuntimeClientProvider
1339
- // Accepts an optional IPowerOperationExecutor instance for executing operations
1340
- // If not provided, uses the default PowerOperationExecutor instance
1341
- constructor(powerOperationExecutor) {
1342
- // Private members for data and metadata clients
1343
- // The data client is responsible for handling data operations
1344
- __publicField(this, "_dataClient");
1345
- // The metadata client is responsible for handling metadata operations
1346
- __publicField(this, "_metadataClient");
1347
- // The operation executor is used to execute operations on the clients
1348
- // It is an instance of IPowerOperationExecutor, which provides the necessary methods for executing operations
1349
- __publicField(this, "_operationExecutor");
1350
- this._operationExecutor = powerOperationExecutor;
1351
- }
1352
- /**
1353
- * Gets or initializes the data client
1354
- * @throws Error if client initialization fails
1355
- * @returns Promise resolving to IRuntimeDataClient
1356
- */
1357
- async getDataClientAsync() {
1358
- try {
1359
- if (!this._dataClient) {
1360
- this._dataClient = await this._initializeDataClient();
1361
- }
1362
- if (!this._dataClient) {
1363
- throw new PowerDataRuntimeError(ErrorCodes.DataClientNotInitialized);
1364
- }
1365
- return this._dataClient;
1366
- } catch (error) {
1367
- throw new PowerDataRuntimeError(ErrorCodes.DataClientInitFailed, getErrorMessage(error));
1368
- }
1369
- }
1370
- /**
1371
- * Gets or initializes the metadata client
1372
- * @throws Error if client initialization fails
1373
- * @returns Promise resolving to IRuntimeMetadataClient
1374
- */
1375
- async getMetadataClientAsync() {
1376
- try {
1377
- if (!this._metadataClient) {
1378
- this._metadataClient = await this._initializeMetadataClient();
1379
- }
1380
- if (!this._metadataClient) {
1381
- throw new PowerDataRuntimeError(ErrorCodes.MetadataClientNotInitialized);
1382
- }
1383
- return this._metadataClient;
1384
- } catch (error) {
1385
- throw new PowerDataRuntimeError(ErrorCodes.MetadataClientInitFailed, getErrorMessage(error));
1386
- }
1387
- }
1388
- /**
1389
- * Initializes the data client
1390
- * @returns Promise resolving to IRuntimeDataClient
1391
- */
1392
- async _initializeDataClient() {
1393
- return RuntimeDataClient.createInstanceAsync(this._operationExecutor);
1394
- }
1395
- /**
1396
- * Initializes the metadata client
1397
- * @returns Promise resolving to IRuntimeMetadataClient
1398
- */
1399
- async _initializeMetadataClient() {
1400
- return RuntimeMetadataClient.createInstanceAsync(this._operationExecutor);
1401
- }
1402
- /**
1403
- * Resets both clients, forcing re-initialization on next use
1404
- * Useful for testing or recovering from error states
1405
- */
1406
- reset() {
1407
- this._dataClient = void 0;
1408
- this._metadataClient = void 0;
1409
- }
1410
- };
1411
-
1412
- function convertOptionsToQueryString(options) {
1413
- if (!options) {
1414
- return "";
1415
- }
1416
- const parts = [];
1417
- if (options.select && options.select.length > 0) {
1418
- parts.push(`$select=${encodeURIComponent(options.select.map((s) => s.trim().replace(/%20/g, "+").replace(/'/g, "%27")).join(","))}`);
1419
- }
1420
- if (options.filter) {
1421
- const encodedFilter = encodeURIComponent(options.filter.trim()).replace(/%20/g, "+").replace(/'/g, "%27");
1422
- parts.push(`$filter=${encodedFilter}`);
1423
- }
1424
- if (options.orderBy && options.orderBy.length > 0) {
1425
- parts.push(`$orderby=${encodeURIComponent(options.orderBy.map((s) => s.trim().replace(/%20/g, "+").replace(/'/g, "%27")).join(","))}`);
1426
- }
1427
- if (options.top !== void 0 && options.top !== null) {
1428
- parts.push(`$top=${options.top}`);
1429
- }
1430
- if (options.skip !== void 0 && options.skip !== null) {
1431
- parts.push(`$skip=${options.skip}`);
1432
- }
1433
- if (options.count !== void 0 && options.count !== null) {
1434
- parts.push(`$count=${options.count}`);
1435
- }
1436
- if (options.skipToken && options.skipToken.trim() !== "") {
1437
- parts.push(`$skiptoken=${encodeURIComponent(options.skipToken.trim())}`);
1438
- }
1439
- return parts.length ? `?${parts.join("&")}` : "";
1440
- }
1441
-
1442
- var ODATA_NEXT_LINK = "@odata.nextLink";
1443
- var DataverseDataOperationExecutor = class {
1444
- constructor(clientProvider) {
1445
- // Static identifiers for services and actions
1446
- // Used to identify specific services and actions within the PowerApps environment
1447
- __publicField(this, "_clientProvider");
1448
- __publicField(this, "_databaseReferences");
1449
- this._clientProvider = clientProvider;
1450
- }
1451
- /**
1452
- * Creates a new record in Dataverse
1453
- * @param tableName - The name of the table
1454
- * @param data - The record data to create
1455
- * @returns Promise resolving to operation result
1456
- */
1457
- async createRecordAsync(tableName, data) {
1458
- return this._executeNativeDataverseOperation(tableName, (dataSourceInfo, tblName) => this._getDataverseRequestUrl(dataSourceInfo, tblName), async (dataClient, requestUrl, dataSourceInfo) => {
1459
- const dataverseResponse = await dataClient.createDataAsync(
1460
- requestUrl,
1461
- DataSources.Dataverse,
1462
- // Use environment name for Dataverse authentication
1463
- tableName,
1464
- data,
1465
- {
1466
- operationName: DataverseOperationName.CreateRecord,
1467
- datasetName: dataSourceInfo.datasetName,
1468
- isDataVerseOperation: true
1469
- }
1470
- );
1471
- const returnValue = {
1472
- success: dataverseResponse.success,
1473
- data: dataverseResponse.data,
1474
- error: dataverseResponse.error
1475
- };
1476
- return returnValue;
1477
- }, DataOperationErrorMessages.CreateFailed);
1478
- }
1479
- /**
1480
- * Updates an existing record in Dataverse
1481
- * @param tableName - The name of the table
1482
- * @param id - The record identifier
1483
- * @param data - The updated record data
1484
- * @returns Promise resolving to operation result
1485
- */
1486
- async updateRecordAsync(tableName, id, data) {
1487
- return this._executeNativeDataverseOperation(tableName, (dataSourceInfo, tblName) => this._getDataverseRequestUrl(dataSourceInfo, tblName, `(${id})`), async (dataClient, requestUrl, dataSourceInfo) => {
1488
- const dataverseResponse = await dataClient.updateDataAsync(requestUrl, DataSources.Dataverse, tableName, data, {
1489
- operationName: DataverseOperationName.UpdateRecord,
1490
- datasetName: dataSourceInfo.datasetName,
1491
- isDataVerseOperation: true
1492
- });
1493
- const returnValue = {
1494
- success: dataverseResponse.success,
1495
- data: dataverseResponse.data,
1496
- error: dataverseResponse.error
1497
- };
1498
- return returnValue;
1499
- }, DataOperationErrorMessages.UpdateFailed);
1500
- }
1501
- /**
1502
- * Deletes a record from Dataverse
1503
- * @param tableName - The name of the table
1504
- * @param id - The record identifier
1505
- * @returns Promise resolving to operation result
1506
- */
1507
- async deleteRecordAsync(tableName, id) {
1508
- return this._executeNativeDataverseOperation(tableName, (dataSourceInfo, tblName) => this._getDataverseRequestUrl(dataSourceInfo, tblName, `(${id})`), async (dataClient, requestUrl, dataSourceInfo) => {
1509
- const dataverseResponse = await dataClient.deleteDataAsync(requestUrl, DataSources.Dataverse, tableName, {
1510
- operationName: DataverseOperationName.DeleteRecord,
1511
- datasetName: dataSourceInfo.datasetName,
1512
- isDataVerseOperation: true
1513
- });
1514
- const returnValue = {
1515
- success: dataverseResponse.success,
1516
- data: dataverseResponse.data,
1517
- error: dataverseResponse.error
1518
- };
1519
- return returnValue;
1520
- }, DataOperationErrorMessages.DeleteFailed);
1521
- }
1522
- /**
1523
- * Retrieves a single record from Dataverse
1524
- * @param tableName - The name of the table
1525
- * @param id - The record identifier
1526
- * @param options - The retrieval options
1527
- * @returns Promise resolving to operation result
1528
- */
1529
- async retrieveRecordAsync(tableName, id, options) {
1530
- const { maxPageSize = 500, ...rest } = options || {};
1531
- const optionsString = convertOptionsToQueryString(rest);
1532
- const headers = { Prefer: `odata.maxpagesize=${maxPageSize},odata.include-annotations=*` };
1533
- return this._executeNativeDataverseOperation(tableName, (dataSourceInfo, tblName) => this._getDataverseRequestUrl(dataSourceInfo, tblName, `(${id})${optionsString}`), async (dataClient, requestUrl, dataSourceInfo) => {
1534
- const dataverseResponse = await dataClient.retrieveDataAsync(
1535
- requestUrl,
1536
- DataSources.Dataverse,
1537
- tableName,
1538
- HttpMethod.GET,
1539
- headers,
1540
- void 0,
1541
- // No body for GET requests
1542
- {
1543
- operationName: DataverseOperationName.RetrieveRecord,
1544
- datasetName: dataSourceInfo.datasetName,
1545
- isDataVerseOperation: true
1546
- }
1547
- );
1548
- const returnValue = {
1549
- success: dataverseResponse.success,
1550
- data: dataverseResponse.data,
1551
- error: dataverseResponse.error
1552
- };
1553
- return returnValue;
1554
- }, DataOperationErrorMessages.RetrieveFailed);
1555
- }
1556
- /**
1557
- * Retrieves multiple records from Dataverse
1558
- * @param tableName - The name of the table
1559
- * @param options - The retrieval options
1560
- * @param maxPageSize - Optional maximum page size
1561
- * @returns Promise resolving to operation result
1562
- */
1563
- async retrieveMultipleRecordsAsync(tableName, options) {
1564
- const { maxPageSize = 500, ...rest } = options || {};
1565
- const optionsString = convertOptionsToQueryString(rest);
1566
- const headers = { Prefer: `odata.maxpagesize=${maxPageSize},odata.include-annotations=*` };
1567
- return this._executeNativeDataverseOperation(tableName, (dataSourceInfo, tblName) => this._getDataverseRequestUrl(dataSourceInfo, tblName, optionsString), async (dataClient, requestUrl, dataSourceInfo) => {
1568
- const dataverseResponse = await dataClient.retrieveDataAsync(
1569
- requestUrl,
1570
- DataSources.Dataverse,
1571
- tableName,
1572
- HttpMethod.GET,
1573
- headers,
1574
- void 0,
1575
- // No body for GET requests
1576
- {
1577
- operationName: DataverseOperationName.RetrieveMultipleRecords,
1578
- datasetName: dataSourceInfo.datasetName,
1579
- isDataVerseOperation: true
1580
- }
1581
- );
1582
- const returnValue = {
1583
- success: dataverseResponse.success,
1584
- data: dataverseResponse?.data?.value || [],
1585
- skipToken: extractSkipToken(dataverseResponse?.data?.[ODATA_NEXT_LINK]),
1586
- error: dataverseResponse.error
1587
- };
1588
- return returnValue;
1589
- }, DataOperationErrorMessages.RetrieveMultipleFailed);
1590
- }
1591
- /**
1592
- * Executes a custom Dataverse operation
1593
- * @param operation - The operation to execute
1594
- * @returns Promise resolving to operation result
1595
- */
1596
- async executeAsync(operation) {
1597
- const { dataverseRequest } = operation;
1598
- if (!dataverseRequest) {
1599
- return {
1600
- success: false,
1601
- data: null,
1602
- error: { message: "Dataverse request details are required for Dataverse operations." }
1603
- };
1604
- }
1605
- const { action, parameters } = dataverseRequest;
1606
- switch (action) {
1607
- // Future custom actions can be handled here
1608
- case "getEntityMetadata":
1609
- const { tableName, options } = parameters;
1610
- if (!tableName) {
1611
- return {
1612
- success: false,
1613
- data: null,
1614
- error: { message: "Table name is required for getEntityMetadata action." }
1615
- };
1616
- }
1617
- return this._getEntityMetadata(tableName, options ?? {});
1618
- default:
1619
- Log.trackEvent("DataverseDataOperation.UnsupportedAction", {
1620
- message: `Unsupported Dataverse action: ${action}`
1621
- });
1622
- return {
1623
- success: false,
1624
- data: null,
1625
- error: { message: `Unsupported Dataverse action: "${action}"` }
1626
- };
1627
- }
1628
- }
1629
- async _getEntityMetadata(tableName, options) {
1630
- const client = await this._getDataClient();
1631
- const dataSourceInfo = await this._getDataverseDataSourceInfo(tableName);
1632
- const url = this._generateMetadataRequestUrl(dataSourceInfo, options);
1633
- return client.retrieveDataAsync(url, DataSources.Dataverse, "EntityDefinitions", HttpMethod.GET, {
1634
- Consistency: "Strong"
1635
- // Force CDS to return latest metadata
1636
- }, void 0, {
1637
- operationName: DataverseOperationName.RetrieveRecord,
1638
- datasetName: dataSourceInfo.datasetName,
1639
- isDataVerseOperation: true
1640
- });
1641
- }
1642
- /**
1643
- * Returns the database references for Dataverse, grouped by environment/database.
1644
- * These come from the launch app response via runtime metadata client.
1645
- */
1646
- async getDatabaseReferences() {
1647
- if (this._databaseReferences) {
1648
- return this._databaseReferences;
1649
- }
1650
- const runtimeDatabaseReferences = await this._loadDatabaseReferencesFromRuntime();
1651
- if (runtimeDatabaseReferences && Object.keys(runtimeDatabaseReferences).length > 0) {
1652
- this._databaseReferences = runtimeDatabaseReferences;
1653
- return this._databaseReferences;
1654
- }
1655
- throw new PowerDataRuntimeError(ErrorCodes.DataSourceNotFound, "Failed to load Dataverse database references from runtime.");
1656
- }
1657
- /**
1658
- * Loads database references from runtime metadata client (launch app response).
1659
- */
1660
- async _loadDatabaseReferencesFromRuntime() {
1661
- try {
1662
- const metadataClient = await this._getMetadataClient();
1663
- const response = await metadataClient.getAppDataSourceConfigsAsync();
1664
- if (!response.success || !response.data) {
1665
- return void 0;
1666
- }
1667
- const cdsDataSources = Object.values(response.data);
1668
- if (cdsDataSources.length === 0) {
1669
- return void 0;
1670
- }
1671
- const databaseReferences = {};
1672
- for (const cdsDataSource of cdsDataSources) {
1673
- const cdsConfig = cdsDataSource;
1674
- const instanceUrl = this._extractInstanceUrlFromRuntimeUrl(cdsConfig.runtimeUrl);
1675
- const envName = "default.cds";
1676
- if (!databaseReferences[envName]) {
1677
- databaseReferences[envName] = {
1678
- databaseDetails: {
1679
- referenceType: "Environmental",
1680
- environmentName: envName,
1681
- overrideValues: {
1682
- status: "NotSpecified",
1683
- environmentVariableName: ""
1684
- },
1685
- linkedEnvironmentMetadata: {
1686
- resourceId: "",
1687
- friendlyName: "",
1688
- uniqueName: "",
1689
- domainName: "",
1690
- version: cdsConfig.version || "9.2",
1691
- instanceUrl,
1692
- instanceApiUrl: cdsConfig.runtimeUrl,
1693
- baseLanguage: 1033,
1694
- instanceState: "Ready",
1695
- createdTime: "",
1696
- platformSku: ""
1697
- }
1698
- },
1699
- dataSources: {}
1700
- };
1701
- }
1702
- const dataSourceName = cdsConfig.entitySetName || cdsConfig.logicalName;
1703
- databaseReferences[envName].dataSources[dataSourceName] = {
1704
- entitySetName: cdsConfig.entitySetName,
1705
- logicalName: cdsConfig.logicalName,
1706
- isHidden: false
1707
- };
1708
- }
1709
- return databaseReferences;
1710
- } catch (error) {
1711
- Log.trackEvent("DataverseDataOperation.FailedToLoadDatabaseReferences", {
1712
- message: "[DataverseDataOperation] Failed to load database references from runtime",
1713
- error
1714
- });
1715
- return void 0;
1716
- }
1717
- }
1718
- _extractInstanceUrlFromRuntimeUrl(runtimeUrl) {
1719
- try {
1720
- const matches = runtimeUrl.match(/^(https?:\/\/[^\/]+)/);
1721
- return matches ? matches[1] : runtimeUrl;
1722
- } catch (error) {
1723
- Log.trackEvent("DataverseDataOperation.FailedToExtractInstanceUrl", {
1724
- message: "[DataverseDataOperation] Failed to extract instance URL from runtime URL",
1725
- error
1726
- });
1727
- return runtimeUrl;
1728
- }
1729
- }
1730
- /**
1731
- * Helper to get a native data client and database reference
1732
- */
1733
- async _getDataClient() {
1734
- const dataClient = await this._clientProvider.getDataClientAsync();
1735
- if (!dataClient) {
1736
- Log.trackEvent("DataverseDataOperation.DataClientNotAvailable", {
1737
- message: "[DataverseDataOperation] Data client is not available"
1738
- });
1739
- throw new PowerDataRuntimeError(ErrorCodes.DataClientNotAvailable, "Data client is not available.");
1740
- }
1741
- return dataClient;
1742
- }
1743
- /**
1744
- * Gets the metadata client instance
1745
- */
1746
- async _getMetadataClient() {
1747
- const metadataClient = await this._clientProvider.getMetadataClientAsync();
1748
- if (!metadataClient) {
1749
- Log.trackEvent("DataverseDataOperation.MetadataClientNotAvailable", {
1750
- message: "[DataverseDataOperation] Metadata client is not available"
1751
- });
1752
- throw new PowerDataRuntimeError(ErrorCodes.MetadataClientNotAvailable);
1753
- }
1754
- return metadataClient;
1755
- }
1756
- /**
1757
- * Template method for connector-style CRUD operations to reduce duplication.
1758
- * Handles client, dataSourceInfo, requestUrl, and error handling.
1759
- */
1760
- async _executeNativeDataverseOperation(tableName, buildUrl, operation, errorMessage) {
1761
- try {
1762
- const dataClient = await this._getDataClient();
1763
- const dataSourceInfo = await this._getDataverseDataSourceInfo(tableName);
1764
- const requestUrl = buildUrl(dataSourceInfo, tableName);
1765
- return operation(dataClient, requestUrl, dataSourceInfo);
1766
- } catch (error) {
1767
- return createErrorResponse(error, errorMessage);
1768
- }
1769
- }
1770
- /**
1771
- * Helper to get the Dataverse datasourceinfo from databaseReferences
1772
- */
1773
- async _getDataverseDataSourceInfo(tableName) {
1774
- let dbRefs;
1775
- try {
1776
- dbRefs = await this.getDatabaseReferences();
1777
- } catch (error) {
1778
- Log.trackEvent("DataverseDataOperation.GetDataSourceInfoFailed", {
1779
- message: "[DataverseDataOperation] Failed to get database references",
1780
- tableName,
1781
- error
1782
- });
1783
- const errorMessage = error instanceof Error ? error.message : String(error);
1784
- throw new PowerDataRuntimeError(ErrorCodes.DataSourceNotFound, `Failed to get Dataverse data source info for table '${tableName}': ${errorMessage}`);
1785
- }
1786
- for (const dbKey of Object.keys(dbRefs)) {
1787
- const db = dbRefs[dbKey];
1788
- if (db.dataSources[tableName]) {
1789
- const ds = db.dataSources[tableName];
1790
- return {
1791
- datasetName: db.databaseDetails?.environmentName,
1792
- referenceType: db.databaseDetails?.referenceType,
1793
- linkedEnvironmentMetadata: db.databaseDetails?.linkedEnvironmentMetadata,
1794
- entitySetName: ds?.entitySetName,
1795
- logicalName: ds?.logicalName,
1796
- isHidden: ds?.isHidden,
1797
- tableId: ds?.logicalName,
1798
- apis: {}
1799
- };
1800
- }
1801
- }
1802
- const notFoundMsg = `No Dataverse data source found for table: ${tableName}`;
1803
- Log.trackEvent("DataverseDataOperation.DataSourceNotFound", {
1804
- message: notFoundMsg,
1805
- tableName
1806
- });
1807
- throw new PowerDataRuntimeError(ErrorCodes.DataSourceNotFound, notFoundMsg);
1808
- }
1809
- /**
1810
- * Helper to construct the Dataverse API URL using instanceUrl if available, otherwise fallback to runtimeUrl.
1811
- */
1812
- _getInstanceUrl(dataSourceInfo) {
1813
- const instanceUrl = dataSourceInfo.linkedEnvironmentMetadata?.instanceUrl;
1814
- if (!instanceUrl) {
1815
- throw new PowerDataRuntimeError(ErrorCodes.DataClientInitFailed, "No instanceUrl found for Dataverse table.");
1816
- }
1817
- const baseUrl = instanceUrl.endsWith("/") ? instanceUrl : `${instanceUrl}/`;
1818
- return baseUrl;
1819
- }
1820
- /**
1821
- * Helper to construct the Dataverse API URL using instanceUrl if available, otherwise fallback to runtimeUrl.
1822
- */
1823
- _getDataverseRequestUrl(dataSourceInfo, tableName, urlPath = "") {
1824
- const baseUrl = this._getInstanceUrl(dataSourceInfo);
1825
- return `${baseUrl}api/data/v9.0/${tableName}${urlPath}`;
1826
- }
1827
- /**
1828
- * Constructs GET request URL for fetching metadata using options object.
1829
- * @param dataSourceInfo - The data source information for the Dataverse table.
1830
- * @param options - The options for the metadata request.
1831
- * @returns The constructed metadata request URL.
1832
- */
1833
- _generateMetadataRequestUrl(dataSourceInfo, options) {
1834
- const { logicalName } = dataSourceInfo;
1835
- if (!logicalName) {
1836
- throw new PowerDataRuntimeError(ErrorCodes.DataClientInitFailed, "No logicalName found for Dataverse table.");
1837
- }
1838
- const url = new URL(`${this._getInstanceUrl(dataSourceInfo)}api/data/v9.0/EntityDefinitions(LogicalName='${logicalName}')`);
1839
- const { metadata, schema } = options;
1840
- const selects = new Set(Array.isArray(metadata) ? metadata : []);
1841
- selects.add("LogicalName");
1842
- const expands = [];
1843
- if (schema?.manyToOne) {
1844
- expands.push("ManyToOneRelationships");
1845
- }
1846
- if (schema?.oneToMany) {
1847
- expands.push("OneToManyRelationships");
1848
- }
1849
- if (schema?.manyToMany) {
1850
- expands.push("ManyToManyRelationships");
1851
- }
1852
- if (schema?.columns === "all") {
1853
- expands.push("Attributes");
1854
- } else if (schema && Array.isArray(schema.columns) && schema.columns.length > 0) {
1855
- const attributesCollection = schema.columns.map((a) => `'${a}'`).join(",");
1856
- expands.push(`Attributes($filter=Microsoft.Dynamics.CRM.In(PropertyName='LogicalName',PropertyValues=[${attributesCollection}]))`);
1857
- }
1858
- url.search = new URLSearchParams({
1859
- $select: [...selects].join(","),
1860
- $expand: expands.join(",")
1861
- }).toString();
1862
- return url.toString();
1863
- }
1864
- };
1865
- function extractSkipToken(nextLink) {
1866
- if (!nextLink?.trim()) {
1867
- return void 0;
1868
- }
1869
- const match = nextLink.match(/[\?&]\$?skiptoken=([^&#]+)/i);
1870
- return match ? decodeURIComponent(match[1]) : void 0;
1871
- }
1872
-
1873
- var ConnectorDataOperationExecutor = class {
1874
- // =====================================
1875
- // Constructor
1876
- // =====================================
1877
- constructor(clientProvider, connectionsService) {
1878
- // =====================================
1879
- // Private Members
1880
- // =====================================
1881
- __publicField(this, "_clientProvider");
1882
- __publicField(this, "_connectionsService");
1883
- __publicField(this, "_databaseReferences");
1884
- __publicField(this, "_connectionReferences");
1885
- this._validateConstructorParams(clientProvider, connectionsService);
1886
- this._clientProvider = clientProvider;
1887
- this._connectionsService = connectionsService;
1888
- }
1889
- // =====================================
1890
- // Public Methods
1891
- // =====================================
1892
- /**
1893
- * Creates a new record in the specified table
1894
- */
1895
- async createRecordAsync(tableName, data) {
1896
- try {
1897
- const { dataClient, connectionReference } = await this._getClientsAndConnection(tableName);
1898
- const requestUrl = await this._buildTableUrl(tableName, connectionReference);
1899
- const result = await dataClient.createDataAsync(requestUrl, connectionReference.apiId, tableName, data, { operationName: ConnectorOperationName.CreateRecord });
1900
- return result;
1901
- } catch (error) {
1902
- return createErrorResponse(error, DataOperationErrorMessages.CreateFailed);
1903
- }
1904
- }
1905
- /**
1906
- * Updates an existing record in the specified table
1907
- */
1908
- async updateRecordAsync(tableName, id, data) {
1909
- try {
1910
- const { dataClient, connectionReference } = await this._getClientsAndConnection(tableName);
1911
- const requestUrl = await this._buildTableUrl(tableName, connectionReference, `/${id}`);
1912
- const result = await dataClient.updateDataAsync(requestUrl, connectionReference.apiId, tableName, data, { operationName: ConnectorOperationName.UpdateRecord });
1913
- return result;
1914
- } catch (error) {
1915
- return createErrorResponse(error, DataOperationErrorMessages.UpdateFailed);
1916
- }
1917
- }
1918
- /**
1919
- * Deletes a record from the specified table
1920
- */
1921
- async deleteRecordAsync(tableName, id) {
1922
- try {
1923
- const { dataClient, connectionReference } = await this._getClientsAndConnection(tableName);
1924
- const requestUrl = await this._buildTableUrl(tableName, connectionReference, `/${id}`);
1925
- const result = await dataClient.deleteDataAsync(requestUrl, connectionReference.apiId, tableName, { operationName: ConnectorOperationName.DeleteRecord });
1926
- return result;
1927
- } catch (error) {
1928
- return createErrorResponse(error, DataOperationErrorMessages.DeleteFailed);
1929
- }
1930
- }
1931
- /**
1932
- * Retrieves a single record from the specified table
1933
- */
1934
- async retrieveRecordAsync(tableName, id, options) {
1935
- try {
1936
- const { dataClient, connectionReference } = await this._getClientsAndConnection(tableName);
1937
- const requestUrl = await this._buildTableUrl(tableName, connectionReference, `/${id}${convertOptionsToQueryString(options)}`);
1938
- const result = await dataClient.retrieveDataAsync(
1939
- requestUrl,
1940
- connectionReference.apiId,
1941
- tableName,
1942
- HttpMethod.GET,
1943
- void 0,
1944
- // body
1945
- { operationName: ConnectorOperationName.RetrieveRecord }
1946
- );
1947
- return result;
1948
- } catch (error) {
1949
- return createErrorResponse(error, DataOperationErrorMessages.RetrieveFailed);
1950
- }
1951
- }
1952
- /**
1953
- * Retrieves multiple records from the specified table
1954
- */
1955
- async retrieveMultipleRecordsAsync(tableName, options) {
1956
- try {
1957
- const { dataClient, connectionReference } = await this._getClientsAndConnection(tableName);
1958
- const requestUrl = await this._buildTableUrl(tableName, connectionReference, convertOptionsToQueryString(options), false);
1959
- const result = await dataClient.retrieveDataAsync(
1960
- requestUrl,
1961
- connectionReference.apiId,
1962
- tableName,
1963
- HttpMethod.GET,
1964
- void 0,
1965
- // body
1966
- { operationName: ConnectorOperationName.RetrieveMultipleRecords }
1967
- );
1968
- return result;
1969
- } catch (error) {
1970
- return createErrorResponse(error, DataOperationErrorMessages.RetrieveMultipleFailed);
1971
- }
1972
- }
1973
- /**
1974
- * Executes a custom operation on the data source
1975
- */
1976
- async executeAsync(operation) {
1977
- try {
1978
- if (!operation?.connectorOperation) {
1979
- throw new Error(`${DataOperationErrorMessages.InvalidRequest}: ${DataOperationErrorMessages.MissingConnectorOperation}`);
1980
- }
1981
- const tableName = operation.connectorOperation.tableName;
1982
- const dataSourceInfo = await this._connectionsService.getDataSource(tableName);
1983
- const { dataClient, connectionReference } = await this._getClientsAndConnection(tableName);
1984
- const config = await this._getOperationConfig(operation, connectionReference, tableName);
1985
- const requestUrl = await this._buildOperationUrl(operation, config);
1986
- const bodyParam = await this._buildOperationBody(operation, tableName);
1987
- const headers = await this._buildOperationHeader(operation, tableName);
1988
- const httpMethod = this._getHttpMethod(requestUrl, dataSourceInfo, operation.connectorOperation.operationName);
1989
- const responseInfo = dataSourceInfo.apis[operation.connectorOperation.operationName]?.responseInfo;
1990
- const result = await dataClient.retrieveDataAsync(requestUrl, config.apiId, tableName, httpMethod, headers, bodyParam, {
1991
- isExecuteAsync: true,
1992
- // Use the connector operation name for telemetry, may be a better idea to use executeAsync
1993
- // here and just log the connector operation name in the custom dimensions leaving comment for PR.
1994
- operationName: `connectorDataOperation.${operation.connectorOperation.operationName}`,
1995
- responseInfo
1996
- });
1997
- return result;
1998
- } catch (error) {
1999
- return createErrorResponse(error, DataOperationErrorMessages.ExecuteFailed);
2000
- }
2001
- }
2002
- // =====================================
2003
- // Private Methods
2004
- // =====================================
2005
- /**
2006
- * Determines the appropriate HTTP method for a request
2007
- * @param requestUrl - The URL for the request
2008
- * @param dataSourceInfo - The data source information
2009
- * @param operation - The operation name
2010
- * @returns The HTTP method to use
2011
- */
2012
- _getHttpMethod(requestUrl, dataSourceInfo, operation) {
2013
- const isSqlStoredProcedure = requestUrl.indexOf("apim/sql") > -1;
2014
- if (isSqlStoredProcedure) {
2015
- return HttpMethod.POST;
2016
- }
2017
- const method = dataSourceInfo.apis[operation]?.method;
2018
- if (method) {
2019
- return method;
2020
- }
2021
- return HttpMethod.GET;
2022
- }
2023
- /**
2024
- * Builds the operation body parameters
2025
- */
2026
- async _buildOperationBody(operation, tableName) {
2027
- const operationName = operation?.connectorOperation?.operationName;
2028
- if (operationName) {
2029
- const dataSourceInfo = await this._connectionsService.getDataSource(tableName);
2030
- const hasBodyParameter = dataSourceInfo?.apis?.[operationName]?.parameters?.some((param) => param.in === "body");
2031
- if (hasBodyParameter) {
2032
- return await this._buildOperationBodyParam(operation, tableName);
2033
- }
2034
- }
2035
- return void 0;
2036
- }
2037
- /**
2038
- * Builds operation body parameters from the operation and data source info
2039
- */
2040
- async _buildOperationBodyParam(operation, tableName) {
2041
- const operationName = operation.connectorOperation?.operationName;
2042
- if (!operationName) {
2043
- return "{}";
2044
- }
2045
- const dataSourceInfo = await this._connectionsService.getDataSource(tableName);
2046
- const apiParams = dataSourceInfo?.apis?.[operationName]?.parameters || [];
2047
- const rawParams = operation.connectorOperation?.parameters || [];
2048
- if (typeof rawParams !== "object" || rawParams === null) {
2049
- return "{}";
2050
- }
2051
- const bodyParam = apiParams.find((param) => param.in === "body");
2052
- if (bodyParam) {
2053
- const value = rawParams[bodyParam.name];
2054
- if (value !== void 0 && value !== null) {
2055
- return JSON.stringify(value);
2056
- }
2057
- }
2058
- return "{}";
2059
- }
2060
- /**
2061
- * Builds the operation header for a given data operation if required.
2062
- *
2063
- * @template TRequest - The type of the request payload for the data operation.
2064
- * @param dataOperationRequest - The data operation containing details about the connector operation.
2065
- * @param tableName - The name of the table associated with the data operation.
2066
- * @returns A promise that resolves to the operation header as a string if a header parameter is required,
2067
- * or `undefined` if no header parameter is needed.
2068
- */
2069
- async _buildOperationHeader(dataOperationRequest, tableName) {
2070
- const operationName = dataOperationRequest.connectorOperation?.operationName;
2071
- if (operationName) {
2072
- const dataSourceInfo = await this._connectionsService.getDataSource(tableName);
2073
- const hasHeaderParameter = dataSourceInfo?.apis?.[operationName]?.parameters?.some((param) => param.in === "header");
2074
- if (hasHeaderParameter) {
2075
- return await this._buildOperationHeaderParam(dataOperationRequest, tableName);
2076
- }
2077
- }
2078
- return void 0;
2079
- }
2080
- /**
2081
- * Builds the operation header parameters as a JSON string for a given data operation.
2082
- *
2083
- * @template TRequest - The type of the request object for the data operation.
2084
- * @param dataOperationRequest - The data operation containing connector operation details and parameters.
2085
- * @param tableName - The name of the table associated with the data operation.
2086
- * @returns A promise that resolves to a JSON string representing the header parameters,
2087
- * or `undefined` if no `header` parameters are available.
2088
- */
2089
- async _buildOperationHeaderParam(dataOperationRequest, tableName) {
2090
- const operationName = dataOperationRequest.connectorOperation?.operationName;
2091
- if (!operationName) {
2092
- return {};
2093
- }
2094
- const dataSourceInfo = await this._connectionsService.getDataSource(tableName);
2095
- const apiParamSpec = dataSourceInfo?.apis?.[operationName]?.parameters || [];
2096
- const inputParams = dataOperationRequest.connectorOperation?.parameters;
2097
- const headers = {};
2098
- if (!inputParams) {
2099
- return void 0;
2100
- }
2101
- if (typeof inputParams === "string") {
2102
- if (apiParamSpec.length === 1 && apiParamSpec[0].in === "header") {
2103
- headers[apiParamSpec[0].name] = inputParams;
2104
- }
2105
- }
2106
- if (typeof inputParams === "object" && !Array.isArray(inputParams)) {
2107
- apiParamSpec.forEach((param) => {
2108
- if (param.in === "header" && param.name in inputParams) {
2109
- headers[param.name] = inputParams[param.name];
2110
- }
2111
- });
2112
- }
2113
- if (Array.isArray(inputParams)) {
2114
- apiParamSpec.forEach((param, index) => {
2115
- if (param.in === "header" && inputParams[index] !== void 0) {
2116
- headers[param.name] = inputParams[index];
2117
- }
2118
- });
2119
- }
2120
- return headers;
2121
- }
2122
- /**
2123
- * Constructs the request URL for table operations
2124
- * @param tableName - The name of the table
2125
- * @param connectionReference - The connection reference
2126
- * @param options - Optional URL parameters
2127
- * @param encodeOptions - Whether to encode the options
2128
- * @returns The constructed URL
2129
- */
2130
- async _buildTableUrl(tableName, connectionReference, options = "", encodeOptions = true) {
2131
- const dataSourceInfo = await this._connectionsService.getDataSource(tableName);
2132
- const isSharedSql = (connectionReference.apiId ?? "").indexOf("shared_sql") > -1;
2133
- const isSharePoint = (connectionReference.apiId ?? "").indexOf("shared_sharepointonline") > -1;
2134
- const urlBuilder = {
2135
- runtimeUrl: connectionReference.runtimeUrl ?? "",
2136
- connectionName: connectionReference.connectionName ?? "",
2137
- datasetName: connectionReference.datasetName ? isSharedSql ? connectionReference.datasetNameOverride : isSharePoint ? encodeURIComponent(encodeURIComponent(connectionReference.datasetName)) : encodeURIComponent(connectionReference.datasetName) : "",
2138
- tableId: isSharedSql ? encodeURIComponent(encodeURIComponent(dataSourceInfo.tableId)) : dataSourceInfo.tableId,
2139
- version: dataSourceInfo.version,
2140
- isSharedSql
2141
- };
2142
- return this._constructUrl(urlBuilder, options, encodeOptions);
2143
- }
2144
- /**
2145
- * Builds the operation URL
2146
- */
2147
- async _buildOperationUrl(operation, config) {
2148
- const operationName = operation.connectorOperation?.operationName;
2149
- if (!operationName) {
2150
- throw new Error(`${DataOperationErrorMessages.InvalidOperationParameters}: ${DataOperationErrorMessages.MissingOperationName}`);
2151
- }
2152
- const dataSourceInfo = await this._connectionsService.getDataSource(config.tableName);
2153
- const isSharedSql = (config.apiId ?? "").indexOf("shared_sql") > -1;
2154
- const path = dataSourceInfo.apis[operationName].path;
2155
- if (isSharedSql) {
2156
- return this._buildSharedSqlOperationUrl(config, path);
2157
- }
2158
- return this._buildStandardOperationUrl(operation, config, operationName, path);
2159
- }
2160
- /**
2161
- * Gets the connection references
2162
- */
2163
- async _getConnectionReferencesAsync() {
2164
- if (this._connectionReferences) {
2165
- return this._connectionReferences;
2166
- }
2167
- const metadataClient = await this._getMetadataClient();
2168
- const response = await metadataClient.getAppConnectionConfigsAsync();
2169
- this._connectionReferences = response.data;
2170
- return this._connectionReferences;
2171
- }
2172
- /**
2173
- * Gets the database references
2174
- */
2175
- async _getDatabaseReferencesAsync() {
2176
- if (this._databaseReferences) {
2177
- return this._databaseReferences;
2178
- }
2179
- const metadataClient = await this._getMetadataClient();
2180
- const response = await metadataClient.getAppDataSourceConfigsAsync();
2181
- this._databaseReferences = response.data;
2182
- return this._databaseReferences;
2183
- }
2184
- /**
2185
- * Gets the metadata client instance
2186
- */
2187
- async _getMetadataClient() {
2188
- const metadataClient = await this._clientProvider.getMetadataClientAsync();
2189
- if (!metadataClient) {
2190
- throw new PowerDataRuntimeError(ErrorCodes.MetadataClientNotAvailable);
2191
- }
2192
- return metadataClient;
2193
- }
2194
- /**
2195
- * Gets the connection reference for a table
2196
- */
2197
- _getConnectionReference(tableName) {
2198
- const connectionReference = this._connectionReferences?.[tableName];
2199
- if (!connectionReference) {
2200
- throw new PowerDataRuntimeError(ErrorCodes.ConnectionReferenceNotFound, tableName);
2201
- }
2202
- return connectionReference;
2203
- }
2204
- /**
2205
- * Gets both the data client and connection reference
2206
- */
2207
- async _getClientsAndConnection(tableName) {
2208
- await this._getReferences();
2209
- const dataClient = await this._clientProvider.getDataClientAsync();
2210
- if (!dataClient) {
2211
- throw new PowerDataRuntimeError(ErrorCodes.DataClientNotAvailable);
2212
- }
2213
- const connectionReference = this._getConnectionReference(tableName);
2214
- return { dataClient, connectionReference };
2215
- }
2216
- /**
2217
- * Builds the URL for shared SQL operations
2218
- */
2219
- _buildSharedSqlOperationUrl(config, path) {
2220
- const version = config.version ? `/${config.version}/` : "/";
2221
- return `${config.runtimeUrl}/${config.connectionName}${version}datasets/${config.datasetName}/procedures${path}`;
2222
- }
2223
- /**
2224
- * Builds the URL for standard operations
2225
- * Assumptions / Invariants:
2226
- * - The connector always defines a required path parameter for the connection id named 'connectionId'.
2227
- * - When a dataset is applicable, the parameter name is 'dataset'.
2228
- * - When a table is applicable, the parameter name is 'tableName'.
2229
- * - A lone string parameter maps to the first remaining (non-synthetic) required API parameter.
2230
- * - Array parameters map positionally to the remaining API parameters after filtering.
2231
- * - Object parameters map by (case-insensitive, hyphen/underscore agnostic) key.
2232
- * @param operation - The data operation containing connector operation details from runtime
2233
- * @param config - The connector operation configuration
2234
- * @param operationName - The name of the operation to be performed
2235
- * @param path - The path template for the operation
2236
- */
2237
- async _buildStandardOperationUrl(operation, config, operationName, path) {
2238
- const dataSourceInfo = await this._connectionsService.getDataSource(config.tableName);
2239
- let apiParams = dataSourceInfo.apis[operationName]?.parameters || [];
2240
- if (apiParams.length > 0) {
2241
- apiParams = apiParams.filter((param) => param.name !== "connectionId" && param.name !== "dataset" && param.name !== "tableName");
2242
- }
2243
- const operationParams = operation.connectorOperation?.parameters;
2244
- const rawParamValues = {
2245
- connectionId: config.connectionName,
2246
- dataset: (
2247
- // The dataset name needs to be double encoded for sharepoint, once here and then once in the HTTP pipeline
2248
- // CRUD operations already handle this, so we need to do the same here
2249
- config.apiId.indexOf("shared_sharepointonline") !== -1 && config.datasetName ? encodeURIComponent(config.datasetName) : config.datasetName
2250
- ),
2251
- tableName: config.tableName
2252
- };
2253
- if (operationParams !== void 0) {
2254
- if (typeof operationParams === "string") {
2255
- if (apiParams.length > 0) {
2256
- const requiredParams = apiParams.filter((param) => param.required);
2257
- rawParamValues[requiredParams?.[0]?.name ?? apiParams[0].name] = operationParams;
2258
- }
2259
- } else if (typeof operationParams === "object" && !Array.isArray(operationParams)) {
2260
- apiParams.forEach((param) => {
2261
- if (operationParams) {
2262
- const value = this._getNormalizedParamValue(operationParams, param.name);
2263
- if (value !== void 0) {
2264
- rawParamValues[param.name] = value;
2265
- }
2266
- }
2267
- });
2268
- } else if (Array.isArray(operationParams)) {
2269
- apiParams.forEach((param, index) => {
2270
- rawParamValues[param.name] = operationParams[index];
2271
- });
2272
- }
2273
- }
2274
- const { processedPath, queryParams } = this._processParameters(
2275
- // deliberately pass the unfiltered list to _processParameters so path placeholders still see synthetic params.
2276
- dataSourceInfo.apis[operationName]?.parameters || [],
2277
- rawParamValues,
2278
- path
2279
- );
2280
- const separator = queryParams ? processedPath.includes("?") ? "&" : "?" : "";
2281
- return `${config.runtimeUrl}${processedPath}${separator}${queryParams}`;
2282
- }
2283
- /**
2284
- * Normalizes the parameter name by replacing hyphens with underscores and performs case-insensitive matching
2285
- */
2286
- _getNormalizedParamValue(obj, paramName) {
2287
- const normalizedParamName = paramName.replace(/-/g, "_").toLowerCase();
2288
- const foundKey = Object.keys(obj).find((key) => key.replace(/-/g, "_").toLowerCase() === normalizedParamName);
2289
- return foundKey !== void 0 ? obj[foundKey] : void 0;
2290
- }
2291
- /**
2292
- * Processes operation parameters into path and query parameters
2293
- * @param apiParams - The API parameter specifications from the data source info
2294
- * @param rawParamValues - The raw parameter values provided in the operation at runtime
2295
- * @param path - The initial path template
2296
- * @returns An object containing the processed path and query parameters
2297
- */
2298
- _processParameters(apiParams, rawParamValues, path) {
2299
- const usedParams = /* @__PURE__ */ new Set();
2300
- let processedPath = path;
2301
- const queryParams = [];
2302
- apiParams.forEach((param, index) => {
2303
- const paramValue = rawParamValues[param.name];
2304
- if (paramValue === void 0) {
2305
- return;
2306
- }
2307
- if (param.in === "path") {
2308
- const placeholder = `{${param.name}}`;
2309
- if (processedPath.includes(placeholder)) {
2310
- processedPath = processedPath.replace(placeholder, encodeURIComponent(String(paramValue)));
2311
- usedParams.add(param.name);
2312
- }
2313
- } else if (param.in === "query") {
2314
- queryParams.push(`${encodeURIComponent(param.name)}=${encodeURIComponent(String(paramValue))}`);
2315
- usedParams.add(param.name);
2316
- }
2317
- });
2318
- return {
2319
- processedPath,
2320
- queryParams: queryParams.join("&")
2321
- };
2322
- }
2323
- /**
2324
- * Gets the operation configuration
2325
- */
2326
- async _getOperationConfig(operation, connectionReference, tableName) {
2327
- if (!operation.connectorOperation) {
2328
- throw new Error(`${DataOperationErrorMessages.InvalidRequest}: ${DataOperationErrorMessages.MissingConnectorOperation}`);
2329
- }
2330
- const dataSourceInfo = await this._connectionsService.getDataSource(tableName);
2331
- const config = {
2332
- tableName,
2333
- apiId: connectionReference.apiId ?? "",
2334
- runtimeUrl: connectionReference.runtimeUrl ?? "",
2335
- connectionName: connectionReference.connectionName ?? "",
2336
- datasetName: connectionReference.datasetName ?? "",
2337
- tableId: dataSourceInfo.tableId,
2338
- version: dataSourceInfo.version
2339
- };
2340
- return config;
2341
- }
2342
- /**
2343
- * Initializes the clients
2344
- */
2345
- async _getReferences() {
2346
- await this._getConnectionReferencesAsync();
2347
- await this._getDatabaseReferencesAsync();
2348
- }
2349
- /**
2350
- * Validates constructor parameters
2351
- */
2352
- _validateConstructorParams(clientProvider, connectionsService) {
2353
- if (!clientProvider) {
2354
- throw new PowerDataRuntimeError(ErrorCodes.ClientProviderNotAvailable);
2355
- }
2356
- if (!connectionsService) {
2357
- throw new PowerDataRuntimeError(ErrorCodes.DataSourceServiceNotAvailable);
2358
- }
2359
- }
2360
- /**
2361
- * Constructs the final URL
2362
- */
2363
- _constructUrl(urlBuilder, options = "", encodeOptions = true) {
2364
- const apiVersion = urlBuilder.version ? `/${urlBuilder.version}/` : "/";
2365
- const encodedOptions = encodeOptions && options ? options.charAt(0) + encodeURIComponent(options.slice(1)) : options;
2366
- if (urlBuilder.datasetName) {
2367
- return `${urlBuilder.runtimeUrl}/${urlBuilder.connectionName}${apiVersion}datasets/${urlBuilder.datasetName}/tables/${urlBuilder.tableId}/items${encodedOptions}`;
2368
- }
2369
- return `${urlBuilder.runtimeUrl}/${urlBuilder.connectionName}/tables/${urlBuilder.tableId}/items${encodedOptions}`;
2370
- }
2371
- };
2372
-
2373
- var DataSourceServiceError;
2374
- /* @__PURE__ */ (function(DataSourceServiceError2) {
2375
- })(DataSourceServiceError || (DataSourceServiceError = {}));
2376
- var RuntimeDataSourceService = class {
2377
- /**
2378
- * Creates a new instance of RuntimeDataSourceService
2379
- */
2380
- constructor(_powerDataSourcesInfoProvider) {
2381
- __publicField(this, "_powerDataSourcesInfoProvider");
2382
- /**
2383
- * Data source information
2384
- */
2385
- __publicField(this, "_dataSourcesInfo");
2386
- /**
2387
- * Indicates whether the service has been initialized
2388
- */
2389
- __publicField(this, "_isInitialized");
2390
- this._powerDataSourcesInfoProvider = _powerDataSourcesInfoProvider;
2391
- this._dataSourcesInfo = {};
2392
- this._isInitialized = false;
2393
- }
2394
- /**
2395
- * Initializes the service by loading user data sources
2396
- * @throws PowerDataRuntimeError if initialization fails
2397
- */
2398
- async initialize() {
2399
- try {
2400
- const userDataSources = await this._getUserDataSources();
2401
- this._dataSourcesInfo = {};
2402
- Object.keys(userDataSources).forEach((key) => {
2403
- this._dataSourcesInfo[key] = userDataSources[key];
2404
- });
2405
- this._isInitialized = true;
2406
- } catch (error) {
2407
- throw new PowerDataRuntimeError(ErrorCodes.InitializationError, getErrorMessage(error));
2408
- }
2409
- }
2410
- /**
2411
- * Gets all user data sources
2412
- * @returns Array of data source information
2413
- * @throws PowerDataRuntimeError if service is not initialized
2414
- */
2415
- async getUserDataSources() {
2416
- await this._ensureInitialized();
2417
- return this._dataSourcesInfo;
2418
- }
2419
- /**
2420
- * Gets information for a specific data source
2421
- * @param dataSource - The ID of the data source
2422
- * @returns Data source information
2423
- * @throws PowerDataRuntimeError if data source is not found or service is not initialized
2424
- */
2425
- async getDataSource(dataSource) {
2426
- await this._ensureInitialized();
2427
- const dataSourceInfo = this._dataSourcesInfo[dataSource];
2428
- if (!dataSourceInfo) {
2429
- const errorMessage = `Unable to find data source: ${dataSource} in data sources info.`;
2430
- throw new PowerDataRuntimeError(ErrorCodes.DataSourceNotFound, errorMessage);
2431
- }
2432
- return dataSourceInfo;
2433
- }
2434
- /**
2435
- * Checks if a data source exists
2436
- * @param dataSourceId - The ID of the data source to check
2437
- * @returns True if the data source exists, false otherwise
2438
- * @throws PowerDataRuntimeError if service is not initialized
2439
- */
2440
- async hasDataSource(dataSource) {
2441
- await this._ensureInitialized();
2442
- return dataSource in this._dataSourcesInfo;
2443
- }
2444
- /**
2445
- * Ensures the service is initialized
2446
- * @throws PowerDataRuntimeError if service is not initialized
2447
- */
2448
- async _ensureInitialized() {
2449
- if (!this._isInitialized) {
2450
- await this.initialize();
2451
- }
2452
- }
2453
- /**
2454
- * Gets user data sources from the provided data source schemas
2455
- * @returns Promise resolving to array of data source information
2456
- */
2457
- async _getUserDataSources() {
2458
- const dataSourcesInfo = await this._powerDataSourcesInfoProvider.getDataSourcesInfo();
2459
- return Promise.resolve(dataSourcesInfo);
2460
- }
2461
- };
2462
-
2463
- var PowerDataRuntime = class {
2464
- /**
2465
- * Creates a new instance of PowerDataRuntime
2466
- * @param params - Initialization parameters
2467
- * @throws DataRuntimeError if initialization fails
2468
- */
2469
- constructor(params) {
2470
- __publicField(this, "_clientProvider");
2471
- __publicField(this, "_dataSourceService");
2472
- __publicField(this, "_dataOperations");
2473
- __publicField(this, "_metadataOperations");
2474
- __publicField(this, "_isInitialized");
2475
- try {
2476
- Log.createInstance(params.powerOperationExecutor);
2477
- this._clientProvider = new RuntimeClientProvider(params.powerOperationExecutor);
2478
- this._dataSourceService = new RuntimeDataSourceService(params.powerDataSourcesInfoProvider);
2479
- this._isInitialized = false;
2480
- this._initialize();
2481
- } catch (error) {
2482
- if (error instanceof Error) {
2483
- Log.trackException(error);
2484
- }
2485
- throw error;
2486
- }
2487
- }
2488
- /**
2489
- * Gets the Data operations interface
2490
- * @throws PowerDataRuntimeError if operations are not initialized
2491
- */
2492
- get Data() {
2493
- this._ensureInitialized();
2494
- if (!this._dataOperations) {
2495
- this._dataOperations = this._createDataOperations();
2496
- }
2497
- return this._dataOperations;
2498
- }
2499
- /**
2500
- * Gets the Metadata operations interface
2501
- * @throws PowerDataRuntimeError if operations are not initialized
2502
- */
2503
- get Metadata() {
2504
- this._ensureInitialized();
2505
- if (!this._metadataOperations) {
2506
- this._metadataOperations = this._createMetadataOperations();
2507
- }
2508
- return this._metadataOperations;
2509
- }
2510
- /**
2511
- * Ensures the PowerDataRuntime is initialized
2512
- * @throws PowerDataRuntimeError if not initialized
2513
- */
2514
- _ensureInitialized() {
2515
- if (!this._isInitialized) {
2516
- throw new PowerDataRuntimeError(ErrorCodes.OperationsNotInitialized);
2517
- }
2518
- }
2519
- /**
2520
- * Initializes the PowerDataRuntime components
2521
- * @throws PowerDataRuntimeError if initialization fails
2522
- */
2523
- _initialize() {
2524
- try {
2525
- this._dataOperations = this._createDataOperations();
2526
- this._metadataOperations = this._createMetadataOperations();
2527
- this._isInitialized = true;
2528
- } catch (error) {
2529
- throw new PowerDataRuntimeError(ErrorCodes.InitializationFailed, getErrorMessage(error));
2530
- }
2531
- }
2532
- /**
2533
- * Creates a new instance of DataOperations
2534
- */
2535
- _createDataOperations() {
2536
- const dataverseOperation = new DataverseDataOperationExecutor(this._clientProvider);
2537
- const connectorOperation = new ConnectorDataOperationExecutor(this._clientProvider, this._dataSourceService);
2538
- return new DefaultDataOperationOrchestrator(dataverseOperation, connectorOperation, this._dataSourceService);
2539
- }
2540
- /**
2541
- * Creates a new instance of MetadataOperations
2542
- */
2543
- _createMetadataOperations() {
2544
- return new RuntimeMetadataOperations(this._clientProvider);
2545
- }
2546
- };
2547
-
2548
- var powerDataRuntimeInstance;
2549
- function getPowerDataRuntime(powerDataSourcesInfoProvider, powerOperationExecutor) {
2550
- if (!powerDataRuntimeInstance) {
2551
- powerDataRuntimeInstance = new PowerDataRuntime({
2552
- powerDataSourcesInfoProvider,
2553
- powerOperationExecutor
2554
- });
2555
- }
2556
- return powerDataRuntimeInstance;
2557
- }
2558
-
2559
- var _PowerDataSourcesInfoProvider = class _PowerDataSourcesInfoProvider {
2560
- /**
2561
- * Private constructor to enforce the singleton pattern.
2562
- * @param dataSourcesInfo The data sources information to initialize the provider with.
2563
- */
2564
- constructor(dataSourcesInfo) {
2565
- __publicField(this, "dataSourcesInfo");
2566
- this.dataSourcesInfo = dataSourcesInfo;
2567
- }
2568
- /**
2569
- * Retrieves the singleton instance of PowerDataSourcesInfoProvider.
2570
- * If the instance does not exist, it initializes it with the provided data sources info.
2571
- *
2572
- * @param dataSourcesInfo Optional parameter to initialize the instance if it doesn't exist.
2573
- * @returns The singleton instance of PowerDataSourcesInfoProvider.
2574
- * @throws Error if the instance is not initialized and no dataSourcesInfo is provided.
2575
- */
2576
- static getInstance(dataSourcesInfo) {
2577
- if (!this.instance) {
2578
- if (!dataSourcesInfo) {
2579
- throw new PowerDataRuntimeError(ErrorCodes.DataSourcesInfoNotFound);
2580
- }
2581
- this.instance = new _PowerDataSourcesInfoProvider(dataSourcesInfo);
2582
- }
2583
- return this.instance;
2584
- }
2585
- /**
2586
- * Retrieves the data sources information.
2587
- *
2588
- * @returns A promise resolving to the data sources information.
2589
- */
2590
- async getDataSourcesInfo() {
2591
- return this.dataSourcesInfo;
2592
- }
2593
- };
2594
- __publicField(_PowerDataSourcesInfoProvider, "instance", null);
2595
- var PowerDataSourcesInfoProvider = _PowerDataSourcesInfoProvider;
2596
- var powerDataSourcesInfoProvider_default = PowerDataSourcesInfoProvider;
2597
-
2598
- var connectionsLoaded = false;
2599
- async function loadConnections() {
2600
- if (connectionsLoaded) {
2601
- return;
2602
- }
2603
- connectionsLoaded = true;
2604
- await loadNonCompositeConnectionsAsync();
2605
- await resolveCompositeConnectionsAsync();
2606
- }
2607
- async function loadNonCompositeConnectionsAsync() {
2608
- return executePluginAsync("AppPowerAppsClientPlugin", "loadNonCompositeConnectionsAsync", []);
2609
- }
2610
- async function resolveCompositeConnectionsAsync() {
2611
- return executePluginAsync("AppPowerAppsClientPlugin", "resolveCompositeConnectionsAsync", []);
2612
- }
2613
-
2614
- var loadConnectionsPromise;
2615
- var OperationExecutor = class {
2616
- /**
2617
- * Executes an operation using the plugin.
2618
- * @param operationName The name of the operation.
2619
- * @param action The action to perform.
2620
- * @param params The parameters for the operation.
2621
- * @returns A promise resolving to the operation result.
2622
- */
2623
- async execute(operationName, action, params) {
2624
- try {
2625
- if (!loadConnectionsPromise) {
2626
- loadConnectionsPromise = loadConnections();
2627
- }
2628
- await loadConnectionsPromise;
2629
- const result = await executePluginAsync(operationName, action, params);
2630
- return {
2631
- success: true,
2632
- data: result
2633
- };
2634
- } catch (error) {
2635
- throw error;
2636
- }
2637
- }
2638
- };
2639
-
2640
- var _executor;
2641
- function getExecutor() {
2642
- if (!_executor) {
2643
- _executor = new OperationExecutor();
2644
- }
2645
- return _executor;
2646
- }
2647
- async function getPowerSdkInstance(dataSourcesInfo) {
2648
- const executor = getExecutor();
2649
- const provider = powerDataSourcesInfoProvider_default.getInstance(dataSourcesInfo);
2650
- return getPowerDataRuntime(provider, executor);
2651
- }
2652
-
2653
- async function createRecordAsync(dataSourcesInfo, tableName, record) {
2654
- return await (await getPowerSdkInstance(dataSourcesInfo)).Data.createRecordAsync(tableName, record);
2655
- }
2656
-
2657
- async function updateRecordAsync(dataSourcesInfo, tableName, recordId, changes) {
2658
- return await (await getPowerSdkInstance(dataSourcesInfo)).Data.updateRecordAsync(tableName, recordId, changes);
2659
- }
2660
-
2661
- async function deleteRecordAsync(dataSourcesInfo, tableName, recordId) {
2662
- return await (await getPowerSdkInstance(dataSourcesInfo)).Data.deleteRecordAsync(tableName, recordId);
2663
- }
2664
-
2665
- async function retrieveRecordAsync(dataSourcesInfo, tableName, recordId, options) {
2666
- return await (await getPowerSdkInstance(dataSourcesInfo)).Data.retrieveRecordAsync(tableName, recordId, options);
2667
- }
2668
-
2669
- async function retrieveMultipleRecordsAsync(dataSourcesInfo, tableName, options) {
2670
- return await (await getPowerSdkInstance(dataSourcesInfo)).Data.retrieveMultipleRecordsAsync(tableName, options);
2671
- }
2672
-
2673
- async function executeAsync(dataSourcesInfo, operation) {
2674
- return await (await getPowerSdkInstance(dataSourcesInfo)).Data.executeAsync(operation);
2675
- }
2676
-
2677
- async function callActionAsync(dataSourcesInfo, actionName, params) {
2678
- var sdkInstance = await getPowerSdkInstance(dataSourcesInfo);
2679
- var orchestrator = sdkInstance.Data;
2680
- var dvExecutor = orchestrator._dataverseOperation;
2681
- var dataClient = await dvExecutor._getDataClient();
2682
- var dbRefs = await dvExecutor.getDatabaseReferences();
2683
- var sInstanceUrl = null;
2684
- var sDatasetName = null;
2685
- for (var sDbKey of Object.keys(dbRefs)) {
2686
- var oDb = dbRefs[sDbKey];
2687
- if (oDb.databaseDetails && oDb.databaseDetails.linkedEnvironmentMetadata) {
2688
- sInstanceUrl = oDb.databaseDetails.linkedEnvironmentMetadata.instanceUrl;
2689
- sDatasetName = oDb.databaseDetails.environmentName;
2690
- break;
2691
- }
2692
- }
2693
- if (!sInstanceUrl) {
2694
- throw new Error("Cannot call unbound action: no Dataverse instance URL found. At least one Dataverse table must be registered.");
2695
- }
2696
- var sBaseUrl = sInstanceUrl.endsWith("/") ? sInstanceUrl : sInstanceUrl + "/";
2697
- var sRequestUrl = sBaseUrl + "api/data/v9.0/" + actionName;
2698
- var oResponse = await dataClient.createDataAsync(
2699
- sRequestUrl,
2700
- DataSources.Dataverse,
2701
- actionName,
2702
- params || {},
2703
- {
2704
- operationName: DataverseOperationName.CreateRecord,
2705
- datasetName: sDatasetName,
2706
- isDataVerseOperation: true
2707
- }
2708
- );
2709
- return {
2710
- success: oResponse.success,
2711
- data: oResponse.data,
2712
- error: oResponse.error
2713
- };
2714
- }
2715
-
2716
- var _dataOperationExecutor;
2717
- function getDataOperationExecutor() {
2718
- return _dataOperationExecutor;
2719
- }
2720
- function setDataOperationExecutor(dataOperationExecutorOverride) {
2721
- _dataOperationExecutor = dataOperationExecutorOverride;
2722
- }
2723
- function getClient(dataSourcesInfo) {
2724
- return {
2725
- createRecordAsync: (tableName, record) => {
2726
- return createRecordAsync(dataSourcesInfo, tableName, record);
2727
- },
2728
- deleteRecordAsync: (tableName, recordId) => {
2729
- return deleteRecordAsync(dataSourcesInfo, tableName, recordId);
2730
- },
2731
- executeAsync: (operation) => {
2732
- return executeAsync(dataSourcesInfo, operation);
2733
- },
2734
- retrieveMultipleRecordsAsync: (tableName, options) => {
2735
- return retrieveMultipleRecordsAsync(dataSourcesInfo, tableName, options);
2736
- },
2737
- retrieveRecordAsync: (tableName, recordId, options) => {
2738
- return retrieveRecordAsync(dataSourcesInfo, tableName, recordId, options);
2739
- },
2740
- updateRecordAsync: (tableName, recordId, changes) => {
2741
- return updateRecordAsync(dataSourcesInfo, tableName, recordId, changes);
2742
- }
2743
- };
2744
- }
2745
-
2746
- var MockDataOperationExecutor = class {
2747
- constructor(data) {
2748
- __publicField(this, "_dataStore");
2749
- this._dataStore = data;
2750
- }
2751
- async createRecordAsync(tableName, data) {
2752
- return {
2753
- success: false,
2754
- error: { message: "createRecordAsync is not supported by MockDataOperationExecutor" },
2755
- data: null
2756
- };
2757
- }
2758
- async updateRecordAsync(tableName, id, data) {
2759
- return {
2760
- success: false,
2761
- error: { message: "updateRecordAsync is not supported by MockDataOperationExecutor" },
2762
- data: null
2763
- };
2764
- }
2765
- async deleteRecordAsync(tableName, id) {
2766
- return {
2767
- success: false,
2768
- error: { message: "deleteRecordAsync is not supported by MockDataOperationExecutor" },
2769
- data: void 0
2770
- };
2771
- }
2772
- async retrieveRecordAsync(tableName, id, options) {
2773
- if (!this._dataStore[tableName]) {
2774
- return {
2775
- success: false,
2776
- error: { message: `table <${tableName}> not found` },
2777
- data: null
2778
- };
2779
- }
2780
- const record = this._dataStore[tableName][id];
2781
- if (!record) {
2782
- return {
2783
- success: false,
2784
- error: { message: `record with id "${id}" not found in table <${tableName}>` },
2785
- data: null
2786
- };
2787
- }
2788
- return {
2789
- success: true,
2790
- data: record
2791
- };
2792
- }
2793
- async retrieveMultipleRecordsAsync(tableName, options) {
2794
- if (!this._dataStore[tableName]) {
2795
- return {
2796
- success: false,
2797
- error: { message: `table <${tableName}> not found` },
2798
- data: []
2799
- };
2800
- }
2801
- return {
2802
- success: true,
2803
- data: Object.values(this._dataStore[tableName])
2804
- };
2805
- }
2806
- async executeAsync(operation) {
2807
- return {
2808
- success: false,
2809
- error: { message: "executeAsync is not supported by MockDataOperationExecutor" },
2810
- data: null
2811
- };
2812
- }
2813
- };
2814
- function createMockDataExecutor(data) {
2815
- return new MockDataOperationExecutor(data);
2816
- }
2817
-
2818
- var entityClusterModeEnum = {
2819
- 0: "Partitioned",
2820
- 1: "Replicated",
2821
- 2: "Local"
2822
- };
2823
- function getEntityClusterModeName(value) {
2824
- return entityClusterModeEnum[value];
2825
- }
2826
- var ownershipTypeEnum = {
2827
- 0: "None",
2828
- 1: "UserOwned",
2829
- 2: "TeamOwned",
2830
- 4: "BusinessOwned",
2831
- 8: "OrganizationOwned",
2832
- 16: "BusinessParented",
2833
- 32: "Filtered"
2834
- };
2835
- function getOwnershipTypeName(value) {
2836
- return ownershipTypeEnum[value];
2837
- }
2838
- var privilegeTypeEnum = {
2839
- 0: "None",
2840
- 1: "Create",
2841
- 2: "Read",
2842
- 3: "Write",
2843
- 4: "Delete",
2844
- 5: "Assign",
2845
- 6: "Share",
2846
- 7: "Append",
2847
- 8: "AppendTo"
2848
- };
2849
- function getPrivilegeTypeName(value) {
2850
- return privilegeTypeEnum[value];
2851
- }
2852
- var attributeTypeCodeEnum = {
2853
- 0: "Boolean",
2854
- 1: "Customer",
2855
- 2: "DateTime",
2856
- 3: "Decimal",
2857
- 4: "Double",
2858
- 5: "Integer",
2859
- 6: "Lookup",
2860
- 7: "Memo",
2861
- 8: "Money",
2862
- 9: "Owner",
2863
- 10: "PartyList",
2864
- 11: "Picklist",
2865
- 12: "State",
2866
- 13: "Status",
2867
- 14: "String",
2868
- 15: "Uniqueidentifier",
2869
- 16: "CalendarRules",
2870
- 17: "Virtual",
2871
- 18: "BigInt",
2872
- 19: "ManagedProperty",
2873
- 20: "EntityName"
2874
- };
2875
- function getAttributeTypeCodeName(value) {
2876
- return attributeTypeCodeEnum[value];
2877
- }
2878
- var attributeRequiredLevelEnum = {
2879
- 0: "None",
2880
- 1: "SystemRequired",
2881
- 2: "ApplicationRequired",
2882
- 3: "Recommended"
2883
- };
2884
- function getAttributeRequiredLevelName(value) {
2885
- return attributeRequiredLevelEnum[value];
2886
- }
2887
- var relationshipTypeEnum = {
2888
- 0: "OneToManyRelationship",
2889
- 1: "ManyToManyRelationship"
2890
- };
2891
- function getRelationshipTypeName(value) {
2892
- return relationshipTypeEnum[value];
2893
- }
2894
- var securityTypesEnum = {
2895
- 0: "None",
2896
- 1: "Append",
2897
- 2: "ParentChild",
2898
- 8: "Pointer",
2899
- 16: "Inheritance"
2900
- // The referencing entity record inherits security from the referenced security record.
2901
- };
2902
- function getSecurityTypesName(value) {
2903
- return securityTypesEnum[value];
2904
- }
2905
- var associatedMenuBehaviorEnum = {
2906
- 0: "UseCollectionName",
2907
- 1: "UseLabel",
2908
- 2: "DoNotDisplay"
2909
- };
2910
- function getAssociatedMenuBehaviorName(value) {
2911
- return associatedMenuBehaviorEnum[value];
2912
- }
2913
- var associatedMenuGroupEnum = {
2914
- 0: "Details",
2915
- 1: "Sales",
2916
- 2: "Service",
2917
- 3: "Marketing"
2918
- };
2919
- function getAssociatedMenuGroupName(value) {
2920
- return associatedMenuGroupEnum[value];
2921
- }
2922
- var cascadeTypeEnum = {
2923
- 0: "NoCascade",
2924
- 1: "Cascade",
2925
- 2: "Active",
2926
- 3: "UserOwned",
2927
- 4: "RemoveLink",
2928
- 5: "Restrict"
2929
- // Prevent the Referenced entity record from being deleted when referencing entities exist.
2930
- };
2931
- function getCascadeTypeName(value) {
2932
- return cascadeTypeEnum[value];
2933
- }
2934
- export {
2935
- callActionAsync,
2936
- createMockDataExecutor,
2937
- getAssociatedMenuBehaviorName,
2938
- getAssociatedMenuGroupName,
2939
- getAttributeRequiredLevelName,
2940
- getAttributeTypeCodeName,
2941
- getCascadeTypeName,
2942
- getClient,
2943
- getContext,
2944
- getEntityClusterModeName,
2945
- getOwnershipTypeName,
2946
- getPrivilegeTypeName,
2947
- getRelationshipTypeName,
2948
- getSecurityTypesName,
2949
- initializeLogger,
2950
- setConfig,
2951
- setDataOperationExecutor
2952
- };