import type { TGatewayClientType } from './gateway.js'; export type TWebPushBindingStatus = 'active' | 'disabled' | 'pending' | 'failed'; export type TWebPushCredentialStatus = 'active' | 'disabled' | 'rotated' | 'revoked'; export type TWebPushVapidKeyStatus = 'active' | 'retiring' | 'retired'; /** * `pushServiceAccepted` means that the remote push service accepted the * encrypted request. It does not prove browser receipt or display. */ export type TWebPushDeliveryState = 'accepted' | 'queued' | 'sending' | 'deferred' | 'pushServiceAccepted' | 'invalidSubscription' | 'failed' | 'expired' | 'cancelled'; export type TWebPushUrgency = 'very-low' | 'low' | 'normal' | 'high'; /** * `appInstanceId` identifies the environment-specific deployed service * instance, not an App Store template or a browser-provided owner. */ export interface IWebPushResourceOwner { gatewayClientType: TGatewayClientType; gatewayClientId: string; appInstanceId: string; } export type TWebPushControllerIntent = 'enabled' | 'disabled' | 'deleted'; /** * Durable controller fence for owner-scoped Web Push mutations. * * `id` and `epoch` are immutable for one owner. `generation` is a positive, * strictly monotonic controller sequence. Reusing a generation is permitted * only for the exact same operation, intent, and canonical request payload. */ export interface IWebPushControllerMutation { id: string; epoch: string; generation: number; operationId: string; intent: TWebPushControllerIntent; } /** JSON form returned by the browser Push API. */ export interface IWebPushSubscription { endpoint: string; expirationTime: number | null; keys: { p256dh: string; auth: string; }; } export interface IWebPushCredentialPublic { id: string; status: TWebPushCredentialStatus; createdAt: number; updatedAt: number; lastRotatedAt?: number; } export interface IWebPushCredentialOneTimeSecret { credential: IWebPushCredentialPublic; secret: string; secretShownOnce: true; } export interface IWebPushVapidKeyPublic { id: string; publicKey: string; status: TWebPushVapidKeyStatus; createdAt: number; activatedAt?: number; retireAfter?: number; retiredAt?: number; } export interface IWebPushBinding { id: string; owner: IWebPushResourceOwner; enabled: boolean; status: TWebPushBindingStatus; credential?: IWebPushCredentialPublic; vapidKeys: IWebPushVapidKeyPublic[]; createdAt: number; updatedAt: number; createdBy?: string; } /** * Privacy-minimal notification signal. Applications fetch display content * from their authenticated API after receiving this event. */ export interface IWebPushNotificationPayload { schemaVersion: 1; event: 'notificationAvailable'; eventId: string; /** Same-origin application route beginning with a single slash. */ route: string; } /** Public delivery metadata. Subscription and encrypted payload data are absent. */ export interface IWebPushDeliveryStatus { spoolItemId: string; state: TWebPushDeliveryState; attempts: number; acceptedAt: number; updatedAt: number; nextAttemptAt?: number; terminalAt?: number; pushServiceStatusCode?: number; errorCode?: string; } export interface IWebPushServiceStatus { ready: boolean; bindingId: string; bindingStatus: TWebPushBindingStatus; activeVapidKey?: IWebPushVapidKeyPublic; retiringVapidKeys: IWebPushVapidKeyPublic[]; maxPayloadBytes: number; maxTtlSeconds: number; contentEncoding: 'aes128gcm'; message?: string; } export type TWebPushCancellationTarget = { type: 'spoolItem'; spoolItemId: string; subscriptionId?: never; } | { type: 'subscription'; subscriptionId: string; spoolItemId?: never; }; export interface IServiceWebPushConfig { enabled?: boolean; }