@microsoft/power-apps-native-host 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -0
- package/compatibility/current.json +1 -1
- package/lib/NOTICE.txt +2957 -371
- package/lib/commonjs/auth/AuthContext.js +49 -22
- package/lib/commonjs/auth/targetAuthorization.js +53 -0
- package/lib/commonjs/bridge/NativePowerAppsBridge.js +33 -2
- package/lib/commonjs/bridge/PowerPagesBridge.js +1 -3
- package/lib/commonjs/bridge/setupNativeHost.js +6 -0
- package/lib/commonjs/config/expoConfig.js +14 -0
- package/lib/commonjs/config/runtimeTenantMode.js +16 -0
- package/lib/commonjs/config/runtimeTenantMode.web.js +9 -0
- package/lib/commonjs/config/tenantMode.js +68 -0
- package/lib/commonjs/connections/PowerPlatformConnectionApi.js +24 -27
- package/lib/commonjs/connections/connectionMetadata.js +2 -2
- package/lib/commonjs/connections/resolveConnections.js +8 -3
- package/lib/commonjs/connections/types.js +9 -2
- package/lib/commonjs/connections/useConnectionRefs.js +19 -10
- package/lib/commonjs/index.js +39 -0
- package/lib/commonjs/platform/CanvasAppResolution.js +33 -0
- package/lib/commonjs/platform/CanvasAppResolutionApi.js +69 -0
- package/lib/commonjs/platform/DataverseGlobalDiscoveryApi.js +50 -13
- package/lib/commonjs/platform/GlobalDiscovery.js +40 -1
- package/lib/commonjs/provider/PowerAppsHostProvider.js +47 -8
- package/lib/commonjs/provider/PowerAppsProvider.js +172 -6
- package/lib/commonjs/target/DefaultPowerAppsExperience.js +564 -0
- package/lib/commonjs/target/PowerAppsExperience.js +41 -0
- package/lib/commonjs/target/PowerAppsTargetBootstrap.js +534 -0
- package/lib/commonjs/target/errors.js +24 -0
- package/lib/commonjs/target/types.js +1 -0
- package/lib/module/auth/AuthContext.js +49 -22
- package/lib/module/auth/targetAuthorization.js +48 -0
- package/lib/module/bridge/NativePowerAppsBridge.js +33 -2
- package/lib/module/bridge/PowerPagesBridge.js +1 -3
- package/lib/module/bridge/setupNativeHost.js +5 -0
- package/lib/module/config/expoConfig.js +14 -0
- package/lib/module/config/runtimeTenantMode.js +12 -0
- package/lib/module/config/runtimeTenantMode.web.js +5 -0
- package/lib/module/config/tenantMode.js +61 -0
- package/lib/module/connections/PowerPlatformConnectionApi.js +24 -27
- package/lib/module/connections/connectionMetadata.js +2 -2
- package/lib/module/connections/resolveConnections.js +9 -4
- package/lib/module/connections/types.js +9 -2
- package/lib/module/connections/useConnectionRefs.js +20 -11
- package/lib/module/index.js +4 -1
- package/lib/module/platform/CanvasAppResolution.js +27 -0
- package/lib/module/platform/CanvasAppResolutionApi.js +65 -0
- package/lib/module/platform/DataverseGlobalDiscoveryApi.js +49 -14
- package/lib/module/platform/GlobalDiscovery.js +37 -1
- package/lib/module/provider/PowerAppsHostProvider.js +47 -8
- package/lib/module/provider/PowerAppsProvider.js +176 -10
- package/lib/module/target/DefaultPowerAppsExperience.js +559 -0
- package/lib/module/target/PowerAppsExperience.js +34 -0
- package/lib/module/target/PowerAppsTargetBootstrap.js +529 -0
- package/lib/module/target/errors.js +19 -0
- package/lib/module/target/types.js +1 -0
- package/lib/typescript/commonjs/auth/AuthContext.d.ts +11 -2
- package/lib/typescript/commonjs/auth/targetAuthorization.d.ts +15 -0
- package/lib/typescript/commonjs/bridge/NativePowerAppsBridge.d.ts +6 -0
- package/lib/typescript/commonjs/bridge/setupNativeHost.d.ts +2 -0
- package/lib/typescript/commonjs/config/runtimeTenantMode.d.ts +3 -0
- package/lib/typescript/commonjs/config/runtimeTenantMode.web.d.ts +3 -0
- package/lib/typescript/commonjs/config/tenantMode.d.ts +14 -0
- package/lib/typescript/commonjs/connections/PowerPlatformConnectionApi.d.ts +5 -2
- package/lib/typescript/commonjs/connections/connectionMetadata.d.ts +1 -1
- package/lib/typescript/commonjs/connections/types.d.ts +7 -1
- package/lib/typescript/commonjs/connections/useConnectionRefs.d.ts +11 -2
- package/lib/typescript/commonjs/index.d.ts +5 -1
- package/lib/typescript/commonjs/platform/CanvasAppResolution.d.ts +4 -0
- package/lib/typescript/commonjs/platform/CanvasAppResolutionApi.d.ts +6 -0
- package/lib/typescript/commonjs/platform/DataverseGlobalDiscoveryApi.d.ts +12 -2
- package/lib/typescript/commonjs/platform/GlobalDiscovery.d.ts +12 -0
- package/lib/typescript/commonjs/provider/PowerAppsHostProvider.d.ts +9 -1
- package/lib/typescript/commonjs/provider/PowerAppsProvider.d.ts +13 -15
- package/lib/typescript/commonjs/target/DefaultPowerAppsExperience.d.ts +6 -0
- package/lib/typescript/commonjs/target/PowerAppsExperience.d.ts +61 -0
- package/lib/typescript/commonjs/target/PowerAppsTargetBootstrap.d.ts +15 -0
- package/lib/typescript/commonjs/target/errors.d.ts +13 -0
- package/lib/typescript/commonjs/target/types.d.ts +34 -0
- package/lib/typescript/module/auth/AuthContext.d.ts +11 -2
- package/lib/typescript/module/auth/targetAuthorization.d.ts +15 -0
- package/lib/typescript/module/bridge/NativePowerAppsBridge.d.ts +6 -0
- package/lib/typescript/module/bridge/setupNativeHost.d.ts +2 -0
- package/lib/typescript/module/config/runtimeTenantMode.d.ts +3 -0
- package/lib/typescript/module/config/runtimeTenantMode.web.d.ts +3 -0
- package/lib/typescript/module/config/tenantMode.d.ts +14 -0
- package/lib/typescript/module/connections/PowerPlatformConnectionApi.d.ts +5 -2
- package/lib/typescript/module/connections/connectionMetadata.d.ts +1 -1
- package/lib/typescript/module/connections/types.d.ts +7 -1
- package/lib/typescript/module/connections/useConnectionRefs.d.ts +11 -2
- package/lib/typescript/module/index.d.ts +5 -1
- package/lib/typescript/module/platform/CanvasAppResolution.d.ts +4 -0
- package/lib/typescript/module/platform/CanvasAppResolutionApi.d.ts +6 -0
- package/lib/typescript/module/platform/DataverseGlobalDiscoveryApi.d.ts +12 -2
- package/lib/typescript/module/platform/GlobalDiscovery.d.ts +12 -0
- package/lib/typescript/module/provider/PowerAppsHostProvider.d.ts +9 -1
- package/lib/typescript/module/provider/PowerAppsProvider.d.ts +13 -15
- package/lib/typescript/module/target/DefaultPowerAppsExperience.d.ts +6 -0
- package/lib/typescript/module/target/PowerAppsExperience.d.ts +61 -0
- package/lib/typescript/module/target/PowerAppsTargetBootstrap.d.ts +15 -0
- package/lib/typescript/module/target/errors.d.ts +13 -0
- package/lib/typescript/module/target/types.d.ts +34 -0
- package/package.json +12 -5
- package/scripts/build-codegen-package.js +34 -3
- package/scripts/dev.js +405 -0
- package/scripts/upgrade-authoring.js +85 -28
- package/scripts/wrap.js +42 -5
- package/src/config/generated-config.d.ts +21 -0
|
@@ -3,36 +3,43 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
exports.fetchAccessibleEnvironments = fetchAccessibleEnvironments;
|
|
7
|
+
exports.fetchInstanceMetadata = fetchInstanceMetadata;
|
|
6
8
|
exports.fetchInstanceUrl = fetchInstanceUrl;
|
|
9
|
+
var _powerAppsNativeCommon = require("@microsoft/power-apps-native-common");
|
|
7
10
|
var _http = require("@microsoft/power-apps-native-common/http");
|
|
8
11
|
var SecureStore = _interopRequireWildcard(require("expo-secure-store"));
|
|
9
12
|
var _index = require("../telemetry/index.js");
|
|
10
13
|
var _GlobalDiscovery = require("./GlobalDiscovery.js");
|
|
14
|
+
var _errors = require("../target/errors.js");
|
|
11
15
|
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.
|
|
16
|
+
const INSTANCE_URL_CACHE_KEY_PREFIX = 'microsoft.power-apps-native-host.instance-url.v3';
|
|
13
17
|
const INSTANCE_URL_CACHE_TTL_MS = 30 * 24 * 60 * 60 * 1000;
|
|
14
18
|
function getInstanceUrlCacheKey(environmentId, region) {
|
|
15
19
|
return `${INSTANCE_URL_CACHE_KEY_PREFIX}.${region.toLowerCase()}.${environmentId.toLowerCase()}`;
|
|
16
20
|
}
|
|
17
21
|
async function getCachedInstanceUrl(environmentId, region) {
|
|
18
22
|
try {
|
|
19
|
-
const
|
|
23
|
+
const cacheKey = getInstanceUrlCacheKey(environmentId, region);
|
|
24
|
+
const cachedValue = await SecureStore.getItemAsync(cacheKey);
|
|
20
25
|
if (!cachedValue) {
|
|
21
26
|
return null;
|
|
22
27
|
}
|
|
23
28
|
const entry = JSON.parse(cachedValue);
|
|
24
|
-
if (typeof entry.instanceUrl !== 'string' || typeof entry.expiresAt !== 'number' || entry.expiresAt <= Date.now()) {
|
|
29
|
+
if (typeof entry.instanceUrl !== 'string' || entry.telemetryLocation !== undefined && entry.telemetryLocation !== 'eu' && entry.telemetryLocation !== 'global' || typeof entry.expiresAt !== 'number' || entry.expiresAt <= Date.now()) {
|
|
30
|
+
await SecureStore.deleteItemAsync(cacheKey);
|
|
25
31
|
return null;
|
|
26
32
|
}
|
|
27
|
-
return entry
|
|
33
|
+
return entry;
|
|
28
34
|
} catch {
|
|
29
35
|
return null;
|
|
30
36
|
}
|
|
31
37
|
}
|
|
32
|
-
async function cacheInstanceUrl(environmentId, region, instanceUrl) {
|
|
38
|
+
async function cacheInstanceUrl(environmentId, region, instanceUrl, telemetryLocation) {
|
|
33
39
|
try {
|
|
34
40
|
const entry = {
|
|
35
41
|
instanceUrl,
|
|
42
|
+
telemetryLocation,
|
|
36
43
|
expiresAt: Date.now() + INSTANCE_URL_CACHE_TTL_MS
|
|
37
44
|
};
|
|
38
45
|
await SecureStore.setItemAsync(getInstanceUrlCacheKey(environmentId, region), JSON.stringify(entry));
|
|
@@ -44,20 +51,40 @@ function getSafeErrorName(error) {
|
|
|
44
51
|
return error instanceof Error ? error.constructor.name : typeof error;
|
|
45
52
|
}
|
|
46
53
|
|
|
47
|
-
/**
|
|
48
|
-
async function
|
|
54
|
+
/** Enumerate enabled commercial-cloud Dataverse environments available to an authenticated tenant account. */
|
|
55
|
+
async function fetchAccessibleEnvironments(tenantId, appDisplayName, appName, acquireToken) {
|
|
56
|
+
try {
|
|
57
|
+
const region = 'prod';
|
|
58
|
+
const token = await acquireToken([(0, _GlobalDiscovery.globalDiscoveryScope)(region)]);
|
|
59
|
+
if (!token) throw new Error('Global Discovery token is unavailable');
|
|
60
|
+
const response = await _index.platformHttpClient.request((0, _GlobalDiscovery.buildGlobalDiscoveryListUrl)(region), {
|
|
61
|
+
method: 'GET',
|
|
62
|
+
headers: {
|
|
63
|
+
Authorization: `Bearer ${token}`,
|
|
64
|
+
'Content-Type': 'application/json'
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
if (!response.ok) throw new Error(`Global Discovery returned ${response.status} ${response.statusText}`);
|
|
68
|
+
const result = await response.json();
|
|
69
|
+
return (0, _GlobalDiscovery.parseDiscoveredEnvironments)(Array.isArray(result.value) ? result.value : [], tenantId, appDisplayName, appName);
|
|
70
|
+
} catch (error) {
|
|
71
|
+
throw new _errors.TargetRuntimeError('discovery-failed', 'discovery', true, 'Your environments could not be loaded. Try again.', undefined, error);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/** Fetch Dataverse environment metadata from the Global Discovery Service. */
|
|
75
|
+
async function fetchInstanceMetadata(environmentId, region, acquireToken, _bearerToken) {
|
|
49
76
|
const scenario = (0, _index.getAppLogger)().trackScenario(_index.HostOperationNames.PlatformFetchInstanceUrl, {
|
|
50
77
|
environmentId,
|
|
51
78
|
region
|
|
52
79
|
});
|
|
53
80
|
try {
|
|
54
|
-
const
|
|
55
|
-
if (
|
|
81
|
+
const cachedMetadata = await getCachedInstanceUrl(environmentId, region);
|
|
82
|
+
if (cachedMetadata) {
|
|
56
83
|
scenario.complete({
|
|
57
84
|
hasInstanceUrl: true,
|
|
58
85
|
cacheHit: true
|
|
59
86
|
});
|
|
60
|
-
return
|
|
87
|
+
return cachedMetadata;
|
|
61
88
|
}
|
|
62
89
|
const url = (0, _GlobalDiscovery.buildGlobalDiscoveryUrl)(environmentId, region);
|
|
63
90
|
const token = await acquireToken([(0, _GlobalDiscovery.globalDiscoveryScope)(region)]);
|
|
@@ -75,20 +102,30 @@ async function fetchInstanceUrl(environmentId, region, acquireToken, _bearerToke
|
|
|
75
102
|
throw new Error(`fetchInstanceUrl: Global Discovery returned ${response.status} ${response.statusText}`);
|
|
76
103
|
}
|
|
77
104
|
const result = await response.json();
|
|
78
|
-
const
|
|
105
|
+
const instance = result.value?.find(instance => instance.EnvironmentId?.toLowerCase() === environmentId.toLowerCase());
|
|
106
|
+
const instanceUrl = instance?.ApiUrl;
|
|
107
|
+
const telemetryLocation = (0, _powerAppsNativeCommon.tryResolveTelemetryLocationFromDataverseRegion)(instance?.Region);
|
|
79
108
|
if (instanceUrl) {
|
|
80
|
-
await cacheInstanceUrl(environmentId, region, instanceUrl);
|
|
109
|
+
await cacheInstanceUrl(environmentId, region, instanceUrl, telemetryLocation);
|
|
81
110
|
}
|
|
82
111
|
scenario.complete({
|
|
83
112
|
hasInstanceUrl: instanceUrl !== undefined,
|
|
84
113
|
cacheHit: false,
|
|
85
114
|
...(0, _http.getHttpCorrelationProperties)(response.headers)
|
|
86
115
|
});
|
|
87
|
-
return instanceUrl
|
|
116
|
+
return instanceUrl ? {
|
|
117
|
+
instanceUrl,
|
|
118
|
+
telemetryLocation
|
|
119
|
+
} : undefined;
|
|
88
120
|
} catch (error) {
|
|
89
121
|
scenario.fail(undefined, {
|
|
90
122
|
errorName: getSafeErrorName(error)
|
|
91
123
|
});
|
|
92
124
|
throw error;
|
|
93
125
|
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** Fetch only the Dataverse instance URL for callers that do not need region metadata. */
|
|
129
|
+
async function fetchInstanceUrl(environmentId, region, acquireToken, bearerToken) {
|
|
130
|
+
return (await fetchInstanceMetadata(environmentId, region, acquireToken, bearerToken))?.instanceUrl;
|
|
94
131
|
}
|
|
@@ -3,9 +3,13 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
exports.buildGlobalDiscoveryListUrl = buildGlobalDiscoveryListUrl;
|
|
6
7
|
exports.buildGlobalDiscoveryUrl = buildGlobalDiscoveryUrl;
|
|
7
8
|
exports.globalDiscoveryEndpoint = globalDiscoveryEndpoint;
|
|
8
9
|
exports.globalDiscoveryScope = globalDiscoveryScope;
|
|
10
|
+
exports.isEnabledDiscoveryState = isEnabledDiscoveryState;
|
|
11
|
+
exports.parseDiscoveredEnvironments = parseDiscoveredEnvironments;
|
|
12
|
+
var _CanvasAppResolution = require("./CanvasAppResolution.js");
|
|
9
13
|
const GLOBAL_DISCOVERY_HOST = {
|
|
10
14
|
prod: 'globaldisco.crm.dynamics.com',
|
|
11
15
|
gcc: 'globaldisco.crm9.dynamics.com',
|
|
@@ -28,6 +32,35 @@ const REGION_DISCOVERY_CLOUD = {
|
|
|
28
32
|
mooncake: 'china'
|
|
29
33
|
};
|
|
30
34
|
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;
|
|
35
|
+
function isEnabledDiscoveryState(state) {
|
|
36
|
+
return state === 0 || typeof state === 'string' && (state === '0' || state.toLowerCase() === 'enabled');
|
|
37
|
+
}
|
|
38
|
+
function parseDiscoveredEnvironments(instances, tenantId, appDisplayName, appName) {
|
|
39
|
+
const normalizedTenantId = tenantId.trim().toLowerCase();
|
|
40
|
+
const environments = new Map();
|
|
41
|
+
for (const instance of instances) {
|
|
42
|
+
if (!isEnabledDiscoveryState(instance.State) || typeof instance.EnvironmentId !== 'string' || !ENVIRONMENT_ID_PATTERN.test(instance.EnvironmentId) || typeof instance.TenantId !== 'string' || instance.TenantId.toLowerCase() !== normalizedTenantId || typeof instance.ApiUrl !== 'string') continue;
|
|
43
|
+
const environmentId = instance.EnvironmentId.toLowerCase();
|
|
44
|
+
try {
|
|
45
|
+
const dataverseApiUrl = (0, _CanvasAppResolution.canonicalizeDataverseOrigin)(instance.ApiUrl);
|
|
46
|
+
if (environments.has(environmentId)) continue;
|
|
47
|
+
environments.set(environmentId, {
|
|
48
|
+
id: environmentId,
|
|
49
|
+
label: typeof instance.FriendlyName === 'string' && instance.FriendlyName.trim() ? instance.FriendlyName.trim() : environmentId,
|
|
50
|
+
tenantId: normalizedTenantId,
|
|
51
|
+
environmentId,
|
|
52
|
+
appDisplayName,
|
|
53
|
+
appName,
|
|
54
|
+
region: 'prod',
|
|
55
|
+
cloud: 'commercial',
|
|
56
|
+
dataverseApiUrl
|
|
57
|
+
});
|
|
58
|
+
} catch {
|
|
59
|
+
// Ignore records with untrusted or malformed API origins.
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return [...environments.values()].sort((left, right) => left.label.localeCompare(right.label));
|
|
63
|
+
}
|
|
31
64
|
function globalDiscoveryEndpoint(region) {
|
|
32
65
|
const cloud = REGION_DISCOVERY_CLOUD[region];
|
|
33
66
|
if (!cloud) {
|
|
@@ -44,8 +77,14 @@ function buildGlobalDiscoveryUrl(environmentId, region) {
|
|
|
44
77
|
}
|
|
45
78
|
const normalizedEnvironmentId = environmentId.toLowerCase();
|
|
46
79
|
const query = new URLSearchParams({
|
|
47
|
-
'$select': 'ApiUrl,EnvironmentId',
|
|
80
|
+
'$select': 'ApiUrl,EnvironmentId,Region',
|
|
48
81
|
'$filter': `EnvironmentId eq '${normalizedEnvironmentId}'`
|
|
49
82
|
});
|
|
50
83
|
return `${globalDiscoveryEndpoint(region)}/api/discovery/v2.0/Instances?${query.toString()}`;
|
|
84
|
+
}
|
|
85
|
+
function buildGlobalDiscoveryListUrl(region) {
|
|
86
|
+
const query = new URLSearchParams({
|
|
87
|
+
'$select': 'ApiUrl,EnvironmentId,FriendlyName,Region,State,TenantId'
|
|
88
|
+
});
|
|
89
|
+
return `${globalDiscoveryEndpoint(region)}/api/discovery/v2.0/Instances?${query.toString()}`;
|
|
51
90
|
}
|
|
@@ -19,6 +19,7 @@ var _connectionState = require("../connections/connectionState.js");
|
|
|
19
19
|
var _isDevPlayer = require("../utils/isDevPlayer.js");
|
|
20
20
|
var _logger = require("../logger.js");
|
|
21
21
|
var _index = require("../telemetry/index.js");
|
|
22
|
+
var _CanvasAppResolution = require("../platform/CanvasAppResolution.js");
|
|
22
23
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
23
24
|
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); }
|
|
24
25
|
/*!
|
|
@@ -73,6 +74,12 @@ function PowerAppsHostProvider({
|
|
|
73
74
|
databaseReferences,
|
|
74
75
|
renderOAuthWebView,
|
|
75
76
|
isvClientId,
|
|
77
|
+
onTelemetryLocationResolved,
|
|
78
|
+
targetGeneration,
|
|
79
|
+
targetTenantId,
|
|
80
|
+
targetAppName,
|
|
81
|
+
targetAccountIdentifier,
|
|
82
|
+
expectedDataverseOrigin,
|
|
76
83
|
onDisambiguationNeeded,
|
|
77
84
|
onConnectionConsent,
|
|
78
85
|
onResourceConsent,
|
|
@@ -153,7 +160,14 @@ function PowerAppsHostProvider({
|
|
|
153
160
|
hasDataverse: (0, _DataverseDataSources.hasDataverseDatabaseReferences)(databaseReferences),
|
|
154
161
|
schemaMap,
|
|
155
162
|
onDisambiguationNeeded,
|
|
156
|
-
isvClientId
|
|
163
|
+
isvClientId,
|
|
164
|
+
onTelemetryLocationResolved,
|
|
165
|
+
targetIdentity: targetGeneration !== undefined && targetTenantId && targetAppName && targetAccountIdentifier ? {
|
|
166
|
+
tenantId: targetTenantId,
|
|
167
|
+
appName: targetAppName,
|
|
168
|
+
generation: targetGeneration,
|
|
169
|
+
accountIdentifier: targetAccountIdentifier
|
|
170
|
+
} : undefined
|
|
157
171
|
});
|
|
158
172
|
|
|
159
173
|
// Reset setup gate when the user signs out.
|
|
@@ -185,8 +199,24 @@ function PowerAppsHostProvider({
|
|
|
185
199
|
// Build the missing-connector entries for ConnectionSetupScreen.
|
|
186
200
|
const missingEntries = (0, _react.useMemo)(() => missingConnectionReferences, [missingConnectionReferences]);
|
|
187
201
|
const resourceConsents = (0, _react.useMemo)(() => [...new Map(launchResourceConsents.map(resource => [resource.resourceId.toLowerCase(), resource])).values()], [launchResourceConsents]);
|
|
188
|
-
const currentConfigKey = (0, _react.useMemo)(() => (0, _types.buildConnectionResolutionKey)(appId, environmentId, _isDevPlayer.isDevPlayer ? connectionReferences : {}
|
|
202
|
+
const currentConfigKey = (0, _react.useMemo)(() => (0, _types.buildConnectionResolutionKey)(appId, environmentId, _isDevPlayer.isDevPlayer ? connectionReferences : {}, targetGeneration !== undefined ? {
|
|
203
|
+
tenantId: targetTenantId,
|
|
204
|
+
appName: targetAppName,
|
|
205
|
+
region,
|
|
206
|
+
generation: targetGeneration,
|
|
207
|
+
accountIdentifier: targetAccountIdentifier
|
|
208
|
+
} : undefined), [appId, environmentId, connectionReferences, _isDevPlayer.isDevPlayer, region, targetAccountIdentifier, targetAppName, targetGeneration, targetTenantId]);
|
|
189
209
|
const resolutionMatchesCurrentConfig = resolvedConfigKey === currentConfigKey;
|
|
210
|
+
const launchTargetMismatch = (() => {
|
|
211
|
+
if (!expectedDataverseOrigin) return false;
|
|
212
|
+
if (!isReady || !resolutionMatchesCurrentConfig) return false;
|
|
213
|
+
if (!dataverseOrgUrl) return true;
|
|
214
|
+
try {
|
|
215
|
+
return !(0, _CanvasAppResolution.areDataverseOriginAliases)(expectedDataverseOrigin, dataverseOrgUrl);
|
|
216
|
+
} catch {
|
|
217
|
+
return true;
|
|
218
|
+
}
|
|
219
|
+
})();
|
|
190
220
|
const needsConsent = (0, _connectionState.shouldShowConnectionReview)(_isDevPlayer.isDevPlayer, requiresConnectionConsent, resourceConsents.length > 0);
|
|
191
221
|
|
|
192
222
|
// Called by ConnectionSetupScreen once every missing connector is resolved.
|
|
@@ -260,17 +290,21 @@ function PowerAppsHostProvider({
|
|
|
260
290
|
connectionRefsRef.current = connectionRefs;
|
|
261
291
|
const configuredBridgeInputsRef = (0, _react.useRef)(undefined);
|
|
262
292
|
const [, setBridgeRegistrationVersion] = (0, _react.useState)(0);
|
|
263
|
-
const hasResolvedConnections = isSignedIn && isReady && resolutionMatchesCurrentConfig && (missingConnectors.length === 0 || consentApproved) && (!needsConsent || consentApproved);
|
|
293
|
+
const hasResolvedConnections = isSignedIn && isReady && resolutionMatchesCurrentConfig && !launchTargetMismatch && (missingConnectors.length === 0 || consentApproved) && (!needsConsent || consentApproved);
|
|
264
294
|
const isBridgeConfiguredFor = (connections, dataSources) => {
|
|
265
295
|
const currentInputs = configuredBridgeInputsRef.current;
|
|
266
|
-
|
|
296
|
+
const runtimeIdentity = targetGeneration === undefined ? undefined : `${targetGeneration}:${targetAccountIdentifier ?? ''}`;
|
|
297
|
+
return currentInputs?.connections === connections && currentInputs.dataSources === dataSources && currentInputs.runtimeIdentity === runtimeIdentity;
|
|
267
298
|
};
|
|
268
299
|
const configureBridgeNow = (0, _react.useCallback)((connections, dataSources) => {
|
|
269
300
|
const previousInputs = configuredBridgeInputsRef.current;
|
|
270
|
-
const
|
|
301
|
+
const runtimeIdentity = targetGeneration === undefined ? undefined : `${targetGeneration}:${targetAccountIdentifier ?? ''}`;
|
|
302
|
+
const shouldConfigureBridge = !previousInputs || previousInputs.connections !== connections || previousInputs.dataSources !== dataSources || previousInputs.runtimeIdentity !== runtimeIdentity;
|
|
271
303
|
if (!shouldConfigureBridge) return;
|
|
272
304
|
(0, _logger.debugLog)(`[PAHost] setupNativeHost: isReady=${isReady} missingConnectors=${missingConnectors.length} setupDone=${setupDone} connections=${Object.keys(connections).join(', ') || '(none)'}`);
|
|
273
305
|
(0, _setupNativeHost.setupNativeHost)({
|
|
306
|
+
targetGeneration,
|
|
307
|
+
runtimeIdentity,
|
|
274
308
|
getConnectorToken: async _apiId => {
|
|
275
309
|
(0, _logger.debugLog)(`[PAHost] getConnectorToken: acquiring token for apiId="${_apiId}"`);
|
|
276
310
|
let token;
|
|
@@ -327,11 +361,12 @@ function PowerAppsHostProvider({
|
|
|
327
361
|
});
|
|
328
362
|
configuredBridgeInputsRef.current = {
|
|
329
363
|
connections,
|
|
330
|
-
dataSources
|
|
364
|
+
dataSources,
|
|
365
|
+
runtimeIdentity
|
|
331
366
|
};
|
|
332
367
|
setBridgeRegistrationVersion(version => version + 1);
|
|
333
368
|
(0, _logger.debugLog)('[PAHost] bridge registered');
|
|
334
|
-
}, [isReady, missingConnectors.length, setupDone]);
|
|
369
|
+
}, [isReady, missingConnectors.length, setupDone, targetAccountIdentifier, targetGeneration]);
|
|
335
370
|
const staticBridgeRegistered = isBridgeConfiguredFor(staticConnectionRefs, cdsDataSources);
|
|
336
371
|
const resolvedBridgeRegistered = hasResolvedConnections && isBridgeConfiguredFor(mergedRefs, cdsDataSources);
|
|
337
372
|
|
|
@@ -369,7 +404,11 @@ function PowerAppsHostProvider({
|
|
|
369
404
|
|
|
370
405
|
if (connectionError) {
|
|
371
406
|
const accessDenied = connectionErrorKind === 'app-access-denied';
|
|
372
|
-
|
|
407
|
+
const appNotFound = connectionErrorKind === 'app-not-found';
|
|
408
|
+
return renderConnectionError(accessDenied ? 'You don’t have access' : appNotFound ? 'App not found' : 'Unable to load app', [connectionError], accessDenied);
|
|
409
|
+
}
|
|
410
|
+
if (launchTargetMismatch) {
|
|
411
|
+
return renderConnectionError('Environment mismatch', ['The app launch response does not match the selected environment. Return to environment selection and try again.']);
|
|
373
412
|
}
|
|
374
413
|
if (configurationErrors.length > 0) {
|
|
375
414
|
return renderConnectionError('Connection configuration error', configurationErrors);
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.PowerAppsProvider = PowerAppsProvider;
|
|
7
|
+
var _CanvasAppResolution = require("../platform/CanvasAppResolution.js");
|
|
7
8
|
var _react = _interopRequireWildcard(require("react"));
|
|
8
9
|
var _reactNative = require("react-native");
|
|
9
10
|
var _reactNativeGestureHandler = require("react-native-gesture-handler");
|
|
@@ -26,6 +27,12 @@ var _createOfflineHostActivationCallbacks = require("../offline/createOfflineHos
|
|
|
26
27
|
var _useOfflineIntegrationWithStartupGate = require("../offline/useOfflineIntegrationWithStartupGate");
|
|
27
28
|
var _SessionDetailsGesture = require("./SessionDetailsGesture.js");
|
|
28
29
|
var _OfflineSdkTelemetry = require("../telemetry/OfflineSdkTelemetry");
|
|
30
|
+
var _setupNativeHost = require("../bridge/setupNativeHost.js");
|
|
31
|
+
var _errors = require("../target/errors.js");
|
|
32
|
+
var _GlobalDiscovery = require("../platform/GlobalDiscovery.js");
|
|
33
|
+
var _tenantMode = require("../config/tenantMode.js");
|
|
34
|
+
var _runtimeTenantMode = require("../config/runtimeTenantMode");
|
|
35
|
+
var _PowerAppsTargetBootstrap = require("../target/PowerAppsTargetBootstrap.js");
|
|
29
36
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
30
37
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
31
38
|
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); }
|
|
@@ -57,7 +64,6 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
|
|
|
57
64
|
*/
|
|
58
65
|
|
|
59
66
|
(0, _powerAppsNativeCommon.suppressKnownWarnings)();
|
|
60
|
-
|
|
61
67
|
// ---- React-Query wiring (runs once at module load) ----
|
|
62
68
|
|
|
63
69
|
// Wire onlineManager to NetInfo so refetchOnReconnect fires on mobile
|
|
@@ -90,6 +96,7 @@ _reactQuery.focusManager.setEventListener(handleFocus => {
|
|
|
90
96
|
// The bare @tamagui/config/v5 preset is only a last-resort fallback for tests
|
|
91
97
|
// and storybook — it will not resolve custom $surface* tokens.
|
|
92
98
|
const defaultTamaguiConfig = (0, _core.createTamagui)(_v.defaultConfig);
|
|
99
|
+
const EMPTY_TARGET_CONNECTION_REFERENCES = {};
|
|
93
100
|
function hasConfiguredValue(value) {
|
|
94
101
|
return typeof value === 'string' && value.trim().length > 0;
|
|
95
102
|
}
|
|
@@ -170,6 +177,65 @@ function readAppInsightsConfig(value) {
|
|
|
170
177
|
// Separate from PowerAppsProvider only because useAuth() must be called inside
|
|
171
178
|
// AuthProvider. All auth-dependent wiring lives here.
|
|
172
179
|
|
|
180
|
+
function TargetInnerProviders({
|
|
181
|
+
target,
|
|
182
|
+
authSession,
|
|
183
|
+
connectionReferences,
|
|
184
|
+
databaseReferences,
|
|
185
|
+
schemaMap,
|
|
186
|
+
renderOAuthWebView,
|
|
187
|
+
onDisambiguationNeeded,
|
|
188
|
+
onConnectionConsent,
|
|
189
|
+
onResourceConsent,
|
|
190
|
+
onConnectionConsentDeclined,
|
|
191
|
+
children
|
|
192
|
+
}) {
|
|
193
|
+
if (authSession.accountTenantId.toLowerCase() !== target.tenantId.toLowerCase()) {
|
|
194
|
+
throw new _errors.TargetRuntimeError('tenant-mismatch', 'authentication', true, 'Sign in with an account that can access the selected environment tenant.', target.id);
|
|
195
|
+
}
|
|
196
|
+
const acquireToken = async scopes => {
|
|
197
|
+
if (scopes.length !== 1) throw new Error('Target token requests must use one audience');
|
|
198
|
+
const scope = scopes[0];
|
|
199
|
+
if (scope === 'https://apihub.azure.com/.default') return authSession.tokenBroker.acquireApiHubToken();
|
|
200
|
+
if (scope === (0, _PowerPlatformEnvironmentApi.powerPlatformScope)(target.region)) return authSession.tokenBroker.acquirePowerPlatformToken(target.region);
|
|
201
|
+
if (scope === (0, _PowerPlatformEnvironmentApi.connectionUserConsentScope)(target.region)) return authSession.tokenBroker.acquireConnectionUserConsentToken(target.region);
|
|
202
|
+
if (scope === (0, _GlobalDiscovery.globalDiscoveryScope)(target.region)) return authSession.tokenBroker.acquireGlobalDiscoveryToken();
|
|
203
|
+
const dataverseSuffix = ['/user_impersonation', '/.default'].find(suffix => scope.endsWith(suffix));
|
|
204
|
+
if (dataverseSuffix) {
|
|
205
|
+
const requestedOrigin = scope.slice(0, -dataverseSuffix.length);
|
|
206
|
+
if ((0, _CanvasAppResolution.areDataverseOriginAliases)(requestedOrigin, target.dataverseApiUrl)) {
|
|
207
|
+
return authSession.tokenBroker.acquireDataverseToken(requestedOrigin);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
throw new Error(`Unsupported target token audience: ${scope}`);
|
|
211
|
+
};
|
|
212
|
+
(0, _react.useEffect)(() => {
|
|
213
|
+
return () => (0, _setupNativeHost.invalidateNativeHostRuntime)();
|
|
214
|
+
}, [authSession.accountIdentifier, authSession.generation]);
|
|
215
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_PowerAppsHostProvider.PowerAppsHostProvider, {
|
|
216
|
+
acquireToken: acquireToken,
|
|
217
|
+
isSignedIn: true,
|
|
218
|
+
onSignOut: authSession.signOut,
|
|
219
|
+
appId: target.appId,
|
|
220
|
+
environmentId: target.environmentId,
|
|
221
|
+
region: target.region,
|
|
222
|
+
connectionReferences: connectionReferences,
|
|
223
|
+
schemaMap: schemaMap,
|
|
224
|
+
databaseReferences: databaseReferences,
|
|
225
|
+
isvClientId: authSession.clientId,
|
|
226
|
+
targetGeneration: authSession.generation,
|
|
227
|
+
targetTenantId: target.tenantId,
|
|
228
|
+
targetAppName: target.appName,
|
|
229
|
+
targetAccountIdentifier: authSession.accountIdentifier,
|
|
230
|
+
expectedDataverseOrigin: target.dataverseApiUrl,
|
|
231
|
+
renderOAuthWebView: renderOAuthWebView,
|
|
232
|
+
onDisambiguationNeeded: onDisambiguationNeeded,
|
|
233
|
+
onConnectionConsent: onConnectionConsent,
|
|
234
|
+
onResourceConsent: onResourceConsent,
|
|
235
|
+
onConnectionConsentDeclined: onConnectionConsentDeclined,
|
|
236
|
+
children: children
|
|
237
|
+
});
|
|
238
|
+
}
|
|
173
239
|
function InnerProviders({
|
|
174
240
|
msalConfig,
|
|
175
241
|
powerConfig,
|
|
@@ -181,6 +247,7 @@ function InnerProviders({
|
|
|
181
247
|
onConnectionConsentDeclined,
|
|
182
248
|
offlineProfile,
|
|
183
249
|
onOfflineEnabledChange,
|
|
250
|
+
onTelemetryLocationResolved,
|
|
184
251
|
children
|
|
185
252
|
}) {
|
|
186
253
|
const {
|
|
@@ -218,6 +285,7 @@ function InnerProviders({
|
|
|
218
285
|
onConnectionConsent: onConnectionConsent,
|
|
219
286
|
onResourceConsent: onResourceConsent,
|
|
220
287
|
onConnectionConsentDeclined: onConnectionConsentDeclined,
|
|
288
|
+
onTelemetryLocationResolved: onTelemetryLocationResolved,
|
|
221
289
|
children: [offline.shouldMountChildren && children, offline.StatusOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(offline.StatusOverlay, {})]
|
|
222
290
|
});
|
|
223
291
|
}
|
|
@@ -233,9 +301,70 @@ function InnerProviders({
|
|
|
233
301
|
* root layout.
|
|
234
302
|
*/
|
|
235
303
|
function PowerAppsProvider({
|
|
304
|
+
...props
|
|
305
|
+
}) {
|
|
306
|
+
const {
|
|
307
|
+
appConfig,
|
|
308
|
+
msalConfig,
|
|
309
|
+
intuneConfig,
|
|
310
|
+
powerConfig,
|
|
311
|
+
schemaMap,
|
|
312
|
+
offlineProfile,
|
|
313
|
+
multiTenantExperience,
|
|
314
|
+
children,
|
|
315
|
+
...commonProps
|
|
316
|
+
} = props;
|
|
317
|
+
const effectiveAppConfig = appConfig ?? {
|
|
318
|
+
expo: _expoConstants.default.expoConfig
|
|
319
|
+
};
|
|
320
|
+
const tenantMode = (0, _tenantMode.resolveTenantMode)(effectiveAppConfig);
|
|
321
|
+
(0, _runtimeTenantMode.assertNativeTenantMode)(tenantMode);
|
|
322
|
+
if (tenantMode === 'multi') {
|
|
323
|
+
const multiTenantConfig = (0, _tenantMode.resolveMultiTenantConfig)(effectiveAppConfig);
|
|
324
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_PowerAppsTargetBootstrap.PowerAppsTargetBootstrap, {
|
|
325
|
+
msalConfig: msalConfig,
|
|
326
|
+
appDisplayName: multiTenantConfig.appDisplayName,
|
|
327
|
+
appName: multiTenantConfig.appName,
|
|
328
|
+
tenantPolicy: multiTenantConfig.tenantPolicy,
|
|
329
|
+
experienceComponent: multiTenantExperience,
|
|
330
|
+
children: (resolvedTarget, authSession) => /*#__PURE__*/(0, _jsxRuntime.jsx)(PowerAppsRuntimeProvider, {
|
|
331
|
+
...commonProps,
|
|
332
|
+
appName: commonProps.appName ?? multiTenantConfig.appDisplayName,
|
|
333
|
+
appConfig: appConfig,
|
|
334
|
+
resolvedTarget: resolvedTarget,
|
|
335
|
+
authSession: authSession,
|
|
336
|
+
targetGeneration: authSession.generation,
|
|
337
|
+
powerConfig: {
|
|
338
|
+
appId: resolvedTarget.appId,
|
|
339
|
+
environmentId: resolvedTarget.environmentId,
|
|
340
|
+
region: resolvedTarget.region,
|
|
341
|
+
geoRegion: powerConfig.geoRegion,
|
|
342
|
+
connectionReferences: _isDevPlayer.isDevPlayer ? powerConfig.connectionReferences ?? {} : {},
|
|
343
|
+
databaseReferences: _isDevPlayer.isDevPlayer ? powerConfig.databaseReferences ?? {} : {}
|
|
344
|
+
},
|
|
345
|
+
schemaMap: _isDevPlayer.isDevPlayer ? schemaMap : {},
|
|
346
|
+
children: children
|
|
347
|
+
})
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(PowerAppsRuntimeProvider, {
|
|
351
|
+
...commonProps,
|
|
352
|
+
appConfig: appConfig,
|
|
353
|
+
msalConfig: msalConfig,
|
|
354
|
+
intuneConfig: intuneConfig,
|
|
355
|
+
powerConfig: powerConfig,
|
|
356
|
+
schemaMap: schemaMap,
|
|
357
|
+
offlineProfile: offlineProfile,
|
|
358
|
+
children: children
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
function PowerAppsRuntimeProvider({
|
|
236
362
|
appConfig,
|
|
237
363
|
msalConfig,
|
|
238
364
|
intuneConfig,
|
|
365
|
+
resolvedTarget,
|
|
366
|
+
authSession,
|
|
367
|
+
targetGeneration,
|
|
239
368
|
powerConfig,
|
|
240
369
|
schemaMap,
|
|
241
370
|
tamaguiConfig = defaultTamaguiConfig,
|
|
@@ -257,13 +386,31 @@ function PowerAppsProvider({
|
|
|
257
386
|
offlineProfile,
|
|
258
387
|
children
|
|
259
388
|
}) {
|
|
389
|
+
const targetAware = resolvedTarget !== undefined;
|
|
390
|
+
if (targetAware) {
|
|
391
|
+
if (!authSession || targetGeneration !== authSession.generation) {
|
|
392
|
+
throw new _errors.TargetRuntimeError('stale-operation', 'switching', false, 'The selected environment changed.');
|
|
393
|
+
}
|
|
394
|
+
if (offlineProfile) {
|
|
395
|
+
throw new _errors.TargetRuntimeError('offline-switch-unsupported', 'configuration', false, 'Offline mode is not available when switching environments.', resolvedTarget.id);
|
|
396
|
+
}
|
|
397
|
+
if (powerConfig.appId && powerConfig.appId.toLowerCase() !== resolvedTarget.appId.toLowerCase() || powerConfig.environmentId && powerConfig.environmentId.toLowerCase() !== resolvedTarget.environmentId.toLowerCase() || powerConfig.region && powerConfig.region.toLowerCase() !== resolvedTarget.region.toLowerCase()) {
|
|
398
|
+
throw new _errors.TargetRuntimeError('invalid-build-config', 'configuration', false, 'The selected environment does not match the packaged app configuration.', resolvedTarget.id);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
260
401
|
// Capture the logger-prop identity at mount time so the effect dep array
|
|
261
402
|
// is stable (loggerProp is an object reference; re-running on every render
|
|
262
403
|
// would reconfigure and leak the previous provider).
|
|
263
404
|
const loggerPropRef = (0, _react.useRef)(loggerProp);
|
|
264
405
|
const appInsightsConfigRef = (0, _react.useRef)(appInsightsConfig ?? readAppInsightsConfig(appConfig?.expo?.extra?.appInsightsConfig ?? _expoConstants.default.expoConfig?.extra?.appInsightsConfig));
|
|
265
406
|
const [offlineTelemetryEnabled, setOfflineTelemetryEnabled] = (0, _react.useState)();
|
|
266
|
-
const
|
|
407
|
+
const oneDsProviderRef = (0, _react.useRef)(undefined);
|
|
408
|
+
const resolvedTelemetryLocationRef = (0, _react.useRef)(undefined);
|
|
409
|
+
const handleTelemetryLocationResolved = (0, _react.useCallback)(location => {
|
|
410
|
+
resolvedTelemetryLocationRef.current = location;
|
|
411
|
+
void oneDsProviderRef.current?.resolveTelemetryLocation(location);
|
|
412
|
+
}, []);
|
|
413
|
+
const missingClientIdInDevPlayer = !targetAware && _reactNative.Platform.OS !== 'web' && _isDevPlayer.isDevPlayer && !hasConfiguredValue(msalConfig?.clientId) && requiresPowerPlatformAuth(powerConfig);
|
|
267
414
|
const missingAppId = _reactNative.Platform.OS !== 'web' && !_isDevPlayer.isDevPlayer && !hasConfiguredValue(powerConfig.appId);
|
|
268
415
|
const missingEnvironmentId = !_isDevPlayer.isDevPlayer && !hasConfiguredValue(powerConfig.environmentId);
|
|
269
416
|
const appId = typeof powerConfig.appId === 'string' ? powerConfig.appId.trim() : '';
|
|
@@ -273,7 +420,7 @@ function PowerAppsProvider({
|
|
|
273
420
|
const skillCorrelationId = typeof appInstanceId === 'string' ? appInstanceId.trim() : '';
|
|
274
421
|
const sessionDetailsGestureEnabled = showSessionDetailsOnLongPress ?? showSessionDetailsOnSwipe ?? true;
|
|
275
422
|
const requiredAuthScopes = (0, _react.useMemo)(() => [(0, _PowerPlatformEnvironmentApi.powerPlatformScope)(powerConfig.region ?? 'prod')], [powerConfig.region]);
|
|
276
|
-
const queryClient = (0, _react.useMemo)(() => (0, _createOfflineHostActivationCallbacks.createHostQueryClient)(), []);
|
|
423
|
+
const queryClient = (0, _react.useMemo)(() => (0, _createOfflineHostActivationCallbacks.createHostQueryClient)(), [targetGeneration, authSession?.accountIdentifier]);
|
|
277
424
|
|
|
278
425
|
// Configure the app logger exactly once per mount inside useEffect so that
|
|
279
426
|
// side effects (provider construction, async resolveDeviceId) never run
|
|
@@ -299,7 +446,9 @@ function PowerAppsProvider({
|
|
|
299
446
|
clientType: appName ?? 'PowerAppsNative',
|
|
300
447
|
appVersion: _expoConstants.default.expoConfig?.version,
|
|
301
448
|
minSeverity: __DEV__ ? 'verbose' : 'info',
|
|
302
|
-
|
|
449
|
+
// Existing host inputs and API responses do not expose authoritative
|
|
450
|
+
// geography for every app. Keep public-cloud telemetry in EU rather
|
|
451
|
+
// than infer residency from an opaque ID or a service endpoint URL.
|
|
303
452
|
commonProperties: {
|
|
304
453
|
...(appId ? {
|
|
305
454
|
appId
|
|
@@ -313,10 +462,14 @@ function PowerAppsProvider({
|
|
|
313
462
|
}
|
|
314
463
|
};
|
|
315
464
|
const configureDefaultLogger = (deviceId = 'react-native') => {
|
|
465
|
+
const resolvedTelemetryLocation = resolvedTelemetryLocationRef.current;
|
|
316
466
|
const oneDsProvider = new _powerAppsNativeCommon.OneDsTelemetryProvider({
|
|
317
467
|
...providerConfig,
|
|
318
|
-
deviceId
|
|
468
|
+
deviceId,
|
|
469
|
+
telemetryLocation: resolvedTelemetryLocation ?? 'eu',
|
|
470
|
+
anonymous: !resolvedTelemetryLocation
|
|
319
471
|
});
|
|
472
|
+
oneDsProviderRef.current = oneDsProvider;
|
|
320
473
|
const providers = [oneDsProvider];
|
|
321
474
|
let appInsightsEnabled = false;
|
|
322
475
|
const configuredAppInsights = appInsightsConfigRef.current;
|
|
@@ -399,7 +552,19 @@ function PowerAppsProvider({
|
|
|
399
552
|
appVersion: _expoConstants.default.expoConfig?.version,
|
|
400
553
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactQuery.QueryClientProvider, {
|
|
401
554
|
client: queryClient,
|
|
402
|
-
children: missingAppId ? /*#__PURE__*/(0, _jsxRuntime.jsx)(MissingAppIdErrorScreen, {}) : missingEnvironmentId ? /*#__PURE__*/(0, _jsxRuntime.jsx)(MissingEnvironmentIdErrorScreen, {}) : missingClientIdInDevPlayer ? /*#__PURE__*/(0, _jsxRuntime.jsx)(MissingClientIdErrorScreen, {}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
555
|
+
children: missingAppId ? /*#__PURE__*/(0, _jsxRuntime.jsx)(MissingAppIdErrorScreen, {}) : missingEnvironmentId ? /*#__PURE__*/(0, _jsxRuntime.jsx)(MissingEnvironmentIdErrorScreen, {}) : missingClientIdInDevPlayer ? /*#__PURE__*/(0, _jsxRuntime.jsx)(MissingClientIdErrorScreen, {}) : targetAware && authSession ? /*#__PURE__*/(0, _jsxRuntime.jsx)(TargetInnerProviders, {
|
|
556
|
+
target: resolvedTarget,
|
|
557
|
+
authSession: authSession,
|
|
558
|
+
connectionReferences: powerConfig.connectionReferences ?? EMPTY_TARGET_CONNECTION_REFERENCES,
|
|
559
|
+
databaseReferences: powerConfig.databaseReferences,
|
|
560
|
+
schemaMap: schemaMap,
|
|
561
|
+
renderOAuthWebView: renderOAuthWebView,
|
|
562
|
+
onDisambiguationNeeded: onDisambiguationNeeded,
|
|
563
|
+
onConnectionConsent: onConnectionConsent,
|
|
564
|
+
onResourceConsent: onResourceConsent,
|
|
565
|
+
onConnectionConsentDeclined: onConnectionConsentDeclined,
|
|
566
|
+
children: children
|
|
567
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_AuthContext.AuthProvider, {
|
|
403
568
|
msalConfig: msalConfig,
|
|
404
569
|
intuneConfig: intuneConfig,
|
|
405
570
|
requiredScopes: requiredAuthScopes,
|
|
@@ -414,6 +579,7 @@ function PowerAppsProvider({
|
|
|
414
579
|
onConnectionConsentDeclined: onConnectionConsentDeclined,
|
|
415
580
|
offlineProfile: offlineProfile,
|
|
416
581
|
onOfflineEnabledChange: setOfflineTelemetryEnabled,
|
|
582
|
+
onTelemetryLocationResolved: handleTelemetryLocationResolved,
|
|
417
583
|
children: children
|
|
418
584
|
})
|
|
419
585
|
})
|