@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.
- package/LICENSE +112 -0
- package/README.md +59 -0
- package/app.plugin.js +4 -0
- package/lib/NOTICE.txt +1659 -0
- package/lib/commonjs/ErrorBoundary.js +128 -0
- package/lib/commonjs/auth/AuthContext.js +281 -0
- package/lib/commonjs/bridge/NativePowerAppsBridge.js +279 -0
- package/lib/commonjs/bridge/setupNativeHost.js +65 -0
- package/lib/commonjs/connections/ConnectionSetupScreen.js +531 -0
- package/lib/commonjs/connections/disambiguate.js +88 -0
- package/lib/commonjs/connections/types.js +58 -0
- package/lib/commonjs/connections/useConnectionSetup.js +236 -0
- package/lib/commonjs/controls/FilePicker.js +183 -0
- package/lib/commonjs/controls/ImagePicker.js +236 -0
- package/lib/commonjs/index.js +246 -0
- package/lib/commonjs/logger.js +27 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/platform/PowerPlatformConnectionApi.js +606 -0
- package/lib/commonjs/platform/PowerPlatformEnvironmentApi.js +194 -0
- package/lib/commonjs/platform/resolveConnections.js +264 -0
- package/lib/commonjs/platform/useConnectionRefs.js +270 -0
- package/lib/commonjs/provider/PowerAppsHostProvider.js +336 -0
- package/lib/commonjs/provider/PowerAppsProvider.js +351 -0
- package/lib/commonjs/telemetry/index.js +70 -0
- package/lib/commonjs/theme/ThemeProvider.js +80 -0
- package/lib/commonjs/theme/tokens.js +50 -0
- package/lib/commonjs/utils/dataverseUtils.js +98 -0
- package/lib/commonjs/utils/isDevPlayer.js +27 -0
- package/lib/module/ErrorBoundary.js +122 -0
- package/lib/module/auth/AuthContext.js +276 -0
- package/lib/module/bridge/NativePowerAppsBridge.js +273 -0
- package/lib/module/bridge/setupNativeHost.js +62 -0
- package/lib/module/connections/ConnectionSetupScreen.js +526 -0
- package/lib/module/connections/disambiguate.js +83 -0
- package/lib/module/connections/types.js +60 -0
- package/lib/module/connections/useConnectionSetup.js +233 -0
- package/lib/module/controls/FilePicker.js +178 -0
- package/lib/module/controls/ImagePicker.js +231 -0
- package/lib/module/index.js +41 -0
- package/lib/module/logger.js +22 -0
- package/lib/module/package.json +1 -0
- package/lib/module/platform/PowerPlatformConnectionApi.js +595 -0
- package/lib/module/platform/PowerPlatformEnvironmentApi.js +186 -0
- package/lib/module/platform/resolveConnections.js +259 -0
- package/lib/module/platform/useConnectionRefs.js +267 -0
- package/lib/module/provider/PowerAppsHostProvider.js +332 -0
- package/lib/module/provider/PowerAppsProvider.js +345 -0
- package/lib/module/telemetry/index.js +55 -0
- package/lib/module/theme/ThemeProvider.js +63 -0
- package/lib/module/theme/tokens.js +46 -0
- package/lib/module/utils/dataverseUtils.js +90 -0
- package/lib/module/utils/isDevPlayer.js +23 -0
- package/lib/typescript/commonjs/ErrorBoundary.d.ts +30 -0
- package/lib/typescript/commonjs/auth/AuthContext.d.ts +57 -0
- package/lib/typescript/commonjs/bridge/NativePowerAppsBridge.d.ts +112 -0
- package/lib/typescript/commonjs/bridge/setupNativeHost.d.ts +39 -0
- package/lib/typescript/commonjs/connections/ConnectionSetupScreen.d.ts +107 -0
- package/lib/typescript/commonjs/connections/disambiguate.d.ts +43 -0
- package/lib/typescript/commonjs/connections/types.d.ts +91 -0
- package/lib/typescript/commonjs/connections/useConnectionSetup.d.ts +96 -0
- package/lib/typescript/commonjs/controls/FilePicker.d.ts +65 -0
- package/lib/typescript/commonjs/controls/ImagePicker.d.ts +76 -0
- package/lib/typescript/commonjs/index.d.ts +42 -0
- package/lib/typescript/commonjs/logger.d.ts +11 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/platform/PowerPlatformConnectionApi.d.ts +205 -0
- package/lib/typescript/commonjs/platform/PowerPlatformEnvironmentApi.d.ts +108 -0
- package/lib/typescript/commonjs/platform/resolveConnections.d.ts +86 -0
- package/lib/typescript/commonjs/platform/useConnectionRefs.d.ts +126 -0
- package/lib/typescript/commonjs/provider/PowerAppsHostProvider.d.ts +123 -0
- package/lib/typescript/commonjs/provider/PowerAppsProvider.d.ts +148 -0
- package/lib/typescript/commonjs/telemetry/index.d.ts +48 -0
- package/lib/typescript/commonjs/theme/ThemeProvider.d.ts +30 -0
- package/lib/typescript/commonjs/theme/tokens.d.ts +27 -0
- package/lib/typescript/commonjs/utils/dataverseUtils.d.ts +39 -0
- package/lib/typescript/commonjs/utils/isDevPlayer.d.ts +19 -0
- package/lib/typescript/module/ErrorBoundary.d.ts +30 -0
- package/lib/typescript/module/auth/AuthContext.d.ts +57 -0
- package/lib/typescript/module/bridge/NativePowerAppsBridge.d.ts +112 -0
- package/lib/typescript/module/bridge/setupNativeHost.d.ts +39 -0
- package/lib/typescript/module/connections/ConnectionSetupScreen.d.ts +107 -0
- package/lib/typescript/module/connections/disambiguate.d.ts +43 -0
- package/lib/typescript/module/connections/types.d.ts +91 -0
- package/lib/typescript/module/connections/useConnectionSetup.d.ts +96 -0
- package/lib/typescript/module/controls/FilePicker.d.ts +65 -0
- package/lib/typescript/module/controls/ImagePicker.d.ts +76 -0
- package/lib/typescript/module/index.d.ts +42 -0
- package/lib/typescript/module/logger.d.ts +11 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/platform/PowerPlatformConnectionApi.d.ts +205 -0
- package/lib/typescript/module/platform/PowerPlatformEnvironmentApi.d.ts +108 -0
- package/lib/typescript/module/platform/resolveConnections.d.ts +86 -0
- package/lib/typescript/module/platform/useConnectionRefs.d.ts +126 -0
- package/lib/typescript/module/provider/PowerAppsHostProvider.d.ts +123 -0
- package/lib/typescript/module/provider/PowerAppsProvider.d.ts +148 -0
- package/lib/typescript/module/telemetry/index.d.ts +48 -0
- package/lib/typescript/module/theme/ThemeProvider.d.ts +30 -0
- package/lib/typescript/module/theme/tokens.d.ts +27 -0
- package/lib/typescript/module/utils/dataverseUtils.d.ts +39 -0
- package/lib/typescript/module/utils/isDevPlayer.d.ts +19 -0
- package/package.json +119 -0
- package/scripts/build-ios-base.js +96 -0
- package/scripts/bundle.js +95 -0
- package/scripts/generate-connector-schemas.js +75 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* power-apps-native-host — AuthContext
|
|
3
|
+
*
|
|
4
|
+
* A generic MSAL auth provider built on power-apps-native-auth's
|
|
5
|
+
* PublicClientApplication. Provides AuthProvider, useAuth, and the
|
|
6
|
+
* AuthState / AuthProviderProps types.
|
|
7
|
+
*
|
|
8
|
+
* Usage in the consuming Expo app:
|
|
9
|
+
*
|
|
10
|
+
* <AuthProvider msalConfig={authConfig.msal}>
|
|
11
|
+
* <PowerAppsHostProvider acquireToken={acquireToken} ...>
|
|
12
|
+
* {children}
|
|
13
|
+
* </PowerAppsHostProvider>
|
|
14
|
+
* </AuthProvider>
|
|
15
|
+
*/
|
|
16
|
+
import React from 'react';
|
|
17
|
+
import type { MsalAuthConfig, IntuneConfig } from '@microsoft/power-apps-native-auth';
|
|
18
|
+
export interface AuthState {
|
|
19
|
+
isLoading: boolean;
|
|
20
|
+
isAuthReady: boolean;
|
|
21
|
+
isSignedIn: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* True only when a real MSAL account is present (a usable token can be
|
|
24
|
+
* acquired). Unlike `isSignedIn`, this is NOT inflated by `noAuthMode`
|
|
25
|
+
* (login-bypassed / demo sessions report `isSignedIn: true` but have no
|
|
26
|
+
* account and `acquireToken` always returns null). Offline engagement must
|
|
27
|
+
* gate on this — engaging offline without a token spins the SDK orchestrator
|
|
28
|
+
* in a perpetual "waiting-for-auth" retry loop.
|
|
29
|
+
*/
|
|
30
|
+
hasRealAccount: boolean;
|
|
31
|
+
error: Error | null;
|
|
32
|
+
acquireToken: (scopes: string[]) => Promise<string | null>;
|
|
33
|
+
signIn: () => Promise<void>;
|
|
34
|
+
signOut: () => Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
export interface AuthProviderProps {
|
|
37
|
+
/**
|
|
38
|
+
* MSAL configuration from the consuming app's auth.config.json (msal section).
|
|
39
|
+
* `useBroker` defaults to `!__DEV__` when omitted — broker is enabled
|
|
40
|
+
* automatically in release builds and disabled in the dev client.
|
|
41
|
+
*/
|
|
42
|
+
msalConfig: MsalAuthConfig;
|
|
43
|
+
/**
|
|
44
|
+
* Intune MAM configuration. `enabled` defaults to `!__DEV__` when omitted,
|
|
45
|
+
* so MAM enrollment is active in release builds and skipped in the dev client.
|
|
46
|
+
* Pass explicitly only to override the default (e.g. in tests).
|
|
47
|
+
*/
|
|
48
|
+
intuneConfig?: IntuneConfig;
|
|
49
|
+
children: React.ReactNode;
|
|
50
|
+
}
|
|
51
|
+
export declare function AuthProvider({ msalConfig, intuneConfig, children }: AuthProviderProps): React.JSX.Element;
|
|
52
|
+
/**
|
|
53
|
+
* Returns the current auth state from the nearest <AuthProvider>.
|
|
54
|
+
* Must be called within the AuthProvider tree.
|
|
55
|
+
*/
|
|
56
|
+
export declare function useAuth(): AuthState;
|
|
57
|
+
//# sourceMappingURL=AuthContext.d.ts.map
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* power-apps-native-host — NativePowerAppsBridge
|
|
3
|
+
*
|
|
4
|
+
* A PowerAppsBridge implementation for React Native that handles all plugin
|
|
5
|
+
* calls in-process: auth tokens are supplied by the host app via callbacks,
|
|
6
|
+
* and HTTP is performed with the global `fetch` (built into RN 0.60+).
|
|
7
|
+
*
|
|
8
|
+
* This file mirrors the bridge in the SDK but lives here so the package can
|
|
9
|
+
* be used without patching the published @microsoft/power-apps tarball.
|
|
10
|
+
*/
|
|
11
|
+
import type { NativeConnectionInstance } from '../connections/types';
|
|
12
|
+
export type CdsDataSourceConfig = Record<string, unknown>;
|
|
13
|
+
/**
|
|
14
|
+
* Per-connection-reference data keyed by data source name
|
|
15
|
+
* (e.g. "commondataserviceforapps", "office365users").
|
|
16
|
+
* Returned to the SDK for AppPowerAppsClientPlugin.loadAppConnectionsAsync_v2
|
|
17
|
+
* and AppPowerAppsClientPlugin.loadNonCompositeConnectionsAsync.
|
|
18
|
+
*/
|
|
19
|
+
export interface AppConnectionReference {
|
|
20
|
+
/** Connector API ID, e.g. "/providers/Microsoft.PowerApps/apis/shared_commondataserviceforapps" */
|
|
21
|
+
apiId: string;
|
|
22
|
+
/** Connector runtime base URL (environment-specific). */
|
|
23
|
+
runtimeUrl: string;
|
|
24
|
+
/** Per-user connection identifier assigned by Power Platform. */
|
|
25
|
+
connectionName: string;
|
|
26
|
+
/** Dataset name (e.g. Dataverse org URL for CDS). */
|
|
27
|
+
datasetName?: string;
|
|
28
|
+
[key: string]: unknown;
|
|
29
|
+
instances?: NativeConnectionInstance[];
|
|
30
|
+
}
|
|
31
|
+
/** @deprecated Use AppConnectionReference */
|
|
32
|
+
export type AppConnection = AppConnectionReference;
|
|
33
|
+
/**
|
|
34
|
+
* Build a connection-references map (keyed by data source name) from the
|
|
35
|
+
* `connectionReferences` section of power.config.json.
|
|
36
|
+
*
|
|
37
|
+
* Each entry from power.config.json looks like:
|
|
38
|
+
* { id: "/providers/Microsoft.PowerApps/apis/shared_XXX", dataSources: ["XXX"], ... }
|
|
39
|
+
*
|
|
40
|
+
* The resulting map shape is what the SDK expects for loadAppConnectionsAsync_v2:
|
|
41
|
+
* { XXX: { apiId, runtimeUrl, connectionName, datasetName } }
|
|
42
|
+
*
|
|
43
|
+
* `runtimeUrl` and `connectionName` default to empty strings — they must be
|
|
44
|
+
* populated at runtime from the Power Platform connections API for the SDK to
|
|
45
|
+
* make actual connector API calls.
|
|
46
|
+
*
|
|
47
|
+
* @param powerConfigConnectionReferences - The `connectionReferences` object
|
|
48
|
+
* from power.config.json.
|
|
49
|
+
*/
|
|
50
|
+
export declare function buildConnectionReferences(powerConfigConnectionReferences: Record<string, {
|
|
51
|
+
id: string;
|
|
52
|
+
dataSources: string[];
|
|
53
|
+
[key: string]: unknown;
|
|
54
|
+
}>): Record<string, AppConnectionReference>;
|
|
55
|
+
export type NativeBridgeOptions = {
|
|
56
|
+
/**
|
|
57
|
+
* Return an auth token scoped to a connector API endpoint.
|
|
58
|
+
* @param apiId - Connection API identifier (e.g. "shared_sharepointonline").
|
|
59
|
+
*/
|
|
60
|
+
getConnectorToken(apiId: string): Promise<string>;
|
|
61
|
+
/**
|
|
62
|
+
* Return an auth token for a Dataverse org URL.
|
|
63
|
+
* @param datasetName - The Dataverse org URL used as the OAuth resource.
|
|
64
|
+
*/
|
|
65
|
+
getDataverseToken(datasetName: string): Promise<string>;
|
|
66
|
+
/** Data-source configs from the app manifest / Power Apps server response. */
|
|
67
|
+
dataSources: CdsDataSourceConfig[];
|
|
68
|
+
/**
|
|
69
|
+
* Connection references keyed by data source name
|
|
70
|
+
* (e.g. { commondataserviceforapps: { apiId, runtimeUrl, connectionName } }).
|
|
71
|
+
* Returned to the SDK for loadAppConnectionsAsync_v2 and
|
|
72
|
+
* loadNonCompositeConnectionsAsync. Build from power.config.json's
|
|
73
|
+
* connectionReferences using buildConnectionReferences().
|
|
74
|
+
*/
|
|
75
|
+
connections: Record<string, AppConnectionReference>;
|
|
76
|
+
};
|
|
77
|
+
export declare class NativePowerAppsBridge {
|
|
78
|
+
private _options;
|
|
79
|
+
constructor(_options: NativeBridgeOptions);
|
|
80
|
+
/**
|
|
81
|
+
* Updates the bridge's options in-place.
|
|
82
|
+
*
|
|
83
|
+
* Call this when connection references or data sources change (e.g. after
|
|
84
|
+
* a new connection is created) without recreating the bridge. The SDK caches
|
|
85
|
+
* the bridge instance after the first data operation, so replacing the bridge
|
|
86
|
+
* via globalThis would have no effect — mutating options is the correct path.
|
|
87
|
+
*/
|
|
88
|
+
updateOptions(options: NativeBridgeOptions): void;
|
|
89
|
+
initialize(): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Hermes-safe body construction. Returns the raw body value so that
|
|
92
|
+
* _sendHttpAsync can pass it directly to fetch without any Blob wrapping.
|
|
93
|
+
*
|
|
94
|
+
* The web-player's RuntimeDataClient wraps all bodies in `new Blob([...])`,
|
|
95
|
+
* which Hermes does not support for ArrayBuffer / TypedArray inputs.
|
|
96
|
+
* Implementing this hook on the bridge bypasses that wrapping entirely.
|
|
97
|
+
*/
|
|
98
|
+
createRequestBody(config: {
|
|
99
|
+
body?: string | Uint8Array | ArrayBuffer | Blob;
|
|
100
|
+
headers?: {
|
|
101
|
+
[key: string]: string;
|
|
102
|
+
};
|
|
103
|
+
}): Blob | string | Uint8Array | ArrayBuffer;
|
|
104
|
+
executePluginAsync<T = unknown>(pluginName: string, pluginAction: string, params: unknown[]): Promise<T>;
|
|
105
|
+
/**
|
|
106
|
+
* Calls fetch and returns the result in the exact shape expected by
|
|
107
|
+
* RuntimeDataClient._executeRequest:
|
|
108
|
+
* [{ status: number; headers: Record<string, string> }, ArrayBuffer]
|
|
109
|
+
*/
|
|
110
|
+
private _sendHttpAsync;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=NativePowerAppsBridge.d.ts.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* power-apps-native-host — setupNativeHost
|
|
3
|
+
*
|
|
4
|
+
* Registers a NativePowerAppsBridge on the JS global (globalThis.powerAppsBridge)
|
|
5
|
+
* so the @microsoft/power-apps SDK picks it up automatically on the first data
|
|
6
|
+
* operation. The SDK reads globalThis.powerAppsBridge in getBridge() before
|
|
7
|
+
* falling back to the web DefaultPowerAppsBridge.
|
|
8
|
+
*
|
|
9
|
+
* Call this once at app root before any data operations. Re-calling with updated
|
|
10
|
+
* options (e.g. when connections change) is safe — it updates the existing bridge
|
|
11
|
+
* in-place without resetting the SDK's cached bridge promise.
|
|
12
|
+
*/
|
|
13
|
+
import type { NativeBridgeOptions } from './NativePowerAppsBridge';
|
|
14
|
+
/**
|
|
15
|
+
* Registers a NativePowerAppsBridge for all @microsoft/power-apps SDK calls.
|
|
16
|
+
*
|
|
17
|
+
* On first call, creates a NativePowerAppsBridge and injects it into
|
|
18
|
+
* `globalThis.powerAppsBridge`. Subsequent calls update the bridge's options
|
|
19
|
+
* in-place so connection references and data sources can change without
|
|
20
|
+
* rebuilding the bridge (important because the SDK caches the bridge instance
|
|
21
|
+
* after first use).
|
|
22
|
+
*
|
|
23
|
+
* Idempotent with the same options reference — no-op if nothing changed.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* // App.tsx (root)
|
|
28
|
+
* import { setupNativeHost } from '@microsoft/power-apps-native-host';
|
|
29
|
+
*
|
|
30
|
+
* setupNativeHost({
|
|
31
|
+
* getConnectorToken: (apiId) => msalClient.acquireToken({ resource: apiId }),
|
|
32
|
+
* getDataverseToken: (datasetName) => msalClient.acquireToken({ resource: datasetName }),
|
|
33
|
+
* dataSources: appManifest.dataSources,
|
|
34
|
+
* connections: appManifest.connections,
|
|
35
|
+
* });
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare function setupNativeHost(options: NativeBridgeOptions): void;
|
|
39
|
+
//# sourceMappingURL=setupNativeHost.d.ts.map
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* power-apps-native-host — ConnectionSetupScreen
|
|
3
|
+
*
|
|
4
|
+
* A ready-made React Native screen that drives the "create missing connections"
|
|
5
|
+
* flow before the Power Apps player is shown.
|
|
6
|
+
*
|
|
7
|
+
* Intended usage in an expo-router layout:
|
|
8
|
+
*
|
|
9
|
+
* // app/(app)/_layout.tsx
|
|
10
|
+
* import { ConnectionSetupScreen } from '@microsoft/power-apps-native-host';
|
|
11
|
+
*
|
|
12
|
+
* if (missingConnectors.length > 0) {
|
|
13
|
+
* return (
|
|
14
|
+
* <ConnectionSetupScreen
|
|
15
|
+
* missingConnectors={missingConnectors} // from useConnectionRefs
|
|
16
|
+
* schemaMap={schemaMap}
|
|
17
|
+
* environmentId={powerConfig.environmentId}
|
|
18
|
+
* region={powerConfig.region}
|
|
19
|
+
* acquireToken={acquireToken}
|
|
20
|
+
* onAllConnected={(resolvedIds) => {
|
|
21
|
+
* // resolvedIds: Record<apiId, connectionId>
|
|
22
|
+
* // Store them, then set missingConnectors = [] to unmount this screen.
|
|
23
|
+
* }}
|
|
24
|
+
* onSkip={() => { ... }} // optional — hide skip button if not provided
|
|
25
|
+
* />
|
|
26
|
+
* );
|
|
27
|
+
* }
|
|
28
|
+
*
|
|
29
|
+
* What the screen does for each missing connector, in order:
|
|
30
|
+
* 1. Shows connector name / description (fetched from API).
|
|
31
|
+
* 2. "Connect" button → calls createConnection → shows an in-app WebView
|
|
32
|
+
* with the OAuth consent URL.
|
|
33
|
+
* 3. "Done" button in WebView header → calls checkNow() to confirm status.
|
|
34
|
+
* 4. On Connected → advances to the next missing connector.
|
|
35
|
+
* 5. When all connectors are resolved → calls onAllConnected.
|
|
36
|
+
*
|
|
37
|
+
* The component has zero production dependencies beyond react-native.
|
|
38
|
+
* It purposely does NOT depend on expo-router or any navigation library —
|
|
39
|
+
* the consuming app decides how to render it (full-screen, modal, etc.).
|
|
40
|
+
*/
|
|
41
|
+
import React from 'react';
|
|
42
|
+
import type { ConnectorSchema } from '../platform/useConnectionRefs';
|
|
43
|
+
export interface MissingConnectorEntry {
|
|
44
|
+
/** Connector API ID (e.g. "/providers/Microsoft.PowerApps/apis/shared_office365users"). */
|
|
45
|
+
apiId: string;
|
|
46
|
+
/** Local ref ID from power.config.json (for correlation). */
|
|
47
|
+
localRefId: string;
|
|
48
|
+
}
|
|
49
|
+
export interface ConnectionSetupScreenProps {
|
|
50
|
+
/**
|
|
51
|
+
* List of connectors that have no Connected connection.
|
|
52
|
+
* Each entry has the apiId and localRefId from the disambiguation result.
|
|
53
|
+
*/
|
|
54
|
+
missingConnectors: MissingConnectorEntry[];
|
|
55
|
+
/**
|
|
56
|
+
* Connector schema map (from generate-connector-schemas / schemaMap).
|
|
57
|
+
* Used to map apiId → connectorId (short name) for API calls.
|
|
58
|
+
*/
|
|
59
|
+
schemaMap: Record<string, ConnectorSchema>;
|
|
60
|
+
environmentId: string;
|
|
61
|
+
region?: string;
|
|
62
|
+
acquireToken: (scopes: string[]) => Promise<string | null>;
|
|
63
|
+
/**
|
|
64
|
+
* Called when all missing connections have been resolved.
|
|
65
|
+
* `resolvedIds` maps apiId → connectionId for all newly created connections.
|
|
66
|
+
*/
|
|
67
|
+
onAllConnected: (resolvedIds: Record<string, string>) => void;
|
|
68
|
+
/**
|
|
69
|
+
* If provided, a "Skip" button is shown. Useful for non-blocking connection flows.
|
|
70
|
+
* The app should handle the case where connections remain unresolved.
|
|
71
|
+
*/
|
|
72
|
+
onSkip?: () => void;
|
|
73
|
+
/**
|
|
74
|
+
* The ISV/wrap-app AAD client ID (from auth.config.json `msal.clientId`).
|
|
75
|
+
* Passed to `useConnectionSetup` so the ISV's service principal is granted
|
|
76
|
+
* access on each newly created connection, fixing the APIM 403 for
|
|
77
|
+
* third-party app tokens.
|
|
78
|
+
*/
|
|
79
|
+
isvClientId?: string;
|
|
80
|
+
/**
|
|
81
|
+
* Optional custom renderer for the OAuth WebView.
|
|
82
|
+
* Receives the consent URL and a dismiss callback.
|
|
83
|
+
* If not provided, `Linking.openURL()` is used to open the URL in the system browser.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* // Using react-native-webview:
|
|
87
|
+
* renderOAuthWebView={(url, onDone) => (
|
|
88
|
+
* <Modal visible animationType="slide">
|
|
89
|
+
* <WebView source={{ uri: url }} />
|
|
90
|
+
* <Button title="Done" onPress={onDone} />
|
|
91
|
+
* </Modal>
|
|
92
|
+
* )}
|
|
93
|
+
*/
|
|
94
|
+
renderOAuthWebView?: (url: string, onDone: () => void) => React.ReactNode;
|
|
95
|
+
/** Optional title override (default: "Set up connections"). */
|
|
96
|
+
title?: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Full-screen component that steps the user through creating each missing
|
|
100
|
+
* connection before the Power Apps player is launched.
|
|
101
|
+
*
|
|
102
|
+
* The screen works through missing connectors sequentially. Once all are
|
|
103
|
+
* resolved `onAllConnected` fires and the parent app should unmount this
|
|
104
|
+
* component and proceed to launch the app.
|
|
105
|
+
*/
|
|
106
|
+
export declare function ConnectionSetupScreen({ missingConnectors, schemaMap, environmentId, region, acquireToken, isvClientId, onAllConnected, onSkip, renderOAuthWebView, title, }: ConnectionSetupScreenProps): React.JSX.Element;
|
|
107
|
+
//# sourceMappingURL=ConnectionSetupScreen.d.ts.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* power-apps-native-host — connection disambiguation logic
|
|
3
|
+
*
|
|
4
|
+
* Pure function that matches power.config.json connectionReferences to the
|
|
5
|
+
* connection instances available in the user's Power Platform environment.
|
|
6
|
+
*
|
|
7
|
+
* Mirrors the core of ConnectionPipeline.matchConnectionsToUsages in the web
|
|
8
|
+
* host but is self-contained — it does not require IConnectionService or any
|
|
9
|
+
* other web-host dependency.
|
|
10
|
+
*/
|
|
11
|
+
import type { NativeConnectionInstance, NativeConnectionResolution } from './types';
|
|
12
|
+
/**
|
|
13
|
+
* Disambiguate a set of connection references against the user's available
|
|
14
|
+
* connection instances.
|
|
15
|
+
*
|
|
16
|
+
* Rules (in priority order):
|
|
17
|
+
* 1. If exactly one `Connected` connection matches the reference apiId → resolved.
|
|
18
|
+
* 2. If zero connections match (or none are Connected) → missing.
|
|
19
|
+
* 3. If multiple Connected connections match → ambiguous (needs user pick).
|
|
20
|
+
*
|
|
21
|
+
* @param connectionReferences The `connectionReferences` object from power.config.json,
|
|
22
|
+
* keyed by local reference ID.
|
|
23
|
+
* @param allConnectionsByApiId All connection instances fetched from the
|
|
24
|
+
* Power Platform connectivity API, keyed by
|
|
25
|
+
* connector apiId.
|
|
26
|
+
*/
|
|
27
|
+
export declare function disambiguateConnections(connectionReferences: Record<string, {
|
|
28
|
+
id: string;
|
|
29
|
+
dataSources: string[];
|
|
30
|
+
}>, allConnectionsByApiId: Record<string, NativeConnectionInstance[]>): NativeConnectionResolution[];
|
|
31
|
+
/**
|
|
32
|
+
* Extract the connection UUID from a raw connection name returned by the API.
|
|
33
|
+
*
|
|
34
|
+
* The API returns names like:
|
|
35
|
+
* "shared_office365users/abc12345def6789012345678901234ab" (connector-prefixed)
|
|
36
|
+
* "abc12345def6789012345678901234ab" (bare UUID, no dashes)
|
|
37
|
+
* "abc12345-def6-7890-1234-5678901234ab" (UUID with dashes)
|
|
38
|
+
*
|
|
39
|
+
* Returns the 32-char hex ID (dashes stripped) or the raw string if no UUID
|
|
40
|
+
* pattern is found.
|
|
41
|
+
*/
|
|
42
|
+
export declare function extractConnectionId(rawName: string): string;
|
|
43
|
+
//# sourceMappingURL=disambiguate.d.ts.map
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* power-apps-native-host — connection disambiguation types
|
|
3
|
+
*
|
|
4
|
+
* Defines the native-host-specific types for connection resolution. The web
|
|
5
|
+
* host equivalents live in @microsoft/power-apps-host, but the native host
|
|
6
|
+
* implements a lighter version that does not depend on IConnectionService.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Resolved authorization state of a connection instance.
|
|
10
|
+
*
|
|
11
|
+
* - `Connected` — platform status is Connected AND the ISV appid is in the connection ACL.
|
|
12
|
+
* - `NeedsAclGrant` — platform status is Connected but the ISV appid is missing from the ACL.
|
|
13
|
+
* - `NotConnected` — platform status is anything other than Connected.
|
|
14
|
+
*/
|
|
15
|
+
export declare enum ConnectionStatus {
|
|
16
|
+
Connected = "Connected",
|
|
17
|
+
NeedsAclGrant = "NeedsAclGrant",
|
|
18
|
+
NotConnected = "NotConnected"
|
|
19
|
+
}
|
|
20
|
+
/** A single connection instance returned by the Power Platform connectivity API. */
|
|
21
|
+
export interface NativeConnectionInstance {
|
|
22
|
+
/** Extracted connection UUID (hex, no dashes). */
|
|
23
|
+
id: string;
|
|
24
|
+
/** Full resource name from the API (connector-prefixed, e.g. "shared_office365users/abc123"). */
|
|
25
|
+
name: string;
|
|
26
|
+
/** Connector API identifier (e.g. "/providers/Microsoft.PowerApps/apis/shared_office365users"). */
|
|
27
|
+
apiId: string;
|
|
28
|
+
/** Resolved authorization status of this connection. */
|
|
29
|
+
status: ConnectionStatus;
|
|
30
|
+
/** Optional human-readable display name from the API. */
|
|
31
|
+
displayName?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Result of attempting to match a single connection reference to an instance.
|
|
35
|
+
*
|
|
36
|
+
* - `resolved` — exactly one Connected connection found; `connectionId` is set.
|
|
37
|
+
* - `missing` — no connections found for this connector in the user's environment.
|
|
38
|
+
* - `ambiguous` — multiple Connected connections found; the app must pick one.
|
|
39
|
+
*/
|
|
40
|
+
export type NativeDisambiguationResult = {
|
|
41
|
+
kind: 'resolved';
|
|
42
|
+
connectionId: string;
|
|
43
|
+
} | {
|
|
44
|
+
kind: 'missing';
|
|
45
|
+
} | {
|
|
46
|
+
kind: 'ambiguous';
|
|
47
|
+
candidates: NativeConnectionInstance[];
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Disambiguation result for a single connection reference (one apiId, possibly
|
|
51
|
+
* mapped to multiple data source names in the final connections map).
|
|
52
|
+
*/
|
|
53
|
+
export interface NativeConnectionResolution {
|
|
54
|
+
/** Local reference key in power.config.json connectionReferences (e.g. "office365users-1"). */
|
|
55
|
+
localRefId: string;
|
|
56
|
+
/** Connector API ID (e.g. "/providers/Microsoft.PowerApps/apis/shared_office365users"). */
|
|
57
|
+
apiId: string;
|
|
58
|
+
/** Data source names this reference covers (e.g. ["office365users"]). */
|
|
59
|
+
dataSources: string[];
|
|
60
|
+
result: NativeDisambiguationResult;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Callback invoked when a connection reference has multiple Connected candidate
|
|
64
|
+
* connections. The consuming app should present a native picker UI (e.g. a
|
|
65
|
+
* bottom sheet) and return the selected connection ID.
|
|
66
|
+
*
|
|
67
|
+
* Return `null` to leave the connection unresolved (the SDK will receive an
|
|
68
|
+
* empty `connectionName` and data operations for that connector will fail).
|
|
69
|
+
*
|
|
70
|
+
* @param context.localRefId — local reference key from power.config.json
|
|
71
|
+
* @param context.apiId — connector API identifier
|
|
72
|
+
* @param context.candidates — list of Connected connection instances to choose from
|
|
73
|
+
*/
|
|
74
|
+
export type OnDisambiguationNeeded = (context: {
|
|
75
|
+
localRefId: string;
|
|
76
|
+
apiId: string;
|
|
77
|
+
candidates: NativeConnectionInstance[];
|
|
78
|
+
}) => Promise<string | null>;
|
|
79
|
+
/**
|
|
80
|
+
* Callback invoked when the user has no connection for a required connector.
|
|
81
|
+
*
|
|
82
|
+
* The consuming app can redirect to the Power Apps maker portal or show an
|
|
83
|
+
* in-app connection setup flow. Return `true` to indicate the user has
|
|
84
|
+
* created a connection and the hook should retry; return `false` to leave the
|
|
85
|
+
* connection unresolved.
|
|
86
|
+
*/
|
|
87
|
+
export type OnMissingConnection = (context: {
|
|
88
|
+
localRefId: string;
|
|
89
|
+
apiId: string;
|
|
90
|
+
}) => Promise<boolean>;
|
|
91
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* power-apps-native-host — useConnectionSetup
|
|
3
|
+
*
|
|
4
|
+
* A hook that drives the "create missing connection" flow for a single connector.
|
|
5
|
+
*
|
|
6
|
+
* Usage pattern (in the ConnectionSetupScreen):
|
|
7
|
+
*
|
|
8
|
+
* const setup = useConnectionSetup({
|
|
9
|
+
* connectorId: 'shared_office365users',
|
|
10
|
+
* environmentId,
|
|
11
|
+
* region,
|
|
12
|
+
* acquireToken,
|
|
13
|
+
* onConnected: (connectionId) => { ... mark resolved, advance to next ... }
|
|
14
|
+
* });
|
|
15
|
+
*
|
|
16
|
+
* // Render setup.consentUrl in a WebView when setup.phase === 'oauth'
|
|
17
|
+
* // Call setup.startCreate() to trigger connection creation
|
|
18
|
+
* // Call setup.checkNow() to re-poll after WebView finishes
|
|
19
|
+
*/
|
|
20
|
+
import type { NativeConnectionInstance } from '../connections/types';
|
|
21
|
+
/**
|
|
22
|
+
* The current phase of the connection setup flow for one connector.
|
|
23
|
+
*
|
|
24
|
+
* idle — not yet started.
|
|
25
|
+
* creating — POST in progress (showing a spinner).
|
|
26
|
+
* oauth — connection created; OAuth consent URL is ready (show WebView).
|
|
27
|
+
* confirming — WebView dismissed; polling for Connected status.
|
|
28
|
+
* connected — connection is Connected; ready to proceed.
|
|
29
|
+
* error — unrecoverable error; `errorMessage` is set.
|
|
30
|
+
*/
|
|
31
|
+
export type ConnectionSetupPhase = 'idle' | 'creating' | 'oauth' | 'confirming' | 'connected' | 'error';
|
|
32
|
+
export interface UseConnectionSetupOptions {
|
|
33
|
+
/**
|
|
34
|
+
* Connector short name (e.g. "shared_office365users").
|
|
35
|
+
* Must match the connectorId used in the connectivity API (schema.name from schemaMap).
|
|
36
|
+
*/
|
|
37
|
+
connectorId: string;
|
|
38
|
+
environmentId: string;
|
|
39
|
+
/** Cluster region (default "prod"). */
|
|
40
|
+
region?: string;
|
|
41
|
+
acquireToken: (scopes: string[]) => Promise<string | null>;
|
|
42
|
+
/** Called with the resolved `NativeConnectionInstance` when the connection is Connected. */
|
|
43
|
+
onConnected?: (instance: NativeConnectionInstance) => void;
|
|
44
|
+
/**
|
|
45
|
+
* The ISV/wrap-app AAD client ID (from auth.config.json `msal.clientId`).
|
|
46
|
+
* After connection creation, `addAadAppToConnectionAcl` is called to append
|
|
47
|
+
* the ISV's client ID to the connection ACE's AppIds list. This is required
|
|
48
|
+
* so that APIM accepts tokens bearing this appid at runtime (otherwise APIM
|
|
49
|
+
* returns 403 "missing connection ACL" for all third-party app tokens).
|
|
50
|
+
*/
|
|
51
|
+
isvClientId?: string;
|
|
52
|
+
/**
|
|
53
|
+
* Redirect URL passed to the getConsentLink API call.
|
|
54
|
+
* Defaults to the standard native-client redirect accepted by Power Platform.
|
|
55
|
+
*/
|
|
56
|
+
oauthRedirectUrl?: string;
|
|
57
|
+
/** Polling options forwarded to pollConnectionStatus. */
|
|
58
|
+
polling?: {
|
|
59
|
+
intervalMs?: number;
|
|
60
|
+
timeoutMs?: number;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export interface UseConnectionSetupResult {
|
|
64
|
+
/** Current phase of the flow. */
|
|
65
|
+
phase: ConnectionSetupPhase;
|
|
66
|
+
/** OAuth consent URL — render in a WebView when phase === 'oauth'. */
|
|
67
|
+
consentUrl: string | null;
|
|
68
|
+
/** Error message when phase === 'error'. */
|
|
69
|
+
errorMessage: string | null;
|
|
70
|
+
/**
|
|
71
|
+
* Start the connection creation flow.
|
|
72
|
+
* Transitions: idle/error → creating → (oauth | connected | error).
|
|
73
|
+
*/
|
|
74
|
+
startCreate: () => Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Call after the OAuth WebView is dismissed (or anytime during 'oauth' phase)
|
|
77
|
+
* to immediately poll the connection status instead of waiting for the next
|
|
78
|
+
* scheduled poll interval.
|
|
79
|
+
* Transitions: oauth → confirming → (connected | error).
|
|
80
|
+
*/
|
|
81
|
+
checkNow: () => Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Call after the in-app browser session completes.
|
|
84
|
+
*
|
|
85
|
+
* If a `code` (CommitTokenCode) was returned in the redirect URL, it is
|
|
86
|
+
* POSTed to `confirmConsentCode` before polling. If no code is provided
|
|
87
|
+
* (custom-scheme redirect or dismiss), polling starts immediately.
|
|
88
|
+
*
|
|
89
|
+
* Transitions: oauth → confirming → (connected | error).
|
|
90
|
+
*/
|
|
91
|
+
completeConsent: (code?: string) => Promise<void>;
|
|
92
|
+
/** Reset the flow back to idle (e.g., for a retry). */
|
|
93
|
+
reset: () => void;
|
|
94
|
+
}
|
|
95
|
+
export declare function useConnectionSetup({ connectorId, environmentId, region, acquireToken, onConnected, isvClientId, oauthRedirectUrl, polling, }: UseConnectionSetupOptions): UseConnectionSetupResult;
|
|
96
|
+
//# sourceMappingURL=useConnectionSetup.d.ts.map
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type StyleProp, type ViewStyle, type TextStyle } from 'react-native';
|
|
3
|
+
export interface PickedFileInfo {
|
|
4
|
+
uri: string;
|
|
5
|
+
name: string;
|
|
6
|
+
mimeType: string;
|
|
7
|
+
/** File-compatible object ready for generated Dataverse upload methods. */
|
|
8
|
+
file: File;
|
|
9
|
+
/** Raw bytes of the file, ready to pass to lower-level upload APIs. */
|
|
10
|
+
bytes: Uint8Array;
|
|
11
|
+
}
|
|
12
|
+
export interface FilePickerProps {
|
|
13
|
+
label?: string;
|
|
14
|
+
/**
|
|
15
|
+
* The file name to display.
|
|
16
|
+
* - In view mode: the name of the existing Dataverse file.
|
|
17
|
+
* - In edit mode: the existing file name; falls back to the name of a newly picked file.
|
|
18
|
+
*/
|
|
19
|
+
fileName?: string | null;
|
|
20
|
+
/**
|
|
21
|
+
* If provided, the file name row becomes tappable: calls this to obtain the
|
|
22
|
+
* raw bytes, writes them to the device cache, and opens the system share sheet.
|
|
23
|
+
*/
|
|
24
|
+
onDownload?: () => Promise<Uint8Array>;
|
|
25
|
+
/** Share sheet dialog title. Defaults to `fileName`. */
|
|
26
|
+
shareTitle?: string;
|
|
27
|
+
/**
|
|
28
|
+
* If provided, a pick/replace button is shown.
|
|
29
|
+
* Called with the picked file and its pre-read bytes; the parent passes
|
|
30
|
+
* `bytes` directly to the upload service at save time.
|
|
31
|
+
*/
|
|
32
|
+
onChange?: (file: PickedFileInfo) => void;
|
|
33
|
+
/** MIME type filter for the document picker. Defaults to all files. */
|
|
34
|
+
acceptedTypes?: string[];
|
|
35
|
+
/** Override the initial pick button label. */
|
|
36
|
+
pickButtonLabel?: string;
|
|
37
|
+
/** Override the replace button label after a file exists. */
|
|
38
|
+
replaceButtonLabel?: string;
|
|
39
|
+
/** Override the button label while the picked file is being read. */
|
|
40
|
+
readingLabel?: string;
|
|
41
|
+
/** Override the outer container (adds margin below by default). */
|
|
42
|
+
containerStyle?: StyleProp<ViewStyle>;
|
|
43
|
+
/** Override the label text style. */
|
|
44
|
+
labelStyle?: StyleProp<TextStyle>;
|
|
45
|
+
/** Override the file-name row container. */
|
|
46
|
+
fileRowStyle?: StyleProp<ViewStyle>;
|
|
47
|
+
/** Override the file-name text. */
|
|
48
|
+
fileNameStyle?: StyleProp<TextStyle>;
|
|
49
|
+
/** Override the pick/replace button container. */
|
|
50
|
+
buttonStyle?: StyleProp<ViewStyle>;
|
|
51
|
+
/** Override the pick/replace button text. */
|
|
52
|
+
buttonTextStyle?: StyleProp<TextStyle>;
|
|
53
|
+
/** Accent colour used for icons, borders and text. Defaults to `'#0078d4'`. */
|
|
54
|
+
accentColor?: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* A unified file component for view and edit scenarios.
|
|
58
|
+
*
|
|
59
|
+
* - Pass `onDownload` alone for a read-only row that opens the share sheet on tap.
|
|
60
|
+
* - Pass `onChange` alone for a pick-only button (e.g. in an edit form).
|
|
61
|
+
* - Pass both to show the existing file name (tappable to download) alongside a
|
|
62
|
+
* replace button — useful when the edit screen should also allow previewing.
|
|
63
|
+
*/
|
|
64
|
+
export declare function FilePicker({ label, fileName, onDownload, shareTitle, onChange, acceptedTypes, pickButtonLabel, replaceButtonLabel, readingLabel, containerStyle, labelStyle, fileRowStyle, fileNameStyle, buttonStyle, buttonTextStyle, accentColor, }: FilePickerProps): React.JSX.Element;
|
|
65
|
+
//# sourceMappingURL=FilePicker.d.ts.map
|