@mackenly/fathom-api
Version:
Typescript wrapper around Fathom Analytics API
801 lines (788 loc) • 21.5 kB
text/typescript
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 };