import type { AppStateStatus } from "react-native"; export type JsonPrimitive = string | number | boolean | null; export type JsonValue = JsonPrimitive | JsonObject | JsonValue[]; export interface JsonObject { [key: string]: JsonValue; } export type NetworkClient = typeof fetch; export interface KeyValueStorageAdapter { getItem(key: string): Promise; setItem(key: string, value: string): Promise; removeItem(key: string): Promise; } export interface AppInfo { name?: string; version?: string; buildNumber?: string; bundleId?: string; environment?: string; } export interface EndpointOverrides { init?: string; refresh?: string; } export interface PiiData { [key: string]: string; } export type PiiEncryptor = ( publicKey: string, payload: PiiData ) => Promise; export interface DeviceContext { sdkVersion: string; platform: string; platformVersion: string; deviceType: "mobile" | "tablet" | "desktop"; locale: string; timezone: string; appState: AppStateStatus; colorScheme?: "light" | "dark" | null; screen: { width: number; height: number; scale: number; fontScale: number; }; app: AppInfo; } export interface EventContext { device: DeviceContext; campaign?: { source?: string; medium?: string; campaign?: string; term?: string; content?: string; }; push?: { campaignId?: string; messageId?: string; provider?: PushProvider; title?: string; }; } export interface EventBase { apiVersion: string; event_name: string; timestamp: string; visitor_id: string; installation_id: string; session_id: string; userId?: string; phone?: string; org_id?: string | null; project_id?: string | null; properties?: Record; context: EventContext; } export interface EventPayload extends EventBase { id: string; } export interface SdkServerConfig { maxBatchSize?: number; flushIntervalMs?: number; idleTimeoutMs?: number; sessionExpiryMs?: number; maxEventsPerMinute?: number; env?: { auth?: string; api?: string; notifications?: string; notificationUrl?: string; notification_url?: string; pushEventsUrl?: string; push_events_url?: string; }; } export interface SsoInitResponse { orgId: string; projectId: string; ingestionUrl: string; notificationUrl?: string; notificationURL?: string; notification_url?: string; notificationsUrl?: string; notifications_url?: string; pushEventsUrl?: string; push_events_url?: string; PII_PublicKey?: string; jwt: string; expiresAt?: string; config?: SdkServerConfig; } export interface SDKConfig { /** * Sirrus project API key. The SDK uses this to call SSO init internally, * then uses the returned JWT and ingestion URL for subsequent API calls. */ apiKey: string; /** * Optional SSO base URL override for QA or self-hosted environments. * Product apps should usually omit this and let the SDK use production. */ ssoUrl?: string; /** * Advanced test hook for mocks or custom transports. Do not pass this in a * normal product app if you want the SDK to call Sirrus APIs directly. */ networkClient?: NetworkClient; storage?: KeyValueStorageAdapter; appInfo?: AppInfo; userInfo?: UserInfo; piiEncryptor?: PiiEncryptor; debug?: boolean; onError?: (error: Error) => void | Promise; deviceContextProvider?: () => Promise> | Partial; endpoints?: EndpointOverrides; notificationUI?: NotificationUiConfig; } export interface TrackOptions { context?: Partial; immediate?: boolean; } export type PushProvider = "fcm" | "apns"; export interface UserInfo { userId: string; phone: string; } export interface PushTokenRegistrationInput { token: string; userId: string; phone: string; } export interface PushNotificationPayload { title?: string; body?: string; subtitle?: string; imageUrl?: string; gifUrl?: string; videoUrl?: string; deeplinkUrl?: string; campaignId?: string; templateId?: string; messageId?: string; provider?: PushProvider; channelId?: string; categoryId?: string; sound?: string; actions?: PushNotificationAction[]; data?: JsonObject; rawPayload?: JsonObject; } export interface PushNotificationAction { id: string; title: string; label?: string; actionType?: string; postback?: string; deeplinkUrl?: string; destructive?: boolean; foreground?: boolean; authenticationRequired?: boolean; } export interface NotificationDisplayRequest { payload: PushNotificationPayload; source: "foreground_receive" | "manual"; } export interface NotificationPresenter { show(request: NotificationDisplayRequest): Promise | void; } export type NotificationHandlingMode = "sirrus-only" | "all"; export type NotificationOwnership = "sirrus" | "external" | "unknown"; export interface NotificationSourceMatcher { sourceKeys?: string[]; sourceValues?: string[]; campaignIdKeys?: string[]; templateIdKeys?: string[]; } export interface NotificationClassification { matched: boolean; ownership: NotificationOwnership; reason: string; } export interface NotificationProcessingResult { handled: boolean; displayed: boolean; opened: boolean; classification: NotificationClassification; } export interface NotificationUiConfig { presenter?: NotificationPresenter; showForegroundNotifications?: boolean; handlingMode?: NotificationHandlingMode; sourceMatcher?: NotificationSourceMatcher; useNativePresenter?: boolean; defaultAndroidChannelId?: string; /** * Android-only shortcut. Each ID is created as a high-importance channel * with the ID as its display name. */ androidChannelIds?: string[]; /** * Android-only full channel definitions for apps that need custom names, * descriptions, vibration, or importance. */ androidChannels?: AndroidNotificationChannelConfig[]; iosCategories?: IOSNotificationCategoryConfig[]; } export interface NotificationPermissionStatus { granted: boolean; status: "granted" | "denied" | "not_determined" | "unavailable"; } export interface NativeNotificationEvent { type: "received" | "opened" | "action_pressed"; actionId?: string; action?: PushNotificationAction; deeplinkUrl?: string; displayedBySystem?: boolean; payload: PushNotificationPayload; } export type NotificationInteractionType = "opened" | "action_pressed"; export interface NotificationInteractionEvent { type: NotificationInteractionType; payload: PushNotificationPayload; actionId?: string; action?: PushNotificationAction; deeplinkUrl?: string; } export type NotificationInteractionListener = ( event: NotificationInteractionEvent ) => void | Promise; export interface AndroidNotificationChannelConfig { id: string; name: string; description?: string; importance?: "min" | "low" | "default" | "high" | "max"; enableVibration?: boolean; vibrationPatternMs?: number[]; sound?: string; } export interface IOSNotificationActionConfig { id: string; title: string; foreground?: boolean; destructive?: boolean; authenticationRequired?: boolean; } export interface IOSNotificationCategoryConfig { id: string; actions?: IOSNotificationActionConfig[]; }