@microsoft/power-apps-native-host 0.2.25 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -10
- package/compatibility/current.json +31 -4
- package/lib/NOTICE.txt +1325 -24
- package/lib/commonjs/auth/AuthContext.js +110 -33
- package/lib/commonjs/bridge/NativePowerAppsBridge.js +11 -18
- package/lib/commonjs/bridge/PowerPagesBridge.js +27 -8
- package/lib/commonjs/bridge/bridgeState.js +40 -0
- package/lib/commonjs/config/babelConfig.js +13 -0
- package/lib/commonjs/config/expoConfig.js +71 -0
- package/lib/commonjs/config/metroConfig.js +70 -0
- package/lib/commonjs/config/metroLogger.js +182 -0
- package/lib/commonjs/config/tamaguiConfig.js +98 -0
- package/lib/commonjs/connections/ConnectionSetupScreen.js +459 -80
- package/lib/commonjs/connections/PowerPlatformConnectionApi.js +946 -0
- package/lib/commonjs/connections/connectionMetadata.js +127 -0
- package/lib/commonjs/connections/connectionState.js +96 -0
- package/lib/commonjs/connections/disambiguate.js +19 -11
- package/lib/commonjs/connections/resolveConnections.js +348 -0
- package/lib/commonjs/connections/types.js +106 -0
- package/lib/commonjs/{platform → connections}/useConnectionRefs.js +130 -65
- package/lib/commonjs/connections/useConnectionSetup.js +111 -52
- package/lib/commonjs/controls/FilePicker.js +6 -0
- package/lib/commonjs/controls/ImagePicker.js +8 -0
- package/lib/commonjs/index.js +167 -4
- package/lib/commonjs/logger.js +9 -6
- package/lib/commonjs/offline/createOfflineHostActivationCallbacks.js +61 -0
- package/lib/commonjs/offline/useOfflineIntegrationWithStartupGate.js +48 -0
- package/lib/commonjs/offline/useOfflineIntegrationWithStartupGate.web.js +13 -0
- package/lib/commonjs/platform/DataverseDataSources.js +18 -0
- package/lib/commonjs/platform/DataverseGlobalDiscoveryApi.js +94 -0
- package/lib/commonjs/platform/GlobalDiscovery.js +51 -0
- package/lib/commonjs/platform/PowerPlatformEnvironmentApi.js +6 -106
- package/lib/commonjs/provider/PowerAppsHostProvider.js +157 -25
- package/lib/commonjs/provider/PowerAppsProvider.js +178 -134
- package/lib/commonjs/provider/SessionDetailsGesture.js +208 -0
- package/lib/commonjs/telemetry/OfflineSdkTelemetry.js +95 -0
- package/lib/commonjs/telemetry/OfflineSdkTelemetry.web.js +9 -0
- package/lib/commonjs/telemetry/index.js +22 -3
- package/lib/module/auth/AuthContext.js +110 -33
- package/lib/module/bridge/NativePowerAppsBridge.js +12 -19
- package/lib/module/bridge/PowerPagesBridge.js +27 -8
- package/lib/module/bridge/bridgeState.js +34 -0
- package/lib/module/config/babelConfig.js +9 -0
- package/lib/module/config/expoConfig.js +67 -0
- package/lib/module/config/metroConfig.js +65 -0
- package/lib/module/config/metroLogger.js +175 -0
- package/lib/module/config/tamaguiConfig.js +93 -0
- package/lib/module/connections/ConnectionSetupScreen.js +460 -81
- package/lib/module/connections/PowerPlatformConnectionApi.js +932 -0
- package/lib/module/connections/connectionMetadata.js +112 -0
- package/lib/module/connections/connectionState.js +82 -0
- package/lib/module/connections/disambiguate.js +19 -12
- package/lib/module/connections/resolveConnections.js +343 -0
- package/lib/module/connections/types.js +91 -0
- package/lib/module/{platform → connections}/useConnectionRefs.js +131 -66
- package/lib/module/connections/useConnectionSetup.js +113 -54
- package/lib/module/controls/FilePicker.js +6 -0
- package/lib/module/controls/ImagePicker.js +8 -0
- package/lib/module/index.js +14 -4
- package/lib/module/logger.js +8 -6
- package/lib/module/offline/createOfflineHostActivationCallbacks.js +55 -0
- package/lib/module/offline/useOfflineIntegrationWithStartupGate.js +44 -0
- package/lib/module/offline/useOfflineIntegrationWithStartupGate.web.js +9 -0
- package/lib/module/platform/DataverseDataSources.js +13 -0
- package/lib/module/platform/DataverseGlobalDiscoveryApi.js +89 -0
- package/lib/module/platform/GlobalDiscovery.js +45 -0
- package/lib/module/platform/PowerPlatformEnvironmentApi.js +5 -104
- package/lib/module/provider/PowerAppsHostProvider.js +160 -28
- package/lib/module/provider/PowerAppsProvider.js +182 -138
- package/lib/module/provider/SessionDetailsGesture.js +203 -0
- package/lib/module/telemetry/OfflineSdkTelemetry.js +91 -0
- package/lib/module/telemetry/OfflineSdkTelemetry.web.js +5 -0
- package/lib/module/telemetry/index.js +15 -4
- package/lib/typescript/commonjs/auth/AuthContext.d.ts +3 -1
- package/lib/typescript/commonjs/auth/AuthContext.web.d.ts +1 -0
- package/lib/typescript/commonjs/bridge/bridgeState.d.ts +5 -0
- package/lib/typescript/commonjs/config/babelConfig.d.ts +12 -0
- package/lib/typescript/commonjs/config/expoConfig.d.ts +21 -0
- package/lib/typescript/commonjs/config/metroConfig.d.ts +6 -0
- package/lib/typescript/commonjs/config/metroLogger.d.ts +21 -0
- package/lib/typescript/commonjs/config/tamaguiConfig.d.ts +1792 -0
- package/lib/typescript/commonjs/connections/ConnectionSetupScreen.d.ts +28 -7
- package/lib/typescript/commonjs/{platform → connections}/PowerPlatformConnectionApi.d.ts +52 -43
- package/lib/typescript/commonjs/connections/connectionMetadata.d.ts +66 -0
- package/lib/typescript/commonjs/connections/connectionState.d.ts +16 -0
- package/lib/typescript/commonjs/connections/disambiguate.d.ts +4 -2
- package/lib/typescript/commonjs/{platform → connections}/resolveConnections.d.ts +22 -20
- package/lib/typescript/commonjs/connections/types.d.ts +129 -1
- package/lib/typescript/commonjs/{platform → connections}/useConnectionRefs.d.ts +36 -25
- package/lib/typescript/commonjs/connections/useConnectionSetup.d.ts +12 -8
- package/lib/typescript/commonjs/controls/FilePicker.d.ts +7 -1
- package/lib/typescript/commonjs/controls/ImagePicker.d.ts +9 -1
- package/lib/typescript/commonjs/index.d.ts +18 -10
- package/lib/typescript/commonjs/logger.d.ts +4 -4
- package/lib/typescript/commonjs/offline/createOfflineHostActivationCallbacks.d.ts +12 -0
- package/lib/typescript/commonjs/offline/useOfflineIntegrationWithStartupGate.d.ts +15 -0
- package/lib/typescript/commonjs/offline/useOfflineIntegrationWithStartupGate.web.d.ts +6 -0
- package/lib/typescript/commonjs/platform/DataverseDataSources.d.ts +28 -0
- package/lib/typescript/commonjs/platform/DataverseGlobalDiscoveryApi.d.ts +3 -0
- package/lib/typescript/commonjs/platform/GlobalDiscovery.d.ts +4 -0
- package/lib/typescript/commonjs/platform/PowerPlatformEnvironmentApi.d.ts +3 -74
- package/lib/typescript/commonjs/provider/PowerAppsHostProvider.d.ts +29 -18
- package/lib/typescript/commonjs/provider/PowerAppsProvider.d.ts +54 -9
- package/lib/typescript/commonjs/provider/SessionDetailsGesture.d.ts +13 -0
- package/lib/typescript/commonjs/telemetry/OfflineSdkTelemetry.d.ts +15 -0
- package/lib/typescript/commonjs/telemetry/OfflineSdkTelemetry.web.d.ts +2 -0
- package/lib/typescript/commonjs/telemetry/index.d.ts +13 -1
- package/lib/typescript/module/auth/AuthContext.d.ts +3 -1
- package/lib/typescript/module/auth/AuthContext.web.d.ts +1 -0
- package/lib/typescript/module/bridge/bridgeState.d.ts +5 -0
- package/lib/typescript/module/config/babelConfig.d.ts +12 -0
- package/lib/typescript/module/config/expoConfig.d.ts +21 -0
- package/lib/typescript/module/config/metroConfig.d.ts +6 -0
- package/lib/typescript/module/config/metroLogger.d.ts +21 -0
- package/lib/typescript/module/config/tamaguiConfig.d.ts +1792 -0
- package/lib/typescript/module/connections/ConnectionSetupScreen.d.ts +28 -7
- package/lib/typescript/module/{platform → connections}/PowerPlatformConnectionApi.d.ts +52 -43
- package/lib/typescript/module/connections/connectionMetadata.d.ts +66 -0
- package/lib/typescript/module/connections/connectionState.d.ts +16 -0
- package/lib/typescript/module/connections/disambiguate.d.ts +4 -2
- package/lib/typescript/module/{platform → connections}/resolveConnections.d.ts +22 -20
- package/lib/typescript/module/connections/types.d.ts +129 -1
- package/lib/typescript/module/{platform → connections}/useConnectionRefs.d.ts +36 -25
- package/lib/typescript/module/connections/useConnectionSetup.d.ts +12 -8
- package/lib/typescript/module/controls/FilePicker.d.ts +7 -1
- package/lib/typescript/module/controls/ImagePicker.d.ts +9 -1
- package/lib/typescript/module/index.d.ts +18 -10
- package/lib/typescript/module/logger.d.ts +4 -4
- package/lib/typescript/module/offline/createOfflineHostActivationCallbacks.d.ts +12 -0
- package/lib/typescript/module/offline/useOfflineIntegrationWithStartupGate.d.ts +15 -0
- package/lib/typescript/module/offline/useOfflineIntegrationWithStartupGate.web.d.ts +6 -0
- package/lib/typescript/module/platform/DataverseDataSources.d.ts +28 -0
- package/lib/typescript/module/platform/DataverseGlobalDiscoveryApi.d.ts +3 -0
- package/lib/typescript/module/platform/GlobalDiscovery.d.ts +4 -0
- package/lib/typescript/module/platform/PowerPlatformEnvironmentApi.d.ts +3 -74
- package/lib/typescript/module/provider/PowerAppsHostProvider.d.ts +29 -18
- package/lib/typescript/module/provider/PowerAppsProvider.d.ts +54 -9
- package/lib/typescript/module/provider/SessionDetailsGesture.d.ts +13 -0
- package/lib/typescript/module/telemetry/OfflineSdkTelemetry.d.ts +15 -0
- package/lib/typescript/module/telemetry/OfflineSdkTelemetry.web.d.ts +2 -0
- package/lib/typescript/module/telemetry/index.d.ts +13 -1
- package/package.json +52 -13
- package/scripts/build-codegen-package.js +283 -0
- package/scripts/start-web.mjs +9 -5
- package/scripts/upgrade/runtime.js +139 -24
- package/scripts/upgrade-authoring.js +274 -180
- package/scripts/upgrade.js +10 -16
- package/src/config/generated-config.d.ts +4 -0
- package/src/config/index.d.ts +3 -0
- package/src/config/tsconfig.json +26 -0
- package/lib/commonjs/platform/PowerPlatformConnectionApi.js +0 -606
- package/lib/commonjs/platform/resolveConnections.js +0 -264
- package/lib/module/platform/PowerPlatformConnectionApi.js +0 -595
- package/lib/module/platform/resolveConnections.js +0 -259
|
@@ -28,11 +28,12 @@ import React from 'react';
|
|
|
28
28
|
import { createTamagui } from '@tamagui/core';
|
|
29
29
|
import type { AuthProviderProps } from '../auth/AuthContext';
|
|
30
30
|
import type { PowerAppsHostProviderProps } from './PowerAppsHostProvider';
|
|
31
|
-
import type { ConnectorSchema } from '../
|
|
32
|
-
import type { DatabaseReference } from '../platform/
|
|
33
|
-
import type { OnDisambiguationNeeded } from '../connections/types.js';
|
|
31
|
+
import type { ConnectorSchema } from '../connections/useConnectionRefs.js';
|
|
32
|
+
import type { DatabaseReference } from '../platform/DataverseDataSources.js';
|
|
33
|
+
import type { ConnectionReferenceConfig, OnDisambiguationNeeded } from '../connections/types.js';
|
|
34
34
|
import type { ThemeTokens } from '../theme/tokens.js';
|
|
35
35
|
import type { ILogger } from '@microsoft/power-apps-native-common';
|
|
36
|
+
import type { ApplicationInsightsTelemetryProviderConfig } from '@microsoft/power-apps-native-common';
|
|
36
37
|
/** Shape of power.config.json consumed by the provider. */
|
|
37
38
|
export interface PowerConfig {
|
|
38
39
|
/**
|
|
@@ -53,10 +54,7 @@ export interface PowerConfig {
|
|
|
53
54
|
* Omit for the default global collector.
|
|
54
55
|
*/
|
|
55
56
|
geoRegion?: string;
|
|
56
|
-
connectionReferences?: Record<string,
|
|
57
|
-
id: string;
|
|
58
|
-
dataSources: string[];
|
|
59
|
-
}>;
|
|
57
|
+
connectionReferences?: Record<string, ConnectionReferenceConfig>;
|
|
60
58
|
databaseReferences?: Record<string, DatabaseReference>;
|
|
61
59
|
/**
|
|
62
60
|
* Allow additional keys — the offline SDK reads arbitrary fields from
|
|
@@ -67,7 +65,29 @@ export interface PowerConfig {
|
|
|
67
65
|
[key: string]: unknown;
|
|
68
66
|
}
|
|
69
67
|
type TamaguiConfig = ReturnType<typeof createTamagui>;
|
|
68
|
+
export interface AppInsightsConfig extends Omit<ApplicationInsightsTelemetryProviderConfig, 'deviceId' | 'sessionId'> {
|
|
69
|
+
/** Explicit opt-in. Application Insights telemetry is disabled unless this is true. */
|
|
70
|
+
enabled: boolean;
|
|
71
|
+
}
|
|
72
|
+
export interface PowerAppsAppConfig {
|
|
73
|
+
expo?: {
|
|
74
|
+
extra?: {
|
|
75
|
+
appInsightsConfig?: unknown;
|
|
76
|
+
[key: string]: unknown;
|
|
77
|
+
};
|
|
78
|
+
[key: string]: unknown;
|
|
79
|
+
};
|
|
80
|
+
[key: string]: unknown;
|
|
81
|
+
}
|
|
70
82
|
export interface PowerAppsProviderProps {
|
|
83
|
+
/**
|
|
84
|
+
* Contents of the generated app.json.
|
|
85
|
+
*
|
|
86
|
+
* Pass this when the app runs inside a host such as Dev Player, where
|
|
87
|
+
* `Constants.expoConfig` describes the host instead of the loaded app.
|
|
88
|
+
* The provider falls back to `Constants.expoConfig` when omitted.
|
|
89
|
+
*/
|
|
90
|
+
appConfig?: PowerAppsAppConfig;
|
|
71
91
|
/** MSAL configuration from auth.config.json (msal section). */
|
|
72
92
|
msalConfig: AuthProviderProps['msalConfig'];
|
|
73
93
|
/** Intune MAM configuration. Defaults to enabled in release builds. */
|
|
@@ -106,6 +126,12 @@ export interface PowerAppsProviderProps {
|
|
|
106
126
|
renderOAuthWebView?: PowerAppsHostProviderProps['renderOAuthWebView'];
|
|
107
127
|
/** See PowerAppsHostProviderProps.onDisambiguationNeeded. */
|
|
108
128
|
onDisambiguationNeeded?: OnDisambiguationNeeded;
|
|
129
|
+
/** See PowerAppsHostProviderProps.onConnectionConsent. */
|
|
130
|
+
onConnectionConsent?: PowerAppsHostProviderProps['onConnectionConsent'];
|
|
131
|
+
/** See PowerAppsHostProviderProps.onResourceConsent. */
|
|
132
|
+
onResourceConsent?: PowerAppsHostProviderProps['onResourceConsent'];
|
|
133
|
+
/** See PowerAppsHostProviderProps.onConnectionConsentDeclined. */
|
|
134
|
+
onConnectionConsentDeclined?: PowerAppsHostProviderProps['onConnectionConsentDeclined'];
|
|
109
135
|
/**
|
|
110
136
|
* App name used as `clientType` in the auto-wired 1DS telemetry provider.
|
|
111
137
|
* Appears in Kusto as the `clientType` column — use a stable
|
|
@@ -125,6 +151,25 @@ export interface PowerAppsProviderProps {
|
|
|
125
151
|
* logger becomes a no-op regardless of build variant.
|
|
126
152
|
*/
|
|
127
153
|
logger?: ILogger | null;
|
|
154
|
+
/**
|
|
155
|
+
* Show app and telemetry session details after a three-finger long press.
|
|
156
|
+
* Available in both development and published native apps. @default true
|
|
157
|
+
*/
|
|
158
|
+
showSessionDetailsOnLongPress?: boolean;
|
|
159
|
+
/**
|
|
160
|
+
* @deprecated Use `showSessionDetailsOnLongPress` instead.
|
|
161
|
+
*/
|
|
162
|
+
showSessionDetailsOnSwipe?: boolean;
|
|
163
|
+
/**
|
|
164
|
+
* Optional customer-owned Application Insights destination.
|
|
165
|
+
*
|
|
166
|
+
* Events are sent directly to the selected C1-owned Application Insights
|
|
167
|
+
* resource and fan out alongside the default Microsoft OneDS provider.
|
|
168
|
+
* Defaults to `appConfig.expo.extra.appInsightsConfig`, then falls back to
|
|
169
|
+
* `Constants.expoConfig.extra.appInsightsConfig`.
|
|
170
|
+
* Ignored when `logger` is provided or `null`.
|
|
171
|
+
*/
|
|
172
|
+
appInsightsConfig?: AppInsightsConfig;
|
|
128
173
|
/**
|
|
129
174
|
* Offline profile JSON — optional override.
|
|
130
175
|
* Primary source: SDK config plugin embeds offline-profile.json into the app
|
|
@@ -142,7 +187,7 @@ export interface PowerAppsProviderProps {
|
|
|
142
187
|
* component, eliminating all provider boilerplate from the consuming app's
|
|
143
188
|
* root layout.
|
|
144
189
|
*/
|
|
145
|
-
export declare function PowerAppsProvider({ msalConfig, intuneConfig, powerConfig, schemaMap, tamaguiConfig, // override with app's tamagui.config.ts
|
|
146
|
-
defaultTheme, theme, darkTheme, followSystemTheme, renderOAuthWebView, onDisambiguationNeeded, appName, logger: loggerProp, offlineProfile, children, }: PowerAppsProviderProps): React.JSX.Element;
|
|
190
|
+
export declare function PowerAppsProvider({ appConfig, msalConfig, intuneConfig, powerConfig, schemaMap, tamaguiConfig, // override with app's tamagui.config.ts
|
|
191
|
+
defaultTheme, theme, darkTheme, followSystemTheme, renderOAuthWebView, onDisambiguationNeeded, onConnectionConsent, onResourceConsent, onConnectionConsentDeclined, appName, logger: loggerProp, showSessionDetailsOnLongPress, showSessionDetailsOnSwipe, appInsightsConfig, offlineProfile, children, }: PowerAppsProviderProps): React.JSX.Element;
|
|
147
192
|
export {};
|
|
148
193
|
//# sourceMappingURL=PowerAppsProvider.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface SessionDetailsGestureProps {
|
|
3
|
+
enabled: boolean;
|
|
4
|
+
appName: string;
|
|
5
|
+
appId?: string;
|
|
6
|
+
environmentId?: string;
|
|
7
|
+
region: string;
|
|
8
|
+
appVersion?: string;
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
}
|
|
11
|
+
export declare function SessionDetailsGesture({ enabled, appName, appId, environmentId, region, appVersion, children, }: SessionDetailsGestureProps): React.JSX.Element;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=SessionDetailsGesture.d.ts.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forwards the privacy-safe Offline SDK transport through the host's existing
|
|
3
|
+
* app logger so offline events carry the same session, device, and user data.
|
|
4
|
+
*
|
|
5
|
+
* The host owns exactly one thing here: binding the SDK transport to this
|
|
6
|
+
* host's logger. Buffering and teardown semantics live in the SDK.
|
|
7
|
+
*
|
|
8
|
+
* Setup and teardown are fail-open but not silent. This runs from an effect in
|
|
9
|
+
* the provider that roots the app, so an unguarded throw would take down the
|
|
10
|
+
* whole tree — telemetry is never worth an app that will not start. An
|
|
11
|
+
* unexpected failure is therefore downgraded to a logged diagnostic rather than
|
|
12
|
+
* swallowed, so broken wiring stays observable.
|
|
13
|
+
*/
|
|
14
|
+
export declare function configureOfflineSdkTelemetry(forwardEvents: boolean): () => void;
|
|
15
|
+
//# sourceMappingURL=OfflineSdkTelemetry.d.ts.map
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
* (`getAppLogger` / `configureAppLogger`). This module re-exports those
|
|
8
8
|
* alongside the canonical host operation-name constants.
|
|
9
9
|
*/
|
|
10
|
-
|
|
10
|
+
import { HttpClient } from '@microsoft/power-apps-native-common/http';
|
|
11
|
+
export { getAppLogger, configureAppLogger, getCustomerTelemetryLogger } from '@microsoft/power-apps-native-common';
|
|
12
|
+
export type { ICustomerTelemetryLogger } from '@microsoft/power-apps-native-common';
|
|
11
13
|
/**
|
|
12
14
|
* Canonical operation names for host package telemetry.
|
|
13
15
|
* Follow the `PowerAppsHost.<Subsystem>.<Action>` convention so events are
|
|
@@ -34,15 +36,25 @@ export declare const HostOperationNames: {
|
|
|
34
36
|
readonly BridgeTokenAcquireFailed: "PowerAppsHost.Bridge.TokenAcquire.Failed";
|
|
35
37
|
/** Top-level React error boundary caught an unhandled JS error. */
|
|
36
38
|
readonly RuntimeUnhandledJsError: "PowerAppsHost.Runtime.UnhandledJsError";
|
|
39
|
+
/** Power Platform RP HTTP request, including backend correlation IDs. */
|
|
40
|
+
readonly PlatformHttpRequest: "PowerAppsHost.Platform.HttpRequest";
|
|
37
41
|
/** Resolve Dataverse instanceUrl from Power Platform environment API. */
|
|
38
42
|
readonly PlatformFetchInstanceUrl: "PowerAppsHost.Platform.FetchInstanceUrl";
|
|
39
43
|
/** useConnectionRefs failed to resolve connections (recoverable). Recorded only on failure. */
|
|
40
44
|
readonly PlatformLoadConnectionsFailed: "PowerAppsHost.Platform.LoadConnections.Failed";
|
|
41
45
|
/** Create a new Power Platform connection. */
|
|
42
46
|
readonly PlatformCreateConnection: "PowerAppsHost.Platform.CreateConnection";
|
|
47
|
+
/** Repair an existing Power Platform connection. */
|
|
48
|
+
readonly PlatformRepairConnection: "PowerAppsHost.Platform.RepairConnection";
|
|
49
|
+
/** Poll a connection until it becomes active. */
|
|
50
|
+
readonly PlatformPollConnectionStatus: "PowerAppsHost.Platform.PollConnectionStatus";
|
|
43
51
|
/** Resolve app connection references for the current launch. */
|
|
44
52
|
readonly PlatformResolveConnectionRefs: "PowerAppsHost.Platform.ResolveConnectionRefs";
|
|
45
53
|
/** Grant this app access to a Power Platform connection ACL. */
|
|
46
54
|
readonly PlatformConnectionAclGrant: "PowerAppsHost.Platform.ConnectionAclGrant";
|
|
55
|
+
/** Installed Offline SDK predates the SDK-owned routing contract. */
|
|
56
|
+
readonly OfflineRoutingContractUnsupported: "PowerAppsHost.Offline.RoutingContract.Unsupported";
|
|
47
57
|
};
|
|
58
|
+
export declare const bridgeHttpClient: HttpClient;
|
|
59
|
+
export declare const platformHttpClient: HttpClient;
|
|
48
60
|
//# sourceMappingURL=index.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@microsoft/power-apps-native-host",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "React Native host integration for @microsoft/power-apps",
|
|
5
5
|
"author": "Microsoft Corporation",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -12,28 +12,44 @@
|
|
|
12
12
|
},
|
|
13
13
|
"main": "./lib/commonjs/index.js",
|
|
14
14
|
"module": "./lib/module/index.js",
|
|
15
|
-
"types": "./
|
|
15
|
+
"types": "./src/config/index.d.ts",
|
|
16
16
|
"exports": {
|
|
17
17
|
".": {
|
|
18
18
|
"browser": {
|
|
19
|
-
"types": "./
|
|
20
|
-
"default": "./lib/
|
|
19
|
+
"types": "./src/config/index.d.ts",
|
|
20
|
+
"default": "./lib/module/index.js"
|
|
21
21
|
},
|
|
22
22
|
"import": {
|
|
23
|
-
"types": "./
|
|
23
|
+
"types": "./src/config/index.d.ts",
|
|
24
24
|
"default": "./lib/module/index.js"
|
|
25
25
|
},
|
|
26
26
|
"require": {
|
|
27
|
-
"types": "./
|
|
27
|
+
"types": "./src/config/index.d.ts",
|
|
28
28
|
"default": "./lib/commonjs/index.js"
|
|
29
29
|
}
|
|
30
30
|
},
|
|
31
31
|
"./package.json": "./package.json",
|
|
32
|
+
"./config/tsconfig": "./src/config/tsconfig.json",
|
|
33
|
+
"./config/*": {
|
|
34
|
+
"browser": {
|
|
35
|
+
"types": "./lib/typescript/module/config/*.d.ts",
|
|
36
|
+
"default": "./lib/module/config/*.js"
|
|
37
|
+
},
|
|
38
|
+
"import": {
|
|
39
|
+
"types": "./lib/typescript/module/config/*.d.ts",
|
|
40
|
+
"default": "./lib/module/config/*.js"
|
|
41
|
+
},
|
|
42
|
+
"require": {
|
|
43
|
+
"types": "./lib/typescript/commonjs/config/*.d.ts",
|
|
44
|
+
"default": "./lib/commonjs/config/*.js"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
32
47
|
"./app.plugin.js": "./app.plugin.js"
|
|
33
48
|
},
|
|
34
49
|
"bin": {
|
|
35
50
|
"generate-connector-schemas": "scripts/generate-connector-schemas.js",
|
|
36
51
|
"js-bundle": "scripts/bundle.js",
|
|
52
|
+
"build-codegen-package": "scripts/build-codegen-package.js",
|
|
37
53
|
"build-ios-base": "scripts/build-ios-base.js",
|
|
38
54
|
"power-apps-web": "scripts/start-web.mjs",
|
|
39
55
|
"wrap": "scripts/wrap.js",
|
|
@@ -42,19 +58,26 @@
|
|
|
42
58
|
"files": [
|
|
43
59
|
"lib/",
|
|
44
60
|
"!lib/**/*.map",
|
|
61
|
+
"src/config/generated-config.d.ts",
|
|
62
|
+
"src/config/index.d.ts",
|
|
63
|
+
"src/config/tsconfig.json",
|
|
45
64
|
"app.plugin.js",
|
|
46
65
|
"scripts/",
|
|
47
66
|
"compatibility/"
|
|
48
67
|
],
|
|
49
68
|
"scripts": {
|
|
50
|
-
"prepack": "npm run
|
|
51
|
-
"build": "bob build && node ../../scripts/notices.js",
|
|
69
|
+
"prepack": "npm run build && npm test",
|
|
70
|
+
"build": "bob build && node ../../scripts/package-build/notices.js",
|
|
52
71
|
"type-check": "tsc --noEmit",
|
|
53
|
-
"test
|
|
72
|
+
"test": "node --test --test-force-exit test/*.test.js",
|
|
73
|
+
"test:upgrade": "node --test --test-force-exit test/upgrade.test.js",
|
|
74
|
+
"test:offline-compatibility": "bob build && node --test test/OfflineSdkCompatibility.test.js"
|
|
54
75
|
},
|
|
55
76
|
"dependencies": {
|
|
56
|
-
"@
|
|
57
|
-
"@microsoft/power-apps-native-
|
|
77
|
+
"@expo/config-plugins": "55.0.11",
|
|
78
|
+
"@microsoft/power-apps-native-assets": "^0.3.0",
|
|
79
|
+
"@microsoft/power-apps-native-auth": "^0.3.8",
|
|
80
|
+
"@microsoft/power-apps-native-common": "^0.2.2",
|
|
58
81
|
"@ster5/global-mutex": "3.3.0",
|
|
59
82
|
"@tamagui/config": "2.4.5",
|
|
60
83
|
"@tamagui/core": "2.4.5",
|
|
@@ -66,12 +89,20 @@
|
|
|
66
89
|
"write-file-atomic": "7.0.1"
|
|
67
90
|
},
|
|
68
91
|
"peerDependencies": {
|
|
92
|
+
"@expo/vector-icons": ">=15.1.1 <16",
|
|
69
93
|
"@microsoft/power-apps": "*",
|
|
70
|
-
"@microsoft/power-apps-native-offline": ">=0.1.
|
|
94
|
+
"@microsoft/power-apps-native-offline": ">=0.1.32",
|
|
71
95
|
"@react-native-community/netinfo": ">=11.0.0",
|
|
72
96
|
"burnt": ">=0.12.2",
|
|
97
|
+
"expo-application": ">=55.0.0 <56",
|
|
73
98
|
"expo-constants": ">=55.0.0 <56",
|
|
99
|
+
"expo-clipboard": ">=55.0.0 <56",
|
|
100
|
+
"expo-document-picker": ">=55.0.13 <56",
|
|
101
|
+
"expo-file-system": ">=55.0.19 <56",
|
|
102
|
+
"expo-image-picker": ">=55.0.20 <56",
|
|
74
103
|
"expo-linking": ">=55.0.14 <56",
|
|
104
|
+
"expo-sharing": ">=55.0.18 <56",
|
|
105
|
+
"expo-secure-store": ">=55.0.0 <56",
|
|
75
106
|
"expo-web-browser": ">=55.0.14 <56",
|
|
76
107
|
"react": ">=19.2.0 <20",
|
|
77
108
|
"react-dom": ">=19.2.0 <19.3.0",
|
|
@@ -91,9 +122,13 @@
|
|
|
91
122
|
}
|
|
92
123
|
},
|
|
93
124
|
"devDependencies": {
|
|
125
|
+
"@microsoft/power-apps-cli": "0.15.3",
|
|
94
126
|
"@types/react": "19.2.14",
|
|
95
127
|
"cross-env": "7.0.3",
|
|
128
|
+
"expo-application": "55.0.15",
|
|
129
|
+
"expo-clipboard": "55.0.13",
|
|
96
130
|
"expo-constants": "55.0.16",
|
|
131
|
+
"expo-secure-store": "55.0.13",
|
|
97
132
|
"expo-web-browser": "55.0.15",
|
|
98
133
|
"react": "19.2.0",
|
|
99
134
|
"react-dom": "19.2.0",
|
|
@@ -109,10 +144,14 @@
|
|
|
109
144
|
"publishConfig": {
|
|
110
145
|
"access": "public"
|
|
111
146
|
},
|
|
112
|
-
"sideEffects":
|
|
147
|
+
"sideEffects": [
|
|
148
|
+
"**/index.js",
|
|
149
|
+
"**/index.ts"
|
|
150
|
+
],
|
|
113
151
|
"react-native-builder-bob": {
|
|
114
152
|
"source": "src",
|
|
115
153
|
"output": "lib",
|
|
154
|
+
"exclude": "config/{generated-config.d.ts,index.d.ts,tsconfig.json}",
|
|
116
155
|
"targets": [
|
|
117
156
|
[
|
|
118
157
|
"module",
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Codegen native package producer.
|
|
4
|
+
*
|
|
5
|
+
* Produces a *self-consistent* native asset package for the Power Apps wrap
|
|
6
|
+
* pipeline from a single `expo export`, so the embedded Hermes bundle and the
|
|
7
|
+
* hash-addressed asset files share one Metro AssetRegistry (their hashes line
|
|
8
|
+
* up with what the runtime asset resolver sees). No JavaScript is compiled or
|
|
9
|
+
* downloaded inside the wrap pipeline — this step runs at customer deploy time.
|
|
10
|
+
*
|
|
11
|
+
* Usage (via the app's npm scripts):
|
|
12
|
+
* build-codegen-package android
|
|
13
|
+
* build-codegen-package ios
|
|
14
|
+
*
|
|
15
|
+
* Emits into ./dist (deploy uploads the whole dist/ to blob):
|
|
16
|
+
* dist/index.android.bundle.hbc | dist/main.jsbundle.hbc ← Hermes bundle
|
|
17
|
+
* dist/powerapps-customer-assets-<platform>/manifest.json
|
|
18
|
+
* dist/powerapps-customer-assets-<platform>/assets/<fileHash>.<type>
|
|
19
|
+
*
|
|
20
|
+
* Android and iOS asset packages are kept in separate, platform-suffixed dirs
|
|
21
|
+
* because their scales/densities (and therefore fileHashes) differ. The wrap
|
|
22
|
+
* pipeline downloads the platform-matching dir and injects it into the base app
|
|
23
|
+
* under the neutral name `powerapps-customer-assets/`, which the native module
|
|
24
|
+
* reads at runtime.
|
|
25
|
+
*
|
|
26
|
+
* manifest.json shape (schemaVersion 1):
|
|
27
|
+
* {
|
|
28
|
+
* "schemaVersion": 1,
|
|
29
|
+
* "platform": "android" | "ios",
|
|
30
|
+
* "bundle": { "path": "index.android.bundle.hbc" },
|
|
31
|
+
* "assets": [
|
|
32
|
+
* { "fileHash": "<md5>", "type": "png", "path": "assets/<md5>.png",
|
|
33
|
+
* "hash": "<metroRegistryHash>", "scale": 2 }
|
|
34
|
+
* ]
|
|
35
|
+
* }
|
|
36
|
+
*
|
|
37
|
+
* The `hash` (Metro AssetRegistry hash) + `scale` let the native module build a
|
|
38
|
+
* runtime lookup the JS resolver keys by `"<hash>@<scale>"`. Integrity fields
|
|
39
|
+
* (sha256, signing) are intentionally out of scope here (Scope 3).
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
'use strict';
|
|
43
|
+
|
|
44
|
+
const { execFileSync, spawn } = require('child_process');
|
|
45
|
+
const path = require('path');
|
|
46
|
+
const fs = require('fs');
|
|
47
|
+
const os = require('os');
|
|
48
|
+
const crypto = require('crypto');
|
|
49
|
+
|
|
50
|
+
const platform = process.argv[2];
|
|
51
|
+
if (platform !== 'android' && platform !== 'ios') {
|
|
52
|
+
console.error('Usage: build-codegen-package <android|ios>');
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const isWin = process.platform === 'win32';
|
|
57
|
+
const isLinux = process.platform === 'linux';
|
|
58
|
+
|
|
59
|
+
const projectRoot = process.cwd();
|
|
60
|
+
const workspaceRoot = path.resolve(projectRoot, '../..');
|
|
61
|
+
|
|
62
|
+
const HERMES_MAGIC = Buffer.from([0xc6, 0x1f, 0xbc, 0x03]);
|
|
63
|
+
// Platform-suffixed in blob so android/ios packages don't clobber each other;
|
|
64
|
+
// the wrap injects into the neutral `powerapps-customer-assets/` on-device.
|
|
65
|
+
const ASSET_DIR_NAME = `powerapps-customer-assets-${platform}`;
|
|
66
|
+
const bundleName =
|
|
67
|
+
platform === 'android' ? 'index.android.bundle.hbc' : 'main.jsbundle.hbc';
|
|
68
|
+
|
|
69
|
+
function resolveExpoBin() {
|
|
70
|
+
const name = isWin ? 'expo.cmd' : 'expo';
|
|
71
|
+
const local = path.join(projectRoot, 'node_modules', '.bin', name);
|
|
72
|
+
const hoisted = path.join(workspaceRoot, 'node_modules', '.bin', name);
|
|
73
|
+
return fs.existsSync(local) ? local : hoisted;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function resolveHermesc() {
|
|
77
|
+
const hcPkg = require.resolve('hermes-compiler/package.json', {
|
|
78
|
+
paths: [projectRoot, workspaceRoot],
|
|
79
|
+
});
|
|
80
|
+
const hcDir = path.dirname(hcPkg);
|
|
81
|
+
const binDir = isWin ? 'win64-bin' : isLinux ? 'linux64-bin' : 'osx-bin';
|
|
82
|
+
const binName = isWin ? 'hermesc.exe' : 'hermesc';
|
|
83
|
+
const flat = path.join(hcDir, binDir, binName);
|
|
84
|
+
const nested = path.join(hcDir, binName, binDir, binName);
|
|
85
|
+
return fs.existsSync(flat) ? flat : nested;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function findFiles(dir, predicate) {
|
|
89
|
+
if (!fs.existsSync(dir)) return [];
|
|
90
|
+
return fs.readdirSync(dir, { withFileTypes: true }).flatMap((entry) => {
|
|
91
|
+
const p = path.join(dir, entry.name);
|
|
92
|
+
return entry.isDirectory()
|
|
93
|
+
? findFiles(p, predicate)
|
|
94
|
+
: predicate(p)
|
|
95
|
+
? [p]
|
|
96
|
+
: [];
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function sha256File(filePath) {
|
|
101
|
+
return crypto
|
|
102
|
+
.createHash('sha256')
|
|
103
|
+
.update(fs.readFileSync(filePath))
|
|
104
|
+
.digest('hex');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function isHermesBytecode(filePath) {
|
|
108
|
+
const fd = fs.openSync(filePath, 'r');
|
|
109
|
+
try {
|
|
110
|
+
const head = Buffer.alloc(4);
|
|
111
|
+
fs.readSync(fd, head, 0, 4, 0);
|
|
112
|
+
return head.equals(HERMES_MAGIC);
|
|
113
|
+
} finally {
|
|
114
|
+
fs.closeSync(fd);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Run `expo export` for the native platform and wait for completion. Unlike
|
|
120
|
+
* `expo export:embed`, this yields hash-addressed assets and (with
|
|
121
|
+
* `--dump-assetmap`) an assetmap.json we can turn into a manifest.
|
|
122
|
+
*/
|
|
123
|
+
function runExpoExport(expoBin, outputDir) {
|
|
124
|
+
const marker = `Exported: ${outputDir}`;
|
|
125
|
+
return new Promise((resolve, reject) => {
|
|
126
|
+
const child = spawn(
|
|
127
|
+
expoBin,
|
|
128
|
+
[
|
|
129
|
+
'export',
|
|
130
|
+
'--platform',
|
|
131
|
+
platform,
|
|
132
|
+
'--output-dir',
|
|
133
|
+
outputDir,
|
|
134
|
+
'--dump-assetmap',
|
|
135
|
+
'--clear',
|
|
136
|
+
],
|
|
137
|
+
{
|
|
138
|
+
cwd: projectRoot,
|
|
139
|
+
env: { ...process.env, CI: process.env.CI ?? '1', EXPO_NO_TELEMETRY: '1' },
|
|
140
|
+
shell: isWin,
|
|
141
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
142
|
+
},
|
|
143
|
+
);
|
|
144
|
+
let tail = '';
|
|
145
|
+
let done = false;
|
|
146
|
+
const forward = (chunk, dest) => {
|
|
147
|
+
dest.write(chunk);
|
|
148
|
+
tail = (tail + chunk).slice(-marker.length * 2);
|
|
149
|
+
if (!done && tail.includes(marker)) {
|
|
150
|
+
done = true;
|
|
151
|
+
if (isWin && child.pid) {
|
|
152
|
+
try {
|
|
153
|
+
execFileSync('taskkill', ['/pid', String(child.pid), '/t', '/f'], {
|
|
154
|
+
stdio: 'ignore',
|
|
155
|
+
});
|
|
156
|
+
} catch {
|
|
157
|
+
child.kill();
|
|
158
|
+
}
|
|
159
|
+
} else {
|
|
160
|
+
child.kill('SIGKILL');
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
child.stdout.on('data', (c) => forward(c, process.stdout));
|
|
165
|
+
child.stderr.on('data', (c) => forward(c, process.stderr));
|
|
166
|
+
child.once('error', reject);
|
|
167
|
+
child.once('exit', (code, signal) => {
|
|
168
|
+
if (done) resolve();
|
|
169
|
+
else
|
|
170
|
+
reject(
|
|
171
|
+
new Error(
|
|
172
|
+
code === 0
|
|
173
|
+
? `Expo export exited before completion marker: ${marker}`
|
|
174
|
+
: `Expo export failed (${signal ? `signal ${signal}` : `code ${code}`})`,
|
|
175
|
+
),
|
|
176
|
+
);
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function locateBundle(exportDir) {
|
|
182
|
+
const jsDir = path.join(exportDir, '_expo', 'static', 'js', platform);
|
|
183
|
+
const candidates = findFiles(jsDir, (p) => /\.(hbc|js)$/.test(p));
|
|
184
|
+
const hbc = candidates.find((p) => p.endsWith('.hbc'));
|
|
185
|
+
if (hbc) return { file: hbc, isHermes: true };
|
|
186
|
+
if (candidates.length === 1) return { file: candidates[0], isHermes: false };
|
|
187
|
+
throw new Error(
|
|
188
|
+
`Expected exactly one native bundle under ${jsDir}, found ${candidates.length}`,
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function buildAssetPackage(exportDir, distDir, bundlePath) {
|
|
193
|
+
const assetMapPath = path.join(exportDir, 'assetmap.json');
|
|
194
|
+
const assetsOutDir = path.join(distDir, ASSET_DIR_NAME, 'assets');
|
|
195
|
+
const manifestPath = path.join(distDir, ASSET_DIR_NAME, 'manifest.json');
|
|
196
|
+
|
|
197
|
+
const manifest = {
|
|
198
|
+
schemaVersion: 1,
|
|
199
|
+
platform,
|
|
200
|
+
// BIN-3: sha256 pins every artifact the wrap pipeline injects. The wrap
|
|
201
|
+
// recomputes these before use, so a truncated or swapped blob fails the
|
|
202
|
+
// build instead of shipping inside a signed app.
|
|
203
|
+
bundle: { path: bundleName, sha256: sha256File(bundlePath) },
|
|
204
|
+
assets: [],
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
// No assets is valid (an app may reference none). Still emit an empty
|
|
208
|
+
// manifest so the wrap injection + native module behave uniformly.
|
|
209
|
+
if (fs.existsSync(assetMapPath)) {
|
|
210
|
+
fs.mkdirSync(assetsOutDir, { recursive: true });
|
|
211
|
+
const assetMap = JSON.parse(fs.readFileSync(assetMapPath, 'utf8'));
|
|
212
|
+
for (const [registryHash, entry] of Object.entries(assetMap)) {
|
|
213
|
+
const type = String(entry.type ?? '').replace(/^\./, '') || 'dat';
|
|
214
|
+
const fileHashes = entry.fileHashes ?? [];
|
|
215
|
+
const scales = entry.scales ?? [];
|
|
216
|
+
for (let i = 0; i < fileHashes.length; i++) {
|
|
217
|
+
const fileHash = fileHashes[i];
|
|
218
|
+
const scale = scales[i] ?? 1;
|
|
219
|
+
const src = path.join(exportDir, 'assets', fileHash);
|
|
220
|
+
if (!fs.existsSync(src)) {
|
|
221
|
+
throw new Error(`Exported asset missing on disk: assets/${fileHash}`);
|
|
222
|
+
}
|
|
223
|
+
const relPath = `assets/${fileHash}.${type}`;
|
|
224
|
+
const destPath = path.join(distDir, ASSET_DIR_NAME, relPath);
|
|
225
|
+
fs.copyFileSync(src, destPath);
|
|
226
|
+
manifest.assets.push({
|
|
227
|
+
fileHash,
|
|
228
|
+
type,
|
|
229
|
+
path: relPath,
|
|
230
|
+
hash: registryHash,
|
|
231
|
+
scale,
|
|
232
|
+
sha256: sha256File(destPath),
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
} else {
|
|
237
|
+
fs.mkdirSync(path.join(distDir, ASSET_DIR_NAME), { recursive: true });
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
|
|
241
|
+
return manifest.assets.length;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
async function main() {
|
|
245
|
+
const distDir = path.join(projectRoot, 'dist');
|
|
246
|
+
fs.mkdirSync(distDir, { recursive: true });
|
|
247
|
+
|
|
248
|
+
const exportDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pa-codegen-export-'));
|
|
249
|
+
try {
|
|
250
|
+
console.log(`\n[package] Step 1: expo export (${platform})`);
|
|
251
|
+
await runExpoExport(resolveExpoBin(), exportDir);
|
|
252
|
+
|
|
253
|
+
console.log('[package] Step 2: locate + stage Hermes bundle');
|
|
254
|
+
const { file, isHermes } = locateBundle(exportDir);
|
|
255
|
+
const outBundle = path.join(distDir, bundleName);
|
|
256
|
+
if (isHermes) {
|
|
257
|
+
fs.copyFileSync(file, outBundle);
|
|
258
|
+
} else {
|
|
259
|
+
console.log('[package] plain JS bundle exported; compiling with hermesc');
|
|
260
|
+
execFileSync(resolveHermesc(), ['-emit-binary', '-out', outBundle, file], {
|
|
261
|
+
stdio: 'inherit',
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
if (!isHermesBytecode(outBundle)) {
|
|
265
|
+
throw new Error(`Staged bundle is not Hermes bytecode: ${outBundle}`);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
console.log('[package] Step 3: build asset package + manifest');
|
|
269
|
+
const count = buildAssetPackage(exportDir, distDir, outBundle);
|
|
270
|
+
|
|
271
|
+
console.log(
|
|
272
|
+
`\n[package] Done. Bundle: "${outBundle}"; assets: ${count}; ` +
|
|
273
|
+
`manifest: "${path.join(distDir, ASSET_DIR_NAME, 'manifest.json')}"`,
|
|
274
|
+
);
|
|
275
|
+
} finally {
|
|
276
|
+
fs.rmSync(exportDir, { recursive: true, force: true });
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
main().catch((error) => {
|
|
281
|
+
console.error(error);
|
|
282
|
+
process.exit(1);
|
|
283
|
+
});
|
package/scripts/start-web.mjs
CHANGED
|
@@ -7,7 +7,9 @@ import process from 'node:process';
|
|
|
7
7
|
|
|
8
8
|
const npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
9
9
|
const npxCommand = process.platform === 'win32' ? 'npx.cmd' : 'npx';
|
|
10
|
-
const
|
|
10
|
+
const localAppPort = process.env.POWER_APPS_WEB_APP_PORT?.trim() || '8082';
|
|
11
|
+
const playerPort = process.env.POWER_APPS_WEB_PLAYER_PORT?.trim() || '8080';
|
|
12
|
+
const localAppUrl = `http://localhost:${localAppPort}`;
|
|
11
13
|
const children = new Set();
|
|
12
14
|
let shuttingDown = false;
|
|
13
15
|
|
|
@@ -106,7 +108,9 @@ function captureLocalPlayUrl(child, environmentId) {
|
|
|
106
108
|
child.stdout.removeAllListeners('data');
|
|
107
109
|
child.stdout.pipe(process.stdout);
|
|
108
110
|
void waitForApp()
|
|
109
|
-
.then(() =>
|
|
111
|
+
.then(() => {
|
|
112
|
+
if (process.env.POWER_APPS_WEB_NO_OPEN !== 'true') openBrowser(playUrl.href);
|
|
113
|
+
})
|
|
110
114
|
.catch((error) => {
|
|
111
115
|
console.error(error instanceof Error ? error.message : String(error));
|
|
112
116
|
shutdown(1);
|
|
@@ -128,10 +132,10 @@ const schemaProcess = spawn(npmCommand, ['run', 'generate-schemas'], {
|
|
|
128
132
|
const schemaExitCode = await new Promise((resolve) => schemaProcess.once('exit', resolve));
|
|
129
133
|
if (schemaExitCode !== 0) process.exit(schemaExitCode ?? 1);
|
|
130
134
|
|
|
131
|
-
run(npxCommand, ['expo', 'start', '--port',
|
|
135
|
+
run(npxCommand, ['expo', 'start', '--port', localAppPort, '--localhost']);
|
|
132
136
|
const powerApps = run(
|
|
133
137
|
npxCommand,
|
|
134
|
-
['
|
|
138
|
+
['pa', 'app', 'run', '--config-only', '--port', playerPort, '--local-app-url', localAppUrl],
|
|
135
139
|
{ stdio: ['inherit', 'pipe', 'inherit'] }
|
|
136
140
|
);
|
|
137
|
-
captureLocalPlayUrl(powerApps, powerConfig.environmentId);
|
|
141
|
+
captureLocalPlayUrl(powerApps, powerConfig.environmentId);
|