@microsoft/power-apps-native-host 0.2.22 → 0.3.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 (156) hide show
  1. package/README.md +162 -26
  2. package/compatibility/current.json +87 -0
  3. package/lib/NOTICE.txt +140 -1226
  4. package/lib/commonjs/auth/AuthContext.js +74 -18
  5. package/lib/commonjs/auth/AuthContext.web.js +32 -0
  6. package/lib/commonjs/auth/completePowerAppsAuthSession.js +16 -0
  7. package/lib/commonjs/bridge/NativePowerAppsBridge.js +20 -17
  8. package/lib/commonjs/bridge/PowerPagesBridge.js +157 -0
  9. package/lib/commonjs/bridge/bridgeState.js +40 -0
  10. package/lib/commonjs/connections/ConnectionSetupScreen.js +459 -80
  11. package/lib/commonjs/connections/PowerPlatformConnectionApi.js +946 -0
  12. package/lib/commonjs/connections/connectionMetadata.js +127 -0
  13. package/lib/commonjs/connections/connectionState.js +96 -0
  14. package/lib/commonjs/connections/disambiguate.js +19 -11
  15. package/lib/commonjs/connections/resolveConnections.js +347 -0
  16. package/lib/commonjs/connections/types.js +106 -0
  17. package/lib/commonjs/{platform → connections}/useConnectionRefs.js +128 -65
  18. package/lib/commonjs/connections/useConnectionSetup.js +111 -52
  19. package/lib/commonjs/controls/FilePicker.js +6 -0
  20. package/lib/commonjs/controls/ImagePicker.js +8 -0
  21. package/lib/commonjs/index.js +188 -6
  22. package/lib/commonjs/logger.js +9 -6
  23. package/lib/commonjs/offline/createOfflineHostActivationCallbacks.js +61 -0
  24. package/lib/commonjs/offline/useOfflineIntegration.js +12 -0
  25. package/lib/commonjs/offline/useOfflineIntegration.web.js +11 -0
  26. package/lib/commonjs/offline/useOfflineIntegrationWithStartupGate.js +46 -0
  27. package/lib/commonjs/offline/useOfflineIntegrationWithStartupGate.web.js +13 -0
  28. package/lib/commonjs/platform/DataverseDataSources.js +14 -0
  29. package/lib/commonjs/platform/DataverseGlobalDiscoveryApi.js +49 -0
  30. package/lib/commonjs/platform/GlobalDiscovery.js +51 -0
  31. package/lib/commonjs/platform/PowerPlatformEnvironmentApi.js +6 -106
  32. package/lib/commonjs/provider/PowerAppsHostProvider.js +156 -25
  33. package/lib/commonjs/provider/PowerAppsHostProvider.web.js +41 -0
  34. package/lib/commonjs/provider/PowerAppsProvider.js +229 -133
  35. package/lib/commonjs/provider/SessionDetailsGesture.js +216 -0
  36. package/lib/commonjs/telemetry/OfflineSdkTelemetry.js +95 -0
  37. package/lib/commonjs/telemetry/OfflineSdkTelemetry.web.js +9 -0
  38. package/lib/commonjs/telemetry/index.js +22 -3
  39. package/lib/module/auth/AuthContext.js +74 -18
  40. package/lib/module/auth/AuthContext.web.js +26 -0
  41. package/lib/module/auth/completePowerAppsAuthSession.js +11 -0
  42. package/lib/module/bridge/NativePowerAppsBridge.js +21 -18
  43. package/lib/module/bridge/PowerPagesBridge.js +151 -0
  44. package/lib/module/bridge/bridgeState.js +34 -0
  45. package/lib/module/connections/ConnectionSetupScreen.js +460 -81
  46. package/lib/module/connections/PowerPlatformConnectionApi.js +932 -0
  47. package/lib/module/connections/connectionMetadata.js +112 -0
  48. package/lib/module/connections/connectionState.js +82 -0
  49. package/lib/module/connections/disambiguate.js +19 -12
  50. package/lib/module/connections/resolveConnections.js +342 -0
  51. package/lib/module/connections/types.js +91 -0
  52. package/lib/module/{platform → connections}/useConnectionRefs.js +129 -66
  53. package/lib/module/connections/useConnectionSetup.js +113 -54
  54. package/lib/module/controls/FilePicker.js +6 -0
  55. package/lib/module/controls/ImagePicker.js +8 -0
  56. package/lib/module/index.js +14 -6
  57. package/lib/module/logger.js +8 -6
  58. package/lib/module/offline/createOfflineHostActivationCallbacks.js +55 -0
  59. package/lib/module/offline/useOfflineIntegration.js +3 -0
  60. package/lib/module/offline/useOfflineIntegration.web.js +7 -0
  61. package/lib/module/offline/useOfflineIntegrationWithStartupGate.js +42 -0
  62. package/lib/module/offline/useOfflineIntegrationWithStartupGate.web.js +9 -0
  63. package/lib/module/platform/DataverseDataSources.js +10 -0
  64. package/lib/module/platform/DataverseGlobalDiscoveryApi.js +45 -0
  65. package/lib/module/platform/GlobalDiscovery.js +45 -0
  66. package/lib/module/platform/PowerPlatformEnvironmentApi.js +5 -104
  67. package/lib/module/provider/PowerAppsHostProvider.js +159 -28
  68. package/lib/module/provider/PowerAppsHostProvider.web.js +36 -0
  69. package/lib/module/provider/PowerAppsProvider.js +233 -137
  70. package/lib/module/provider/SessionDetailsGesture.js +211 -0
  71. package/lib/module/telemetry/OfflineSdkTelemetry.js +91 -0
  72. package/lib/module/telemetry/OfflineSdkTelemetry.web.js +5 -0
  73. package/lib/module/telemetry/index.js +15 -4
  74. package/lib/typescript/commonjs/auth/AuthContext.d.ts +3 -1
  75. package/lib/typescript/commonjs/auth/AuthContext.web.d.ts +21 -0
  76. package/lib/typescript/commonjs/auth/completePowerAppsAuthSession.d.ts +8 -0
  77. package/lib/typescript/commonjs/bridge/PowerPagesBridge.d.ts +18 -0
  78. package/lib/typescript/commonjs/bridge/bridgeState.d.ts +5 -0
  79. package/lib/typescript/commonjs/connections/ConnectionSetupScreen.d.ts +28 -7
  80. package/lib/typescript/commonjs/{platform → connections}/PowerPlatformConnectionApi.d.ts +52 -43
  81. package/lib/typescript/commonjs/connections/connectionMetadata.d.ts +66 -0
  82. package/lib/typescript/commonjs/connections/connectionState.d.ts +16 -0
  83. package/lib/typescript/commonjs/connections/disambiguate.d.ts +4 -2
  84. package/lib/typescript/commonjs/{platform → connections}/resolveConnections.d.ts +19 -19
  85. package/lib/typescript/commonjs/connections/types.d.ts +129 -1
  86. package/lib/typescript/commonjs/{platform → connections}/useConnectionRefs.d.ts +33 -24
  87. package/lib/typescript/commonjs/connections/useConnectionSetup.d.ts +12 -8
  88. package/lib/typescript/commonjs/controls/FilePicker.d.ts +7 -1
  89. package/lib/typescript/commonjs/controls/ImagePicker.d.ts +9 -1
  90. package/lib/typescript/commonjs/index.d.ts +20 -10
  91. package/lib/typescript/commonjs/logger.d.ts +4 -4
  92. package/lib/typescript/commonjs/offline/createOfflineHostActivationCallbacks.d.ts +12 -0
  93. package/lib/typescript/commonjs/offline/useOfflineIntegration.d.ts +2 -0
  94. package/lib/typescript/commonjs/offline/useOfflineIntegration.web.d.ts +4 -0
  95. package/lib/typescript/commonjs/offline/useOfflineIntegrationWithStartupGate.d.ts +15 -0
  96. package/lib/typescript/commonjs/offline/useOfflineIntegrationWithStartupGate.web.d.ts +6 -0
  97. package/lib/typescript/commonjs/platform/DataverseDataSources.d.ts +27 -0
  98. package/lib/typescript/commonjs/platform/DataverseGlobalDiscoveryApi.d.ts +3 -0
  99. package/lib/typescript/commonjs/platform/GlobalDiscovery.d.ts +4 -0
  100. package/lib/typescript/commonjs/platform/PowerPlatformEnvironmentApi.d.ts +3 -74
  101. package/lib/typescript/commonjs/provider/PowerAppsHostProvider.d.ts +29 -18
  102. package/lib/typescript/commonjs/provider/PowerAppsHostProvider.web.d.ts +5 -0
  103. package/lib/typescript/commonjs/provider/PowerAppsProvider.d.ts +32 -10
  104. package/lib/typescript/commonjs/provider/SessionDetailsGesture.d.ts +13 -0
  105. package/lib/typescript/commonjs/telemetry/OfflineSdkTelemetry.d.ts +15 -0
  106. package/lib/typescript/commonjs/telemetry/OfflineSdkTelemetry.web.d.ts +2 -0
  107. package/lib/typescript/commonjs/telemetry/index.d.ts +13 -1
  108. package/lib/typescript/module/auth/AuthContext.d.ts +3 -1
  109. package/lib/typescript/module/auth/AuthContext.web.d.ts +21 -0
  110. package/lib/typescript/module/auth/completePowerAppsAuthSession.d.ts +8 -0
  111. package/lib/typescript/module/bridge/PowerPagesBridge.d.ts +18 -0
  112. package/lib/typescript/module/bridge/bridgeState.d.ts +5 -0
  113. package/lib/typescript/module/connections/ConnectionSetupScreen.d.ts +28 -7
  114. package/lib/typescript/module/{platform → connections}/PowerPlatformConnectionApi.d.ts +52 -43
  115. package/lib/typescript/module/connections/connectionMetadata.d.ts +66 -0
  116. package/lib/typescript/module/connections/connectionState.d.ts +16 -0
  117. package/lib/typescript/module/connections/disambiguate.d.ts +4 -2
  118. package/lib/typescript/module/{platform → connections}/resolveConnections.d.ts +19 -19
  119. package/lib/typescript/module/connections/types.d.ts +129 -1
  120. package/lib/typescript/module/{platform → connections}/useConnectionRefs.d.ts +33 -24
  121. package/lib/typescript/module/connections/useConnectionSetup.d.ts +12 -8
  122. package/lib/typescript/module/controls/FilePicker.d.ts +7 -1
  123. package/lib/typescript/module/controls/ImagePicker.d.ts +9 -1
  124. package/lib/typescript/module/index.d.ts +24 -14
  125. package/lib/typescript/module/logger.d.ts +4 -4
  126. package/lib/typescript/module/offline/createOfflineHostActivationCallbacks.d.ts +12 -0
  127. package/lib/typescript/module/offline/useOfflineIntegration.d.ts +2 -0
  128. package/lib/typescript/module/offline/useOfflineIntegration.web.d.ts +4 -0
  129. package/lib/typescript/module/offline/useOfflineIntegrationWithStartupGate.d.ts +15 -0
  130. package/lib/typescript/module/offline/useOfflineIntegrationWithStartupGate.web.d.ts +6 -0
  131. package/lib/typescript/module/platform/DataverseDataSources.d.ts +27 -0
  132. package/lib/typescript/module/platform/DataverseGlobalDiscoveryApi.d.ts +3 -0
  133. package/lib/typescript/module/platform/GlobalDiscovery.d.ts +4 -0
  134. package/lib/typescript/module/platform/PowerPlatformEnvironmentApi.d.ts +3 -74
  135. package/lib/typescript/module/provider/PowerAppsHostProvider.d.ts +29 -18
  136. package/lib/typescript/module/provider/PowerAppsHostProvider.web.d.ts +5 -0
  137. package/lib/typescript/module/provider/PowerAppsProvider.d.ts +34 -12
  138. package/lib/typescript/module/provider/SessionDetailsGesture.d.ts +13 -0
  139. package/lib/typescript/module/telemetry/OfflineSdkTelemetry.d.ts +15 -0
  140. package/lib/typescript/module/telemetry/OfflineSdkTelemetry.web.d.ts +2 -0
  141. package/lib/typescript/module/telemetry/index.d.ts +13 -1
  142. package/package.json +43 -18
  143. package/scripts/build-ios-base.js +66 -27
  144. package/scripts/bundle.js +212 -5
  145. package/scripts/generate-connector-schemas.js +8 -6
  146. package/scripts/metro-logger.js +213 -0
  147. package/scripts/start-web.mjs +137 -0
  148. package/scripts/upgrade/runtime.js +463 -0
  149. package/scripts/upgrade/system.js +244 -0
  150. package/scripts/upgrade-authoring.js +534 -0
  151. package/scripts/upgrade.js +188 -0
  152. package/scripts/wrap.js +536 -0
  153. package/lib/commonjs/platform/PowerPlatformConnectionApi.js +0 -606
  154. package/lib/commonjs/platform/resolveConnections.js +0 -264
  155. package/lib/module/platform/PowerPlatformConnectionApi.js +0 -595
  156. package/lib/module/platform/resolveConnections.js +0 -259
@@ -0,0 +1,151 @@
1
+ "use strict";
2
+
3
+ import { bridgeHttpClient, getAppLogger, HostOperationNames } from "../telemetry/index.js";
4
+ import { getHttpCorrelationProperties } from '@microsoft/power-apps-native-common/http';
5
+ function toPowerPagesUrl(url) {
6
+ const parsedUrl = new URL(url, window.location.origin);
7
+ if (parsedUrl.origin === window.location.origin && parsedUrl.pathname.startsWith('/_api/')) {
8
+ return `${parsedUrl.pathname}${parsedUrl.search}`;
9
+ }
10
+ const lowerPath = parsedUrl.pathname.toLowerCase();
11
+ if (lowerPath.includes('/$metadata') || lowerPath.includes('/entitydefinitions') || lowerPath.includes('/$batch') || lowerPath.includes('/microsoft.dynamics.crm.')) {
12
+ throw new Error(`PowerPagesBridge does not support this Dataverse operation: ${parsedUrl.pathname}`);
13
+ }
14
+ const dataverseApiPattern = /\/api\/data\/v\d+(?:\.\d+)+\//gi;
15
+ let finalMatch = null;
16
+ let match;
17
+ while ((match = dataverseApiPattern.exec(parsedUrl.pathname)) !== null) {
18
+ finalMatch = match;
19
+ }
20
+ if (finalMatch?.index === undefined) {
21
+ throw new Error(`PowerPagesBridge only supports Dataverse Web API requests: ${parsedUrl.pathname}`);
22
+ }
23
+ const resourcePath = parsedUrl.pathname.slice(finalMatch.index + finalMatch[0].length);
24
+ return `/_api/${resourcePath}${parsedUrl.search}`;
25
+ }
26
+ let requestVerificationTokenPromise;
27
+ function getRequestVerificationToken() {
28
+ requestVerificationTokenPromise ??= (async () => {
29
+ const response = await bridgeHttpClient.request('/_layout/tokenhtml', {
30
+ credentials: 'same-origin'
31
+ });
32
+ if (!response.ok) {
33
+ throw new Error(`PowerPagesBridge could not get a CSRF token (${response.status})`);
34
+ }
35
+ const tokenDocument = new DOMParser().parseFromString(await response.text(), 'text/html');
36
+ const token = tokenDocument.querySelector('input[name="__RequestVerificationToken"]')?.getAttribute('value');
37
+ if (!token) {
38
+ throw new Error('PowerPagesBridge could not find a CSRF token in /_layout/tokenhtml');
39
+ }
40
+ return token;
41
+ })().catch(error => {
42
+ requestVerificationTokenPromise = undefined;
43
+ throw error;
44
+ });
45
+ return requestVerificationTokenPromise;
46
+ }
47
+ function createHeaders(headers, token) {
48
+ const result = new Headers();
49
+ for (const [name, value] of Object.entries(headers ?? {})) {
50
+ if (name.toLowerCase() !== 'authorization') {
51
+ result.set(name, value);
52
+ }
53
+ }
54
+ result.set('__RequestVerificationToken', token);
55
+ return result;
56
+ }
57
+ export class PowerPagesBridge {
58
+ constructor(options) {
59
+ this.options = options;
60
+ }
61
+ updateOptions(options) {
62
+ this.options = options;
63
+ }
64
+ async initialize() {}
65
+ createRequestBody(config) {
66
+ return config.body ?? '';
67
+ }
68
+ async executePluginAsync(pluginName, pluginAction, params) {
69
+ const pluginKey = `${pluginName}.${pluginAction}`;
70
+ switch (pluginKey) {
71
+ case 'AppIdentityServicePlugin.getAppAccessTokenAsync':
72
+ case 'AppIdentityServicePlugin.getAppDynamicResourceAccessTokenAsync':
73
+ return '';
74
+ case 'AppPowerAppsClientPlugin.getAppCdsDataSourceConfigsAsync':
75
+ return this.options.dataSources;
76
+ case 'AppPowerAppsClientPlugin.loadAppConnectionsAsync_v2':
77
+ case 'AppPowerAppsClientPlugin.loadNonCompositeConnectionsAsync':
78
+ return this.options.connections;
79
+ case 'AppPowerAppsClientPlugin.resolveCompositeConnectionsAsync':
80
+ return null;
81
+ case 'AppHttpClientPlugin.sendHttpAsync':
82
+ return this.sendHttpAsync(params);
83
+ case 'PublishedAppTelemetry.trackEvent':
84
+ case 'PublishedAppTelemetry.trackException':
85
+ case 'PublishedAppTelemetry.trackMetric':
86
+ case 'PublishedAppTelemetry.startScenario':
87
+ case 'PublishedAppTelemetry.endScenario':
88
+ case 'PublishedAppTelemetry.setDefaultProperties':
89
+ return undefined;
90
+ default:
91
+ throw new Error(`PowerPagesBridge does not support ${pluginKey}`);
92
+ }
93
+ }
94
+ async sendHttpAsync(params) {
95
+ const request = params[0];
96
+ const body = params[1];
97
+ const powerPagesUrl = toPowerPagesUrl(request.url);
98
+ const token = await getRequestVerificationToken();
99
+ let response;
100
+ try {
101
+ response = await bridgeHttpClient.request(powerPagesUrl, {
102
+ method: request.method,
103
+ headers: createHeaders(request.headers, token),
104
+ body: body || undefined,
105
+ credentials: 'same-origin'
106
+ });
107
+ } catch (error) {
108
+ throw error;
109
+ }
110
+ const correlationProperties = getHttpCorrelationProperties(response.headers);
111
+ const responseHeaders = {};
112
+ response.headers.forEach((value, name) => {
113
+ responseHeaders[name === 'content-type' ? 'Content-Type' : name] = value;
114
+ });
115
+ let responseBody;
116
+ try {
117
+ responseBody = await response.arrayBuffer();
118
+ } catch (error) {
119
+ getAppLogger().trackErrorEvent(HostOperationNames.BridgeHttpRequest, {
120
+ phase: 'readResponseBody',
121
+ errorName: error instanceof Error ? error.constructor.name : typeof error,
122
+ httpStatus: response.status,
123
+ ...correlationProperties
124
+ });
125
+ throw error;
126
+ }
127
+ if (!response.ok) {
128
+ const responseText = new TextDecoder().decode(responseBody).slice(0, 1000);
129
+ const detail = responseText ? `: ${responseText}` : '';
130
+ // RuntimeDataClient treats JSON tuples as successful before inspecting status.
131
+ // Reject with its HTTP-plugin error shape so 4xx/5xx responses remain failures.
132
+ throw [[`Power Pages Web API request failed (${response.status})${detail}`, undefined, {
133
+ status: response.status,
134
+ headers: responseHeaders
135
+ }], responseBody];
136
+ }
137
+ return [{
138
+ status: response.status,
139
+ headers: responseHeaders
140
+ }, responseBody];
141
+ }
142
+ }
143
+ let bridge;
144
+ export function setupPowerPagesHost(options) {
145
+ if (bridge) {
146
+ bridge.updateOptions(options);
147
+ return;
148
+ }
149
+ bridge = new PowerPagesBridge(options);
150
+ globalThis.powerAppsBridge = bridge;
151
+ }
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+
3
+ export function getRequestBodyForMethod(method, body) {
4
+ const normalizedMethod = method.toUpperCase();
5
+ return normalizedMethod === 'GET' || normalizedMethod === 'HEAD' ? null : body;
6
+ }
7
+ export function assertSuccessfulHttpStatus(status, method) {
8
+ if (status >= 200 && status < 300) return;
9
+ throw new Error(`HTTP ${status} for ${method.toUpperCase()} request`);
10
+ }
11
+ export function updateBridgeOptionsInPlace(current, next) {
12
+ const connections = current.connections;
13
+ for (const key of Object.keys(connections)) {
14
+ if (!(key in next.connections)) delete connections[key];
15
+ }
16
+ for (const [key, nextConnection] of Object.entries(next.connections)) {
17
+ const currentConnection = connections[key];
18
+ if (currentConnection) {
19
+ for (const property of Object.keys(currentConnection)) {
20
+ delete currentConnection[property];
21
+ }
22
+ Object.assign(currentConnection, nextConnection);
23
+ } else {
24
+ connections[key] = nextConnection;
25
+ }
26
+ }
27
+ const dataSources = current.dataSources;
28
+ dataSources.splice(0, dataSources.length, ...next.dataSources);
29
+ return {
30
+ ...next,
31
+ connections,
32
+ dataSources
33
+ };
34
+ }