@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,148 @@
1
+ /*!
2
+ * power-apps-native-host — PowerAppsProvider
3
+ *
4
+ * A single provider that composes all infrastructure required to run a
5
+ * Power Apps canvas app inside an Expo shell:
6
+ *
7
+ * GestureHandlerRootView
8
+ * └── TamaguiProvider (defaults to @tamagui/config/v3)
9
+ * └── PortalProvider (required by ToastViewport)
10
+ * └── ToastProvider + ToastViewport
11
+ * └── QueryClientProvider (own QueryClient, wired to NetInfo + AppState)
12
+ * └── AuthProvider
13
+ * └── PowerAppsHostProvider (connected via useAuth)
14
+ * └── children
15
+ *
16
+ * Usage:
17
+ *
18
+ * <PowerAppsProvider
19
+ * msalConfig={authConfig.msal}
20
+ * powerConfig={powerConfig}
21
+ * schemaMap={schemaMap}
22
+ * >
23
+ * <StatusBar style="auto" />
24
+ * <Slot />
25
+ * </PowerAppsProvider>
26
+ */
27
+ import React from 'react';
28
+ import { createTamagui } from '@tamagui/core';
29
+ import type { AuthProviderProps } from '../auth/AuthContext.js';
30
+ import type { PowerAppsHostProviderProps } from './PowerAppsHostProvider.js';
31
+ import type { ConnectorSchema } from '../platform/useConnectionRefs.js';
32
+ import type { DatabaseReference } from '../platform/PowerPlatformEnvironmentApi.js';
33
+ import type { OnDisambiguationNeeded } from '../connections/types.js';
34
+ import type { ThemeTokens } from '../theme/tokens.js';
35
+ import type { ILogger } from '@microsoft/power-apps-native-common';
36
+ /** Shape of power.config.json consumed by the provider. */
37
+ export interface PowerConfig {
38
+ /**
39
+ * PowerApps app GUID written by `pac wrap` / the publish pipeline.
40
+ * When set, the host fetches connection references from the PowerApps RP
41
+ * `/apps/{appId}/launch` endpoint at runtime instead of reading the static
42
+ * `connectionReferences` object below. Leave `null` (or omit) during local
43
+ * development — the static `connectionReferences` will be used as a fallback.
44
+ */
45
+ appId?: string | null;
46
+ environmentId?: string;
47
+ region?: string;
48
+ /**
49
+ * BAP environment `location` value (`environment.properties.location` from the
50
+ * Get Environments API). EU locations — `"europe"`, `"unitedkingdom"`,
51
+ * `"france"`, `"germany"`, `"italy"`, `"poland"`, `"norway"`, `"sweden"`,
52
+ * `"switzerland"` — route telemetry to the EU 1DS collector.
53
+ * Omit for the default global collector.
54
+ */
55
+ geoRegion?: string;
56
+ connectionReferences?: Record<string, {
57
+ id: string;
58
+ dataSources: string[];
59
+ }>;
60
+ databaseReferences?: Record<string, DatabaseReference>;
61
+ /**
62
+ * Allow additional keys — the offline SDK reads arbitrary fields from
63
+ * powerConfig. NOTE: offline activation is configured via the app's
64
+ * `offline-profile.json` (embedded into the Expo manifest as
65
+ * `extra.__offlineProfile`), NOT via a `powerConfig` field.
66
+ */
67
+ [key: string]: unknown;
68
+ }
69
+ type TamaguiConfig = ReturnType<typeof createTamagui>;
70
+ export interface PowerAppsProviderProps {
71
+ /** MSAL configuration from auth.config.json (msal section). */
72
+ msalConfig: AuthProviderProps['msalConfig'];
73
+ /** Intune MAM configuration. Defaults to enabled in release builds. */
74
+ intuneConfig?: AuthProviderProps['intuneConfig'];
75
+ /** Contents of power.config.json. */
76
+ powerConfig: PowerConfig;
77
+ /**
78
+ * Connector schema map keyed by data source name.
79
+ * Generated automatically by generate-connector-schemas.
80
+ */
81
+ schemaMap: Record<string, ConnectorSchema>;
82
+ /**
83
+ * Tamagui design-system config.
84
+ * Defaults to the standard @tamagui/config/v3 preset.
85
+ */
86
+ tamaguiConfig?: TamaguiConfig;
87
+ /** Tamagui default colour theme. @default 'light' */
88
+ defaultTheme?: string;
89
+ /**
90
+ * Light-mode theme tokens for the built-in ThemeProvider.
91
+ * Defaults to the Power Platform green light palette.
92
+ * Pass a ThemeTokens object built from brand/tokens.ts to apply your brand.
93
+ */
94
+ theme?: ThemeTokens;
95
+ /**
96
+ * Dark-mode theme tokens for the built-in ThemeProvider.
97
+ * Defaults to the Power Platform green dark palette.
98
+ */
99
+ darkTheme?: ThemeTokens;
100
+ /**
101
+ * When `true`, the ThemeProvider automatically switches between `theme` and
102
+ * `darkTheme` based on the device colour scheme. @default true
103
+ */
104
+ followSystemTheme?: boolean;
105
+ /** See PowerAppsHostProviderProps.renderOAuthWebView. */
106
+ renderOAuthWebView?: PowerAppsHostProviderProps['renderOAuthWebView'];
107
+ /** See PowerAppsHostProviderProps.onDisambiguationNeeded. */
108
+ onDisambiguationNeeded?: OnDisambiguationNeeded;
109
+ /**
110
+ * App name used as `clientType` in the auto-wired 1DS telemetry provider.
111
+ * Appears in Kusto as the `clientType` column — use a stable
112
+ * `<Product><Variant>` string (e.g. `'PowerAppsDevPlayer'`).
113
+ * Ignored when `logger` is provided or `null`.
114
+ */
115
+ appName?: string;
116
+ /**
117
+ * Logger to use for host-package telemetry (auth, HTTP, platform APIs).
118
+ *
119
+ * - Omit (default): a `Logger` wired to `OneDsTelemetryProvider` (1DS JS)
120
+ * is auto-created. `clusterCategory` is derived from `powerConfig.region`
121
+ * (falls back to `'dev'`). This is the recommended path for all apps.
122
+ * - Pass an `ILogger` instance: that logger is used as-is, giving full
123
+ * control over providers and severity.
124
+ * - Pass `null`: telemetry is explicitly disabled (opt-out). The host
125
+ * logger becomes a no-op regardless of build variant.
126
+ */
127
+ logger?: ILogger | null;
128
+ /**
129
+ * Offline profile JSON — optional override.
130
+ * Primary source: SDK config plugin embeds offline-profile.json into the app
131
+ * manifest at prebuild time (read via expo-constants). This prop is only needed
132
+ * if you want to pass the profile programmatically (e.g., tests).
133
+ */
134
+ offlineProfile?: Record<string, unknown>;
135
+ children: React.ReactNode;
136
+ }
137
+ /**
138
+ * Top-level provider for Power Apps canvas apps running inside an Expo shell.
139
+ *
140
+ * Composes GestureHandlerRootView, TamaguiProvider, ToastProvider,
141
+ * QueryClientProvider, AuthProvider, and PowerAppsHostProvider into a single
142
+ * component, eliminating all provider boilerplate from the consuming app's
143
+ * root layout.
144
+ */
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;
147
+ export {};
148
+ //# sourceMappingURL=PowerAppsProvider.d.ts.map
@@ -0,0 +1,48 @@
1
+ /*!
2
+ * Copyright (C) Microsoft Corporation. All rights reserved.
3
+ *
4
+ * power-apps-native-host — package telemetry
5
+ *
6
+ * The shared logger singleton lives in `@microsoft/power-apps-native-common`
7
+ * (`getAppLogger` / `configureAppLogger`). This module re-exports those
8
+ * alongside the canonical host operation-name constants.
9
+ */
10
+ export { getAppLogger, configureAppLogger } from '@microsoft/power-apps-native-common';
11
+ /**
12
+ * Canonical operation names for host package telemetry.
13
+ * Follow the `PowerAppsHost.<Subsystem>.<Action>` convention so events are
14
+ * filterable in Kusto by prefix.
15
+ */
16
+ export declare const HostOperationNames: {
17
+ /** MSAL PublicClientApplication.init() + initial account resolution. */
18
+ readonly AuthInit: "PowerAppsHost.Auth.Init";
19
+ /** Interactive sign-in (acquireToken interactive). */
20
+ readonly AuthSignIn: "PowerAppsHost.Auth.SignIn";
21
+ /** Sign-out (token cache clear + broker logout). */
22
+ readonly AuthSignOut: "PowerAppsHost.Auth.SignOut";
23
+ /** Silent token acquisition. Recorded only on failure. */
24
+ readonly AuthAcquireTokenSilentFailed: "PowerAppsHost.Auth.AcquireTokenSilent.Failed";
25
+ /** Intune MAM enrollment after sign-in. */
26
+ readonly AuthIntuneEnroll: "PowerAppsHost.Auth.Intune.Enroll";
27
+ /** Intune MAM unenrollment during sign-out. */
28
+ readonly AuthIntuneUnenroll: "PowerAppsHost.Auth.Intune.Unenroll";
29
+ /** SDK-originated HTTP request relayed through NativePowerAppsBridge. */
30
+ readonly BridgeHttpRequest: "PowerAppsHost.Bridge.HttpRequest";
31
+ /** Plugin call forwarded through NativePowerAppsBridge (verbose; also used for unhandled). */
32
+ readonly BridgeUnhandledPlugin: "PowerAppsHost.Bridge.PluginCall";
33
+ /** Connector/Dataverse token acquisition for the bridge. Recorded only on failure. */
34
+ readonly BridgeTokenAcquireFailed: "PowerAppsHost.Bridge.TokenAcquire.Failed";
35
+ /** Top-level React error boundary caught an unhandled JS error. */
36
+ readonly RuntimeUnhandledJsError: "PowerAppsHost.Runtime.UnhandledJsError";
37
+ /** Resolve Dataverse instanceUrl from Power Platform environment API. */
38
+ readonly PlatformFetchInstanceUrl: "PowerAppsHost.Platform.FetchInstanceUrl";
39
+ /** useConnectionRefs failed to resolve connections (recoverable). Recorded only on failure. */
40
+ readonly PlatformLoadConnectionsFailed: "PowerAppsHost.Platform.LoadConnections.Failed";
41
+ /** Create a new Power Platform connection. */
42
+ readonly PlatformCreateConnection: "PowerAppsHost.Platform.CreateConnection";
43
+ /** Resolve app connection references for the current launch. */
44
+ readonly PlatformResolveConnectionRefs: "PowerAppsHost.Platform.ResolveConnectionRefs";
45
+ /** Grant this app access to a Power Platform connection ACL. */
46
+ readonly PlatformConnectionAclGrant: "PowerAppsHost.Platform.ConnectionAclGrant";
47
+ };
48
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,30 @@
1
+ /**
2
+ * ThemeProvider — distributes {@link ThemeTokens} through the component tree.
3
+ *
4
+ * `PowerAppsProvider` mounts this automatically. Use directly only when
5
+ * composing providers manually.
6
+ */
7
+ import React from 'react';
8
+ import { type ThemeTokens } from './tokens.js';
9
+ export interface ThemeControl {
10
+ setTheme: (tokens: ThemeTokens) => void;
11
+ resetTheme: () => void;
12
+ }
13
+ export interface ThemeProviderProps {
14
+ theme?: ThemeTokens;
15
+ darkTheme?: ThemeTokens;
16
+ /** @default true */
17
+ followSystem?: boolean;
18
+ children: React.ReactNode;
19
+ }
20
+ export declare function ThemeProvider({ theme, darkTheme, followSystem, children, }: ThemeProviderProps): React.JSX.Element;
21
+ /** Returns current {@link ThemeTokens} from the nearest ThemeProvider. */
22
+ export declare function useThemeTokens(): ThemeTokens;
23
+ /**
24
+ * Returns `{ setTheme, resetTheme }` for imperative theme overrides.
25
+ * Stable reference — does not re-render consumers on theme change.
26
+ */
27
+ export declare function useThemeControl(): ThemeControl;
28
+ export type { ThemeTokens } from './tokens.js';
29
+ export { lightTheme, darkTheme } from './tokens.js';
30
+ //# sourceMappingURL=ThemeProvider.d.ts.map
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Theme token schema and built-in palettes for power-apps-native-host.
3
+ *
4
+ * Pass a custom {@link ThemeTokens} object to `PowerAppsProvider` to override
5
+ * the default Microsoft blue palette.
6
+ */
7
+ export interface ThemeTokens {
8
+ surface0: string;
9
+ surface1: string;
10
+ surface2: string;
11
+ surface3: string;
12
+ surface4: string;
13
+ text0: string;
14
+ text1: string;
15
+ text2: string;
16
+ text3: string;
17
+ accentDeep: string;
18
+ accentBase: string;
19
+ accentSoft: string;
20
+ accentOnAccent: string;
21
+ isDark: boolean;
22
+ }
23
+ /** Microsoft blue light palette (default). */
24
+ export declare const lightTheme: ThemeTokens;
25
+ /** Microsoft blue dark palette (default). */
26
+ export declare const darkTheme: ThemeTokens;
27
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Utilities for reading local file:// URIs and converting them into the binary
3
+ * format expected by the Dataverse upload endpoint via NativePowerAppsBridge.
4
+ *
5
+ * Background:
6
+ * - `fetch('file://')` fails silently on Android.
7
+ * - `fetch('data:...')` throws "Network request failed" on Android.
8
+ * - `new Blob([Uint8Array])` crashes Hermes ("ArrayBufferView not supported").
9
+ * - NativePowerAppsBridge accepts `Uint8Array` and extracts `.buffer` as the
10
+ * fetch body, which React Native sends as raw bytes correctly.
11
+ *
12
+ * Solution: read via `readAsStringAsync` (base64) → `atob` → `Uint8Array`.
13
+ */
14
+ /**
15
+ * Read a local `file://` URI and return its contents as a `Uint8Array`.
16
+ * Safe on both Android and iOS.
17
+ */
18
+ export declare function readFileAsUint8Array(uri: string): Promise<Uint8Array>;
19
+ /**
20
+ * Detect the image MIME type from the first bytes of a base64-encoded string.
21
+ * Returns 'image/jpeg' as a safe default.
22
+ */
23
+ export declare function detectImageMime(base64: string): string;
24
+ /** Convert a base64 string into bytes suitable for Dataverse binary upload APIs. */
25
+ export declare function base64ToUint8Array(base64: string): Uint8Array;
26
+ /**
27
+ * Create a lightweight File-compatible object for generated Dataverse upload methods.
28
+ * React Native does not consistently provide a browser File implementation, but the
29
+ * generated services only require `name` and `arrayBuffer()`.
30
+ */
31
+ export declare function createDataverseUploadFile(name: string, mimeType: string, bytes: Uint8Array): File;
32
+ /** Create a File-compatible image object from Dataverse-style base64 image content. */
33
+ export declare function base64ToDataverseUploadFile(base64: string, name?: string): File;
34
+ /**
35
+ * Build a `data:<mime>;base64,<data>` URI from a raw base64 string returned
36
+ * by Dataverse for an image column.
37
+ */
38
+ export declare function base64ToDataUri(base64: string): string;
39
+ //# sourceMappingURL=dataverseUtils.d.ts.map
@@ -0,0 +1,19 @@
1
+ /**
2
+ * True when the JS bundle is running inside the Power Apps Dev Player shell.
3
+ *
4
+ * Two signals are combined to cover both execution paths:
5
+ *
6
+ * 1. `Constants.expoConfig.extra.isDevPlayer` — set in apps/dev-player/app.config.js.
7
+ * Fires when the dev-player's **own** JS bundle is active (e.g. the launcher screen).
8
+ *
9
+ * 2. `NativeModules.PowerAppsDevLauncher` — the dev-player's Expo native module,
10
+ * registered in the dev-player APK/IPA regardless of which JS bundle is loaded.
11
+ * Fires when a template bundle is loaded via QR-code/URL into the dev-player shell,
12
+ * because expo-constants then reflects the template's manifest (no isDevPlayer flag)
13
+ * but the native module is still present in the host binary.
14
+ *
15
+ * Neither signal fires in a standalone release APK generated from the template, so
16
+ * `isDevPlayer` is false there and all debug logging is silenced.
17
+ */
18
+ export declare const isDevPlayer: boolean;
19
+ //# sourceMappingURL=isDevPlayer.d.ts.map
package/package.json ADDED
@@ -0,0 +1,119 @@
1
+ {
2
+ "name": "@microsoft/power-apps-native-host",
3
+ "version": "0.2.22",
4
+ "description": "React Native host integration for @microsoft/power-apps",
5
+ "author": "Microsoft Corporation",
6
+ "license": "SEE LICENSE IN LICENSE",
7
+ "bugs": {
8
+ "email": "pawrap-team@microsoft.com"
9
+ },
10
+ "main": "./lib/commonjs/index.js",
11
+ "module": "./lib/module/index.js",
12
+ "types": "./lib/typescript/commonjs/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "import": {
16
+ "types": "./lib/typescript/module/index.d.ts",
17
+ "default": "./lib/module/index.js"
18
+ },
19
+ "require": {
20
+ "types": "./lib/typescript/commonjs/index.d.ts",
21
+ "default": "./lib/commonjs/index.js"
22
+ }
23
+ },
24
+ "./package.json": "./package.json",
25
+ "./app.plugin.js": "./app.plugin.js"
26
+ },
27
+ "bin": {
28
+ "generate-connector-schemas": "scripts/generate-connector-schemas.js",
29
+ "js-bundle": "scripts/bundle.js",
30
+ "build-ios-base": "scripts/build-ios-base.js"
31
+ },
32
+ "files": [
33
+ "lib/",
34
+ "!lib/**/*.map",
35
+ "app.plugin.js",
36
+ "scripts/"
37
+ ],
38
+ "scripts": {
39
+ "prepack": "bob build && node ../../scripts/notices.js",
40
+ "build": "bob build && node ../../scripts/notices.js",
41
+ "type-check": "tsc --noEmit"
42
+ },
43
+ "dependencies": {
44
+ "@microsoft/power-apps-native-auth": "^0.3.4",
45
+ "@microsoft/power-apps-native-common": "^0.1.8",
46
+ "@tamagui/config": "1.144.4",
47
+ "@tamagui/core": "1.144.4",
48
+ "@tamagui/portal": "1.144.4",
49
+ "@tamagui/toast": "1.144.4",
50
+ "@tanstack/react-query": "5.62.0"
51
+ },
52
+ "peerDependencies": {
53
+ "@microsoft/power-apps": "*",
54
+ "@microsoft/power-apps-native-offline": ">=0.1.0",
55
+ "@react-native-community/netinfo": ">=11.0.0",
56
+ "burnt": ">=0.12.2",
57
+ "expo-constants": ">=55.0.0",
58
+ "expo-linking": ">=55.0.14",
59
+ "expo-web-browser": ">=55.0.14",
60
+ "react": ">=19.2.0",
61
+ "react-native": ">=0.83.4",
62
+ "react-native-gesture-handler": ">=2.0.0",
63
+ "react-native-safe-area-context": ">=5.6.2"
64
+ },
65
+ "peerDependenciesMeta": {
66
+ "@react-native-community/netinfo": {
67
+ "optional": true
68
+ },
69
+ "burnt": {
70
+ "optional": true
71
+ },
72
+ "react-native-gesture-handler": {
73
+ "optional": true
74
+ }
75
+ },
76
+ "devDependencies": {
77
+ "@types/react": "19.2.14",
78
+ "cross-env": "7.0.3",
79
+ "expo-constants": "55.0.16",
80
+ "expo-web-browser": "55.0.15",
81
+ "react-native-safe-area-context": "5.6.2",
82
+ "typescript": "5.9.3"
83
+ },
84
+ "keywords": [
85
+ "power-apps",
86
+ "react-native",
87
+ "native-host"
88
+ ],
89
+ "publishConfig": {
90
+ "access": "public"
91
+ },
92
+ "sideEffects": false,
93
+ "react-native-builder-bob": {
94
+ "source": "src",
95
+ "output": "lib",
96
+ "targets": [
97
+ [
98
+ "module",
99
+ {
100
+ "esm": true,
101
+ "sourceMaps": false
102
+ }
103
+ ],
104
+ [
105
+ "commonjs",
106
+ {
107
+ "esm": true,
108
+ "sourceMaps": false
109
+ }
110
+ ],
111
+ [
112
+ "typescript",
113
+ {
114
+ "project": "tsconfig.build.json"
115
+ }
116
+ ]
117
+ ]
118
+ }
119
+ }
@@ -0,0 +1,96 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * build-ios-base — Build a code-signing-free base IPA for the Power Apps wrap pipeline.
4
+ *
5
+ * Equivalent to the one-liner previously in package.json's production:ios script.
6
+ * Extracts the xcarchive Products into an IPA that the wrap pipeline can re-sign
7
+ * with the customer's provisioning profile.
8
+ *
9
+ * Usage (via npm script in the consuming expo-app):
10
+ * build-ios-base
11
+ *
12
+ * Output: /tmp/pawrap-base.ipa
13
+ *
14
+ * Prerequisites:
15
+ * expo prebuild --platform ios --clean (generates ios/)
16
+ * cd ios && pod install
17
+ */
18
+
19
+ 'use strict';
20
+
21
+ const { execFileSync } = require('child_process');
22
+ const path = require('path');
23
+ const fs = require('fs');
24
+ const os = require('os');
25
+
26
+ if (process.platform !== 'darwin') {
27
+ console.error('build-ios-base: iOS builds require macOS.');
28
+ process.exit(1);
29
+ }
30
+
31
+ // When invoked as an npm binary the cwd is the consuming package.
32
+ const projectRoot = process.cwd();
33
+ const iosDir = path.join(projectRoot, 'ios');
34
+
35
+ if (!fs.existsSync(iosDir)) {
36
+ console.error(
37
+ 'build-ios-base: ios/ directory not found.\n' +
38
+ 'Run: expo prebuild --platform ios --clean && cd ios && pod install'
39
+ );
40
+ process.exit(1);
41
+ }
42
+
43
+ // Locate the generated .xcworkspace — take the first one found.
44
+ const xcworkspace = fs
45
+ .readdirSync(iosDir)
46
+ .find((f) => f.endsWith('.xcworkspace'));
47
+
48
+ if (!xcworkspace) {
49
+ console.error(
50
+ 'build-ios-base: no .xcworkspace found in ios/.\n' +
51
+ 'Run: expo prebuild --platform ios --clean && cd ios && pod install'
52
+ );
53
+ process.exit(1);
54
+ }
55
+
56
+ // Derive scheme name from workspace name (strip .xcworkspace).
57
+ const scheme = xcworkspace.replace('.xcworkspace', '');
58
+
59
+ const archivePath = path.join(os.tmpdir(), 'pawrap-base.xcarchive');
60
+ const ipaDir = path.join(os.tmpdir(), 'pawrap-base-ipa');
61
+ const payloadDir = path.join(ipaDir, 'Payload');
62
+ const ipaPath = path.join(os.tmpdir(), 'pawrap-base.ipa');
63
+
64
+ function run(cmd, args, opts = {}) {
65
+ console.log(`\n▶ ${cmd} ${args.join(' ')}`);
66
+ execFileSync(cmd, args, { stdio: 'inherit', ...opts });
67
+ }
68
+
69
+ // 1. Archive (no code signing — wrap pipeline signs with customer cert).
70
+ run('xcodebuild', [
71
+ '-workspace', path.join(iosDir, xcworkspace),
72
+ '-scheme', scheme,
73
+ '-configuration', 'Release',
74
+ 'archive',
75
+ '-archivePath', archivePath,
76
+ '-destination', 'generic/platform=iOS',
77
+ 'CODE_SIGNING_REQUIRED=NO',
78
+ 'CODE_SIGN_IDENTITY=',
79
+ 'CODE_SIGNING_ALLOWED=NO',
80
+ ]);
81
+
82
+ // 2. Package into an IPA.
83
+ fs.rmSync(ipaDir, { recursive: true, force: true });
84
+ fs.mkdirSync(payloadDir, { recursive: true });
85
+
86
+ const appsGlob = path.join(archivePath, 'Products', 'Applications');
87
+ for (const app of fs.readdirSync(appsGlob)) {
88
+ if (app.endsWith('.app')) {
89
+ fs.cpSync(path.join(appsGlob, app), path.join(payloadDir, app), { recursive: true });
90
+ }
91
+ }
92
+
93
+ fs.rmSync(ipaPath, { force: true });
94
+ run('zip', ['-r', ipaPath, '.'], { cwd: ipaDir });
95
+
96
+ console.log(`\n✓ Base IPA ready: ${ipaPath}`);
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Cross-platform Metro → Hermes bundle script.
4
+ *
5
+ * Runs two steps:
6
+ * 1. expo export:embed — produces a plain Metro JS bundle
7
+ * 2. hermesc — compiles it to Hermes bytecode (.hbc)
8
+ *
9
+ * Usage (via npm script in the consuming expo-app):
10
+ * bundle android → dist/index.android.bundle.hbc
11
+ * bundle ios → dist/main.jsbundle.hbc
12
+ *
13
+ * Works on macOS, Linux, and Windows.
14
+ */
15
+
16
+ 'use strict';
17
+
18
+ const { execFileSync } = require('child_process');
19
+ const path = require('path');
20
+ const fs = require('fs');
21
+
22
+ const platform = process.argv[2];
23
+ if (platform !== 'android' && platform !== 'ios') {
24
+ console.error('Usage: bundle <android|ios>');
25
+ process.exit(1);
26
+ }
27
+
28
+ const isWin = process.platform === 'win32';
29
+ const isLinux = process.platform === 'linux';
30
+
31
+ // When invoked as an npm binary the cwd is the consuming package (e.g. templates/expo-app/).
32
+ const projectRoot = process.cwd();
33
+ const workspaceRoot = path.resolve(projectRoot, '../..');
34
+
35
+ const distDir = path.join(projectRoot, 'dist');
36
+ fs.mkdirSync(distDir, { recursive: true });
37
+
38
+ const bundleFile = platform === 'android'
39
+ ? path.join(distDir, 'index.android.bundle')
40
+ : path.join(distDir, 'main.jsbundle');
41
+ const assetsDir = path.join(distDir, platform === 'android' ? 'android-assets' : 'ios-assets');
42
+ const outputFile = bundleFile + '.hbc';
43
+
44
+ // ── Step 1: Metro bundle ─────────────────────────────────────────────────────
45
+ console.log(`\n[bundle] Step 1: Metro bundle (${platform})`);
46
+
47
+ // In a standalone project, expo lives in projectRoot/node_modules/.bin/.
48
+ // In an npm workspace (monorepo), binaries are hoisted to workspaceRoot/node_modules/.bin/.
49
+ // Try the project-local bin first so standalone projects work without a monorepo.
50
+ const expoBinName = isWin ? 'expo.cmd' : 'expo';
51
+ const expoBinLocal = path.join(projectRoot, 'node_modules', '.bin', expoBinName);
52
+ const expoBinHoisted = path.join(workspaceRoot, 'node_modules', '.bin', expoBinName);
53
+ const expoBin = fs.existsSync(expoBinLocal) ? expoBinLocal : expoBinHoisted;
54
+
55
+ // expo export:embed resolveArgs scans argv in reverse; the first non-flag string it encounters
56
+ // (i.e. the LAST positional in the array) is set as projectRoot when i === args.length - 1.
57
+ // So projectRoot must be the final argument.
58
+ //
59
+ // expo-router may be in projectRoot/node_modules (standalone) or workspaceRoot/node_modules (monorepo).
60
+ const entryFileLocal = path.join(projectRoot, 'node_modules', 'expo-router', 'entry.js');
61
+ const entryFileHoisted = path.join(workspaceRoot, 'node_modules', 'expo-router', 'entry.js');
62
+ const entryFile = fs.existsSync(entryFileLocal) ? entryFileLocal : entryFileHoisted;
63
+
64
+ execFileSync(
65
+ expoBin,
66
+ [
67
+ 'export:embed',
68
+ '--platform', platform,
69
+ '--entry-file', entryFile,
70
+ '--bundle-output', bundleFile,
71
+ '--assets-dest', assetsDir,
72
+ '--dev', 'false',
73
+ projectRoot, // ← must be last: sets expo CLI's projectRoot
74
+ ],
75
+ { stdio: 'inherit', cwd: projectRoot },
76
+ );
77
+
78
+ // ── Step 2: Hermes compile ───────────────────────────────────────────────────
79
+ console.log(`\n[bundle] Step 2: hermesc compile → ${outputFile}`);
80
+
81
+ const hcPkg = require.resolve('hermes-compiler/package.json', {
82
+ paths: [projectRoot, workspaceRoot],
83
+ });
84
+
85
+ const binDir = isWin ? 'win64-bin' : isLinux ? 'linux64-bin' : 'osx-bin';
86
+ const binName = isWin ? 'hermesc.exe' : 'hermesc';
87
+ // hermes-compiler ships the binary in a subdirectory matching the package name: hermesc/<platform>/hermesc
88
+ const hcDir = path.dirname(hcPkg);
89
+ const hermesc = fs.existsSync(path.join(hcDir, binDir, binName))
90
+ ? path.join(hcDir, binDir, binName)
91
+ : path.join(hcDir, binName, binDir, binName); // fallback: nested hermesc/osx-bin/hermesc
92
+
93
+ execFileSync(hermesc, ['-emit-binary', '-out', outputFile, bundleFile], { stdio: 'inherit' });
94
+
95
+ console.log(`\n[bundle] Done. Output: "${outputFile}"`);