codeapp-js 0.2.2 → 1.0.0

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 (176) 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/codeApp/.power/schemas/appschemas/dataSourcesInfo.ts +6275 -0
  15. package/codeApp/.power/schemas/jira/jira.Schema.json +6903 -0
  16. package/codeApp/.power/schemas/keyvault/keyvault.Schema.json +1600 -0
  17. package/{examples/combined demo/.power/schemas/office365groups/office365groups.Schema.json → codeApp/.power/schemas/office365groups/office365groups.Schema.json} +2203 -2203
  18. package/codeApp/.power/schemas/teams/teams.Schema.json +11112 -0
  19. package/codeApp/dist/codeapp.js +103 -1043
  20. package/codeApp/dist/connectors/azureKeyvault.js +459 -0
  21. package/codeApp/dist/connectors/jira.js +1247 -0
  22. package/codeApp/dist/connectors/office365groups.js +642 -0
  23. package/codeApp/dist/connectors/office365users.js +513 -0
  24. package/codeApp/dist/connectors/outlook.js +1393 -0
  25. package/{examples/kanban/dist → codeApp/dist/connectors}/sharepoint.js +466 -339
  26. package/codeApp/dist/connectors/sql.js +149 -0
  27. package/codeApp/dist/connectors/teams.js +280 -0
  28. package/codeApp/dist/index.js +1 -1
  29. package/codeApp/dist/power-apps-data.js +725 -176
  30. package/codeApp/src/generated/index.ts +12 -0
  31. package/codeApp/src/generated/models/AzureKeyVaultModel.ts +107 -0
  32. package/codeApp/src/generated/models/JiraModel.ts +501 -0
  33. package/codeApp/src/generated/services/AzureKeyVaultService.ts +257 -0
  34. package/codeApp/src/generated/services/JiraService.ts +1124 -0
  35. package/examples/{kanban → apps/kanban}/dist/dataverse.js +94 -94
  36. package/examples/{kanban → apps/kanban}/dist/index.css +605 -605
  37. package/examples/{kanban → apps/kanban}/dist/index.html +21 -21
  38. package/examples/{kanban → apps/kanban}/dist/index.js +860 -860
  39. package/examples/{kanban → apps/kanban}/dist/office365groups.js +97 -97
  40. package/examples/apps/kanban/dist/office365users.js +451 -0
  41. package/examples/{kanban → apps/kanban}/dist/outlook.js +162 -162
  42. package/examples/{planning Poker/dist/power-apps-data.js → apps/kanban/dist/power-apps-data.js} +2953 -2953
  43. package/{dev files/sharepoint.js → examples/apps/kanban/dist/sharepoint.js} +195 -99
  44. package/examples/{kanban → apps/kanban}/power.config.json +35 -35
  45. package/examples/{planning Poker → apps/planning Poker}/additional files/customizations (tables).xml +6428 -6428
  46. package/examples/{planning Poker → apps/planning Poker}/additional files/dataverse-tables.json +165 -165
  47. package/examples/{planning Poker → apps/planning Poker}/additional files/readme.md +122 -122
  48. package/examples/{planning Poker → apps/planning Poker}/dist/dataverse.js +78 -78
  49. package/examples/{planning Poker → apps/planning Poker}/dist/index.html +198 -198
  50. package/examples/{planning Poker → apps/planning Poker}/dist/index.js +954 -954
  51. package/examples/{kanban/dist/power-apps-data.js → apps/planning Poker/dist/power-apps-data.js } +2953 -2953
  52. package/examples/{planning Poker → apps/planning Poker}/dist/styles.css +815 -815
  53. package/examples/{planning Poker → apps/planning Poker}/power.config.json +50 -50
  54. package/examples/{solution explorer → apps/solution explorer}/dist/codeapp.js +1098 -1098
  55. package/examples/{solution explorer → apps/solution explorer}/dist/index.html +80 -80
  56. package/examples/{solution explorer → apps/solution explorer}/dist/index.js +735 -735
  57. package/examples/{solution explorer → apps/solution explorer}/dist/styles.css +571 -571
  58. package/examples/{solution explorer → apps/solution explorer}/power.config.json +150 -150
  59. package/examples/{todo → apps/todo}/dist/dataverse.js +64 -64
  60. package/examples/{todo → apps/todo}/dist/index.html +75 -75
  61. package/examples/{todo → apps/todo}/dist/index.js +8 -8
  62. package/examples/{todo → apps/todo}/dist/power-apps-data.js +2953 -2953
  63. package/examples/{todo → apps/todo}/dist/renderer.js +375 -375
  64. package/examples/{todo → apps/todo}/dist/styles.css +691 -691
  65. package/examples/{todo → apps/todo}/power.config.json +34 -34
  66. package/examples/combined demo/.power/schemas/appschemas/dataSourcesInfo.ts +6275 -7830
  67. package/examples/combined demo/.power/schemas/jira/jira.Schema.json +6903 -0
  68. package/examples/combined demo/.power/schemas/keyvault/keyvault.Schema.json +1600 -0
  69. package/examples/combined demo/.power/schemas/teams/teams.Schema.json +11112 -0
  70. package/examples/combined demo/dist/codeapp.js +394 -1098
  71. package/examples/combined demo/dist/index.html +29 -511
  72. package/examples/combined demo/dist/index.js +490 -470
  73. package/examples/combined demo/dist/office365users.js +513 -0
  74. package/examples/combined demo/dist/outlook.js +1393 -0
  75. package/examples/combined demo/dist/power-apps-data.js +3079 -3006
  76. package/examples/combined demo/dist/styles.css +483 -0
  77. package/examples/combined demo/power.config.json +33 -42
  78. package/examples/combined demo/src/generated/index.ts +12 -14
  79. package/examples/combined demo/src/generated/models/AzureKeyVaultModel.ts +107 -0
  80. package/examples/combined demo/src/generated/models/JiraModel.ts +501 -0
  81. package/examples/combined demo/src/generated/services/AzureKeyVaultService.ts +257 -0
  82. package/examples/combined demo/src/generated/services/JiraService.ts +1124 -0
  83. package/examples/dataverse Demo/dist/codeapp.js +394 -1085
  84. package/examples/{outlook Demo2/OutlookDemo_1_0_0_1.zip → dataverse Demo/dist/icon-512.png} +0 -0
  85. package/examples/dataverse Demo/dist/index.html +146 -54
  86. package/examples/dataverse Demo/dist/index.js +693 -83
  87. package/examples/dataverse Demo/dist/power-apps-data.js +3079 -2911
  88. package/examples/dataverse Demo/dist/styles.css +528 -0
  89. package/examples/dataverse Demo/power.config.json +41 -35
  90. package/examples/dataverse Demo/readme.md +79 -79
  91. package/examples/groups Demo/dist/codeapp.js +394 -1085
  92. package/examples/groups Demo/dist/icon-512.png +0 -0
  93. package/examples/groups Demo/dist/index.html +21 -25
  94. package/examples/groups Demo/dist/index.js +304 -113
  95. package/examples/groups Demo/dist/office365groups.js +642 -0
  96. package/examples/groups Demo/dist/power-apps-data.js +3079 -2911
  97. package/examples/groups Demo/dist/styles.css +509 -0
  98. package/examples/groups Demo/power.config.json +25 -25
  99. package/examples/myProfile/dist/codeapp.js +398 -0
  100. package/examples/myProfile/dist/index.html +21 -184
  101. package/examples/myProfile/dist/index.js +324 -141
  102. package/examples/myProfile/dist/office365users.js +517 -169
  103. package/examples/myProfile/dist/power-apps-data.js +3080 -2953
  104. package/examples/myProfile/dist/styles.css +458 -0
  105. package/examples/myProfile/power.config.json +24 -23
  106. package/examples/outlook Demo/dist/codeapp.js +394 -1085
  107. package/examples/outlook Demo/dist/index.html +150 -35
  108. package/examples/outlook Demo/dist/index.js +516 -170
  109. package/examples/outlook Demo/dist/outlook.js +1393 -121
  110. package/examples/outlook Demo/dist/power-apps-data.js +3079 -2911
  111. package/examples/outlook Demo/dist/styles.css +408 -84
  112. package/examples/outlook Demo/power.config.json +24 -23
  113. package/examples/outlook Demo/readme.md +92 -82
  114. package/examples/sharePoint Demo/dist/codeapp.js +394 -1085
  115. package/examples/sharePoint Demo/dist/icon-512.png +0 -0
  116. package/examples/sharePoint Demo/dist/index.html +22 -255
  117. package/examples/sharePoint Demo/dist/index.js +899 -262
  118. package/examples/sharePoint Demo/dist/power-apps-data.js +3079 -2911
  119. package/examples/sharePoint Demo/dist/sharepoint.js +466 -0
  120. package/examples/sharePoint Demo/dist/styles.css +587 -0
  121. package/examples/sharePoint Demo/power.config.json +23 -22
  122. package/package.json +1 -1
  123. package/readme.md +479 -61
  124. package/.github/instructions/wyattdave.instructions.md +0 -39
  125. package/.vscode/settings.json +0 -6
  126. package/dev files/dataverse.js +0 -105
  127. package/dev files/office365groups.js +0 -65
  128. package/dev files/office365users.js +0 -169
  129. package/dev files/outlook.js +0 -330
  130. package/examples/combined demo/.power/schemas/office365/office365.Schema.json +0 -21098
  131. package/examples/combined demo/.power/schemas/office365users/office365users.Schema.json +0 -2094
  132. package/examples/kanban/agent/decision-log.md +0 -9
  133. package/examples/kanban/agent/mockup-01-editorial-glass.html +0 -159
  134. package/examples/kanban/agent/mockup-02-dark-rail.html +0 -147
  135. package/examples/kanban/agent/mockup-03-paper-grid.html +0 -114
  136. package/examples/kanban/agent/mockup-04-neon-minimal.html +0 -141
  137. package/examples/kanban/agent/mockup-05-mono-architect.html +0 -119
  138. package/examples/kanban/dist/environmentVar.js +0 -55
  139. package/examples/kanban/dist/office365users.js +0 -169
  140. package/examples/kanban/src/generated/index.ts +0 -14
  141. package/examples/outlook Demo2/agent/decision-log.md +0 -7
  142. package/examples/outlook Demo2/dist/codeapp.js +0 -1334
  143. package/examples/outlook Demo2/dist/index.html +0 -98
  144. package/examples/outlook Demo2/dist/index.js +0 -346
  145. package/examples/outlook Demo2/dist/styles.css +0 -639
  146. package/examples/outlook Demo2/power.config.json +0 -23
  147. package/examples/planning Poker/.vscode/settings.json +0 -5
  148. package/examples/sharePoint Demo/agent/decision-log.md +0 -17
  149. package/examples/solution explorer/agent/decision-log.md +0 -27
  150. package/examples/solution explorer/agent/mockup-01-swiss-grid.html +0 -452
  151. package/examples/solution explorer/agent/mockup-02-dark-glass.html +0 -496
  152. package/examples/solution explorer/agent/mockup-03-paper-console.html +0 -510
  153. package/examples/solution explorer/agent/mockup-04-neon-noir.html +0 -546
  154. package/examples/solution explorer/agent/mockup-05-zen-garden.html +0 -534
  155. package/examples/solution explorer/dist/power-apps-data.js +0 -3007
  156. package/scripts/build-power-sdk.mjs +0 -69
  157. /package/{examples/kanban → codeApp}/src/generated/models/Office365GroupsModel.ts +0 -0
  158. /package/{examples/kanban → codeApp}/src/generated/models/Office365OutlookModel.ts +0 -0
  159. /package/{examples/kanban → codeApp}/src/generated/models/Office365UsersModel.ts +0 -0
  160. /package/{examples/kanban → codeApp}/src/generated/services/Office365GroupsService.ts +0 -0
  161. /package/{examples/kanban → codeApp}/src/generated/services/Office365OutlookService.ts +0 -0
  162. /package/{examples/kanban → codeApp}/src/generated/services/Office365UsersService.ts +0 -0
  163. /package/{dev files → examples/apps/kanban/dist}/environmentVar.js +0 -0
  164. /package/examples/{outlook Demo2 → apps/kanban}/src/generated/index.ts +0 -0
  165. /package/examples/{outlook Demo2 → apps/kanban}/src/generated/models/Office365GroupsModel.ts +0 -0
  166. /package/examples/{outlook Demo2 → apps/kanban}/src/generated/models/Office365OutlookModel.ts +0 -0
  167. /package/examples/{outlook Demo2 → apps/kanban}/src/generated/models/Office365UsersModel.ts +0 -0
  168. /package/examples/{outlook Demo2 → apps/kanban}/src/generated/services/Office365GroupsService.ts +0 -0
  169. /package/examples/{outlook Demo2 → apps/kanban}/src/generated/services/Office365OutlookService.ts +0 -0
  170. /package/examples/{outlook Demo2 → apps/kanban}/src/generated/services/Office365UsersService.ts +0 -0
  171. /package/examples/{planning Poker → apps/planning Poker}/additional files/AgilePoker_1_0_0_1.zip +0 -0
  172. /package/examples/{planning Poker → apps/planning Poker}/additional files/PokerTables_1_0_0_1.zip +0 -0
  173. /package/examples/{outlook Demo2 → apps/solution explorer}/dist/icon-512.png +0 -0
  174. /package/examples/{outlook Demo2 → apps/solution explorer}/dist/power-apps-data.js +0 -0
  175. /package/examples/{todo → apps/todo}/dist/icon192.png +0 -0
  176. /package/examples/{solution explorer → combined demo}/dist/icon-512.png +0 -0
@@ -147,18 +147,167 @@ function initClient() {
147
147
 
148
148
  // ── Internal: execute a connector operation ────────────────────
149
149
  async function execOp(operationName, parameters) {
150
- const client = await initClient();
151
- const result = await client.executeAsync({
152
- connectorOperation: {
153
- tableName: DATA_SOURCE,
154
- operationName,
155
- parameters,
156
- },
150
+ try {
151
+ const client = await initClient();
152
+ const result = await client.executeAsync({
153
+ connectorOperation: {
154
+ tableName: DATA_SOURCE,
155
+ operationName,
156
+ parameters: parameters || {},
157
+ },
158
+ });
159
+
160
+ if (!result) {
161
+ throw new Error("No result returned");
162
+ }
163
+
164
+ if (result.success === false) {
165
+ throw new Error(getSpErrorMessage(result.error));
166
+ }
167
+
168
+ return Object.prototype.hasOwnProperty.call(result, "data") ? result.data : result;
169
+ } catch (oError) {
170
+ throw new Error("SharePoint " + operationName + " failed: " + getSpErrorMessage(oError));
171
+ }
172
+ }
173
+
174
+ function getSpErrorMessage(oError) {
175
+ if (!oError) {
176
+ return "Unknown error";
177
+ }
178
+
179
+ if (typeof oError === "string") {
180
+ return oError;
181
+ }
182
+
183
+ if (oError instanceof Error && oError.message) {
184
+ return oError.message;
185
+ }
186
+
187
+ const aCandidates = [
188
+ oError.message,
189
+ oError.error && oError.error.message,
190
+ oError.body && oError.body.message,
191
+ oError.body && oError.body.error && oError.body.error.message,
192
+ oError.data && oError.data.message,
193
+ oError.detail,
194
+ ];
195
+
196
+ const sCandidate = aCandidates.find(function(sValue) {
197
+ return typeof sValue === "string" && sValue.trim() !== "";
157
198
  });
158
- if (!result.success) {
159
- throw new Error(result.error?.message || "Operation failed");
199
+
200
+ if (sCandidate) {
201
+ return sCandidate;
202
+ }
203
+
204
+ try {
205
+ return JSON.stringify(oError);
206
+ } catch (oStringifyError) {
207
+ return String(oError);
208
+ }
209
+ }
210
+
211
+ function requireNonEmptyString(sValue, sLabel) {
212
+ if (typeof sValue !== "string" || sValue.trim() === "") {
213
+ throw new Error("SharePoint " + sLabel + " is required.");
214
+ }
215
+
216
+ return sValue.trim();
217
+ }
218
+
219
+ function requireRecord(oValue, sLabel) {
220
+ if (!oValue || typeof oValue !== "object" || Array.isArray(oValue)) {
221
+ throw new Error("SharePoint " + sLabel + " must be an object.");
222
+ }
223
+
224
+ return oValue;
225
+ }
226
+
227
+ function normalizeHeaders(oHeaders) {
228
+ if (oHeaders == null) {
229
+ return {};
230
+ }
231
+
232
+ if (typeof oHeaders !== "object" || Array.isArray(oHeaders)) {
233
+ throw new Error("SharePoint request headers must be an object.");
234
+ }
235
+
236
+ return oHeaders;
237
+ }
238
+
239
+ function normalizeNumericQueryValue(value, sLabel) {
240
+ if (value == null || value === "") {
241
+ return null;
160
242
  }
161
- return result.data;
243
+
244
+ const iValue = Number(value);
245
+ if (!Number.isFinite(iValue)) {
246
+ throw new Error("SharePoint " + sLabel + " must be numeric.");
247
+ }
248
+
249
+ return iValue;
250
+ }
251
+
252
+ function requireItemId(iItemId) {
253
+ if ((typeof iItemId !== "string" && typeof iItemId !== "number") || String(iItemId).trim() === "") {
254
+ throw new Error("SharePoint item ID is required.");
255
+ }
256
+
257
+ return iItemId;
258
+ }
259
+
260
+ function buildListContext(sSiteUrl, sListId) {
261
+ return {
262
+ siteUrl: encodeURIComponent(requireNonEmptyString(sSiteUrl, "site URL")),
263
+ table: requireNonEmptyString(sListId, "list ID"),
264
+ };
265
+ }
266
+
267
+ function buildItemQueryParameters(sSiteUrl, sListId, { filter, orderBy, top, skip } = {}) {
268
+ const oParams = buildListContext(sSiteUrl, sListId);
269
+
270
+ if (filter) {
271
+ oParams.$filter = String(filter);
272
+ }
273
+ if (orderBy) {
274
+ oParams.$orderby = String(orderBy);
275
+ }
276
+
277
+ const iTop = normalizeNumericQueryValue(top, "top");
278
+ const iSkip = normalizeNumericQueryValue(skip, "skip");
279
+ if (iTop != null) {
280
+ oParams.$top = iTop;
281
+ }
282
+ if (iSkip != null) {
283
+ oParams.$skip = iSkip;
284
+ }
285
+
286
+ return oParams;
287
+ }
288
+
289
+ function normalizeCollection(oPayload) {
290
+ if (Array.isArray(oPayload)) {
291
+ return oPayload;
292
+ }
293
+
294
+ const aCandidates = [
295
+ oPayload,
296
+ oPayload && oPayload.value,
297
+ oPayload && oPayload.items,
298
+ oPayload && oPayload.results,
299
+ oPayload && oPayload.body,
300
+ oPayload && oPayload.data,
301
+ oPayload && oPayload.result,
302
+ oPayload && oPayload.response,
303
+ oPayload && oPayload.d && oPayload.d.results,
304
+ ];
305
+
306
+ const aMatch = aCandidates.find(function(oCandidate) {
307
+ return Array.isArray(oCandidate);
308
+ });
309
+
310
+ return aMatch || [];
162
311
  }
163
312
 
164
313
  // ═══════════════════════════════════════════════════════════════
@@ -170,13 +319,13 @@ export async function callSharePointOperation(operationName, parameters = {}) {
170
319
  return execOp(operationName, parameters);
171
320
  }
172
321
 
173
- // ── Send HTTP Request (for list-name-based operations) ─────────
174
- export async function sendHttpRequest({ method = "GET", uri, headers, body }) {
322
+ // ── Send HTTP Request (raw escape hatch) ───────────────────────
323
+ export async function sendHttpRequest({ method = "GET", uri, headers, body } = {}) {
175
324
  return execOp("HttpRequest", {
176
- method,
177
- uri,
178
- headers: headers || {},
179
- body: body || "",
325
+ method: String(method || "GET").toUpperCase(),
326
+ uri: requireNonEmptyString(uri, "request URI"),
327
+ headers: normalizeHeaders(headers),
328
+ body: body == null ? "" : body,
180
329
  });
181
330
  }
182
331
 
@@ -186,89 +335,36 @@ export async function sendHttpRequest({ method = "GET", uri, headers, body }) {
186
335
 
187
336
  // ── Get Items ──────────────────────────────────────────────────
188
337
  export async function getItems(sSiteUrl, sListId, { filter, orderBy, top, skip } = {}) {
189
- let params = { siteUrl: encodeURIComponent(sSiteUrl), table: sListId };
190
- if (filter) params.$filter = filter;
191
- if (orderBy) params.$orderby = orderBy;
192
- if (top != null) params.$top = top;
193
- if (skip != null) params.$skip = skip;
194
- return execOp("GetItems", params);
338
+ return execOp("GetItems", buildItemQueryParameters(sSiteUrl, sListId, { filter, orderBy, top, skip }));
195
339
  }
196
340
 
197
341
  // ── Get Item ───────────────────────────────────────────────────
198
342
  export async function getItem(sSiteUrl, sListId, iItemId) {
199
- return execOp("GetItem", {
200
- siteUrl: encodeURIComponent(sSiteUrl),
201
- table: sListId,
202
- id: iItemId,
203
- });
343
+ return execOp("GetItem", Object.assign(buildListContext(sSiteUrl, sListId), {
344
+ id: requireItemId(iItemId),
345
+ }));
204
346
  }
205
347
 
206
348
  // ── Create Item ────────────────────────────────────────────────
207
349
  export async function createItem(sSiteUrl, sListId, oFields) {
208
- return execOp("PostItem", {
209
- siteUrl: encodeURIComponent(sSiteUrl),
210
- table: sListId,
211
- item: oFields,
212
- });
350
+ return execOp("PostItem", Object.assign(buildListContext(sSiteUrl, sListId), {
351
+ item: requireRecord(oFields, "item payload"),
352
+ }));
213
353
  }
214
354
 
215
355
  // ── Update Item ────────────────────────────────────────────────
216
356
  export async function updateItem(sSiteUrl, sListId, iItemId, oChangedFields) {
217
- return execOp("PatchItem", {
218
- siteUrl: encodeURIComponent(sSiteUrl),
219
- table: sListId,
220
- id: iItemId,
221
- item: oChangedFields,
222
- });
357
+ return execOp("PatchItem", Object.assign(buildListContext(sSiteUrl, sListId), {
358
+ id: requireItemId(iItemId),
359
+ item: requireRecord(oChangedFields, "item payload"),
360
+ }));
223
361
  }
224
362
 
225
363
  // ── Delete Item ────────────────────────────────────────────────
226
364
  export async function deleteItem(sSiteUrl, sListId, iItemId) {
227
- return execOp("DeleteItem", {
228
- siteUrl: encodeURIComponent(sSiteUrl),
229
- table: sListId,
230
- id: iItemId,
231
- });
232
- }
233
-
234
- // ═══════════════════════════════════════════════════════════════
235
- // ITEMS (HTTP API — uses list name)
236
- // ═══════════════════════════════════════════════════════════════
237
-
238
- // ── Get Items by List Name ─────────────────────────────────────
239
- export async function getItemsByName(sSiteUrl, sListName, { filter, orderBy, top, skip } = {}) {
240
- let sUri = sSiteUrl + "/_api/web/lists/getbytitle('" + sListName + "')/items";
241
- let aQuery = [];
242
- if (filter) aQuery.push("$filter=" + filter);
243
- if (orderBy) aQuery.push("$orderby=" + orderBy);
244
- if (top != null) aQuery.push("$top=" + top);
245
- if (skip != null) aQuery.push("$skip=" + skip);
246
- if (aQuery.length > 0) sUri = sUri + "?" + aQuery.join("&");
247
- return sendHttpRequest({ method: "GET", uri: sUri, headers: { Accept: "application/json;odata=nometadata" } });
248
- }
249
-
250
- // ── Get Item by List Name ──────────────────────────────────────
251
- export async function getItemByName(sSiteUrl, sListName, iItemId) {
252
- let sUri = sSiteUrl + "/_api/web/lists/getbytitle('" + sListName + "')/items(" + iItemId + ")";
253
- return sendHttpRequest({ method: "GET", uri: sUri, headers: { Accept: "application/json;odata=nometadata" } });
254
- }
255
-
256
- // ── Create Item by List Name ───────────────────────────────────
257
- export async function createItemByName(sSiteUrl, sListName, oFields) {
258
- let sUri = sSiteUrl + "/_api/web/lists/getbytitle('" + sListName + "')/items";
259
- return sendHttpRequest({ method: "POST", uri: sUri, headers: { Accept: "application/json;odata=nometadata", "Content-Type": "application/json;odata=nometadata" }, body: JSON.stringify(oFields) });
260
- }
261
-
262
- // ── Update Item by List Name ───────────────────────────────────
263
- export async function updateItemByName(sSiteUrl, sListName, iItemId, oChangedFields) {
264
- let sUri = sSiteUrl + "/_api/web/lists/getbytitle('" + sListName + "')/items(" + iItemId + ")";
265
- return sendHttpRequest({ method: "PATCH", uri: sUri, headers: { Accept: "application/json;odata=nometadata", "Content-Type": "application/json;odata=nometadata", "If-Match": "*" }, body: JSON.stringify(oChangedFields) });
266
- }
267
-
268
- // ── Delete Item by List Name ───────────────────────────────────
269
- export async function deleteItemByName(sSiteUrl, sListName, iItemId) {
270
- let sUri = sSiteUrl + "/_api/web/lists/getbytitle('" + sListName + "')/items(" + iItemId + ")";
271
- return sendHttpRequest({ method: "DELETE", uri: sUri, headers: { Accept: "application/json;odata=nometadata", "If-Match": "*" } });
365
+ return execOp("DeleteItem", Object.assign(buildListContext(sSiteUrl, sListId), {
366
+ id: requireItemId(iItemId),
367
+ }));
272
368
  }
273
369
 
274
370
  // ═══════════════════════════════════════════════════════════════
@@ -277,15 +373,15 @@ export async function deleteItemByName(sSiteUrl, sListName, iItemId) {
277
373
 
278
374
  // ── List Tables (Lists) ────────────────────────────────────────
279
375
  export async function listTables(sSiteUrl) {
280
- return execOp("GetTables", {
281
- siteUrl: encodeURIComponent(sSiteUrl),
282
- });
376
+ return normalizeCollection(await execOp("GetTables", {
377
+ siteUrl: encodeURIComponent(requireNonEmptyString(sSiteUrl, "site URL")),
378
+ }));
283
379
  }
284
380
 
285
381
  // ── List Library (Document Libraries) ──────────────────────────
286
382
  export async function listLibrary(sSiteUrl) {
287
383
  return execOp("GetDataSetsMetadata", {
288
- siteUrl: encodeURIComponent(sSiteUrl),
384
+ siteUrl: encodeURIComponent(requireNonEmptyString(sSiteUrl, "site URL")),
289
385
  });
290
386
  }
291
387
 
@@ -296,9 +392,9 @@ export async function listLibrary(sSiteUrl) {
296
392
  // ── Create File ────────────────────────────────────────────────
297
393
  export async function createFile(sSiteUrl, sLibraryName, sFileName, fileContent) {
298
394
  return execOp("CreateFile", {
299
- siteUrl: encodeURIComponent(sSiteUrl),
300
- folderPath: sLibraryName,
301
- name: sFileName,
395
+ siteUrl: encodeURIComponent(requireNonEmptyString(sSiteUrl, "site URL")),
396
+ folderPath: requireNonEmptyString(sLibraryName, "folder path"),
397
+ name: requireNonEmptyString(sFileName, "file name"),
302
398
  body: fileContent,
303
399
  });
304
400
  }
@@ -306,8 +402,8 @@ export async function createFile(sSiteUrl, sLibraryName, sFileName, fileContent)
306
402
  // ── Update File ────────────────────────────────────────────────
307
403
  export async function updateFile(sSiteUrl, sFileId, fileContent) {
308
404
  return execOp("UpdateFile", {
309
- siteUrl: encodeURIComponent(sSiteUrl),
310
- id: sFileId,
405
+ siteUrl: encodeURIComponent(requireNonEmptyString(sSiteUrl, "site URL")),
406
+ id: requireNonEmptyString(String(sFileId || ""), "file ID"),
311
407
  body: fileContent,
312
408
  });
313
409
  }
@@ -315,17 +411,17 @@ export async function updateFile(sSiteUrl, sFileId, fileContent) {
315
411
  // ── Delete File ────────────────────────────────────────────────
316
412
  export async function deleteFile(sSiteUrl, sFileId) {
317
413
  return execOp("DeleteFile", {
318
- siteUrl: encodeURIComponent(sSiteUrl),
319
- id: sFileId,
414
+ siteUrl: encodeURIComponent(requireNonEmptyString(sSiteUrl, "site URL")),
415
+ id: requireNonEmptyString(String(sFileId || ""), "file ID"),
320
416
  });
321
417
  }
322
418
 
323
419
  // ── Move File ──────────────────────────────────────────────────
324
420
  export async function moveFile(sSiteUrl, sSourceFileId, sDestinationFolderPath, sNewFileName) {
325
421
  return execOp("MoveFile", {
326
- siteUrl: encodeURIComponent(sSiteUrl),
327
- id: sSourceFileId,
328
- destinationFolderPath: sDestinationFolderPath,
422
+ siteUrl: encodeURIComponent(requireNonEmptyString(sSiteUrl, "site URL")),
423
+ id: requireNonEmptyString(String(sSourceFileId || ""), "source file ID"),
424
+ destinationFolderPath: requireNonEmptyString(sDestinationFolderPath, "destination folder path"),
329
425
  newFileName: sNewFileName || "",
330
426
  });
331
427
  }
@@ -333,7 +429,7 @@ export async function moveFile(sSiteUrl, sSourceFileId, sDestinationFolderPath,
333
429
  // ── Get File Metadata ──────────────────────────────────────────
334
430
  export async function getFileMetadata(sSiteUrl, sFileId) {
335
431
  return execOp("GetFileMetadata", {
336
- siteUrl: encodeURIComponent(sSiteUrl),
337
- id: sFileId,
432
+ siteUrl: encodeURIComponent(requireNonEmptyString(sSiteUrl, "site URL")),
433
+ id: requireNonEmptyString(String(sFileId || ""), "file ID"),
338
434
  });
339
435
  }
@@ -1,35 +1,35 @@
1
- {
2
- "appDisplayName": "Kanban",
3
- "description": "",
4
- "environmentId": "<ENVIRONMENT ID>",
5
- "buildPath": "./dist",
6
- "buildEntryPoint": "index.html",
7
- "logoPath": "<ICON IMAGE PATH>",
8
- "localAppUrl": "http://localhost:3000",
9
- "region": "prod",
10
- "connectionReferences": {
11
- "dataverse": {
12
- "id": "/providers/Microsoft.PowerApps/apis/shared_commondataserviceforapps",
13
- "displayName": "Microsoft Dataverse",
14
- "dataSources": [
15
- "commondataserviceforapps"
16
- ],
17
- "authenticationType": null,
18
- "sharedConnectionId": null,
19
- "dataSets": {}
20
- }
21
- },
22
- "databaseReferences": {
23
- "default.cds": {
24
- "databaseDetails": null,
25
- "dataSources": {
26
- "tasks": {
27
- "entitySetName": "tasks",
28
- "logicalName": "task",
29
- "isHidden": false
30
- }
31
- },
32
- "actions": null
33
- }
34
- }
35
- }
1
+ {
2
+ "appDisplayName": "Kanban",
3
+ "description": "",
4
+ "environmentId": "<ENVIRONMENT ID>",
5
+ "buildPath": "./dist",
6
+ "buildEntryPoint": "index.html",
7
+ "logoPath": "<ICON IMAGE PATH>",
8
+ "localAppUrl": "http://localhost:3000",
9
+ "region": "prod",
10
+ "connectionReferences": {
11
+ "dataverse": {
12
+ "id": "/providers/Microsoft.PowerApps/apis/shared_commondataserviceforapps",
13
+ "displayName": "Microsoft Dataverse",
14
+ "dataSources": [
15
+ "commondataserviceforapps"
16
+ ],
17
+ "authenticationType": null,
18
+ "sharedConnectionId": null,
19
+ "dataSets": {}
20
+ }
21
+ },
22
+ "databaseReferences": {
23
+ "default.cds": {
24
+ "databaseDetails": null,
25
+ "dataSources": {
26
+ "tasks": {
27
+ "entitySetName": "tasks",
28
+ "logicalName": "task",
29
+ "isHidden": false
30
+ }
31
+ },
32
+ "actions": null
33
+ }
34
+ }
35
+ }