@microsoft/power-apps-native-host 0.2.22

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 (104) hide show
  1. package/LICENSE +112 -0
  2. package/README.md +59 -0
  3. package/app.plugin.js +4 -0
  4. package/lib/NOTICE.txt +1659 -0
  5. package/lib/commonjs/ErrorBoundary.js +128 -0
  6. package/lib/commonjs/auth/AuthContext.js +281 -0
  7. package/lib/commonjs/bridge/NativePowerAppsBridge.js +279 -0
  8. package/lib/commonjs/bridge/setupNativeHost.js +65 -0
  9. package/lib/commonjs/connections/ConnectionSetupScreen.js +531 -0
  10. package/lib/commonjs/connections/disambiguate.js +88 -0
  11. package/lib/commonjs/connections/types.js +58 -0
  12. package/lib/commonjs/connections/useConnectionSetup.js +236 -0
  13. package/lib/commonjs/controls/FilePicker.js +183 -0
  14. package/lib/commonjs/controls/ImagePicker.js +236 -0
  15. package/lib/commonjs/index.js +246 -0
  16. package/lib/commonjs/logger.js +27 -0
  17. package/lib/commonjs/package.json +1 -0
  18. package/lib/commonjs/platform/PowerPlatformConnectionApi.js +606 -0
  19. package/lib/commonjs/platform/PowerPlatformEnvironmentApi.js +194 -0
  20. package/lib/commonjs/platform/resolveConnections.js +264 -0
  21. package/lib/commonjs/platform/useConnectionRefs.js +270 -0
  22. package/lib/commonjs/provider/PowerAppsHostProvider.js +336 -0
  23. package/lib/commonjs/provider/PowerAppsProvider.js +351 -0
  24. package/lib/commonjs/telemetry/index.js +70 -0
  25. package/lib/commonjs/theme/ThemeProvider.js +80 -0
  26. package/lib/commonjs/theme/tokens.js +50 -0
  27. package/lib/commonjs/utils/dataverseUtils.js +98 -0
  28. package/lib/commonjs/utils/isDevPlayer.js +27 -0
  29. package/lib/module/ErrorBoundary.js +122 -0
  30. package/lib/module/auth/AuthContext.js +276 -0
  31. package/lib/module/bridge/NativePowerAppsBridge.js +273 -0
  32. package/lib/module/bridge/setupNativeHost.js +62 -0
  33. package/lib/module/connections/ConnectionSetupScreen.js +526 -0
  34. package/lib/module/connections/disambiguate.js +83 -0
  35. package/lib/module/connections/types.js +60 -0
  36. package/lib/module/connections/useConnectionSetup.js +233 -0
  37. package/lib/module/controls/FilePicker.js +178 -0
  38. package/lib/module/controls/ImagePicker.js +231 -0
  39. package/lib/module/index.js +41 -0
  40. package/lib/module/logger.js +22 -0
  41. package/lib/module/package.json +1 -0
  42. package/lib/module/platform/PowerPlatformConnectionApi.js +595 -0
  43. package/lib/module/platform/PowerPlatformEnvironmentApi.js +186 -0
  44. package/lib/module/platform/resolveConnections.js +259 -0
  45. package/lib/module/platform/useConnectionRefs.js +267 -0
  46. package/lib/module/provider/PowerAppsHostProvider.js +332 -0
  47. package/lib/module/provider/PowerAppsProvider.js +345 -0
  48. package/lib/module/telemetry/index.js +55 -0
  49. package/lib/module/theme/ThemeProvider.js +63 -0
  50. package/lib/module/theme/tokens.js +46 -0
  51. package/lib/module/utils/dataverseUtils.js +90 -0
  52. package/lib/module/utils/isDevPlayer.js +23 -0
  53. package/lib/typescript/commonjs/ErrorBoundary.d.ts +30 -0
  54. package/lib/typescript/commonjs/auth/AuthContext.d.ts +57 -0
  55. package/lib/typescript/commonjs/bridge/NativePowerAppsBridge.d.ts +112 -0
  56. package/lib/typescript/commonjs/bridge/setupNativeHost.d.ts +39 -0
  57. package/lib/typescript/commonjs/connections/ConnectionSetupScreen.d.ts +107 -0
  58. package/lib/typescript/commonjs/connections/disambiguate.d.ts +43 -0
  59. package/lib/typescript/commonjs/connections/types.d.ts +91 -0
  60. package/lib/typescript/commonjs/connections/useConnectionSetup.d.ts +96 -0
  61. package/lib/typescript/commonjs/controls/FilePicker.d.ts +65 -0
  62. package/lib/typescript/commonjs/controls/ImagePicker.d.ts +76 -0
  63. package/lib/typescript/commonjs/index.d.ts +42 -0
  64. package/lib/typescript/commonjs/logger.d.ts +11 -0
  65. package/lib/typescript/commonjs/package.json +1 -0
  66. package/lib/typescript/commonjs/platform/PowerPlatformConnectionApi.d.ts +205 -0
  67. package/lib/typescript/commonjs/platform/PowerPlatformEnvironmentApi.d.ts +108 -0
  68. package/lib/typescript/commonjs/platform/resolveConnections.d.ts +86 -0
  69. package/lib/typescript/commonjs/platform/useConnectionRefs.d.ts +126 -0
  70. package/lib/typescript/commonjs/provider/PowerAppsHostProvider.d.ts +123 -0
  71. package/lib/typescript/commonjs/provider/PowerAppsProvider.d.ts +148 -0
  72. package/lib/typescript/commonjs/telemetry/index.d.ts +48 -0
  73. package/lib/typescript/commonjs/theme/ThemeProvider.d.ts +30 -0
  74. package/lib/typescript/commonjs/theme/tokens.d.ts +27 -0
  75. package/lib/typescript/commonjs/utils/dataverseUtils.d.ts +39 -0
  76. package/lib/typescript/commonjs/utils/isDevPlayer.d.ts +19 -0
  77. package/lib/typescript/module/ErrorBoundary.d.ts +30 -0
  78. package/lib/typescript/module/auth/AuthContext.d.ts +57 -0
  79. package/lib/typescript/module/bridge/NativePowerAppsBridge.d.ts +112 -0
  80. package/lib/typescript/module/bridge/setupNativeHost.d.ts +39 -0
  81. package/lib/typescript/module/connections/ConnectionSetupScreen.d.ts +107 -0
  82. package/lib/typescript/module/connections/disambiguate.d.ts +43 -0
  83. package/lib/typescript/module/connections/types.d.ts +91 -0
  84. package/lib/typescript/module/connections/useConnectionSetup.d.ts +96 -0
  85. package/lib/typescript/module/controls/FilePicker.d.ts +65 -0
  86. package/lib/typescript/module/controls/ImagePicker.d.ts +76 -0
  87. package/lib/typescript/module/index.d.ts +42 -0
  88. package/lib/typescript/module/logger.d.ts +11 -0
  89. package/lib/typescript/module/package.json +1 -0
  90. package/lib/typescript/module/platform/PowerPlatformConnectionApi.d.ts +205 -0
  91. package/lib/typescript/module/platform/PowerPlatformEnvironmentApi.d.ts +108 -0
  92. package/lib/typescript/module/platform/resolveConnections.d.ts +86 -0
  93. package/lib/typescript/module/platform/useConnectionRefs.d.ts +126 -0
  94. package/lib/typescript/module/provider/PowerAppsHostProvider.d.ts +123 -0
  95. package/lib/typescript/module/provider/PowerAppsProvider.d.ts +148 -0
  96. package/lib/typescript/module/telemetry/index.d.ts +48 -0
  97. package/lib/typescript/module/theme/ThemeProvider.d.ts +30 -0
  98. package/lib/typescript/module/theme/tokens.d.ts +27 -0
  99. package/lib/typescript/module/utils/dataverseUtils.d.ts +39 -0
  100. package/lib/typescript/module/utils/isDevPlayer.d.ts +19 -0
  101. package/package.json +119 -0
  102. package/scripts/build-ios-base.js +96 -0
  103. package/scripts/bundle.js +95 -0
  104. package/scripts/generate-connector-schemas.js +75 -0
@@ -0,0 +1,76 @@
1
+ import React from 'react';
2
+ import { type StyleProp, type ViewStyle, type TextStyle, type ImageStyle } from 'react-native';
3
+ import * as ExpoImagePicker from 'expo-image-picker';
4
+ export interface PickedImageInfo {
5
+ uri: string;
6
+ name: string;
7
+ mimeType: string;
8
+ base64: string;
9
+ /** File-compatible object ready for generated Dataverse upload methods. */
10
+ file: File;
11
+ /** Raw bytes of the image, ready to pass to lower-level upload APIs. */
12
+ bytes: Uint8Array;
13
+ }
14
+ export interface ImagePickerProps {
15
+ label?: string;
16
+ /**
17
+ * Base64 string from Dataverse (the `cr_assetimage` thumbnail).
18
+ * The component builds the preview data URI internally.
19
+ * Pass `null` / `undefined` when there is no existing image.
20
+ */
21
+ initialBase64?: string | null;
22
+ /**
23
+ * Called when the user picks a new image.
24
+ * Receives the base64-encoded string, ready to include in a Dataverse PATCH body.
25
+ * Called with `null` if the user clears the image (future use).
26
+ */
27
+ onChange?: (base64: string | null) => void;
28
+ /** Called when the user picks a new image. Includes a generated-service-ready File object. */
29
+ onImageChange?: (image: PickedImageInfo | null) => void;
30
+ /** File name used when the selected image asset does not provide one. */
31
+ imageFileName?: string;
32
+ /** JPEG/PNG compression quality passed to expo-image-picker. Defaults to 0.8. */
33
+ quality?: number;
34
+ /** Enable the platform image editor after selecting or taking a photo. Defaults to false. */
35
+ allowsEditing?: boolean;
36
+ /** Android-only crop aspect ratio used when `allowsEditing` is true. */
37
+ aspect?: [number, number];
38
+ /** Android-only crop shape used when `allowsEditing` is true. */
39
+ cropShape?: ExpoImagePicker.CropShape;
40
+ /** Include EXIF metadata in the Expo picker asset. Defaults to false. */
41
+ exif?: boolean;
42
+ /** Use Android's legacy media picker. Defaults to false. */
43
+ legacy?: boolean;
44
+ /** Override the camera button label. */
45
+ cameraButtonLabel?: string;
46
+ /** Override the initial image-library button label. */
47
+ selectButtonLabel?: string;
48
+ /** Override the image-library button label after an image exists. */
49
+ changeButtonLabel?: string;
50
+ /** Override the button label while the picked image is being read. */
51
+ readingLabel?: string;
52
+ /** Override the outer container (adds margin below by default). */
53
+ containerStyle?: StyleProp<ViewStyle>;
54
+ /** Override the label text style. */
55
+ labelStyle?: StyleProp<TextStyle>;
56
+ /** Override the button row container. */
57
+ buttonRowStyle?: StyleProp<ViewStyle>;
58
+ /** Override each button container. */
59
+ buttonStyle?: StyleProp<ViewStyle>;
60
+ /** Override each button text. */
61
+ buttonTextStyle?: StyleProp<TextStyle>;
62
+ /** Override the image preview. */
63
+ previewStyle?: StyleProp<ImageStyle>;
64
+ /** Accent colour used for icons, borders and text. Defaults to `'#0078d4'`. */
65
+ accentColor?: string;
66
+ }
67
+ /**
68
+ * A self-contained image picker that shows a preview and lets the user
69
+ * choose a new image from the library. Works on Android and iOS.
70
+ *
71
+ * - Existing images are seeded from a Dataverse base64 string via `initialBase64`.
72
+ * - On pick, the image is returned as base64 for legacy callers and as a
73
+ * File-compatible object for generated Dataverse upload methods.
74
+ */
75
+ export declare function ImagePicker({ label, initialBase64, onChange, containerStyle, labelStyle, buttonRowStyle, buttonStyle, buttonTextStyle, previewStyle, accentColor, onImageChange, imageFileName, quality, allowsEditing, aspect, cropShape, exif, legacy, cameraButtonLabel, selectButtonLabel, changeButtonLabel, readingLabel, }: ImagePickerProps): React.JSX.Element;
76
+ //# sourceMappingURL=ImagePicker.d.ts.map
@@ -0,0 +1,42 @@
1
+ /*!
2
+ * power-apps-native-host
3
+ * React Native host integration for @microsoft/power-apps
4
+ *
5
+ */
6
+ export { NativePowerAppsBridge } from './bridge/NativePowerAppsBridge';
7
+ export type { NativeBridgeOptions, CdsDataSourceConfig, AppConnection, AppConnectionReference } from './bridge/NativePowerAppsBridge';
8
+ export { buildConnectionReferences } from './bridge/NativePowerAppsBridge';
9
+ export { setupNativeHost } from './bridge/setupNativeHost';
10
+ export { AuthProvider, useAuth } from './auth/AuthContext';
11
+ export type { AuthState, AuthProviderProps } from './auth/AuthContext';
12
+ export type { AuthConfig, MsalAuthConfig, IntuneConfig } from '@microsoft/power-apps-native-auth';
13
+ export { PowerAppsHostProvider } from './provider/PowerAppsHostProvider';
14
+ export type { PowerAppsHostProviderProps } from './provider/PowerAppsHostProvider';
15
+ export { PowerAppsProvider } from './provider/PowerAppsProvider';
16
+ export type { PowerAppsProviderProps, PowerConfig } from './provider/PowerAppsProvider';
17
+ export { fetchInstanceUrl, buildCdsDataSources, buildEnvironmentEndpoint, POWER_PLATFORM_API_SCOPE } from './platform/PowerPlatformEnvironmentApi';
18
+ export type { LinkedEnvironmentMetadata, DatabaseReference, DatabaseReferenceDataSource } from './platform/PowerPlatformEnvironmentApi';
19
+ export { useConnectionRefs } from './platform/useConnectionRefs';
20
+ export type { UseConnectionRefsOptions, UseConnectionRefsResult, ConnectorSchema } from './platform/useConnectionRefs';
21
+ export { fetchConnectorMetadata, fetchConnectionsForConnector, createConnection, pollConnectionStatus, confirmConsentCode, fetchAppLaunchData, } from './platform/PowerPlatformConnectionApi';
22
+ export type { ConnectorMetadata, CreateConnectionResult, AppLaunchResult, } from './platform/PowerPlatformConnectionApi';
23
+ export { disambiguateConnections, extractConnectionId } from './connections/disambiguate';
24
+ export type { NativeConnectionInstance, NativeConnectionResolution, NativeDisambiguationResult, OnDisambiguationNeeded, OnMissingConnection, } from './connections/types';
25
+ export { useConnectionSetup } from './connections/useConnectionSetup';
26
+ export type { ConnectionSetupPhase, UseConnectionSetupOptions, UseConnectionSetupResult, } from './connections/useConnectionSetup';
27
+ export { ConnectionSetupScreen } from './connections/ConnectionSetupScreen';
28
+ export type { MissingConnectorEntry, ConnectionSetupScreenProps, } from './connections/ConnectionSetupScreen';
29
+ export { ThemeProvider, useThemeTokens, useThemeControl } from './theme/ThemeProvider';
30
+ export type { ThemeProviderProps, ThemeControl } from './theme/ThemeProvider';
31
+ export { lightTheme, darkTheme } from './theme/tokens';
32
+ export type { ThemeTokens } from './theme/tokens';
33
+ export { FilePicker } from './controls/FilePicker';
34
+ export type { FilePickerProps, PickedFileInfo } from './controls/FilePicker';
35
+ export { ImagePicker } from './controls/ImagePicker';
36
+ export type { ImagePickerProps, PickedImageInfo } from './controls/ImagePicker';
37
+ export { isDevPlayer } from './utils/isDevPlayer';
38
+ export { base64ToDataverseUploadFile, base64ToUint8Array, createDataverseUploadFile, } from './utils/dataverseUtils';
39
+ export { getAppLogger, configureAppLogger, HostOperationNames } from './telemetry';
40
+ export type { ILogger } from '@microsoft/power-apps-native-common';
41
+ export { ErrorBoundary } from './ErrorBoundary';
42
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Conditional debug logger for power-apps-native-host.
3
+ *
4
+ * Debug logs (debugLog / debugWarn) are only emitted when the JS bundle
5
+ * is running inside the Power Apps Dev Player (detected via
6
+ * `Constants.expoConfig.extra.isDevPlayer`). They are silenced in release
7
+ * APKs generated from the template so the production log stream stays clean.
8
+ */
9
+ export declare function debugLog(...args: unknown[]): void;
10
+ export declare function debugWarn(...args: unknown[]): void;
11
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}
@@ -0,0 +1,205 @@
1
+ /*!
2
+ * power-apps-native-host — PowerPlatformConnectionApi
3
+ *
4
+ * Typed wrappers around the Power Platform environment-scoped connectivity API
5
+ * for connection CRUD operations and connector metadata retrieval.
6
+ *
7
+ * These mirror the endpoints used by ConnectorsApi in @microsoft/power-apps-common
8
+ * but are implemented as plain async functions so they have no external dependencies.
9
+ */
10
+ import type { NativeConnectionInstance } from '../connections/types';
11
+ import type { AppConnectionReference } from '../bridge/NativePowerAppsBridge';
12
+ /**
13
+ * Token scope for the Power Apps RP (api.powerapps.com).
14
+ * Required when calling modifyPermissions to register a service principal
15
+ * in the connection ACE so that APIM accepts third-party app tokens at runtime.
16
+ */
17
+ export declare const SERVICE_POWERAPPS_SCOPE = "https://service.powerapps.com/.default";
18
+ /** Subset of connector metadata returned by the Power Platform API. */
19
+ export interface ConnectorMetadata {
20
+ /** Short connector name, e.g. "shared_office365users". */
21
+ name: string;
22
+ /** Connector display name, e.g. "Office 365 Users". */
23
+ displayName: string;
24
+ /** URL of the connector icon. */
25
+ iconUri: string;
26
+ /** Description text. */
27
+ description: string;
28
+ /** Whether this is a first-party (Microsoft-published) connector. */
29
+ isFirstParty: boolean;
30
+ }
31
+ /**
32
+ * Fetch metadata for a single connector from the Power Platform API.
33
+ *
34
+ * @param connectorId - Connector short name (e.g. "shared_office365users")
35
+ * or full API path suffix.
36
+ * @param environmentId - Environment GUID.
37
+ * @param region - Cluster region string (default "prod").
38
+ * @param token - Pre-acquired Power Platform API bearer token.
39
+ */
40
+ export declare function fetchConnectorMetadata(connectorId: string, environmentId: string, region: string, token: string): Promise<ConnectorMetadata | null>;
41
+ /**
42
+ * Fetch all connections for a given connector in the environment.
43
+ * Returns only the `NativeConnectionInstance` shape used by the disambiguation layer.
44
+ */
45
+ export declare function fetchConnectionsForConnector(connectorId: string, environmentId: string, region: string, token: string): Promise<NativeConnectionInstance[]>;
46
+ /**
47
+ * Result of initiating an OAuth connection creation.
48
+ *
49
+ * `pending` — the connection has been created but is not yet authenticated.
50
+ * The `consentLink` URL must be opened (in a WebView or browser) so the
51
+ * user can complete the OAuth consent flow. Poll `pollConnectionStatus`
52
+ * until the status changes to "Connected".
53
+ *
54
+ * `connected` — the connection was created and is already Connected (e.g.,
55
+ * first-party SSO connections that do not need explicit OAuth consent).
56
+ *
57
+ * `error` — creation failed; `message` contains the error description.
58
+ */
59
+ export type CreateConnectionResult = {
60
+ status: 'pending';
61
+ connectionName: string;
62
+ consentLink: string;
63
+ } | {
64
+ status: 'connected';
65
+ connectionName: string;
66
+ } | {
67
+ status: 'error';
68
+ message: string;
69
+ };
70
+ /**
71
+ * Create a new connection for a connector in the user's environment.
72
+ *
73
+ * Calls:
74
+ * POST {envBase}/connectivity/apis/{connectorId}/connections
75
+ *
76
+ * If the response contains a `consentLink`, the connection needs OAuth
77
+ * completion (caller should open the URL and then poll `pollConnectionStatus`).
78
+ * If the connection status is already "Connected", returns `connected`.
79
+ *
80
+ * @param connectorId - Connector short name (e.g. "shared_office365users").
81
+ * @param environmentId - Environment GUID.
82
+ * @param region - Cluster region.
83
+ * @param token - Power Platform API bearer token.
84
+ * @param displayName - Optional display name for the new connection.
85
+ * @param oauthRedirectUrl - Redirect URL sent to getConsentLink. The OAuth provider
86
+ * will redirect the user here after consent. Defaults to
87
+ * the standard native-client redirect accepted by Power Platform.
88
+ */
89
+ export declare function createConnection(connectorId: string, environmentId: string, region: string, token: string, displayName?: string, oauthRedirectUrl?: string): Promise<CreateConnectionResult>;
90
+ /**
91
+ * Poll a connection's status until it is "Connected" or a timeout is reached.
92
+ *
93
+ * @param connectionName - The connection resource name (from createConnection result).
94
+ * @param environmentId - Environment GUID.
95
+ * @param region - Cluster region.
96
+ * @param token - Power Platform API bearer token.
97
+ * @param options.intervalMs - Polling interval in ms (default 2000).
98
+ * @param options.timeoutMs - Maximum time to wait in ms (default 60000).
99
+ * @returns The resolved `NativeConnectionInstance` if Connected, or `null` if timed out.
100
+ */
101
+ export declare function pollConnectionStatus(connectorId: string, connectionName: string, environmentId: string, region: string, acquireToken: (scopes: string[]) => Promise<string | null>, options?: {
102
+ intervalMs?: number;
103
+ timeoutMs?: number;
104
+ }): Promise<NativeConnectionInstance | null>;
105
+ /**
106
+ * Confirm a consent code returned by the APIM consent server in the OAuth
107
+ * redirect URL (`?code=<commitTokenCode>`).
108
+ *
109
+ * The consent server embeds a 32-char hex CommitTokenCode in the redirect URL
110
+ * when the OAuth exchange completes successfully. POSTing it here causes APIM
111
+ * to exchange it for the real OAuth tokens and activate the connection
112
+ * (status → Connected).
113
+ *
114
+ * When the redirect URL uses a custom scheme (e.g. `expo-app://oauth-callback`),
115
+ * the consent server may instead return `?error=no+code+returned` and activate
116
+ * the connection server-side. In that case this function is not called and the
117
+ * caller should poll `pollConnectionStatus` directly.
118
+ *
119
+ * @param connectorId - Connector short name (e.g. "shared_office365users").
120
+ * @param connectionId - Bare connection hex ID (no connector prefix).
121
+ * @param environmentId - Environment GUID.
122
+ * @param region - Cluster region.
123
+ * @param token - Power Platform API bearer token.
124
+ * @param code - CommitTokenCode from the redirect URL `?code=` param.
125
+ * @returns `true` if the server accepted the code, `false` otherwise.
126
+ */
127
+ export declare function confirmConsentCode(connectorId: string, connectionId: string, environmentId: string, region: string, token: string, code: string): Promise<boolean>;
128
+ /**
129
+ * Processed result of the PowerApps app launch API call, ready to be applied
130
+ * directly to the NativePowerAppsBridge without further network calls.
131
+ */
132
+ export interface AppLaunchResult {
133
+ /**
134
+ * AppConnectionReference map keyed by data source name.
135
+ * Passed directly to `setupNativeHost({ connections: ... })`.
136
+ */
137
+ connectionRefs: Record<string, AppConnectionReference>;
138
+ /**
139
+ * Dataverse org URL derived from the environment's
140
+ * `linkedEnvironmentMetadata.instanceUrl` (empty string if the environment
141
+ * has no linked Dataverse database).
142
+ */
143
+ dataverseOrgUrl: string;
144
+ /**
145
+ * Connector short-names (e.g. "shared_office365users") for which the
146
+ * launch API found no "Connected" connection instance for the signed-in
147
+ * user. These connectors need the connection setup flow.
148
+ */
149
+ missingConnectors: string[];
150
+ }
151
+ /**
152
+ * Fetch app launch data from the Power Platform environment-scoped launch
153
+ * endpoint and process it into the shape the NativePowerAppsBridge needs.
154
+ *
155
+ * A single call returns everything required to run the app:
156
+ * - `app.properties.connectionReferences` — connectors the app requires
157
+ * - `apis[]` — connector metadata (primaryRuntimeUrl)
158
+ * - `connections[]` — the current user's resolved connections
159
+ * - `app.properties.environment.properties.linkedEnvironmentMetadata.instanceUrl`
160
+ * — Dataverse org URL
161
+ *
162
+ * Endpoint (environment-scoped, same base as all Power Platform API calls):
163
+ * GET {envEndpoint}/powerapps/apps/{appId}/launch
164
+ * ?api-version=2&lastKnownGoodPublishedVersion=true
165
+ *
166
+ * Authentication: bearer token for {@link powerPlatformScope}`(region)`.
167
+ *
168
+ * @param appId - PowerApps app GUID (from `power.config.json` → `appId`).
169
+ * @param environmentId - Environment GUID.
170
+ * @param region - Cluster region (default "prod").
171
+ * @param token - Bearer token for {@link powerPlatformScope}`(region)`.
172
+ * @returns Processed launch data, or `null` if the call fails.
173
+ */
174
+ export declare function fetchAppLaunchData(appId: string, environmentId: string, region: string, token: string): Promise<AppLaunchResult | null>;
175
+ /**
176
+ * Decode the `oid` (object ID) claim from a JWT access token.
177
+ *
178
+ * The oid claim is in the base64url-encoded payload section (middle part).
179
+ * Available in Hermes (React Native) via the global `atob`.
180
+ */
181
+ export declare function parseJwtOid(jwtToken: string): string | null;
182
+ /**
183
+ * Add the ISV's AAD application (client) ID to the connection's ACL AppIds
184
+ * list via the Power Apps RP `addAadAppToConnectionAcl` endpoint.
185
+ *
186
+ * The RP finds the user's existing ACE (identified by `userOid`) and appends
187
+ * `isvClientId` to its `AppIds` list. APIM's stage-2 token check verifies
188
+ * that the requesting token's `appid` is present in this list, so without
189
+ * this call APIM returns 403 "missing connection ACL" for third-party tokens.
190
+ *
191
+ * POST https://api.powerapps.com/providers/Microsoft.PowerApps/environments/{environmentId}
192
+ * /apis/{connectorId}/connections/{connectionId}/addAadAppToConnectionAcl
193
+ * ?api-version=2016-11-01
194
+ *
195
+ * Body: { "aadApplicationId": "<ISV client ID>", "objectId": "<user OID>" }
196
+ *
197
+ * @param connectorId - Connector short name (e.g. "shared_office365users").
198
+ * @param connectionId - Bare 32-char hex connection ID.
199
+ * @param environmentId - Environment GUID.
200
+ * @param isvClientId - The ISV's AAD application (client) ID.
201
+ * @param userOid - The signed-in user's AAD object ID (oid JWT claim).
202
+ * @param token - Bearer token for `https://service.powerapps.com/.default`.
203
+ */
204
+ export declare function addAadAppToConnectionAcl(connectorId: string, connectionId: string, environmentId: string, isvClientId: string, userOid: string, token: string): Promise<boolean>;
205
+ //# sourceMappingURL=PowerPlatformConnectionApi.d.ts.map
@@ -0,0 +1,108 @@
1
+ /*!
2
+ * power-apps-native-host — PowerPlatformEnvironmentApi
3
+ *
4
+ * Mirrors the Host SDK's DefaultAppMetadataProvider.fetchAppMetadataFromPowerConfig
5
+ * pattern: resolves the Power Platform environment-scoped API endpoint from the
6
+ * environment GUID and region, then fetches linkedEnvironmentMetadata to obtain
7
+ * the Dataverse instanceUrl.
8
+ *
9
+ * Reference (Host SDK):
10
+ * packages/power-apps-host/src/providers/defaults/DefaultAppMetadataProvider.ts
11
+ * packages/power-apps-common/src/services/PowerPlatformApiDiscovery.ts
12
+ */
13
+ /**
14
+ * Build the Power Platform environment-scoped API base URL.
15
+ *
16
+ * Algorithm (mirrors PowerPlatformApiDiscovery.generateDomain):
17
+ * 1. Strip dashes from the environment GUID to get a hex string.
18
+ * 2. Split into prefix (all but last N chars) and suffix (last N chars),
19
+ * where N = 2 for prod/firstrelease, 1 for all other regions.
20
+ * 3. Compose: `{prefix}.{suffix}.environment.{hostNameSuffix}`
21
+ *
22
+ * Example (prod, environmentId = "d909aac0-59d0-e5b1-900d-c082ef5774d7"):
23
+ * hexName = "d909aac059d0e5b1900dc082ef5774d7"
24
+ * suffix = "d7"
25
+ * prefix = "d909aac059d0e5b1900dc082ef5774"
26
+ * → "d909aac059d0e5b1900dc082ef5774.d7.environment.api.powerplatform.com"
27
+ */
28
+ export declare function buildEnvironmentEndpoint(environmentId: string, region: string): string;
29
+ export interface LinkedEnvironmentMetadata {
30
+ resourceId?: string;
31
+ friendlyName?: string;
32
+ uniqueName?: string;
33
+ domainName?: string;
34
+ version?: string;
35
+ instanceUrl?: string;
36
+ instanceApiUrl?: string;
37
+ baseLanguage?: number;
38
+ instanceState?: string;
39
+ createdTime?: string;
40
+ platformSku?: string;
41
+ }
42
+ /**
43
+ * Token scope for the Power Platform management API (prod cluster).
44
+ * Non-prod clusters (test, gov, high, dev, mooncake, etc.) host the management
45
+ * API on their own audience, so prod-scope tokens are rejected with 401 by
46
+ * those clusters. Prefer {@link powerPlatformScope} when the region is known.
47
+ */
48
+ export declare const POWER_PLATFORM_API_SCOPE = "https://api.powerplatform.com/.default";
49
+ /**
50
+ * Region-aware Power Platform management API scope. The audience must match the
51
+ * cluster the request is sent to; reuses the same region → hostname table as
52
+ * {@link buildEnvironmentEndpoint}.
53
+ */
54
+ export declare function powerPlatformScope(region: string): string;
55
+ /**
56
+ * Fetch the Dataverse instanceUrl for a Power Platform environment by calling
57
+ * the environment-scoped Power Platform management API — the same call that
58
+ * the Host SDK's DefaultAppMetadataProvider makes to populate
59
+ * `databaseReferences[*].databaseDetails.linkedEnvironmentMetadata`.
60
+ *
61
+ * @param environmentId - Environment GUID (from power.config.json `environmentId`).
62
+ * @param region - Cluster region string (from power.config.json `region`, default "prod").
63
+ * @param acquireToken - Callback to obtain a bearer token for the given scopes.
64
+ * Scope will be {@link powerPlatformScope}`(region)`.
65
+ * @param bearerToken - Optional pre-fetched bearer token for {@link powerPlatformScope}`(region)`.
66
+ * Pass this to avoid a redundant `acquireToken` round-trip when the
67
+ * caller has already obtained a token for the same audience.
68
+ * @returns The Dataverse org URL (e.g. "https://org12345.crm.dynamics.com"), or
69
+ * `undefined` if the environment has no linked CDS database.
70
+ */
71
+ export declare function fetchInstanceUrl(environmentId: string, region: string, acquireToken: (scopes: string[]) => Promise<string | null>, bearerToken?: string): Promise<string | undefined>;
72
+ /**
73
+ * Shape of a single Dataverse table entry inside power.config.json
74
+ * `databaseReferences[*].dataSources[*]`.
75
+ */
76
+ export interface DatabaseReferenceDataSource {
77
+ entitySetName?: string;
78
+ logicalName?: string;
79
+ }
80
+ /**
81
+ * Shape of a single database reference entry inside power.config.json
82
+ * `databaseReferences`.
83
+ */
84
+ export interface DatabaseReference {
85
+ dataSources?: Record<string, DatabaseReferenceDataSource>;
86
+ }
87
+ /**
88
+ * Build the CDS data source config array that the SDK reads via
89
+ * AppPowerAppsClientPlugin.getAppCdsDataSourceConfigsAsync.
90
+ *
91
+ * Pass the resolved Dataverse org URL (from useConnectionRefs) and the
92
+ * databaseReferences map from power.config.json. The resulting array is
93
+ * passed directly to <PowerAppsHostProvider dataSources={...} />.
94
+ *
95
+ * @param databaseReferences - The `databaseReferences` map from power.config.json.
96
+ * @param dataverseOrgUrl - The resolved Dataverse org URL
97
+ * (connectionRefs['commondataserviceforapps']?.datasetName).
98
+ * Pass an empty string before the org URL is known;
99
+ * the host provider will receive empty runtimeUrl entries
100
+ * and the SDK will not attempt Dataverse calls.
101
+ */
102
+ export declare function buildCdsDataSources(databaseReferences: Record<string, DatabaseReference>, dataverseOrgUrl: string): Array<{
103
+ runtimeUrl: string;
104
+ entitySetName: string;
105
+ logicalName: string;
106
+ version: string;
107
+ }>;
108
+ //# sourceMappingURL=PowerPlatformEnvironmentApi.d.ts.map
@@ -0,0 +1,86 @@
1
+ /*!
2
+ * power-apps-native-host — resolveConnections
3
+ *
4
+ * Pure async helpers for the two connection-resolution strategies used by
5
+ * useConnectionRefs:
6
+ *
7
+ * • resolveViaStaticRefs — per-connector resolution using the static
8
+ * connectionReferences map from power.config.json. Used by the Dev Player
9
+ * and during local development (no appId) or when the launch API is
10
+ * unavailable. Handles pre-disambiguation ACL grants so inaccessible
11
+ * connections are excluded before the user is asked to pick.
12
+ *
13
+ * • applyAclGrants — post-resolution ACL grants used by the fast path
14
+ * (production APKs via fetchAppLaunchData).
15
+ *
16
+ * Both helpers return / consume the shared AppLaunchResult shape so the
17
+ * hook orchestrator can handle them uniformly.
18
+ */
19
+ import type { AppLaunchResult } from './PowerPlatformConnectionApi';
20
+ import type { OnDisambiguationNeeded, OnMissingConnection } from '../connections/types';
21
+ import type { AppConnectionReference } from '../bridge/NativePowerAppsBridge';
22
+ /**
23
+ * Connector schema entry generated by `generate-connector-schemas`.
24
+ * Keyed by data source name in the `schemaMap` passed to `useConnectionRefs`.
25
+ */
26
+ export interface ConnectorSchema {
27
+ /** Connector name used as the connectorId in API calls, e.g. "shared_commondataserviceforapps". */
28
+ name: string;
29
+ properties: {
30
+ primaryRuntimeUrl: string;
31
+ };
32
+ }
33
+ export interface StaticRefsOptions {
34
+ /**
35
+ * Static connectionReferences from power.config.json.
36
+ * Shape: { [refId]: { id: string; dataSources: string[] } }
37
+ */
38
+ connectionReferences: Record<string, {
39
+ id: string;
40
+ dataSources: string[];
41
+ }>;
42
+ /** Connector schema map keyed by data source name. */
43
+ schemaMap: Record<string, ConnectorSchema>;
44
+ environmentId: string;
45
+ region: string;
46
+ /** Used for ACL grants and the Dataverse instanceUrl fetch. */
47
+ acquireToken: (scopes: string[]) => Promise<string | null>;
48
+ /** Pre-acquired Power Platform API bearer token. */
49
+ token: string;
50
+ /** ISV client ID — when provided, runs pre-disambiguation ACL grants. */
51
+ isvClientId?: string;
52
+ onDisambiguationNeeded?: OnDisambiguationNeeded;
53
+ onMissingConnection?: OnMissingConnection;
54
+ }
55
+ /**
56
+ * Resolve connections from the static `connectionReferences` map.
57
+ *
58
+ * Steps:
59
+ * 1. Build an apiId → schema lookup.
60
+ * 2. In parallel: fetch the Dataverse instanceUrl and all connection instances
61
+ * for every connector.
62
+ * 3. If `isvClientId` is set, run pre-disambiguation ACL grants — connections
63
+ * where the grant fails are marked `NeedsAclGrant` and excluded from
64
+ * resolution, prompting the user to create a new connection.
65
+ * 4. Disambiguate: resolve single matches, invoke callbacks for ambiguous /
66
+ * missing cases, perform one-shot retries when `onMissingConnection` returns
67
+ * `true`.
68
+ * 5. Build and return an `AppLaunchResult`-shaped object.
69
+ */
70
+ export declare function resolveViaStaticRefs({ connectionReferences, schemaMap, environmentId, region, acquireToken, token, isvClientId, onDisambiguationNeeded, onMissingConnection, }: StaticRefsOptions): Promise<AppLaunchResult>;
71
+ /**
72
+ * Run idempotent post-resolution ACL grants on behalf of the ISV app.
73
+ *
74
+ * Used by the fast path (production APKs via `fetchAppLaunchData`) where the
75
+ * launch API has already resolved the user's connections — grants are applied
76
+ * after the fact so APIM accepts tokens issued to the ISV's AAD app.
77
+ *
78
+ * For the slow path the grants run before disambiguation inside
79
+ * `resolveViaStaticRefs`, where they can still influence which connections
80
+ * are considered available.
81
+ *
82
+ * Failures are swallowed — a failed grant will surface as a 403 at runtime
83
+ * when the connector is called.
84
+ */
85
+ export declare function applyAclGrants(connectionRefs: Record<string, AppConnectionReference>, environmentId: string, isvClientId: string, acquireToken: (scopes: string[]) => Promise<string | null>): Promise<void>;
86
+ //# sourceMappingURL=resolveConnections.d.ts.map
@@ -0,0 +1,126 @@
1
+ /*!
2
+ * power-apps-native-host — useConnectionRefs
3
+ *
4
+ * Resolves per-user connectionIds from the Power Platform environment-scoped
5
+ * connectivity API, then builds a fully-populated connection-references map
6
+ * ready to pass to <PowerAppsHostProvider connections={...} />.
7
+ *
8
+ * Now supports connection disambiguation: when multiple Connected connections
9
+ * exist for the same connector, the `onDisambiguationNeeded` callback lets the
10
+ * consuming app present a native picker UI (e.g. a bottom sheet) so the user
11
+ * can choose which connection to use. When no connection exists for a connector
12
+ * the `onMissingConnection` callback fires so the consuming app can guide the
13
+ * user to create one.
14
+ *
15
+ * Usage:
16
+ * import { useConnectionRefs } from '@microsoft/power-apps-native-host';
17
+ * import powerConfig from '../power.config.json';
18
+ * import { schemaMap } from '../src/connectorSchemas';
19
+ *
20
+ * const { connectionRefs, isReady, error, missingConnectors } = useConnectionRefs({
21
+ * isSignedIn,
22
+ * acquireToken,
23
+ * environmentId: authConfig.powerPlatform.environmentId,
24
+ * region: authConfig.powerPlatform.region,
25
+ * connectionReferences: powerConfig.connectionReferences,
26
+ * schemaMap,
27
+ * onDisambiguationNeeded: async ({ localRefId, apiId, candidates }) => {
28
+ * // Show a picker sheet and return the selected connectionId, or null to skip.
29
+ * return showConnectionPicker(candidates);
30
+ * },
31
+ * });
32
+ */
33
+ import { type OnDisambiguationNeeded, type OnMissingConnection } from '../connections/types';
34
+ import type { ConnectorSchema } from './resolveConnections';
35
+ import type { AppConnectionReference } from '../bridge/NativePowerAppsBridge';
36
+ export type { ConnectorSchema } from './resolveConnections';
37
+ export interface UseConnectionRefsOptions {
38
+ isSignedIn: boolean;
39
+ acquireToken: (scopes: string[]) => Promise<string | null>;
40
+ /** Power Platform environment GUID (from auth.config.json). */
41
+ environmentId: string;
42
+ /**
43
+ * Routing region for the environment.
44
+ * @default 'prod'
45
+ */
46
+ region?: string;
47
+ /**
48
+ * PowerApps app GUID (from power.config.json `appId`).
49
+ * When provided (and not running inside the Dev Player), connection
50
+ * references are fetched at runtime from the PowerApps RP
51
+ * `/apps/{appId}/launch` endpoint and take precedence over the static
52
+ * `connectionReferences` object below.
53
+ * Leave undefined during local development to use the static fallback.
54
+ */
55
+ appId?: string;
56
+ /**
57
+ * The connectionReferences map from power.config.json.
58
+ * Shape: { [refId]: { id: string; dataSources: string[] } }
59
+ */
60
+ connectionReferences: Record<string, {
61
+ id: string;
62
+ dataSources: string[];
63
+ }>;
64
+ /**
65
+ * Connector schema map keyed by data source name.
66
+ * Generated automatically by generate-connector-schemas.
67
+ * Shape: { [dataSourceName]: ConnectorSchema }
68
+ */
69
+ schemaMap: Record<string, ConnectorSchema>;
70
+ /**
71
+ * Called when multiple Connected connections exist for the same connector.
72
+ * Present a native picker UI and return the chosen connectionId, or null to
73
+ * leave the connection unresolved.
74
+ */
75
+ onDisambiguationNeeded?: OnDisambiguationNeeded;
76
+ /**
77
+ * Called when no connections are found for a required connector.
78
+ * The app can redirect the user to a connection setup flow; return `true` to
79
+ * trigger a one-time retry of the connection fetch, `false` to leave it unresolved.
80
+ */
81
+ onMissingConnection?: OnMissingConnection;
82
+ /**
83
+ * The ISV's AAD application (client) ID. When provided, each resolved
84
+ * `Connected` connection is checked via `addAadAppToConnectionAcl`.
85
+ * Connections where the grant fails are marked `NeedsAclGrant` and treated
86
+ * as missing so the setup screen can guide the user to create a new one.
87
+ */
88
+ isvClientId?: string;
89
+ }
90
+ export interface UseConnectionRefsResult {
91
+ connectionRefs: Record<string, AppConnectionReference>;
92
+ isReady: boolean;
93
+ error: string | null;
94
+ /**
95
+ * API IDs of connectors for which no connection was found (or the user did
96
+ * not resolve during disambiguation). Useful for surfacing a "Set up
97
+ * connections" prompt in the app UI.
98
+ */
99
+ missingConnectors: string[];
100
+ /**
101
+ * The Dataverse org URL for this environment (e.g. "https://org12345.crm.dynamics.com").
102
+ * Fetched from the Power Platform environment metadata independently of whether a
103
+ * commondataserviceforapps connection reference is configured.
104
+ * Empty string until isReady is true or if the environment has no linked Dataverse database.
105
+ */
106
+ dataverseOrgUrl: string;
107
+ }
108
+ /**
109
+ * Resolves Power Platform connection references for the current user, with
110
+ * disambiguation support for environments where multiple connections exist for
111
+ * the same connector.
112
+ *
113
+ * On sign-in this hook:
114
+ * 1. If `appId` is set (production template), fetches connection references
115
+ * from the PowerApps RP `/apps/{appId}/launch` endpoint and uses those
116
+ * in place of the static `connectionReferences` from power.config.json.
117
+ * 2. Acquires a Power Platform API token.
118
+ * 3. In parallel: fetches the Dataverse instanceUrl and ALL connections for
119
+ * each configured connector.
120
+ * 4. Runs disambiguation: resolves single matches, invokes `onDisambiguationNeeded`
121
+ * for multiple matches, and invokes `onMissingConnection` for absent ones.
122
+ * 5. Pre-warms the Dataverse token in the MSAL cache.
123
+ * 6. Sets isReady=true with the fully-populated connections map.
124
+ */
125
+ export declare function useConnectionRefs({ isSignedIn, acquireToken, appId, environmentId, region, connectionReferences, schemaMap, onDisambiguationNeeded, onMissingConnection, isvClientId, }: UseConnectionRefsOptions): UseConnectionRefsResult;
126
+ //# sourceMappingURL=useConnectionRefs.d.ts.map