/** * Payload construction, size enforcement, header building, and APNs response * parsing shared by the device pusher and the broadcaster. * * @packageDocumentation */ import type * as http2 from 'node:http2'; import { type LiveActivityState, type LiveActivityAttributesData, type AlertConfig } from '../shared/schema'; import { type ApnsPriority, type ApnsResult } from './types'; /** The `aps` envelope as serialized to APNs JSON (wire keys are kebab-case). */ interface ApsEnvelope { /** Event timestamp in epoch **seconds**. */ timestamp: number; /** Lifecycle event. */ event: 'start' | 'update' | 'end'; /** * Normalized content state (camelCase keys, matches Swift `Codable`). * Present for `update`/`start`; optional for `end` (omitting it keeps the * activity's last rendered state). */ 'content-state'?: LiveActivityState; /** Optional alert banner (string or structured). */ alert?: { title: string; body: string; sound?: string; }; /** Stale date in epoch **seconds**. */ 'stale-date'?: number; /** Relevance score (sort weight). */ 'relevance-score'?: number; /** Dismissal date in epoch **seconds**. */ 'dismissal-date'?: number; /** Bare attributes struct name (start). */ 'attributes-type'?: string; /** Immutable attributes (start). */ attributes?: LiveActivityAttributesData; /** iOS 18: subscribe started activity to a broadcast channel (start). */ 'input-push-channel'?: string; /** iOS 18: request a per-activity update token for the started activity (start). */ 'input-push-token'?: number; } /** The full APNs JSON body. */ export interface ApnsPayload { aps: ApsEnvelope; } /** Inputs for {@link buildUpdatePayload}. */ export interface BuildUpdateInput { state: LiveActivityState; alert?: AlertConfig; staleDate?: Date | number; relevanceScore?: number; dismissalDate?: Date | number; } /** Build the `event:'update'` APNs payload (content-state normalized). */ export declare function buildUpdatePayload(input: BuildUpdateInput): ApnsPayload; /** Inputs for {@link buildEndPayload}. */ export interface BuildEndInput { state?: LiveActivityState; dismissalDate?: Date | number; } /** Build the `event:'end'` APNs payload (final state optional). */ export declare function buildEndPayload(input: BuildEndInput): ApnsPayload; /** Inputs for {@link buildStartPayload}. */ export interface BuildStartInput { attributesType: string; attributes: LiveActivityAttributesData; state: LiveActivityState; alert: AlertConfig; staleDate?: Date | number; relevanceScore?: number; inputPushToken?: boolean; inputPushChannel?: string; } /** * Build the `event:'start'` (push-to-start) APNs payload. * * @throws {ApnsError} of kind `'invalid-argument'` if `alert` is missing — APNs * rejects `start` pushes without an alert. */ export declare function buildStartPayload(input: BuildStartInput): ApnsPayload; /** * Serialize a payload to JSON and enforce the 4 KB APNs limit on the **byte** * length (UTF-8), throwing before any network I/O if exceeded. * * @throws {ApnsError} of kind `'payload-too-large'`. */ export declare function serializePayload(payload: ApnsPayload): { json: string; byteLength: number; }; /** Build the common APNs header set for a device push. */ export declare function buildPushHeaders(options: { token: string; topic: string; priority: ApnsPriority; byteLength: number; apnsId?: string; expiration?: number; /** Broadcast channel id (mutually exclusive with `topic` per Apple). */ channelId?: string; }): http2.OutgoingHttpHeaders; /** Derive the APNs topic for Live Activities from a bundle id. */ export declare function liveActivityTopic(bundleId: string): string; /** * Parse a raw HTTP/2 response into a typed {@link ApnsResult}. Never throws; * callers decide whether to surface a failure as an {@link ApnsError}. */ export declare function parseApnsResult(response: { status: number; headers: http2.IncomingHttpHeaders; body: string; }): ApnsResult; export {}; //# sourceMappingURL=payload.d.ts.map