import type { PlanMeta } from '@prisma-next/contract/types'; import type { AnyMongoTypeMaps, MongoContract, MongoContractWithTypeMaps, RootModelName, } from '@prisma-next/mongo-contract'; import type { AnyMongoCommand, MongoQueryPlan } from '@prisma-next/mongo-query-ast/execution'; import { blindCast } from '@prisma-next/utils/casts'; import { asMongoContract, type CollectionHandle, createCollectionHandle } from './state-classes'; /** * Public entry point of the query builder. `mongoQuery(...).from(rootName)` * yields the root state of the three-state machine * (`CollectionHandle` → `FilteredCollection` → `PipelineChain`). * * `rawCommand(cmd)` is the escape hatch for cases the typed surface does * not cover (yet) — it accepts any `AnyMongoCommand` (typed CRUD or a * `RawMongoCommand` of `Document`s) and packages it into a `MongoQueryPlan` * with `lane: 'mongo-query'`. Row type is `unknown` because the runtime * cannot know what the caller's command yields. */ export interface QueryRoot< TContract extends MongoContractWithTypeMaps, > { from( rootName: K, ): CollectionHandle>; rawCommand(command: C): MongoQueryPlan; } export function mongoQuery< TContract extends MongoContractWithTypeMaps, >(options: { contractJson: unknown }): QueryRoot { const contract = blindCast< TContract, 'mongoQuery accepts validated contract JSON with domain.namespaces' >(options.contractJson); return { from(rootName: K) { return createCollectionHandle(contract, rootName); }, rawCommand(command: C): MongoQueryPlan { const c = asMongoContract(contract); const storageHash = c.storage?.storageHash; if (!storageHash) { throw new Error( 'Contract is missing storage.storageHash. Pass a validated contract to mongoQuery().', ); } const meta: PlanMeta = { target: 'mongo', storageHash: String(storageHash), lane: 'mongo-query', }; return { collection: command.collection, command, meta }; }, }; }