import type { google } from '@gcf/firestore-protos'; import { Timestamp } from 'firebase-admin/firestore'; import { MetaDocumentExists } from '../../data-accessor.js'; import { GapicContext } from '../gapic-context.js'; import { StreamEndpoint } from '../stream-endpoint.js'; import { QueryValidationData } from './query-validation.js'; import { TransactionHelper } from './transaction-helper.js'; /** * StructuredQuery REST API reference for rules: * * https://cloud.google.com/firestore/docs/reference/rest/v1/StructuredQuery */ /** * Builds, validates, and executes Firestore StructuredQuery and * AggregationQuery requests against the in-memory data store. * * Design notes: * - Validation (inequalities/orderBy compatibility, cursor shapes, etc.) is * performed up front via helpers in query-validation.ts. * - The instance is immutable with respect to request interpretation * (predicates/comparators/transformers are computed once in applyStructureQuery()). * - Execution is deterministic and synchronous over the in-memory snapshot * but invoked asynchronously by StreamEndpoint to match Firestore’s async surface. */ export declare class QueryBuilder { private readonly encoder; /** Collection id targeted by the FROM clause (undefined means “any root”). */ collectionId: string | undefined; /** Whether descendants are included (collection group). */ allDescendants: boolean; /** Conjunction/disjunction of where/unary filters. */ wherePredicate: (doc: MetaDocumentExists) => boolean; /** Cursor boundary predicate derived from startAt/endAt. */ cursorPredicate: (doc: MetaDocumentExists) => boolean; /** Total ordering comparator derived from orderBy (+ implicit __name__). */ orderByComparator: (x: MetaDocumentExists, y: MetaDocumentExists) => number; /** Optional post-processing for findNearest KNN transforms. */ findNearestTransformer: ((docs: MetaDocumentExists[]) => MetaDocumentExists[]) | undefined; /** Result offset after filtering/sorting (StructuredQuery.offset). */ offset: number; /** Result limit (StructuredQuery.limit.value). */ limit: number | undefined; /** Optional field mask for projection (StructuredQuery.select.fields). */ fieldMask: string[] | undefined; /** * The parent resource path of the query (document root or document path). * Always validated via assertRequestArgument(). */ readonly parentPath: string; /** Optional point-in-time read time. */ readonly readTime?: Timestamp; /** Existing transaction id (GAPIC bytes) when provided. */ readonly transaction?: Uint8Array | null; /** New transaction request options when provided. */ readonly newTransaction?: google.firestore.v1.ITransactionOptions | null; /** * @param request The raw request object (RunQuery or RunAggregationQuery). * @param encoder A function that converts the resolved docs into the * corresponding GAPIC response(s) and pushes to the stream. * @throws {GoogleError} {Status.INVALID_ARGUMENT} when required arguments are missing. */ private constructor(); /** * Constructs a QueryBuilder for a StructuredQuery (RunQuery). * * Validates common request constraints, parses the StructuredQuery into * predicates and comparators, and wires an encoder that emits * google.firestore.v1.RunQueryResponse messages for each result row (and a * trailing message conveying readTime/transaction when empty). * * @param context GapicContext providing serializer and accessors. * @param request RunQuery request payload. * @returns A configured QueryBuilder. * @throws {GoogleError} {Status.INVALID_ARGUMENT} on missing/invalid fields. * @throws {GoogleError} {Status.FAILED_PRECONDITION} on invalid transaction shapes. */ static fromQuery(context: GapicContext, request?: google.firestore.v1.IRunQueryRequest): QueryBuilder; /** * Constructs a QueryBuilder for a StructuredAggregationQuery (RunAggregationQuery). * * Parses COUNT/SUM/AVG aggregations into an executable plan and wires an * encoder that emits a single google.firestore.v1.RunAggregationQueryResponse * with aggregateFields and readTime. * * Notes: * - The mock supports COUNT, SUM, and AVG only. * - SUM emits integerValue when all inputs are integers; otherwise doubleValue. * - AVG emits doubleValue; if no numeric inputs exist, the value is nullValue. * * @param context GapicContext providing serializer and accessors. * @param request RunAggregationQuery request payload. * @returns A configured QueryBuilder. * @throws {GoogleError} {Status.INVALID_ARGUMENT} on missing/invalid fields or duplicate aliases. * @throws {GoogleError} {Status.UNIMPLEMENTED} for unsupported aggregation kinds. */ static fromAggregationQuery(context: GapicContext, request?: google.firestore.v1.IRunAggregationQueryRequest): QueryBuilder; /** * Executes the built query (or aggregation) under the provided TransactionHelper * and emits responses to the given StreamEndpoint. * * Semantics: * - If a transaction is active, a readTime is ensured and every returned * document is registered as a read. * - For RunQuery, a response is pushed per row (or a single empty response * with readTime if no rows). For RunAggregationQuery, a single response. * * @param tm Transaction helper resolving transaction/readTime context. * @param stream Stream endpoint to emit responses to. */ executeRequest(tm: TransactionHelper, stream: StreamEndpoint): void; /** * Executes the query against the current in-memory snapshot at the given readTime. * * Pipeline: * accessor.query() → sort(orderBy) → filter(cursors) → slice(offset/limit) * → optional findNearest post-transform. * * @param context GapicContext. * @param readTime Point-in-time read. * @returns Final list of documents to encode. */ run(context: GapicContext, readTime: Timestamp): MetaDocumentExists[]; /** * Parses and applies a StructuredQuery to this builder: * - offset/limit * - from(collectionId, allDescendants) * - where/unary filters → wherePredicate * - orderBy (+ implicit constraints) → orderByComparator * - startAt/endAt → cursorPredicate * - findNearest → optional post-transformer * - select.fields → fieldMask * * @param context GapicContext. * @param query StructuredQuery payload. * @throws {GoogleError} {Status.INVALID_ARGUMENT} on invalid shapes/values. */ private applyStructureQuery; } export declare function buildFindNearestTransformer(context: GapicContext, query: google.firestore.v1.IStructuredQuery, validationData: QueryValidationData): ((docs: MetaDocumentExists[]) => MetaDocumentExists[]) | undefined; //# sourceMappingURL=query-builder.d.ts.map