UNPKG

@mackenly/fathom-api

Version:

Typescript wrapper around Fathom Analytics API

801 lines (788 loc) 21.5 kB
import { z } from 'zod'; /** * Fathom Analytics API version */ type ApiVersion = 'v1'; /** * Configuration options for the Fathom Analytics client */ interface FathomClientOptions { /** * API token for authentication */ token: string; /** * API version to use * @default 'v1' */ version?: ApiVersion; /** * Base URL for the API * @default 'https://api.usefathom.com' */ baseUrl?: string; } /** * Pagination parameters for list endpoints */ interface PaginationParams { /** * A limit on the number of objects to be returned, between 1 and 100 * @default 10 */ limit?: number; /** * A cursor for pagination/navigation. * An object ID that specifies the starting point for pagination */ starting_after?: string; /** * A cursor for pagination/navigation. * An object ID that specifies the ending point for pagination */ ending_before?: string; } /** * Common response structure for list endpoints */ interface ListResponse<T> { object: 'list'; url: string; has_more: boolean; data: T[]; } /** * Error response from the API */ interface ErrorResponse { error: string; message?: string; } /** * HTTP methods supported by the API */ type HttpMethod = 'GET' | 'POST' | 'DELETE'; /** * Error class for Fathom API errors */ declare class FathomApiError extends Error { status: number; error: string; constructor(message: string, status: number); } /** * Core HTTP client for making API requests */ declare class HttpClient { private baseUrl; private token; private headers; constructor(options: FathomClientOptions); /** * Make an HTTP request to the Fathom API * * @param method - HTTP method * @param path - API endpoint path * @param params - Query parameters * @param data - Request body for POST/PUT requests * @returns Promise with the response data * @throws FathomApiError if the API returns an error */ request<T>(method: HttpMethod, path: string, params?: Record<string, any>, data?: Record<string, any>): Promise<T>; /** * Make a GET request to the Fathom API */ get<T>(path: string, params?: Record<string, any>): Promise<T>; /** * Make a POST request to the Fathom API */ post<T>(path: string, data?: Record<string, any>, params?: Record<string, any>): Promise<T>; /** * Make a DELETE request to the Fathom API */ delete<T>(path: string, params?: Record<string, any>): Promise<T>; } /** * Base interface for all Fathom API objects */ interface FathomObject { id: string; object: string; } /** * Account entity */ interface Account extends FathomObject { object: 'account'; name: string; email: string; } /** * Site entity */ interface Site extends FathomObject { object: 'site'; name: string; sharing: 'none' | 'private' | 'public'; created_at: string; } /** * Site with deletion status */ interface DeletedSite extends Site { deleted: boolean; } /** * Site with data wiping status */ interface WipedSite extends Site { wiped: boolean; } /** * Event entity */ interface Event extends FathomObject { object: 'event'; name: string; site_id: string; created_at: string; } /** * Event with deletion status */ interface DeletedEvent extends Event { deleted: boolean; } /** * Event with data wiping status */ interface WipedEvent extends Event { wiped: boolean; } /** * Content entry for current visitors breakdown */ interface ContentEntry { pathname: string; hostname: string; total: number; } /** * Referrer entry for current visitors breakdown */ interface ReferrerEntry { referrer_hostname: string; referrer_pathname: string; total: number; } /** * Current visitors response */ interface CurrentVisitorsResponse { total: number; content?: ContentEntry[]; referrers?: ReferrerEntry[]; } /** * Account API resource */ declare class AccountResource { private readonly http; constructor(http: HttpClient); /** * Get account information * * @returns Promise with account information */ get(): Promise<Account>; } /** * Parameters for creating a site */ interface CreateSiteParams { /** * The name of the website */ name: string; /** * The sharing configuration * @default 'none' */ sharing?: 'none' | 'private' | 'public'; /** * When sharing is set to private, you must also send a password */ share_password?: string; } /** * Parameters for updating a site */ interface UpdateSiteParams { /** * The name of the website */ name?: string; /** * The sharing configuration */ sharing?: 'none' | 'private' | 'public'; /** * When sharing is set to private, you must also send a password */ share_password?: string; } /** * Parameters for creating an event */ interface CreateEventParams { /** * The name of the event */ name: string; } /** * Parameters for updating an event */ interface UpdateEventParams { /** * The name of the event */ name: string; } /** * Filter operator for aggregation queries */ type FilterOperator = 'is' | 'is not' | 'is like' | 'is not like'; /** * Filter for aggregation queries */ interface AggregationFilter { property: string; operator: FilterOperator; value: string; } /** * Parameters for aggregation queries */ interface AggregationParams { /** * The entity you want to report on */ entity: 'pageview' | 'event'; /** * The ID of the entity that you want to report on */ entity_id: string; /** * The SUM aggregates you wish to include, separated by a comma */ aggregates: string; /** * By default, we don't do any kind of date grouping * @default 'none' */ date_grouping?: 'hour' | 'day' | 'month' | 'year' | 'none'; /** * The fields you want to group by */ field_grouping?: string; /** * The field you want to sort by */ sort_by?: string; /** * The timezone you want us to use in our queries * @default 'UTC' */ timezone?: string; /** * Start date timestamp */ date_from?: string; /** * End date timestamp */ date_to?: string; /** * A limit on the number of entries to return */ limit?: number; /** * Array of filter objects */ filters?: AggregationFilter[]; } /** * Parameters for current visitors query */ interface CurrentVisitorsParams { /** * The ID of the site */ site_id: string; /** * Set to true if you want a detailed breakdown * @default false */ detailed?: boolean; } /** * Sites API resource */ declare class SitesResource { private readonly http; constructor(http: HttpClient); /** * List all sites * * @param params - Pagination parameters * @returns Promise with a list of sites */ list(params?: PaginationParams): Promise<ListResponse<Site>>; /** * Get a single site * * @param siteId - The ID of the site * @returns Promise with site information */ get(siteId: string): Promise<Site>; /** * Create a new site * * @param params - Site creation parameters * @returns Promise with the created site */ create(params: CreateSiteParams): Promise<Site>; /** * Update a site * * @param siteId - The ID of the site * @param params - Site update parameters * @returns Promise with the updated site */ update(siteId: string, params: UpdateSiteParams): Promise<Site>; /** * Wipe all data from a site * * @param siteId - The ID of the site * @returns Promise with the wiped site */ wipe(siteId: string): Promise<WipedSite>; /** * Delete a site * * @param siteId - The ID of the site * @returns Promise with the deleted site */ delete(siteId: string): Promise<DeletedSite>; } /** * Events API resource */ declare class EventsResource { private readonly http; private readonly siteId; constructor(http: HttpClient, siteId: string); /** * List all events for a site * * @param params - Pagination parameters * @returns Promise with a list of events */ list(params?: PaginationParams): Promise<ListResponse<Event>>; /** * Get a single event * * @param eventId - The ID of the event * @returns Promise with event information */ get(eventId: string): Promise<Event>; /** * Create a new event * * @param params - Event creation parameters * @returns Promise with the created event */ create(params: CreateEventParams): Promise<Event>; /** * Update an event * * @param eventId - The ID of the event * @param params - Event update parameters * @returns Promise with the updated event */ update(eventId: string, params: UpdateEventParams): Promise<Event>; /** * Wipe all data from an event * * @param eventId - The ID of the event * @returns Promise with the wiped event */ wipe(eventId: string): Promise<WipedEvent>; /** * Delete an event * * @param eventId - The ID of the event * @returns Promise with the deleted event */ delete(eventId: string): Promise<DeletedEvent>; } /** * Reports API resource */ declare class ReportsResource { private readonly http; constructor(http: HttpClient); /** * Generate an aggregation report * * This endpoints's response does not match the API documentation. * As such, we're using the type for what actually gets returned. * This may break in the future if the API changes. * * @link https://usefathom.com/api#aggregation * @param params - Aggregation parameters * @returns Promise with aggregation data */ aggregation<T = Record<string, any>>(params: AggregationParams): Promise<Array<T>>; /** * Get current visitors for a site * * @param params - Current visitors parameters * @returns Promise with current visitors information */ currentVisitors(params: CurrentVisitorsParams): Promise<CurrentVisitorsResponse>; /** * Convenience method to get pageview stats for a site * * @param siteId - The ID of the site to get pageviews for * @param options - Additional options for the aggregation * @returns Promise with pageview stats */ getPageviewStats(siteId: string, options?: { dateFrom?: string; dateTo?: string; timezone?: string; groupBy?: 'day' | 'month' | 'year' | 'hour'; limit?: number; }): Promise<Array<{ date: string; visits: number; uniques: number; pageviews: number; bounce_rate: number; avg_duration: number; }>>; /** * Convenience method to get top pages for a site * * @param siteId - The ID of the site * @param options - Additional options for the aggregation * @returns Promise with top pages data */ getTopPages(siteId: string, options?: { dateFrom?: string; dateTo?: string; timezone?: string; limit?: number; }): Promise<Array<{ pathname: string; visits: number; uniques: number; pageviews: number; bounce_rate: number; avg_duration: number; }>>; /** * Convenience method to get referrer sources for a site * * @param siteId - The ID of the site * @param options - Additional options for the aggregation * @returns Promise with referrer data */ getReferrerSources(siteId: string, options?: { dateFrom?: string; dateTo?: string; timezone?: string; limit?: number; }): Promise<Array<{ referrer_hostname: string; visits: number; uniques: number; }>>; /** * Convenience method to get event conversions * * @param siteId - The ID of the site * @param eventId - The ID of the event * @param options - Additional options for the aggregation * @returns Promise with event conversion data */ getEventConversions(siteId: string, eventId: string, options?: { dateFrom?: string; dateTo?: string; timezone?: string; groupBy?: 'day' | 'month' | 'year' | 'hour'; }): Promise<Array<{ date: string; conversions: number; unique_conversions: number; }>>; } /** * Fathom Analytics API v1 Client */ declare class FathomApiV1 { private readonly http; /** * Account resource */ readonly account: AccountResource; /** * Sites resource */ readonly sites: SitesResource; /** * Reports resource */ readonly reports: ReportsResource; constructor(http: HttpClient); /** * Get events resource for a specific site * * @param siteId - The ID of the site * @returns Events resource */ events(siteId: string): EventsResource; /** * Convenience method to get account information * * @returns Promise with account information */ getAccount(): Promise<Account>; /** * Convenience method to get current visitors for a site * * @param siteId - The ID of the site * @param detailed - Whether to include detailed information * @returns Promise with current visitors information */ getCurrentVisitors(siteId: string, detailed?: boolean): Promise<CurrentVisitorsResponse>; /** * Convenience method to get a site by ID * * @param siteId - The ID of the site * @returns Promise with site information */ getSite(siteId: string): Promise<Site>; /** * Convenience method to get all sites * This method handles pagination automatically until all sites are retrieved * * @param limit - Maximum number of sites to retrieve (optional) * @returns Promise with an array of sites */ getAllSites(limit?: number): Promise<Site[]>; /** * Convenience method to get an event by ID * * @param siteId - The ID of the site * @param eventId - The ID of the event * @returns Promise with event information */ getEvent(siteId: string, eventId: string): Promise<Event>; /** * Convenience method to get all events for a site * This method handles pagination automatically until all events are retrieved * * @param siteId - The ID of the site * @param limit - Maximum number of events to retrieve (optional) * @returns Promise with an array of events */ getAllEvents(siteId: string, limit?: number): Promise<Event[]>; } /** * Pagination schema * This schema validates the pagination parameters for API requests. */ declare const paginationSchema: z.ZodObject<{ limit: z.ZodOptional<z.ZodNumber>; starting_after: z.ZodOptional<z.ZodString>; ending_before: z.ZodOptional<z.ZodString>; }>; /** * Site schema * This schema validates the site data for creating a site. */ declare const createSiteSchema: z.ZodEffects<z.ZodObject<{ name: z.ZodString; sharing: z.ZodOptional<z.ZodEnum<["none", "private", "public"]>>; share_password: z.ZodOptional<z.ZodString>; }>>; /** * Site schema * This schema validates the optional fields for updating a site. */ declare const updateSiteSchema: z.ZodEffects<z.ZodObject<{ name: z.ZodOptional<z.ZodString>; sharing: z.ZodOptional<z.ZodEnum<["none", "private", "public"]>>; share_password: z.ZodOptional<z.ZodString>; }>>; /** * Event schema * This schema validates the event data for creating an event. */ declare const createEventSchema: z.ZodObject<{ name: z.ZodString; }>; /** * Update event schema * This schema validates the event data for updating an event. */ declare const updateEventSchema: z.ZodObject<{ name: z.ZodString; }>; /** * Aggregation report validation schema * This schema validates the parameters for an aggregation report. */ declare const aggregationParamsSchema: z.ZodObject<{ entity: z.ZodEnum<["pageview", "event"]>; entity_id: z.ZodString; aggregates: z.ZodString; date_grouping: z.ZodOptional<z.ZodEnum<["hour", "day", "month", "year", "none"]>>; field_grouping: z.ZodOptional<z.ZodString>; sort_by: z.ZodOptional<z.ZodString>; timezone: z.ZodOptional<z.ZodString>; date_from: z.ZodOptional<z.ZodString>; date_to: z.ZodOptional<z.ZodString>; limit: z.ZodOptional<z.ZodNumber>; filters: z.ZodOptional<z.ZodArray<z.ZodObject<{ property: z.ZodString; operator: z.ZodEnum<["is", "is not", "is like", "is not like"]>; value: z.ZodString; }>>>; }>; /** * Current visitors validation schema * This schema validates the parameters for retrieving current visitors at a site. */ declare const currentVisitorsParamsSchema: z.ZodObject<{ site_id: z.ZodString; detailed: z.ZodOptional<z.ZodBoolean>; }>; /** * Client options schema * This schema validates the options for creating a client. */ declare const clientOptionsSchema: z.ZodObject<{ token: z.ZodString; version: z.ZodOptional<z.ZodEnum<["v1"]>>; baseUrl: z.ZodOptional<z.ZodString>; }>; /** * Validate data against a schema * * @param schema - Zod schema to validate against * @param data - Data to validate * @returns Validated data * @throws FathomApiError if validation fails */ declare function validate<T>(schema: z.ZodType<T>, data: unknown): T; /** * Aggregation schema * @alias aggregationParamsSchema */ declare const aggregationSchema: z.ZodObject<{ entity: z.ZodEnum<["pageview", "event"]>; entity_id: z.ZodString; aggregates: z.ZodString; date_grouping: z.ZodOptional<z.ZodEnum<["hour", "day", "month", "year", "none"]>>; field_grouping: z.ZodOptional<z.ZodString>; sort_by: z.ZodOptional<z.ZodString>; timezone: z.ZodOptional<z.ZodString>; date_from: z.ZodOptional<z.ZodString>; date_to: z.ZodOptional<z.ZodString>; limit: z.ZodOptional<z.ZodNumber>; filters: z.ZodOptional<z.ZodArray<z.ZodObject<{ property: z.ZodString; operator: z.ZodEnum<["is", "is not", "is like", "is not like"]>; value: z.ZodString; }>>>; }, z.UnknownKeysParam, z.ZodTypeAny, { entity: "event" | "pageview"; entity_id: string; aggregates: string; filters?: { value: string; property: string; operator: "is" | "is not" | "is like" | "is not like"; }[] | undefined; limit?: number | undefined; date_grouping?: "none" | "hour" | "day" | "month" | "year" | undefined; field_grouping?: string | undefined; sort_by?: string | undefined; timezone?: string | undefined; date_from?: string | undefined; date_to?: string | undefined; }, { entity: "event" | "pageview"; entity_id: string; aggregates: string; filters?: { value: string; property: string; operator: "is" | "is not" | "is like" | "is not like"; }[] | undefined; limit?: number | undefined; date_grouping?: "none" | "hour" | "day" | "month" | "year" | undefined; field_grouping?: string | undefined; sort_by?: string | undefined; timezone?: string | undefined; date_from?: string | undefined; date_to?: string | undefined; }>; /** * Current visitors schema * @alias currentVisitorsParamsSchema */ declare const currentVisitorsSchema: z.ZodObject<{ site_id: z.ZodString; detailed: z.ZodOptional<z.ZodBoolean>; }, z.UnknownKeysParam, z.ZodTypeAny, { site_id: string; detailed?: boolean | undefined; }, { site_id: string; detailed?: boolean | undefined; }>; /** * Fathom Analytics API SDK * A fully typed client for interacting with the Fathom Analytics API * @link https://github.com/mackenly/fathom-api * @link https://usefathom.com/docs/api */ declare class FathomApi { private http; private v1; /** * Create a new Fathom API client * * @param options - Client configuration options */ constructor(options: FathomClientOptions); /** * Access the v1 API * * @returns Fathom Analytics API v1 client */ get api(): FathomApiV1; /** * Access a specific version of the API * * @param version - API version to use * @returns API client for the specified version */ version(version: ApiVersion): FathomApiV1; } export { Account, AggregationFilter, AggregationParams, ApiVersion, ContentEntry, CreateEventParams, CreateSiteParams, CurrentVisitorsParams, CurrentVisitorsResponse, DeletedEvent, DeletedSite, ErrorResponse, Event, FathomApi, FathomApiError, FathomApiV1, FathomClientOptions, FathomObject, FilterOperator, HttpClient, HttpMethod, ListResponse, PaginationParams, ReferrerEntry, Site, UpdateEventParams, UpdateSiteParams, WipedEvent, WipedSite, aggregationParamsSchema, aggregationSchema, clientOptionsSchema, createEventSchema, createSiteSchema, currentVisitorsParamsSchema, currentVisitorsSchema, FathomApi as default, paginationSchema, updateEventSchema, updateSiteSchema, validate };