import type { ExpoConfig } from '@expo/config-types'; export type ExtensionType = 'widget' | 'clip' | 'stickers' | 'messages' | 'share' | 'action' | 'wallet' | 'wallet-ui' | 'safari' | 'notification-content' | 'notification-service' | 'intent' | 'intent-ui' | 'spotlight' | 'bg-download' | 'quicklook-thumbnail' | 'location-push' | 'credentials-provider' | 'account-auth' | 'app-intent' | 'device-activity-monitor' | 'matter' | 'watch' | 'content-blocker' | 'keyboard' | 'photo-editing' | 'file-provider' | 'file-provider-ui' | 'broadcast-upload' | 'broadcast-setup-ui' | 'call-directory' | 'message-filter' | 'unwanted-communication' | 'network-packet-tunnel' | 'network-app-proxy' | 'network-dns-proxy' | 'network-filter-data' | 'shield-action' | 'shield-config' | 'classkit-context' | 'authentication-services' | 'spotlight-delegate' | 'quicklook-preview' | 'print-service' | 'smart-card' | 'virtual-conference' | 'watch-widget'; export interface Color { light?: string; dark?: string; color?: string; darkColor?: string; } export type ShareExtensionContentType = 'text' | 'url' | 'image' | 'video' | 'file' | 'webpage'; export interface ShareExtensionActivationRule { /** * Type of content to accept * - text: Plain text content * - url: URLs (including web URLs) * - image: Image files * - video: Video files * - file: Generic files * - webpage: Web pages (requires preprocessingFile for full support) */ type: ShareExtensionContentType; /** * Maximum number of items to accept (default: 1) * Only applicable for url, image, video, and file types */ maxCount?: number; } export interface StickerPack { name: string; assets: string[]; } export interface IntentUIConfig { enabled: boolean; name?: string; bundleIdentifier?: string; } export interface IntentsConfig { intentsSupported?: string[]; intentsRestrictedWhileLocked?: string[]; ui?: boolean | IntentUIConfig; } export interface WalletUIConfig { enabled: boolean; name?: string; bundleIdentifier?: string; } export interface WalletConfig { ui?: boolean | WalletUIConfig; } export declare const TYPE_MINIMUM_DEPLOYMENT_TARGETS: Record; export declare const TYPE_BUNDLE_IDENTIFIER_SUFFIXES: Record; export type NativeLinkMode = 'entry' | 'host'; interface BaseIosTargetConfig { icon?: string; deploymentTarget?: string; bundleIdentifier?: string; displayName?: string; colors?: Record; images?: Record; stickerPacks?: StickerPack[]; /** * Icon for extension target * - For stickers and messages: Path to source image file (e.g., "./assets/imessage-icon.png") * - For action extensions: SF Symbol name (e.g., "photo.fill") or image asset name * @example * targetIcon: "./assets/icon.png" // iMessage app icon file path (stickers / messages) * targetIcon: "photo.fill" // Action extension SF Symbol * targetIcon: "MyActionIcon" // Action extension image asset name */ targetIcon?: string; frameworks?: string[]; /** * How the nested RN target links native host packages. * `entry` (default): invert unused autolinked packages off provider + linker. * `host`: copy the host fat link (old behavior). */ nativeLink?: NativeLinkMode; entitlements?: Record; infoPlist?: Record; swiftVersion?: string; targetedDeviceFamily?: string; clangEnableModules?: boolean | string; swiftEmitLocStrings?: boolean | string; /** * Content types this share extension accepts * Only applies to share extension targets * @example * activationRules: [ * { type: 'text' }, * { type: 'url' }, * { type: 'image', maxCount: 5 } * ] */ activationRules?: ShareExtensionActivationRule[]; /** * JavaScript file for preprocessing web content * Only applies to share extension targets * Enables NSExtensionActivationSupportsWebPageWithMaxCount * @see https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/Share.html */ preprocessingFile?: string; /** * Custom manifest.json configuration for Safari web extensions * Only applies to Safari extension targets with 'entry' field * Merged with auto-generated manifest when using React Native Web mode * @example * manifest: { * permissions: ['storage', 'tabs'], * content_scripts: [{ matches: ['*://*.example.com/*'] }] * } */ manifest?: { name?: string; version?: string; description?: string; permissions?: string[]; content_scripts?: { matches: string[]; js?: string[]; css?: string[]; }[]; icons?: Record; }; /** * Siri Intents configuration for intent extensions * When ui is enabled, generates both Intent and Intent UI extensions * @example * intents: { * intentsSupported: ['INStartWorkoutIntent', 'INPauseWorkoutIntent'], * ui: true * } */ intents?: IntentsConfig; /** * Wallet extension configuration for payment pass provisioning * When ui is enabled, generates both Non-UI and UI (auth) extensions * @example * wallet: { * ui: true // Creates both wallet and wallet-ui targets * } * // Or with custom config: * wallet: { * ui: { enabled: true, name: 'MyWalletAuth' } * } */ wallet?: WalletConfig; /** * File Provider domain identity (type='file-provider'). * Source of truth for FileProviderDomain.register() — strict CNG. */ fileProviderDomain?: { identifier: string; displayName: string; }; /** * Host App Intent metadata (type='app-intent'). Generated into main app on prebuild. */ appIntents?: AppIntentHostConfig[]; /** * App Shortcuts provider entries (type='app-intent'). Generated into main app on prebuild. */ appShortcuts?: AppShortcutConfig[]; /** * Expo-ui Edit Widget (AppIntentConfiguration, iOS 17+). * Parameters land in Layout `environment.configuration`. */ configuration?: WidgetConfiguration; /** WidgetKit families for expo-ui Static/AppIntentConfiguration. */ supportedFamilies?: WidgetFamily[]; /** Disable default WidgetKit content margins (expo-ui). */ contentMarginsDisabled?: boolean; /** * WidgetKit picker products (`name` matches `createTarget` / Swift `kind:`). * When omitted or empty, one widget uses `name` + scalar ios fields. * Live Activity belongs on `liveActivity`, not in this list. */ kinds?: IosWidgetKindConfig[]; /** * ActivityKit Live Activity in the same widget `.appex` (shorthand when one). * Prefer `liveActivities` when declaring two or more in one target. * Native CNG uses `attributesName` / `static` / `contentState` / `pushType`. * Expo-ui Bundles add `WidgetLiveActivity()`. */ liveActivity?: LiveActivityConfig; /** * Multiple Live Activities in the same widget `.appex`. * Do not set together with `liveActivity` — use one form per target. */ liveActivities?: LiveActivityConfig[]; } /** WidgetKit family names (expo-ui supportedFamilies). */ export type WidgetFamily = 'systemSmall' | 'systemMedium' | 'systemLarge' | 'systemExtraLarge' | 'accessoryCircular' | 'accessoryRectangular' | 'accessoryInline'; export type WidgetParameterString = { title: string; type: 'string'; default: string; }; export type WidgetParameterNumber = { title: string; type: 'number'; default: number; }; export type WidgetParameterBoolean = { title: string; type: 'boolean'; default: boolean; }; export type WidgetParameterEnum = { title: string; type: 'enum'; values: { name: string; value: string; }[]; default: string; }; export type WidgetParameter = WidgetParameterString | WidgetParameterNumber | WidgetParameterBoolean | WidgetParameterEnum; /** Expo-ui configurable Edit Widget schema (maps to AppIntentConfiguration). */ export type WidgetConfiguration = { title?: string; description?: string; parameters: Record; }; /** Live Activity field schema for CNG codegen */ export interface LiveActivityConfig { attributesName: string; static?: Record; contentState: Record; /** * When `'token'`, ActivityKit requests a push token (APNs updates / push-to-start). * Simulator cannot prove remote push — agent-device stays CLAIMS for DI/push/StandBy. */ pushType?: 'token' | null; } /** Gallery WidgetKit picker product (`createTarget` name = Swift struct). */ export interface IosWidgetKindConfig { type?: 'widget'; name: string; displayName?: string; description?: string; supportedFamilies?: WidgetFamily[]; contentMarginsDisabled?: boolean; configuration?: WidgetConfiguration; } /** * Leftover kinds row shape. Author Live Activity on `ios.liveActivity`. * A `{ type: "live-activity" }` kinds row throws. */ export type IosLiveActivityKindConfig = LiveActivityConfig & { type: 'live-activity'; }; /** Gallery WidgetKit picker product. Not a Live Activity. */ export type IosKindConfig = IosWidgetKindConfig; export interface AppIntentHostConfig { className: string; title: string; description?: string; openAppWhenRun?: boolean; /** Swift symbol for user-owned perform hook under targets//ios/ */ performHook: string; } export interface AppShortcutConfig { intent: string; phrases: string[]; shortTitle: string; systemImageName?: string; } export type ReactNativeCompatibleType = 'share' | 'action' | 'clip' | 'messages' | 'notification-content'; export type NativeOnlyType = Exclude; export interface IOSTargetConfigWithReactNative extends BaseIosTargetConfig { } export interface IOSTargetConfigNativeOnly extends BaseIosTargetConfig { } export type IOSTargetConfig = IOSTargetConfigWithReactNative | IOSTargetConfigNativeOnly; /** One AppWidgetProvider / picker row. Scalar `android.*` is the 1:1 default. */ export interface AndroidWidgetProviderConfig { /** Identity for xml (`widgetprovider_`) and default class names. */ name: string; /** Widget picker label. */ displayName?: string; /** * AppWidgetProvider FQCN, or a simple class name under * `{package}.widget.{sanitizedTarget}`. Placed widgets bind to FQCN — keep * this stable when you colocate several providers in one target. */ className?: string; minWidth?: string; minHeight?: string; resizeMode?: string; updatePeriodMillis?: number; widgetCategory?: string; previewImage?: string; description?: string; maxResizeWidth?: string; maxResizeHeight?: string; targetCellWidth?: number; targetCellHeight?: number; initialLayout?: string; } export interface AndroidTargetConfig { resourceName?: string; /** * Widget rendering approach (default: 'glance') * - 'glance': Modern Jetpack Compose-based widgets using Glance API * - 'remoteviews': Traditional XML layout-based widgets using RemoteViews */ widgetType?: 'glance' | 'remoteviews'; /** * Opt-in list of AppWidgetProvider rows (picker + FQCN). When omitted or * empty, the plugin registers one provider from the scalar fields below. */ providers?: AndroidWidgetProviderConfig[]; minWidth?: string; minHeight?: string; resizeMode?: string; updatePeriodMillis?: number; widgetCategory?: string; previewImage?: string; description?: string; maxResizeWidth?: string; maxResizeHeight?: string; targetCellWidth?: number; targetCellHeight?: number; initialLayout?: string; colors?: Record; /** Named images copied into `android/res/drawable*` (PNG/WebP/JPEG/GIF or VectorDrawable XML). */ images?: Record; /** * Share/action MIME activation (optional). When omitted, plugin uses * `ios.activationRules` if present, else text+url defaults. */ activationRules?: ShareExtensionActivationRule[]; /** * Notification channel id (notification-service / notification-content). * Default: `expo_targets_`. */ channelId?: string; /** Human-readable channel name for NotificationManager. */ channelName?: string; /** * Content category key (notification-content). Defaults to iOS * `UNNotificationExtensionCategory` or `myNotificationCategory`. */ category?: string; /** * Title suffix applied by the local notification-service processor. * Default: ` [expo-targets]` (matches iOS NSE example). */ mutationMarker?: string; /** * DocumentsProvider authority (file-provider). * Default: `{android.package}.expo_targets.documents.`. */ authority?: string; /** IME label override (keyboard). */ imeLabel?: string; /** VPN service label (network-packet-tunnel). */ vpnDisplayName?: string; /** * Extra `implementation("…")` coordinates for the host app `build.gradle`. * Use for widget deepen that needs libraries the host does not already ship. */ implementation?: string[]; /** * When true, inject `com.google.zxing:core` (QR encode helper on * `ExpoTargetsQr`). Off by default. */ qr?: boolean; } /** Authoring mode — see docs/react-native-extensions.md and resolveUiMode(). */ export type UiMode = 'native' | 'expo-ui' | 'react-native'; interface BaseTargetConfig { name: string; displayName?: string; appGroup?: string; platforms: string[]; android?: AndroidTargetConfig; /** * UI authoring mode. Defaults: share-class + `entry` → `react-native`; * `widget`/`watch-widget` + `entry` → `expo-ui`; no `entry` → `native`. * Share-class Host trees set `ui: 'expo-ui'` explicitly. */ ui?: UiMode; /** * JS entry for react-native (share-class / safari) or expo-ui layout * (widget sandbox / Host-in-RN). Path relative to project root. */ entry?: string; /** * Extra packages to omit from the nested extension's ExpoModulesProvider * and linker. For RN-native `entry` targets, unused autolinked host packages * are inverted out by default. Crash-class packages (`expo-updates`, * `expo-dev-client`, `expo-dev-launcher`, `expo-dev-menu`) always merge. * This list is force-strip only. */ excludedPackages?: string[]; /** * Force-keep these autolinked packages on the extension even when the JS * entry does not import them. */ linkedPackages?: string[]; } type TargetConfigReactNativeCompatible = BaseTargetConfig & { type: ReactNativeCompatibleType; ios?: IOSTargetConfigWithReactNative; }; type TargetConfigNativeOnly = BaseTargetConfig & { type: NativeOnlyType; ios?: IOSTargetConfigNativeOnly; }; export type TargetConfig = TargetConfigReactNativeCompatible | TargetConfigNativeOnly; export type TargetConfigFunction = (config: ExpoConfig) => TargetConfig; export declare const getAppGroup: (identifier: string) => string; export declare const getTargetBundleIdentifier: (appBundleId: string, targetName: string) => string; export {}; //# sourceMappingURL=config.d.ts.map