import type { Simplify } from "effect/Types"; /** * Type-only helpers for Cloudflare Zaraz events. * * These declarations are not an Alchemy EventSource resource and do not send * events at runtime. They only model the browser-side `window.zaraz` API and * Zaraz HTTP event payloads so application code can share an event contract * with infrastructure code. */ /** * A map of Zaraz event names to the properties accepted by each event. * * Use `undefined` for events that do not accept custom properties. */ export type EventMap = Record; type RequireAtLeastOne = { readonly [K in keyof T]-?: Required> & Partial>; }[keyof T]; /** * Product properties supported by Cloudflare Zaraz ecommerce events. */ export type EcommerceProduct = { readonly product_id?: string; readonly sku?: string; readonly category?: string; readonly name?: string; readonly brand?: string; readonly variant?: string; readonly price?: number; readonly currency?: string; readonly value?: number; readonly quantity?: number; readonly coupon?: string; readonly position?: number; }; /** * Order and checkout properties supported by Cloudflare Zaraz ecommerce events. */ export type EcommerceOrder = { readonly checkout_id?: string; readonly order_id?: string; readonly affiliation?: string; readonly total?: number; readonly revenue?: number; readonly shipping?: number; readonly tax?: number; readonly discount?: number; readonly coupon?: string; readonly currency?: string; readonly products?: readonly EcommerceProduct[]; }; export type EcommercePromotion = { readonly creative?: string; }; export type EcommerceSearch = { readonly query?: string; }; export type EcommerceCheckoutStep = { readonly step?: number; }; export type EcommercePayment = { readonly payment_type?: string; }; export type EcommerceRefund = { readonly amount?: number; readonly amount_refunded?: number; readonly currency?: string; readonly refund_reason?: string; }; /** * Standard ecommerce events supported by Cloudflare's `zaraz.ecommerce()` API. */ export type EcommerceEvents = { readonly "Product List Viewed": RequireAtLeastOne< Pick >; readonly "Products Searched": RequireAtLeastOne; readonly "Product Clicked": RequireAtLeastOne; readonly "Product Added": RequireAtLeastOne; readonly "Product Added to Wishlist": RequireAtLeastOne; readonly "Product Removed": RequireAtLeastOne; readonly "Product Viewed": RequireAtLeastOne; readonly "Cart Viewed": RequireAtLeastOne; readonly "Checkout Started": RequireAtLeastOne; readonly "Checkout Step Viewed": RequireAtLeastOne; readonly "Checkout Step Completed": RequireAtLeastOne; readonly "Payment Info Entered": RequireAtLeastOne; readonly "Order Completed": RequireAtLeastOne; readonly "Order Updated": RequireAtLeastOne; readonly "Order Refunded": RequireAtLeastOne< EcommerceOrder & EcommerceRefund >; readonly "Order Cancelled": RequireAtLeastOne; readonly "Clicked Promotion": RequireAtLeastOne; readonly "Viewed Promotion": RequireAtLeastOne; readonly "Shipping Info Entered": RequireAtLeastOne; }; declare const ZarazEventContractTypeId: unique symbol; /** * Type-only contract for an application's Zaraz events. * * The runtime value is intentionally empty. Application browser code should * import derived types and call Cloudflare's injected `window.zaraz` API rather * than importing Alchemy runtime code into the client bundle. */ export type EventContract< Events extends EventMap, EcommerceEvents extends EventMap = {}, > = { readonly [ZarazEventContractTypeId]: { readonly events: Events; readonly ecommerceEvents: EcommerceEvents; }; }; /** * Define an application's Zaraz event contract. * * @example * ```typescript * const zaraz = Cloudflare.Config.events<{ * Login: { method: "google" | "email" | "email-link" }; * "Button Clicked": { button_label: string; context?: string }; * }>(); * * const zarazWithEcommerce = Cloudflare.Config.events<{ * Login: { method: "google" | "email" | "email-link" }; * }>({ ecommerce: true }); * * export type AppZarazEvents = Cloudflare.Zaraz.InferZarazEvents; * ``` */ export function defineZarazEvents(options: { readonly ecommerce: true; }): EventContract; export function defineZarazEvents(options?: { readonly ecommerce?: false; }): EventContract; export function defineZarazEvents(_options?: { readonly ecommerce?: boolean; }): EventContract { return {} as EventContract; } export type InferZarazEvents = Contract extends EventContract ? Events : never; export type InferZarazEcommerceEvents = Contract extends EventContract ? EcommerceEvents : never; export type EventName = Extract; export type EventProperties< Events extends EventMap, Name extends EventName, > = Events[Name]; type ZarazEventPropertiesArgs = [Properties] extends [undefined] ? [properties?: undefined] : undefined extends Properties ? [properties?: Exclude] : [properties: Properties]; /** * Type for Cloudflare's injected `window.zaraz.track` function. */ export type Track = < const Name extends EventName, >( eventName: Name, ...args: ZarazEventPropertiesArgs ) => Promise; /** * Type for Cloudflare's injected `window.zaraz.ecommerce` function. */ export type Ecommerce = Track; export type SetScope = "page" | "session" | "persist"; /** * Type for Cloudflare's injected browser-side Zaraz API. */ export type WebApi< Events extends EventMap, EcommerceEvents extends EventMap = {}, > = { set: (name: string, value: unknown, options?: { scope?: SetScope }) => void; track: Track; ecommerce: Ecommerce; preview: (debugKey: string) => Promise; debug: (debugKey: string) => Promise; showConsentModal: () => Promise; pageVariables: Record; }; export type System = { cookies?: Record; device?: { ip?: string; resolution?: string; viewport?: string; language?: string; "user-agent"?: string; }; page?: { title?: string; url?: string; referrer?: string; encoding?: string; }; }; export type ClientProperties< Events extends EventMap, Name extends EventName = EventName, > = Name extends EventName ? Events[Name] extends undefined ? { readonly __zarazTrack: Name } : Simplify : never; export type HttpEvent = { readonly client: ClientProperties; readonly system?: System; }; export type HttpEventsPayload = { readonly events: readonly HttpEvent[]; };