CosmosDbStore — Azure Cosmos DB multi-model store

Read this page in the documentation

CosmosDbStore — Azure Cosmos DB multi-model store Overview Azure Cosmos DB is a multi-model database — document, key/value, graph, and column-family models exposed through a family of APIs. This store drives it through the document (SQL / Core) API: documents live in a container inside a database, addressed by an id. That access pattern does not fit the SQL-shaped Dialect interface (no identifier escaping, no DDL builder), so CosmosDbStore implements the minimal NoSqlStore marker interface (src/nosql/store.ts) — connection lifecycle plus a getClient() escape hatch — and exposes Cosmos DB's real item CRUD plus its SQL query API directly. Identity: Property | Value | --------- | ----------------- | name | 'cosmosdb' | library | '@azure/cosmos' | The store is built on the official @azure/cosmos SDK. Container handles are resolved through the SDK's fluent chain: client.database(db).container(container). Lazy loading — not a hard dependency @azure/cosmos is not a hard dependency of this package. It is an optional peer dependency loaded lazily via require('@azure/cosmos') inside connect(), rather than a top-level import. Importing this module therefore does not require the SDK to be installed — it is only needed when a Cosmos DB store is actually connected without an injected client. Injected client CosmosDbStoreOptions accepts a pre-built client (a native CosmosClient, or any object exposing a compatible database() chain). When provided, connect() uses it directly and never loads the driver. This is how the test suite injects a mock client (no SDK, no network), and how callers can supply a custom-configured CosmosClient. Connection Build a store from connection options and call connect(): CosmosDbStoreOptions: Option | Type | Purpose | ----------- | -------------- | --------------------------------------------------------------------------------- | endpoint | string | Cosmos DB account endpoint, e.g. https://acct.documents.azure.com. | key | string | Account primary/secondary key. | database | string | Default database id. Defaults to 'default' when omitted. | container | string | Default container id used when a method omits the container. Defaults to 'default'. | client | CosmosClient | A pre-built client to use directly. When set, the SDK is not loaded. | Injected-client form Supply your own client (or a mock) to bypass driver-based construction: Methods Every CRUD/query method resolves a container via container(collection) — i.e. client.database(defaultDatabase).container(collection) — then calls the SDK. Driver failures are wrapped in a DatabaseError (preserving the original error); using any method before connect() (or after disconnect()) throws a ConnectionError. The first argument to each data method (collection) is the container id. Lifecycle Method | Signature | Behavior | -------------- | ------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------- | connect | connect(): Promise<void> | Uses an injected client if provided, otherwise lazy-requires @azure/cosmos and builds a CosmosClient from endpoint/key. Idempotent when already connected. Wraps failures in ConnectionError. | disconnect | disconnect(): Promise<void> | Drops the client reference (the Cosmos SDK client holds no long-lived socket). A later call must connect() again. | isConnected | isConnected(): boolean | true only when connected and a client is present. | getClient | getClient(): CosmosClient | Returns the underlying client. Throws ConnectionError if not connected. | container | container(container?: string, database?: string): any | Resolves a container handle via database(db).container(container), falling back to the configured defaults. | Document CRUD & query Method | Signature | Behavior | -------- | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | insert | insert(collection: string, doc: Record<string, unknown>): Promise<unknown> | Creates a document via container.items.create(doc). Returns the created resource's id (falling back to doc.id). | get | get(collection: string, id: string): Promise<unknown> | Reads a document via container.item(id).read(). Returns the stored resource. | update | update(collection: string, id: string, patch: Record<string, unknown>): Promise<unknown> | Reads the current document, shallow-merges patch (forcing id), and replace()s it. Returns the replaced resource. | delete | delete(collection: string, id: string): Promise<unknown> | Deletes via container.item(id).delete(). Returns the raw SDK delete response. | query | query(collection: string, statement: unknown, options?: CosmosDbQueryOptions): Promise<unknown[]> | Runs a Cosmos SQL query (string or SqlQuerySpec) via container.items.query(statement, options).fetchAll(). Returns the matched resources (or []). | CosmosDbQueryOptions is an open bag ({ [key: string]: unknown }) passed straight through as native FeedOptions (e.g. maxItemCount). Example Verification status Unit / mock-verified only. The tests in tests/nosql/cosmosdb.test.ts are fully mock-driven: a fake client whose database().container() chain returns jest-mocked items/item handles is injected via CosmosDbStoreOptions.client. The real @azure/cosmos package is not installed, and there is no live Cosmos DB access and no network in the test run. What this proves: insert/get/update/delete route to items.create / item(id).read / item(id).replace (with the merged doc) / item(id).delete, and insert returns the resource id. container() resolves through database('appdb').container('users') with the configured defaults. query forwards the statement and options to items.query(...).fetchAll() and returns resources. Lifecycle: connecting via an injected client without loading the SDK, idempotent double-connect, disconnect() clearing state, and ConnectionError before connect(). Error handling: driver failures wrapped in DatabaseError for both CRUD and query paths. What this does not prove: live execution against real Azure Cosmos DB. The call/response shapes are verified against the SDK's documented contract, but end-to-end execution over the wire has not been exercised here. Related reading All data stores — the full catalogue, grouped by purpose Database types — where this sits among the 22 categories