import type { Encodable } from "@automate.ax/codec" import type { Webflow } from "webflow-api" interface EmptyRequest { body: object query: object } export interface WebflowCurrentOperations { "batch-create-custom-fonts": Operation< { items: WebflowCustomFontCreateInput[] }, WebflowCustomFontBatchCreateResult > "batch-delete-custom-fonts": Operation< { items: Array<{ id: string }> }, WebflowCustomFontBatchDeleteResult > "create-comment-reply": Operation<{ content: string }, WebflowCommentReply> "create-custom-font": Operation< WebflowCustomFontCreateInput, WebflowCustomFontUploadResult > "delete-custom-font": EmptyRequest & { output: void } "delete-google-tag": EmptyRequest & { output: WebflowGoogleTags } "delete-google-tags": EmptyRequest & { output: void } "get-analyze-time-on-page-report": QueryOperation< WebflowAnalyzeTimeOnPageQuery, WebflowAnalyzeTimeOnPageReport > "get-analyze-top-dimensions-report": QueryOperation< WebflowAnalyzeTopDimensionsQuery, WebflowAnalyzeTopDimensionsReport > "get-analyze-top-events-report": QueryOperation< WebflowAnalyzeTopEventsQuery, WebflowAnalyzeTopEventsReport > "get-analyze-top-pages-report": QueryOperation< WebflowAnalyzeTopPagesQuery, WebflowAnalyzeTopPagesReport > "get-analyze-traffic-report": QueryOperation< WebflowAnalyzeTrafficQuery, WebflowAnalyzeTrafficReport > "get-custom-font": EmptyRequest & { output: WebflowCustomFontResult } "list-custom-fonts": QueryOperation< WebflowPaginationQuery, WebflowCustomFontList > "list-google-tags": EmptyRequest & { output: WebflowGoogleTags } "patch-collection": Operation "replace-custom-font-file": Operation< WebflowCustomFontFileInput, WebflowCustomFontUploadResult > "resolve-comment-thread": Operation< { resolved: boolean }, Webflow.CommentThread > "update-custom-font": Operation< WebflowCustomFontUpdateInput, WebflowCustomFontResult > "upsert-google-tags": Operation } interface Operation { body: TBody output: TOutput query: object } interface QueryOperation { body: object output: TOutput query: TQuery } /** Requires at least one property from a provider update body. */ type AtLeastOne = { [TKey in keyof T]-?: Required> & Partial> }[keyof T] export interface WebflowGoogleTag { displayName: string order?: number tagId: string } export interface WebflowGoogleTags { googleTagIds: WebflowGoogleTag[] } export interface WebflowAnalyzeWindowQuery { endTime: string startTime: string } export interface WebflowAnalyzeDimensionQuery { browser?: string country?: string deviceType?: "desktop" | "mobile" | "tablet" pagePath?: string referrer?: string trafficSource?: string utmCampaign?: string utmMedium?: string utmSource?: string } export interface WebflowAnalyzeTrafficQuery extends WebflowAnalyzeWindowQuery, WebflowAnalyzeDimensionQuery { bucketTimeZone: string filter?: WebflowAnalyzeFilter metricScope: WebflowAnalyzeMetricScope } export interface WebflowAnalyzeTopPagesQuery extends WebflowAnalyzeWindowQuery, WebflowAnalyzeDimensionQuery { filter?: WebflowAnalyzeFilter limit?: number sortBy?: WebflowAnalyzeMetricScope timeseries?: { bucketTimeZone: string } } export interface WebflowAnalyzeTopDimensionsQuery extends WebflowAnalyzeWindowQuery, WebflowAnalyzeDimensionQuery { dimension: | "audienceIds" | "browser" | "country" | "deviceType" | "language" | "locale" | "os" | "referrer" | "region" | "trafficSource" | "utmCampaign" | "utmContent" | "utmMedium" | "utmSource" | "utmTerm" filter?: WebflowAnalyzeFilter limit?: number metricScope: "session" | "user" } export interface WebflowAnalyzeTopEventsQuery extends WebflowAnalyzeWindowQuery, Omit { filter?: WebflowAnalyzeEventFilter limit?: number timeseries?: { bucketTimeZone: string } } export interface WebflowAnalyzeTimeOnPageQuery extends WebflowAnalyzeWindowQuery, WebflowAnalyzeDimensionQuery { filter?: WebflowAnalyzeFilter metricScope: WebflowAnalyzeMetricScope timeseries?: { bucketTimeZone: string granularityPeriod: "day" | "week" } } export type WebflowAnalyzeMetricScope = "pageview" | "session" | "user" export interface WebflowAnalyzeFilterOperator { eq?: string in?: string[] ne?: string nin?: string[] } export type WebflowAnalyzeFilter = Partial< Record< | "audienceIds" | "browser" | "collectionId" | "country" | "dayOfWeek" | "deviceBrand" | "deviceType" | "domain" | "itemSlug" | "language" | "locale" | "nextCollectionId" | "nextItemSlug" | "nextPageId" | "os" | "pageId" | "pagePath" | "previousCollectionId" | "previousItemSlug" | "previousPageId" | "referrer" | "region" | "timeOfDay" | "timezone" | "trafficSource" | "utmCampaign" | "utmContent" | "utmMedium" | "utmSource" | "utmTerm" | "visitStatus", WebflowAnalyzeFilterOperator > > export type WebflowAnalyzeEventFilter = Omit< WebflowAnalyzeFilter, | "nextCollectionId" | "nextItemSlug" | "nextPageId" | "previousCollectionId" | "previousItemSlug" | "previousPageId" | "referrer" > export interface WebflowAnalyzeWindow { endTime: string startTime: string } export interface WebflowAnalyzeBucketing { bucketTimeZone: string granularityPeriod: "day" } export interface WebflowAnalyzeTrafficReport { bucketing: WebflowAnalyzeBucketing data: Array<{ count: number; timestamp: string }> filter?: WebflowAnalyzeFilter metricScope: WebflowAnalyzeMetricScope report: "traffic" window: WebflowAnalyzeWindow } export interface WebflowAnalyzeTopPagesReport { bucketing?: WebflowAnalyzeBucketing data: Array<{ collectionId?: string itemSlug?: string pageId: string pageviewCount: number sessionCount: number timeseries?: Array<{ pageviewCount: number; timestamp: string }> title: string userCount: number }> filter?: WebflowAnalyzeFilter limit: number report: "top_pages" sortBy: WebflowAnalyzeMetricScope window: WebflowAnalyzeWindow } export interface WebflowAnalyzeTopDimensionsReport { data: Array<{ attributeKey: string; count: number; name: string }> dimension: WebflowAnalyzeTopDimensionsQuery["dimension"] filter?: WebflowAnalyzeFilter limit: number metricScope: "session" | "user" report: "top_dimensions" window: WebflowAnalyzeWindow } export interface WebflowAnalyzeTopEventsReport { bucketing?: WebflowAnalyzeBucketing data: Array<{ cmsContext?: Array<{ collectionId: string; itemId: string }> collectionId?: string componentContext?: Array<{ componentId: string; instanceId: string }> count: number eventId: string itemSlug?: string name?: string pageId?: string pageName?: string timeseries?: Array<{ count: number; timestamp: string }> }> filter?: WebflowAnalyzeEventFilter limit: number report: "top_events" window: WebflowAnalyzeWindow } export interface WebflowAnalyzeTimeOnPageReport { bucketing?: { bucketTimeZone: string granularityPeriod: "day" | "week" } data: Array<{ averageSeconds: number; timestamp: string }> filter?: WebflowAnalyzeFilter metricScope: WebflowAnalyzeMetricScope report: "time_on_page" window: WebflowAnalyzeWindow } /** Provider update body that rejects no-op collection patches. */ export type WebflowCollectionUpdateInput = AtLeastOne<{ displayName?: string fieldGroups?: WebflowCollectionFieldGroup[] singularName?: string slug?: string }> export interface WebflowCollection { createdOn?: string displayName: string fieldGroups?: WebflowCollectionFieldGroup[] fields: WebflowCollectionField[] id: string lastUpdated?: string singularName: string slug?: string } export interface WebflowCollectionFieldGroup { description?: string displayName: string fieldIds: string[] } export interface WebflowCollectionField { displayName: string helpText?: string id: string isEditable?: boolean isRequired: boolean slug?: string type: | "Color" | "DateTime" | "Email" | "ExtFileRef" | "File" | "Image" | "Link" | "MultiImage" | "MultiReference" | "Number" | "Option" | "Phone" | "PlainText" | "Reference" | "RichText" | "Switch" | "VideoLink" validations?: Record | null } export interface WebflowCommentReply { author: { email: string; id: string; name: string } breakpoint: string commentId: string content: string createdOn: string id: string isResolved: boolean lastUpdated: string localeId?: string mentionedUsers?: Array<{ email: string; id: string; name: string }> pageId: string siteId: string } export interface WebflowPaginationQuery { limit?: number offset?: number } export interface WebflowPagination { limit: number offset: number total: number } export interface WebflowCustomFontAxis { defaultValue: number max: number min: number name?: string tag: string } export interface WebflowCustomFontCreateInput { axes?: WebflowCustomFontAxis[] fileHash: string fileName: string fontDisplay: WebflowFontDisplay fontFamily: string italic: boolean weight: number } export interface WebflowCustomFontFileInput { axes?: WebflowCustomFontAxis[] fileHash: string fileName: string } /** Provider update body that rejects no-op custom-font patches. */ export type WebflowCustomFontUpdateInput = AtLeastOne<{ fontDisplay?: WebflowFontDisplay fontFamily?: string italic?: boolean weight?: number }> export type WebflowFontDisplay = | "auto" | "block" | "fallback" | "optional" | "swap" export interface WebflowCustomFont { axes: WebflowCustomFontAxis[] fileName: string fontDisplay: WebflowFontDisplay fontFamily: string format: | "embedded-opentype" | "opentype" | "svg" | "truetype" | "woff" | "woff2" hostedUrl: string id: string italic: boolean weight: number } export interface WebflowCustomFontUpload { expiresAt: string fields: { "Cache-Control": string "Content-MD5": string "Content-Type": string "X-Amz-Algorithm": string "X-Amz-Credential": string "X-Amz-Date": string "X-Amz-Security-Token"?: string "X-Amz-Signature": string Policy: string acl: string bucket: string key: string success_action_status: string } url: string } export interface WebflowCustomFontResult { customFont: WebflowCustomFont } export interface WebflowCustomFontUploadResult extends WebflowCustomFontResult { upload: WebflowCustomFontUpload } export interface WebflowCustomFontList { customFonts: WebflowCustomFont[] pagination: WebflowPagination } export interface WebflowCustomFontBatchCreateResult { created: WebflowCustomFontUploadResult[] failed: Array<{ fileName: string; index: number; msg: string; name: string }> } export interface WebflowCustomFontBatchDeleteResult { deleted: Array<{ id: string }> failed: Array<{ id: string; msg: string; name: string }> }