@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
@@ -9,9 +9,14 @@ var _reactNative = require("react-native");
9
9
  var _reactNativeSafeAreaContext = require("react-native-safe-area-context");
10
10
  var _setupNativeHost = require("../bridge/setupNativeHost.js");
11
11
  var _NativePowerAppsBridge = require("../bridge/NativePowerAppsBridge.js");
12
- var _useConnectionRefs = require("../platform/useConnectionRefs.js");
12
+ var _useConnectionRefs = require("../connections/useConnectionRefs.js");
13
+ var _DataverseDataSources = require("../platform/DataverseDataSources.js");
13
14
  var _PowerPlatformEnvironmentApi = require("../platform/PowerPlatformEnvironmentApi.js");
14
15
  var _ConnectionSetupScreen = require("../connections/ConnectionSetupScreen.js");
16
+ var _types = require("../connections/types.js");
17
+ var _PowerPlatformConnectionApi = require("../connections/PowerPlatformConnectionApi.js");
18
+ var _connectionState = require("../connections/connectionState.js");
19
+ var _isDevPlayer = require("../utils/isDevPlayer.js");
15
20
  var _logger = require("../logger.js");
16
21
  var _index = require("../telemetry/index.js");
17
22
  var _jsxRuntime = require("react/jsx-runtime");
@@ -48,6 +53,7 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
48
53
  // Entra ID token scope for the APIM connector proxy (API Hub).
49
54
  const CONNECTOR_SCOPE = 'https://apihub.azure.com/.default';
50
55
  const EMPTY_DATABASE_REFERENCES = {};
56
+ const EMPTY_CONNECTION_REFERENCES = {};
51
57
  /**
52
58
  * Initialises the NativePowerAppsBridge and manages the full pre-launch
53
59
  * pipeline — connection resolution, disambiguation, and creation — before
@@ -58,6 +64,7 @@ const EMPTY_DATABASE_REFERENCES = {};
58
64
  function PowerAppsHostProvider({
59
65
  acquireToken,
60
66
  isSignedIn,
67
+ onSignOut,
61
68
  appId,
62
69
  environmentId,
63
70
  region = 'prod',
@@ -67,18 +74,75 @@ function PowerAppsHostProvider({
67
74
  renderOAuthWebView,
68
75
  isvClientId,
69
76
  onDisambiguationNeeded,
77
+ onConnectionConsent,
78
+ onResourceConsent,
79
+ onConnectionConsentDeclined,
70
80
  children
71
81
  }) {
72
82
  // Extra refs produced by ConnectionSetupScreen for newly-created connections.
73
83
  const [extraConnectionRefs, setExtraConnectionRefs] = (0, _react.useState)({});
74
-
75
- // setupDone is derived — true as soon as extraConnectionRefs is populated.
76
- const setupDone = Object.keys(extraConnectionRefs).length > 0;
84
+ const [consentApproved, setConsentApproved] = (0, _react.useState)(false);
85
+ const setupDone = consentApproved;
86
+ const renderConnectionError = (title, messages, useNeutralText = false) => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
87
+ style: {
88
+ flex: 1,
89
+ padding: 24,
90
+ justifyContent: 'center',
91
+ backgroundColor: '#F8F8F8'
92
+ },
93
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
94
+ style: {
95
+ fontSize: 20,
96
+ fontWeight: '700',
97
+ color: '#1A1A1A',
98
+ marginBottom: 12
99
+ },
100
+ children: title
101
+ }), messages.map(message => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
102
+ style: {
103
+ fontSize: 14,
104
+ color: useNeutralText ? '#323130' : '#C4262E',
105
+ lineHeight: 20,
106
+ marginBottom: 8
107
+ },
108
+ children: message
109
+ }, message)), isSignedIn && onSignOut ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
110
+ accessibilityRole: "button",
111
+ onPress: () => {
112
+ void onSignOut();
113
+ },
114
+ style: {
115
+ alignSelf: 'flex-start',
116
+ backgroundColor: '#0F6CBD',
117
+ paddingHorizontal: 20,
118
+ paddingVertical: 12,
119
+ borderRadius: 4,
120
+ marginTop: 12
121
+ },
122
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
123
+ style: {
124
+ color: '#FFFFFF',
125
+ fontSize: 15,
126
+ fontWeight: '600'
127
+ },
128
+ children: "Sign out"
129
+ })
130
+ }) : null]
131
+ });
77
132
  const {
78
133
  connectionRefs,
79
134
  isReady,
135
+ error: connectionError,
136
+ errorKind: connectionErrorKind,
80
137
  missingConnectors,
81
- dataverseOrgUrl
138
+ missingConnectionReferences,
139
+ connectionRequirements,
140
+ resourceConsents: launchResourceConsents,
141
+ configurationErrors,
142
+ requiresConnectionConsent,
143
+ resolvedConfigKey,
144
+ dataverseOrgUrl,
145
+ databaseReferences: resolvedDatabaseReferences
82
146
  } = (0, _useConnectionRefs.useConnectionRefs)({
83
147
  isSignedIn,
84
148
  acquireToken,
@@ -96,39 +160,43 @@ function PowerAppsHostProvider({
96
160
  if (!isSignedIn) {
97
161
  (0, _logger.debugLog)('[PAHost] user signed out — resetting bridge state');
98
162
  setExtraConnectionRefs({});
163
+ setConsentApproved(false);
99
164
  }
100
165
  }, [isSignedIn]);
166
+ (0, _react.useEffect)(() => {
167
+ setExtraConnectionRefs({});
168
+ setConsentApproved(false);
169
+ }, [appId, environmentId, connectionReferences]);
101
170
 
102
171
  // Merge hook refs with anything the setup screen created.
103
172
  const mergedRefs = (0, _react.useMemo)(() => ({
104
173
  ...connectionRefs,
105
174
  ...extraConnectionRefs
106
175
  }), [connectionRefs, extraConnectionRefs]);
107
- const staticConnectionRefs = (0, _react.useMemo)(() => (0, _NativePowerAppsBridge.buildConnectionReferences)(connectionReferences), [connectionReferences]);
176
+ const staticConnectionRefs = (0, _react.useMemo)(() => _isDevPlayer.isDevPlayer ? (0, _NativePowerAppsBridge.buildConnectionReferences)(connectionReferences) : EMPTY_CONNECTION_REFERENCES, [connectionReferences, _isDevPlayer.isDevPlayer]);
108
177
 
109
178
  // dataverseOrgUrl comes directly from useConnectionRefs (fetched from the
110
179
  // environment metadata regardless of whether a commondataserviceforapps
111
180
  // connection reference is configured). This allows Dataverse calls to work
112
181
  // even when there is no explicit Dataverse connection in connectionReferences.
113
- const cdsDataSources = (0, _react.useMemo)(() => (0, _PowerPlatformEnvironmentApi.buildCdsDataSources)(databaseReferences ?? EMPTY_DATABASE_REFERENCES, dataverseOrgUrl), [databaseReferences, dataverseOrgUrl]);
182
+ const cdsDataSources = (0, _react.useMemo)(() => (0, _DataverseDataSources.buildCdsDataSources)(_isDevPlayer.isDevPlayer ? databaseReferences ?? EMPTY_DATABASE_REFERENCES : resolvedDatabaseReferences, dataverseOrgUrl), [databaseReferences, resolvedDatabaseReferences, dataverseOrgUrl, _isDevPlayer.isDevPlayer]);
114
183
 
115
184
  // Build the missing-connector entries for ConnectionSetupScreen.
116
- const missingEntries = (0, _react.useMemo)(() => missingConnectors.map(apiId => {
117
- const localRefId = Object.keys(connectionReferences).find(k => connectionReferences[k].id === apiId) ?? apiId;
118
- return {
119
- apiId,
120
- localRefId
121
- };
122
- }), [missingConnectors, connectionReferences]);
185
+ const missingEntries = (0, _react.useMemo)(() => missingConnectionReferences, [missingConnectionReferences]);
186
+ const resourceConsents = (0, _react.useMemo)(() => [...new Map(launchResourceConsents.map(resource => [resource.resourceId.toLowerCase(), resource])).values()], [launchResourceConsents]);
187
+ const currentConfigKey = (0, _react.useMemo)(() => (0, _types.buildConnectionResolutionKey)(appId, environmentId, _isDevPlayer.isDevPlayer ? connectionReferences : {}), [appId, environmentId, connectionReferences, _isDevPlayer.isDevPlayer]);
188
+ const resolutionMatchesCurrentConfig = resolvedConfigKey === currentConfigKey;
189
+ const needsConsent = (0, _connectionState.shouldShowConnectionReview)(_isDevPlayer.isDevPlayer, requiresConnectionConsent, resourceConsents.length > 0);
123
190
 
124
191
  // Called by ConnectionSetupScreen once every missing connector is resolved.
125
- const handleSetupComplete = (0, _react.useCallback)(resolvedIds => {
192
+ const handleSetupComplete = (0, _react.useCallback)(async resolvedIds => {
126
193
  const refs = {};
127
- for (const [apiId, connectionId] of Object.entries(resolvedIds)) {
128
- const localRefId = Object.keys(connectionReferences).find(k => connectionReferences[k].id === apiId);
129
- if (!localRefId) continue;
130
- const dataSources = connectionReferences[localRefId].dataSources;
131
- const runtimeUrl = dataSources.map(ds => schemaMap[ds]?.properties?.primaryRuntimeUrl).find(Boolean) ?? '';
194
+ for (const [localRefId, connectionId] of Object.entries(resolvedIds)) {
195
+ const requirement = connectionRequirements.find(item => item.localRefId === localRefId);
196
+ if (!requirement) continue;
197
+ const apiId = requirement.apiId;
198
+ const dataSources = requirement.dataSources;
199
+ const runtimeUrl = dataSources.map(ds => connectionRefsRef.current[ds]?.runtimeUrl ?? (_isDevPlayer.isDevPlayer ? schemaMap[ds]?.properties?.primaryRuntimeUrl : undefined)).find(Boolean) ?? '';
132
200
  for (const ds of dataSources) {
133
201
  refs[ds] = {
134
202
  apiId,
@@ -142,7 +210,44 @@ function PowerAppsHostProvider({
142
210
  }
143
211
  }
144
212
  setExtraConnectionRefs(refs);
145
- }, [connectionReferences, schemaMap]);
213
+ const mergedForConsent = {
214
+ ...connectionRefsRef.current,
215
+ ...refs
216
+ };
217
+ const usages = connectionRequirements.map(requirement => ({
218
+ localRefId: requirement.localRefId,
219
+ apiId: requirement.apiId,
220
+ connectionId: requirement.dataSources.map(dataSource => mergedForConsent[dataSource]?.connectionName).find(Boolean) ?? '',
221
+ dataSources: requirement.dataSources,
222
+ appActions: requirement.appActions ?? [],
223
+ apiScopes: requirement.apiScopes
224
+ }));
225
+ if (usages.some(usage => !usage.connectionId)) {
226
+ throw new Error('Not all required connections have been resolved.');
227
+ }
228
+ if (!_isDevPlayer.isDevPlayer && resourceConsents.length > 0 && !onResourceConsent) {
229
+ throw new Error('Protected resource consent requires an onResourceConsent persistence callback.');
230
+ }
231
+ const shouldPersistUsages = (0, _connectionState.shouldPersistConnectionUsages)(_isDevPlayer.isDevPlayer, appId);
232
+ if (shouldPersistUsages && appId && usages.length > 0) {
233
+ const token = await acquireToken([(0, _PowerPlatformEnvironmentApi.powerPlatformScope)(region)]);
234
+ if (!token) throw new Error('Unable to acquire a token to register connection usage.');
235
+ await Promise.all(usages.map(usage => (0, _PowerPlatformConnectionApi.postConnectionUsage)(appId, usage, environmentId, region, token)));
236
+ await (0, _PowerPlatformConnectionApi.reportScopeConsents)(appId, usages, environmentId, region, token);
237
+ }
238
+ if (!_isDevPlayer.isDevPlayer) {
239
+ await onConnectionConsent?.(usages);
240
+ await onResourceConsent?.(resourceConsents);
241
+ }
242
+ setConsentApproved(true);
243
+ }, [acquireToken, appId, environmentId, region, schemaMap, connectionRequirements, onConnectionConsent, onResourceConsent, resourceConsents, _isDevPlayer.isDevPlayer]);
244
+ const consentDetails = (0, _react.useMemo)(() => connectionRequirements.map(requirement => ({
245
+ localRefId: requirement.localRefId,
246
+ connectorId: requirement.connectorId,
247
+ displayName: requirement.displayName ?? requirement.connectorId.replace(/^shared_/, ''),
248
+ description: `Uses ${requirement.dataSources.join(', ')}`,
249
+ appActions: requirement.appActions ?? []
250
+ })), [connectionRequirements]);
146
251
 
147
252
  // ---- Bridge wiring ----
148
253
 
@@ -154,7 +259,7 @@ function PowerAppsHostProvider({
154
259
  connectionRefsRef.current = connectionRefs;
155
260
  const configuredBridgeInputsRef = (0, _react.useRef)(undefined);
156
261
  const [, setBridgeRegistrationVersion] = (0, _react.useState)(0);
157
- const hasResolvedConnections = isSignedIn && isReady && (missingConnectors.length === 0 || setupDone);
262
+ const hasResolvedConnections = isSignedIn && isReady && resolutionMatchesCurrentConfig && (missingConnectors.length === 0 || consentApproved) && (!needsConsent || consentApproved);
158
263
  const isBridgeConfiguredFor = (connections, dataSources) => {
159
264
  const currentInputs = configuredBridgeInputsRef.current;
160
265
  return currentInputs?.connections === connections && currentInputs.dataSources === dataSources;
@@ -254,13 +359,34 @@ function PowerAppsHostProvider({
254
359
  }
255
360
  }, [isSignedIn, isReady]);
256
361
  (0, _react.useEffect)(() => {
257
- if (isSignedIn && isReady && missingConnectors.length > 0 && !setupDone) {
362
+ if (isSignedIn && isReady && (missingConnectors.length > 0 || needsConsent) && !setupDone) {
258
363
  (0, _logger.debugLog)(`[PAHost] render: showing ConnectionSetupScreen for ${missingConnectors.length} missing connector(s):`, missingConnectors.join(', '));
259
364
  }
260
- }, [isSignedIn, isReady, missingConnectors, setupDone]);
365
+ }, [isSignedIn, isReady, missingConnectors, needsConsent, setupDone]);
261
366
 
262
367
  // ---- Render ----
263
368
 
369
+ if (connectionError) {
370
+ const accessDenied = connectionErrorKind === 'app-access-denied';
371
+ return renderConnectionError(accessDenied ? 'You don’t have access' : 'Unable to load app', [connectionError], accessDenied);
372
+ }
373
+ if (configurationErrors.length > 0) {
374
+ return renderConnectionError('Connection configuration error', configurationErrors);
375
+ }
376
+ if (isSignedIn && !resolutionMatchesCurrentConfig) {
377
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
378
+ style: {
379
+ flex: 1,
380
+ alignItems: 'center',
381
+ justifyContent: 'center',
382
+ backgroundColor: '#F8F8F8'
383
+ },
384
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
385
+ size: "large"
386
+ })
387
+ });
388
+ }
389
+
264
390
  // First mount: register the native bridge with static manifest refs before
265
391
  // any route children can mount and call into @microsoft/power-apps.
266
392
  if (!staticBridgeRegistered && !hasResolvedConnections) {
@@ -296,7 +422,7 @@ function PowerAppsHostProvider({
296
422
  // Wrapped in SafeAreaProvider so useSafeAreaInsets() works even when the
297
423
  // consuming app hasn't mounted its own SafeAreaProvider yet. Nesting is
298
424
  // safe — react-native-safe-area-context treats inner providers as no-ops.
299
- if (isSignedIn && isReady && missingConnectors.length > 0 && !setupDone) {
425
+ if (isSignedIn && isReady && (missingConnectors.length > 0 || needsConsent) && !setupDone) {
300
426
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSafeAreaContext.SafeAreaProvider, {
301
427
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ConnectionSetupScreen.ConnectionSetupScreen, {
302
428
  missingConnectors: missingEntries,
@@ -304,8 +430,13 @@ function PowerAppsHostProvider({
304
430
  environmentId: environmentId,
305
431
  region: region,
306
432
  acquireToken: acquireToken,
433
+ onSignOut: isSignedIn ? onSignOut : undefined,
307
434
  isvClientId: isvClientId,
308
435
  onAllConnected: handleSetupComplete,
436
+ consentDetails: consentDetails,
437
+ resourceConsents: resourceConsents,
438
+ onConsentDeclined: onConnectionConsentDeclined,
439
+ showReview: !_isDevPlayer.isDevPlayer,
309
440
  renderOAuthWebView: renderOAuthWebView
310
441
  // No onSkip — connections are required.
311
442
  })
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.PowerAppsHostProvider = PowerAppsHostProvider;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _reactNativeSafeAreaContext = require("react-native-safe-area-context");
9
+ var _NativePowerAppsBridge = require("../bridge/NativePowerAppsBridge.js");
10
+ var _PowerPagesBridge = require("../bridge/PowerPagesBridge.js");
11
+ var _jsxRuntime = require("react/jsx-runtime");
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
+ function PowerAppsHostProvider({
14
+ connectionReferences,
15
+ databaseReferences,
16
+ children
17
+ }) {
18
+ const isPowerPages = typeof window !== 'undefined' && Boolean(window.Microsoft?.Dynamic365?.Portal?.version);
19
+ if (isPowerPages) {
20
+ const connectorRuntimeUrl = window.location.origin;
21
+ const dataverseRuntimeUrl = `${window.location.origin}/api/data/v9.0/`;
22
+ const connections = (0, _NativePowerAppsBridge.buildConnectionReferences)(connectionReferences);
23
+ for (const connection of Object.values(connections)) {
24
+ connection.runtimeUrl = connectorRuntimeUrl;
25
+ connection.datasetName = window.location.origin;
26
+ }
27
+ const dataSources = Object.values(databaseReferences ?? {}).flatMap(databaseReference => Object.values(databaseReference.dataSources ?? {}).map(dataSource => ({
28
+ runtimeUrl: dataverseRuntimeUrl,
29
+ entitySetName: dataSource.entitySetName ?? '',
30
+ logicalName: dataSource.logicalName ?? '',
31
+ version: '9.2'
32
+ })));
33
+ (0, _PowerPagesBridge.setupPowerPagesHost)({
34
+ connections,
35
+ dataSources
36
+ });
37
+ }
38
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSafeAreaContext.SafeAreaProvider, {
39
+ children: children
40
+ });
41
+ }