@microsoft/power-apps-native-host 0.2.25 → 0.3.3

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 (154) hide show
  1. package/README.md +21 -10
  2. package/compatibility/current.json +31 -4
  3. package/lib/NOTICE.txt +1325 -24
  4. package/lib/commonjs/auth/AuthContext.js +110 -33
  5. package/lib/commonjs/bridge/NativePowerAppsBridge.js +11 -18
  6. package/lib/commonjs/bridge/PowerPagesBridge.js +27 -8
  7. package/lib/commonjs/bridge/bridgeState.js +40 -0
  8. package/lib/commonjs/config/babelConfig.js +13 -0
  9. package/lib/commonjs/config/expoConfig.js +71 -0
  10. package/lib/commonjs/config/metroConfig.js +70 -0
  11. package/lib/commonjs/config/metroLogger.js +182 -0
  12. package/lib/commonjs/config/tamaguiConfig.js +98 -0
  13. package/lib/commonjs/connections/ConnectionSetupScreen.js +459 -80
  14. package/lib/commonjs/connections/PowerPlatformConnectionApi.js +946 -0
  15. package/lib/commonjs/connections/connectionMetadata.js +127 -0
  16. package/lib/commonjs/connections/connectionState.js +96 -0
  17. package/lib/commonjs/connections/disambiguate.js +19 -11
  18. package/lib/commonjs/connections/resolveConnections.js +348 -0
  19. package/lib/commonjs/connections/types.js +106 -0
  20. package/lib/commonjs/{platform → connections}/useConnectionRefs.js +130 -65
  21. package/lib/commonjs/connections/useConnectionSetup.js +111 -52
  22. package/lib/commonjs/controls/FilePicker.js +6 -0
  23. package/lib/commonjs/controls/ImagePicker.js +8 -0
  24. package/lib/commonjs/index.js +167 -4
  25. package/lib/commonjs/logger.js +9 -6
  26. package/lib/commonjs/offline/createOfflineHostActivationCallbacks.js +61 -0
  27. package/lib/commonjs/offline/useOfflineIntegrationWithStartupGate.js +48 -0
  28. package/lib/commonjs/offline/useOfflineIntegrationWithStartupGate.web.js +13 -0
  29. package/lib/commonjs/platform/DataverseDataSources.js +18 -0
  30. package/lib/commonjs/platform/DataverseGlobalDiscoveryApi.js +94 -0
  31. package/lib/commonjs/platform/GlobalDiscovery.js +51 -0
  32. package/lib/commonjs/platform/PowerPlatformEnvironmentApi.js +6 -106
  33. package/lib/commonjs/provider/PowerAppsHostProvider.js +157 -25
  34. package/lib/commonjs/provider/PowerAppsProvider.js +178 -134
  35. package/lib/commonjs/provider/SessionDetailsGesture.js +208 -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 +110 -33
  40. package/lib/module/bridge/NativePowerAppsBridge.js +12 -19
  41. package/lib/module/bridge/PowerPagesBridge.js +27 -8
  42. package/lib/module/bridge/bridgeState.js +34 -0
  43. package/lib/module/config/babelConfig.js +9 -0
  44. package/lib/module/config/expoConfig.js +67 -0
  45. package/lib/module/config/metroConfig.js +65 -0
  46. package/lib/module/config/metroLogger.js +175 -0
  47. package/lib/module/config/tamaguiConfig.js +93 -0
  48. package/lib/module/connections/ConnectionSetupScreen.js +460 -81
  49. package/lib/module/connections/PowerPlatformConnectionApi.js +932 -0
  50. package/lib/module/connections/connectionMetadata.js +112 -0
  51. package/lib/module/connections/connectionState.js +82 -0
  52. package/lib/module/connections/disambiguate.js +19 -12
  53. package/lib/module/connections/resolveConnections.js +343 -0
  54. package/lib/module/connections/types.js +91 -0
  55. package/lib/module/{platform → connections}/useConnectionRefs.js +131 -66
  56. package/lib/module/connections/useConnectionSetup.js +113 -54
  57. package/lib/module/controls/FilePicker.js +6 -0
  58. package/lib/module/controls/ImagePicker.js +8 -0
  59. package/lib/module/index.js +14 -4
  60. package/lib/module/logger.js +8 -6
  61. package/lib/module/offline/createOfflineHostActivationCallbacks.js +55 -0
  62. package/lib/module/offline/useOfflineIntegrationWithStartupGate.js +44 -0
  63. package/lib/module/offline/useOfflineIntegrationWithStartupGate.web.js +9 -0
  64. package/lib/module/platform/DataverseDataSources.js +13 -0
  65. package/lib/module/platform/DataverseGlobalDiscoveryApi.js +89 -0
  66. package/lib/module/platform/GlobalDiscovery.js +45 -0
  67. package/lib/module/platform/PowerPlatformEnvironmentApi.js +5 -104
  68. package/lib/module/provider/PowerAppsHostProvider.js +160 -28
  69. package/lib/module/provider/PowerAppsProvider.js +182 -138
  70. package/lib/module/provider/SessionDetailsGesture.js +203 -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 +1 -0
  76. package/lib/typescript/commonjs/bridge/bridgeState.d.ts +5 -0
  77. package/lib/typescript/commonjs/config/babelConfig.d.ts +12 -0
  78. package/lib/typescript/commonjs/config/expoConfig.d.ts +21 -0
  79. package/lib/typescript/commonjs/config/metroConfig.d.ts +6 -0
  80. package/lib/typescript/commonjs/config/metroLogger.d.ts +21 -0
  81. package/lib/typescript/commonjs/config/tamaguiConfig.d.ts +1792 -0
  82. package/lib/typescript/commonjs/connections/ConnectionSetupScreen.d.ts +28 -7
  83. package/lib/typescript/commonjs/{platform → connections}/PowerPlatformConnectionApi.d.ts +52 -43
  84. package/lib/typescript/commonjs/connections/connectionMetadata.d.ts +66 -0
  85. package/lib/typescript/commonjs/connections/connectionState.d.ts +16 -0
  86. package/lib/typescript/commonjs/connections/disambiguate.d.ts +4 -2
  87. package/lib/typescript/commonjs/{platform → connections}/resolveConnections.d.ts +22 -20
  88. package/lib/typescript/commonjs/connections/types.d.ts +129 -1
  89. package/lib/typescript/commonjs/{platform → connections}/useConnectionRefs.d.ts +36 -25
  90. package/lib/typescript/commonjs/connections/useConnectionSetup.d.ts +12 -8
  91. package/lib/typescript/commonjs/controls/FilePicker.d.ts +7 -1
  92. package/lib/typescript/commonjs/controls/ImagePicker.d.ts +9 -1
  93. package/lib/typescript/commonjs/index.d.ts +18 -10
  94. package/lib/typescript/commonjs/logger.d.ts +4 -4
  95. package/lib/typescript/commonjs/offline/createOfflineHostActivationCallbacks.d.ts +12 -0
  96. package/lib/typescript/commonjs/offline/useOfflineIntegrationWithStartupGate.d.ts +15 -0
  97. package/lib/typescript/commonjs/offline/useOfflineIntegrationWithStartupGate.web.d.ts +6 -0
  98. package/lib/typescript/commonjs/platform/DataverseDataSources.d.ts +28 -0
  99. package/lib/typescript/commonjs/platform/DataverseGlobalDiscoveryApi.d.ts +3 -0
  100. package/lib/typescript/commonjs/platform/GlobalDiscovery.d.ts +4 -0
  101. package/lib/typescript/commonjs/platform/PowerPlatformEnvironmentApi.d.ts +3 -74
  102. package/lib/typescript/commonjs/provider/PowerAppsHostProvider.d.ts +29 -18
  103. package/lib/typescript/commonjs/provider/PowerAppsProvider.d.ts +54 -9
  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 +1 -0
  110. package/lib/typescript/module/bridge/bridgeState.d.ts +5 -0
  111. package/lib/typescript/module/config/babelConfig.d.ts +12 -0
  112. package/lib/typescript/module/config/expoConfig.d.ts +21 -0
  113. package/lib/typescript/module/config/metroConfig.d.ts +6 -0
  114. package/lib/typescript/module/config/metroLogger.d.ts +21 -0
  115. package/lib/typescript/module/config/tamaguiConfig.d.ts +1792 -0
  116. package/lib/typescript/module/connections/ConnectionSetupScreen.d.ts +28 -7
  117. package/lib/typescript/module/{platform → connections}/PowerPlatformConnectionApi.d.ts +52 -43
  118. package/lib/typescript/module/connections/connectionMetadata.d.ts +66 -0
  119. package/lib/typescript/module/connections/connectionState.d.ts +16 -0
  120. package/lib/typescript/module/connections/disambiguate.d.ts +4 -2
  121. package/lib/typescript/module/{platform → connections}/resolveConnections.d.ts +22 -20
  122. package/lib/typescript/module/connections/types.d.ts +129 -1
  123. package/lib/typescript/module/{platform → connections}/useConnectionRefs.d.ts +36 -25
  124. package/lib/typescript/module/connections/useConnectionSetup.d.ts +12 -8
  125. package/lib/typescript/module/controls/FilePicker.d.ts +7 -1
  126. package/lib/typescript/module/controls/ImagePicker.d.ts +9 -1
  127. package/lib/typescript/module/index.d.ts +18 -10
  128. package/lib/typescript/module/logger.d.ts +4 -4
  129. package/lib/typescript/module/offline/createOfflineHostActivationCallbacks.d.ts +12 -0
  130. package/lib/typescript/module/offline/useOfflineIntegrationWithStartupGate.d.ts +15 -0
  131. package/lib/typescript/module/offline/useOfflineIntegrationWithStartupGate.web.d.ts +6 -0
  132. package/lib/typescript/module/platform/DataverseDataSources.d.ts +28 -0
  133. package/lib/typescript/module/platform/DataverseGlobalDiscoveryApi.d.ts +3 -0
  134. package/lib/typescript/module/platform/GlobalDiscovery.d.ts +4 -0
  135. package/lib/typescript/module/platform/PowerPlatformEnvironmentApi.d.ts +3 -74
  136. package/lib/typescript/module/provider/PowerAppsHostProvider.d.ts +29 -18
  137. package/lib/typescript/module/provider/PowerAppsProvider.d.ts +54 -9
  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 +52 -13
  143. package/scripts/build-codegen-package.js +283 -0
  144. package/scripts/start-web.mjs +9 -5
  145. package/scripts/upgrade/runtime.js +139 -24
  146. package/scripts/upgrade-authoring.js +274 -180
  147. package/scripts/upgrade.js +10 -16
  148. package/src/config/generated-config.d.ts +4 -0
  149. package/src/config/index.d.ts +3 -0
  150. package/src/config/tsconfig.json +26 -0
  151. package/lib/commonjs/platform/PowerPlatformConnectionApi.js +0 -606
  152. package/lib/commonjs/platform/resolveConnections.js +0 -264
  153. package/lib/module/platform/PowerPlatformConnectionApi.js +0 -595
  154. package/lib/module/platform/resolveConnections.js +0 -259
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createHostQueryClient = createHostQueryClient;
7
+ exports.createOfflineHostActivationCallbacks = createOfflineHostActivationCallbacks;
8
+ exports.resolveSdkMountDecision = resolveSdkMountDecision;
9
+ var _reactQuery = require("@tanstack/react-query");
10
+ function setNetworkMode(queryClient, networkMode) {
11
+ const current = queryClient.getDefaultOptions();
12
+ queryClient.setDefaultOptions({
13
+ ...current,
14
+ queries: {
15
+ ...current.queries,
16
+ staleTime: 60_000,
17
+ retry: 2,
18
+ networkMode
19
+ },
20
+ mutations: {
21
+ ...current.mutations,
22
+ retry: 0,
23
+ networkMode
24
+ }
25
+ });
26
+ }
27
+ function createHostQueryClient() {
28
+ return new _reactQuery.QueryClient({
29
+ defaultOptions: {
30
+ queries: {
31
+ staleTime: 60_000,
32
+ retry: 2
33
+ },
34
+ mutations: {
35
+ retry: 0
36
+ }
37
+ }
38
+ });
39
+ }
40
+ function createOfflineHostActivationCallbacks(queryClient) {
41
+ return {
42
+ prepareForOfflineActivation: () => queryClient.cancelQueries(),
43
+ completeOfflineActivation: async () => {
44
+ setNetworkMode(queryClient, 'always');
45
+ await queryClient.invalidateQueries();
46
+ },
47
+ rollbackOfflineActivation: async () => {
48
+ setNetworkMode(queryClient, undefined);
49
+ await queryClient.invalidateQueries();
50
+ }
51
+ };
52
+ }
53
+ function resolveSdkMountDecision(value) {
54
+ return typeof value === 'boolean' ? {
55
+ shouldMountChildren: value,
56
+ contractSupported: true
57
+ } : {
58
+ shouldMountChildren: true,
59
+ contractSupported: false
60
+ };
61
+ }
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useOfflineIntegrationWithStartupGate = useOfflineIntegrationWithStartupGate;
7
+ var _react = require("react");
8
+ var _reactQuery = require("@tanstack/react-query");
9
+ var _powerAppsNativeCommon = require("@microsoft/power-apps-native-common");
10
+ var _DataverseGlobalDiscoveryApi = require("../platform/DataverseGlobalDiscoveryApi.js");
11
+ var _DataverseDataSources = require("../platform/DataverseDataSources.js");
12
+ var _index = require("../telemetry/index.js");
13
+ var _createOfflineHostActivationCallbacks = require("./createOfflineHostActivationCallbacks.js");
14
+ var _useOfflineIntegration = require("./useOfflineIntegration");
15
+ function useOfflineIntegrationWithStartupGate({
16
+ powerConfig,
17
+ offlineProfile,
18
+ acquireToken,
19
+ hasRealAccount,
20
+ isAuthReady
21
+ }) {
22
+ const queryClient = (0, _reactQuery.useQueryClient)();
23
+ const hasDataverse = (0, _DataverseDataSources.hasDataverseDatabaseReferences)(powerConfig.databaseReferences);
24
+ const resolveInstanceUrl = (0, _react.useCallback)(async (environmentId, region, acqToken) => hasDataverse ? (await (0, _DataverseGlobalDiscoveryApi.fetchInstanceUrl)(environmentId, region, acqToken)) ?? null : null, [hasDataverse]);
25
+ const hostActivationCallbacks = (0, _react.useMemo)(() => (0, _createOfflineHostActivationCallbacks.createOfflineHostActivationCallbacks)(queryClient), [queryClient]);
26
+ const offline = (0, _useOfflineIntegration.useOfflineIntegration)({
27
+ powerConfig,
28
+ offlineProfile,
29
+ acquireToken,
30
+ isSignedIn: hasRealAccount,
31
+ authState: isAuthReady ? hasRealAccount ? 'authenticated' : 'signed-out' : 'hydrating',
32
+ fetchInstanceUrl: resolveInstanceUrl,
33
+ hostActivationCallbacks
34
+ });
35
+ const mountDecision = (0, _createOfflineHostActivationCallbacks.resolveSdkMountDecision)(offline.shouldMountChildren);
36
+ (0, _react.useEffect)(() => {
37
+ if (!mountDecision.contractSupported) {
38
+ (0, _powerAppsNativeCommon.getAppLogger)().trackErrorEvent(_index.HostOperationNames.OfflineRoutingContractUnsupported, {
39
+ fallbackRoute: 'online'
40
+ });
41
+ }
42
+ }, [mountDecision.contractSupported]);
43
+ return {
44
+ isEnabled: offline.isEnabled,
45
+ StatusOverlay: offline.StatusOverlay,
46
+ shouldMountChildren: mountDecision.shouldMountChildren
47
+ };
48
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useOfflineIntegrationWithStartupGate = useOfflineIntegrationWithStartupGate;
7
+ function useOfflineIntegrationWithStartupGate(_options) {
8
+ return {
9
+ isEnabled: false,
10
+ StatusOverlay: null,
11
+ shouldMountChildren: true
12
+ };
13
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.buildCdsDataSources = buildCdsDataSources;
7
+ exports.hasDataverseDatabaseReferences = hasDataverseDatabaseReferences;
8
+ function hasDataverseDatabaseReferences(databaseReferences) {
9
+ return Object.keys(databaseReferences ?? {}).length > 0;
10
+ }
11
+ function buildCdsDataSources(databaseReferences, dataverseOrgUrl) {
12
+ return Object.values(databaseReferences).flatMap(databaseReference => Object.values(databaseReference.dataSources ?? {}).map(dataSource => ({
13
+ runtimeUrl: dataverseOrgUrl ? `${dataverseOrgUrl}/api/data/v9.0/` : '',
14
+ entitySetName: dataSource.entitySetName ?? '',
15
+ logicalName: dataSource.logicalName ?? '',
16
+ version: '9.2'
17
+ })));
18
+ }
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.fetchInstanceUrl = fetchInstanceUrl;
7
+ var _http = require("@microsoft/power-apps-native-common/http");
8
+ var SecureStore = _interopRequireWildcard(require("expo-secure-store"));
9
+ var _index = require("../telemetry/index.js");
10
+ var _GlobalDiscovery = require("./GlobalDiscovery.js");
11
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
12
+ const INSTANCE_URL_CACHE_KEY_PREFIX = 'microsoft.power-apps-native-host.instance-url.v1';
13
+ const INSTANCE_URL_CACHE_TTL_MS = 30 * 24 * 60 * 60 * 1000;
14
+ function getInstanceUrlCacheKey(environmentId, region) {
15
+ return `${INSTANCE_URL_CACHE_KEY_PREFIX}.${region.toLowerCase()}.${environmentId.toLowerCase()}`;
16
+ }
17
+ async function getCachedInstanceUrl(environmentId, region) {
18
+ try {
19
+ const cachedValue = await SecureStore.getItemAsync(getInstanceUrlCacheKey(environmentId, region));
20
+ if (!cachedValue) {
21
+ return null;
22
+ }
23
+ const entry = JSON.parse(cachedValue);
24
+ if (typeof entry.instanceUrl !== 'string' || typeof entry.expiresAt !== 'number' || entry.expiresAt <= Date.now()) {
25
+ return null;
26
+ }
27
+ return entry.instanceUrl;
28
+ } catch {
29
+ return null;
30
+ }
31
+ }
32
+ async function cacheInstanceUrl(environmentId, region, instanceUrl) {
33
+ try {
34
+ const entry = {
35
+ instanceUrl,
36
+ expiresAt: Date.now() + INSTANCE_URL_CACHE_TTL_MS
37
+ };
38
+ await SecureStore.setItemAsync(getInstanceUrlCacheKey(environmentId, region), JSON.stringify(entry));
39
+ } catch {
40
+ // SecureStore may be unavailable (for example, on web); discovery still succeeds.
41
+ }
42
+ }
43
+ function getSafeErrorName(error) {
44
+ return error instanceof Error ? error.constructor.name : typeof error;
45
+ }
46
+
47
+ /** Fetch the Dataverse instance URL from the Dataverse Global Discovery Service. */
48
+ async function fetchInstanceUrl(environmentId, region, acquireToken, _bearerToken) {
49
+ const scenario = (0, _index.getAppLogger)().trackScenario(_index.HostOperationNames.PlatformFetchInstanceUrl, {
50
+ environmentId,
51
+ region
52
+ });
53
+ try {
54
+ const cachedInstanceUrl = await getCachedInstanceUrl(environmentId, region);
55
+ if (cachedInstanceUrl) {
56
+ scenario.complete({
57
+ hasInstanceUrl: true,
58
+ cacheHit: true
59
+ });
60
+ return cachedInstanceUrl;
61
+ }
62
+ const url = (0, _GlobalDiscovery.buildGlobalDiscoveryUrl)(environmentId, region);
63
+ const token = await acquireToken([(0, _GlobalDiscovery.globalDiscoveryScope)(region)]);
64
+ if (!token) {
65
+ throw new Error('fetchInstanceUrl: failed to acquire Dataverse Global Discovery token');
66
+ }
67
+ const response = await _index.platformHttpClient.request(url, {
68
+ method: 'GET',
69
+ headers: {
70
+ Authorization: `Bearer ${token}`,
71
+ 'Content-Type': 'application/json'
72
+ }
73
+ });
74
+ if (!response.ok) {
75
+ throw new Error(`fetchInstanceUrl: Global Discovery returned ${response.status} ${response.statusText}`);
76
+ }
77
+ const result = await response.json();
78
+ const instanceUrl = result.value?.find(instance => instance.EnvironmentId?.toLowerCase() === environmentId.toLowerCase())?.ApiUrl;
79
+ if (instanceUrl) {
80
+ await cacheInstanceUrl(environmentId, region, instanceUrl);
81
+ }
82
+ scenario.complete({
83
+ hasInstanceUrl: instanceUrl !== undefined,
84
+ cacheHit: false,
85
+ ...(0, _http.getHttpCorrelationProperties)(response.headers)
86
+ });
87
+ return instanceUrl;
88
+ } catch (error) {
89
+ scenario.fail(undefined, {
90
+ errorName: getSafeErrorName(error)
91
+ });
92
+ throw error;
93
+ }
94
+ }
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.buildGlobalDiscoveryUrl = buildGlobalDiscoveryUrl;
7
+ exports.globalDiscoveryEndpoint = globalDiscoveryEndpoint;
8
+ exports.globalDiscoveryScope = globalDiscoveryScope;
9
+ const GLOBAL_DISCOVERY_HOST = {
10
+ prod: 'globaldisco.crm.dynamics.com',
11
+ gcc: 'globaldisco.crm9.dynamics.com',
12
+ usg: 'globaldisco.crm.microsoftdynamics.us',
13
+ dod: 'globaldisco.crm.appsplatform.us',
14
+ china: 'globaldisco.crm.dynamics.cn'
15
+ };
16
+ const REGION_DISCOVERY_CLOUD = {
17
+ dev: 'prod',
18
+ test: 'prod',
19
+ preprod: 'prod',
20
+ preview: 'prod',
21
+ firstrelease: 'prod',
22
+ prod: 'prod',
23
+ gccmoderate: 'gcc',
24
+ gov: 'gcc',
25
+ gcchigh: 'usg',
26
+ high: 'usg',
27
+ dod: 'dod',
28
+ mooncake: 'china'
29
+ };
30
+ const ENVIRONMENT_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
31
+ function globalDiscoveryEndpoint(region) {
32
+ const cloud = REGION_DISCOVERY_CLOUD[region];
33
+ if (!cloud) {
34
+ throw new Error(`Dataverse Global Discovery is not available for Power Platform region "${region}"`);
35
+ }
36
+ return `https://${GLOBAL_DISCOVERY_HOST[cloud]}`;
37
+ }
38
+ function globalDiscoveryScope(region) {
39
+ return `${globalDiscoveryEndpoint(region)}/user_impersonation`;
40
+ }
41
+ function buildGlobalDiscoveryUrl(environmentId, region) {
42
+ if (!ENVIRONMENT_ID_PATTERN.test(environmentId)) {
43
+ throw new Error(`Invalid Power Platform environment ID: "${environmentId}"`);
44
+ }
45
+ const normalizedEnvironmentId = environmentId.toLowerCase();
46
+ const query = new URLSearchParams({
47
+ '$select': 'ApiUrl,EnvironmentId',
48
+ '$filter': `EnvironmentId eq '${normalizedEnvironmentId}'`
49
+ });
50
+ return `${globalDiscoveryEndpoint(region)}/api/discovery/v2.0/Instances?${query.toString()}`;
51
+ }
@@ -4,22 +4,13 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.POWER_PLATFORM_API_SCOPE = void 0;
7
- exports.buildCdsDataSources = buildCdsDataSources;
8
7
  exports.buildEnvironmentEndpoint = buildEnvironmentEndpoint;
9
- exports.fetchInstanceUrl = fetchInstanceUrl;
8
+ exports.connectionUserConsentScope = connectionUserConsentScope;
10
9
  exports.powerPlatformScope = powerPlatformScope;
11
- var _index = require("../telemetry/index.js");
12
10
  /*!
13
11
  * power-apps-native-host — PowerPlatformEnvironmentApi
14
12
  *
15
- * Mirrors the Host SDK's DefaultAppMetadataProvider.fetchAppMetadataFromPowerConfig
16
- * pattern: resolves the Power Platform environment-scoped API endpoint from the
17
- * environment GUID and region, then fetches linkedEnvironmentMetadata to obtain
18
- * the Dataverse instanceUrl.
19
- *
20
- * Reference (Host SDK):
21
- * packages/power-apps-host/src/providers/defaults/DefaultAppMetadataProvider.ts
22
- * packages/power-apps-common/src/services/PowerPlatformApiDiscovery.ts
13
+ * Resolves Power Platform RP endpoints and scopes.
23
14
  */
24
15
 
25
16
  // ---------------------------------------------------------------------------
@@ -78,10 +69,6 @@ function buildEnvironmentEndpoint(environmentId, region) {
78
69
  return `https://${hexPrefix}.${hexSuffix}.environment.${hostNameSuffix}`;
79
70
  }
80
71
 
81
- // ---------------------------------------------------------------------------
82
- // Public API
83
- // ---------------------------------------------------------------------------
84
-
85
72
  /**
86
73
  * Token scope for the Power Platform management API (prod cluster).
87
74
  * Non-prod clusters (test, gov, high, dev, mooncake, etc.) host the management
@@ -99,96 +86,9 @@ function powerPlatformScope(region) {
99
86
  const host = HOST_NAME_SUFFIX[region] ?? HOST_NAME_SUFFIX['prod'];
100
87
  return `https://${host}/.default`;
101
88
  }
102
- function getSafeErrorName(error) {
103
- return error instanceof Error ? error.constructor.name : typeof error;
104
- }
105
89
 
106
- /**
107
- * Fetch the Dataverse instanceUrl for a Power Platform environment by calling
108
- * the environment-scoped Power Platform management API — the same call that
109
- * the Host SDK's DefaultAppMetadataProvider makes to populate
110
- * `databaseReferences[*].databaseDetails.linkedEnvironmentMetadata`.
111
- *
112
- * @param environmentId - Environment GUID (from power.config.json `environmentId`).
113
- * @param region - Cluster region string (from power.config.json `region`, default "prod").
114
- * @param acquireToken - Callback to obtain a bearer token for the given scopes.
115
- * Scope will be {@link powerPlatformScope}`(region)`.
116
- * @param bearerToken - Optional pre-fetched bearer token for {@link powerPlatformScope}`(region)`.
117
- * Pass this to avoid a redundant `acquireToken` round-trip when the
118
- * caller has already obtained a token for the same audience.
119
- * @returns The Dataverse org URL (e.g. "https://org12345.crm.dynamics.com"), or
120
- * `undefined` if the environment has no linked CDS database.
121
- */
122
- async function fetchInstanceUrl(environmentId, region, acquireToken, bearerToken) {
123
- const scenario = (0, _index.getAppLogger)().trackScenario(_index.HostOperationNames.PlatformFetchInstanceUrl, {
124
- environmentId,
125
- region
126
- });
127
- try {
128
- const baseUrl = buildEnvironmentEndpoint(environmentId, region);
129
- const url = `${baseUrl}/powerapps/environment?api-version=1&%24filter=name+eq+%27${encodeURIComponent(environmentId)}%27`;
130
- const token = bearerToken ?? (await acquireToken([powerPlatformScope(region)]));
131
- if (!token) {
132
- throw new Error('fetchInstanceUrl: failed to acquire Power Platform API token');
133
- }
134
- const response = await fetch(url, {
135
- method: 'GET',
136
- headers: {
137
- Authorization: `Bearer ${token}`,
138
- 'Content-Type': 'application/json'
139
- }
140
- });
141
- if (!response.ok) {
142
- throw new Error(`fetchInstanceUrl: environment API returned ${response.status} ${response.statusText}`);
143
- }
144
- const env = await response.json();
145
- const instanceUrl = env.properties?.linkedEnvironmentMetadata?.instanceUrl;
146
- scenario.complete({
147
- hasInstanceUrl: instanceUrl !== undefined
148
- });
149
- return instanceUrl;
150
- } catch (e) {
151
- scenario.fail(undefined, {
152
- errorName: getSafeErrorName(e)
153
- });
154
- throw e;
155
- }
156
- }
157
-
158
- // ---------------------------------------------------------------------------
159
- // buildCdsDataSources
160
- // ---------------------------------------------------------------------------
161
-
162
- /**
163
- * Shape of a single Dataverse table entry inside power.config.json
164
- * `databaseReferences[*].dataSources[*]`.
165
- */
166
-
167
- /**
168
- * Shape of a single database reference entry inside power.config.json
169
- * `databaseReferences`.
170
- */
171
-
172
- /**
173
- * Build the CDS data source config array that the SDK reads via
174
- * AppPowerAppsClientPlugin.getAppCdsDataSourceConfigsAsync.
175
- *
176
- * Pass the resolved Dataverse org URL (from useConnectionRefs) and the
177
- * databaseReferences map from power.config.json. The resulting array is
178
- * passed directly to <PowerAppsHostProvider dataSources={...} />.
179
- *
180
- * @param databaseReferences - The `databaseReferences` map from power.config.json.
181
- * @param dataverseOrgUrl - The resolved Dataverse org URL
182
- * (connectionRefs['commondataserviceforapps']?.datasetName).
183
- * Pass an empty string before the org URL is known;
184
- * the host provider will receive empty runtimeUrl entries
185
- * and the SDK will not attempt Dataverse calls.
186
- */
187
- function buildCdsDataSources(databaseReferences, dataverseOrgUrl) {
188
- return Object.values(databaseReferences).flatMap(dbRef => Object.values(dbRef.dataSources ?? {}).map(ds => ({
189
- runtimeUrl: dataverseOrgUrl ? `${dataverseOrgUrl}/api/data/v9.0/` : '',
190
- entitySetName: ds.entitySetName ?? '',
191
- logicalName: ds.logicalName ?? '',
192
- version: '9.2'
193
- })));
90
+ /** Delegated permission required by the connection user-consent endpoint. */
91
+ function connectionUserConsentScope(region) {
92
+ const host = HOST_NAME_SUFFIX[region] ?? HOST_NAME_SUFFIX['prod'];
93
+ return `https://${host}/Connectivity.Connections.UserConsent`;
194
94
  }