import { GscAggregationType, GscDataState } from "../contracts.mjs"; import { Country, Device, SearchType } from "./constants.mjs"; interface DimensionValueMap { query: string; queryCanonical: string; page: string; country: Country; device: Device; searchAppearance: string; date: string; /** Hour bucket — ISO-8601 with PT offset, e.g. `2025-07-14T13:00:00-07:00`. Use with `dataState: 'hourly_all'`. */ hour: string; } type Dimension = keyof DimensionValueMap; interface QueryParamValueMap { searchType: SearchType; } type QueryParamName = keyof QueryParamValueMap; interface Column { readonly __columnBrand: 'gscdump.Column'; readonly dimension: D; } interface QueryParam

{ readonly __queryParamBrand: 'gscdump.QueryParam'; readonly param: P; } type FilterOperator = 'equals' | 'notEquals' | 'contains' | 'notContains' | 'includingRegex' | 'excludingRegex'; type DateOperator = 'gte' | 'gt' | 'lte' | 'lt' | 'between'; type MetricOperator = 'metricGte' | 'metricGt' | 'metricLte' | 'metricLt' | 'metricBetween'; type SpecialOperator = 'topLevel'; interface InternalFilter { dimension: Dimension | QueryParamName | Metric; operator: FilterOperator | DateOperator | MetricOperator | SpecialOperator; expression: string; expression2?: string; } interface Filter { readonly __filterBrand: 'gscdump.Filter'; readonly _constraints: C; readonly _filters: InternalFilter[]; readonly _nestedGroups?: Filter[]; readonly _groupType?: 'and' | 'or'; } type MergeConstraints[]> = UnionToIntersection; type UnionToIntersection = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never; interface GSCResult { rows: Array>; } type GSCRow = { [K in D[number]]: K extends keyof C ? C[K] : DimensionValueMap[K]; } & { clicks: number; impressions: number; ctr: number; position: number; }; type Metric = 'clicks' | 'impressions' | 'ctr' | 'position'; interface MetricColumn { readonly __metricColumnBrand: 'gscdump.MetricColumn'; readonly metric: M; } interface BuilderState { dimensions: Dimension[]; metrics?: Metric[]; filter?: Filter; prefilter?: Filter; orderBy?: { column: Metric | 'date'; dir: 'asc' | 'desc'; }; rowLimit?: number; startRow?: number; /** GSC `dataState`. `'hourly_all'` is required when grouping by `hour`. */ dataState?: GscDataState; /** GSC `aggregationType`. `'byNewsShowcasePanel'` requires `type=discover|googleNews` with NEWS_SHOWCASE searchAppearance. */ aggregationType?: GscAggregationType; /** GSC search corpus. Wins over any `searchType` filter when both are set. */ searchType?: SearchType; } interface JsonInternalFilter { dimension: string; operator: string; expression: string; expression2?: string; } interface JsonFilter { _filters: JsonInternalFilter[]; _nestedGroups?: JsonFilter[]; _groupType?: 'and' | 'or'; } type FilterInput = Filter | JsonFilter; export { BuilderState, Column, DateOperator, Dimension, DimensionValueMap, Filter, FilterInput, FilterOperator, GSCResult, GSCRow, InternalFilter, JsonFilter, JsonInternalFilter, MergeConstraints, Metric, MetricColumn, MetricOperator, QueryParam, QueryParamName, QueryParamValueMap, SpecialOperator, UnionToIntersection };