|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +This file provides guidance to AI coding agents (Claude Code, Codex, Copilot, Cursor, Aider, etc.) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +This is the official MongoDB Node.js driver (`mongodb` npm package). It provides a TypeScript/JavaScript interface for applications to interact with MongoDB deployments. The driver implements the cross-driver MongoDB specifications. |
| 8 | + |
| 9 | +## Common Commands |
| 10 | + |
| 11 | +### Building |
| 12 | + |
| 13 | +```bash |
| 14 | +npm run build:ts # Compile TypeScript to lib/ |
| 15 | +npm run check:ts # Type-check without emitting |
| 16 | +``` |
| 17 | + |
| 18 | +### Linting |
| 19 | + |
| 20 | +```bash |
| 21 | +npm run check:eslint # Run ESLint |
| 22 | +npm run fix:eslint # Auto-fix ESLint issues |
| 23 | +``` |
| 24 | + |
| 25 | +### Testing |
| 26 | + |
| 27 | +Tests require a running MongoDB instance. To start one locally: |
| 28 | + |
| 29 | +```bash |
| 30 | +git submodule update --init |
| 31 | +export DRIVERS_TOOLS=$(pwd)/drivers-evergreen-tools |
| 32 | +VERSION='latest' TOPOLOGY='replica_set' bash .evergreen/run-orchestration.sh |
| 33 | +source mo-expansion.sh |
| 34 | +``` |
| 35 | + |
| 36 | +```bash |
| 37 | +npm run check:unit # Unit tests (no database required) |
| 38 | +npm run check:test # Integration tests (requires database) |
| 39 | +npm test # Lint + unit + integration |
| 40 | + |
| 41 | +# Run a single test by name pattern |
| 42 | +npm run check:unit -- -g "pattern" |
| 43 | +npm run check:test -- -g "pattern" |
| 44 | +``` |
| 45 | + |
| 46 | +Tests use Mocha with 60-second timeout. Integration tests use a custom metadata UI that supports test filtering by topology, MongoDB version, auth, etc. via metadata: |
| 47 | + |
| 48 | +```js |
| 49 | +describe( |
| 50 | + 'my test', |
| 51 | + { metadata: { requires: { topology: ['replicaset'], mongodb: '>=6.0' } } }, |
| 52 | + function () {} |
| 53 | +); |
| 54 | +``` |
| 55 | + |
| 56 | +## Architecture |
| 57 | + |
| 58 | +### Layered Design |
| 59 | + |
| 60 | +``` |
| 61 | +Public API (MongoClient, Db, Collection, Cursors) |
| 62 | + → Operations (CRUD, Aggregation, Indexes, Bulk writes) |
| 63 | + → Sessions & Transactions |
| 64 | + → SDAM – Server Discovery And Monitoring (src/sdam/) |
| 65 | + → CMAP – Connection Management And Pooling (src/cmap/) |
| 66 | + → Wire Protocol & BSON serialization |
| 67 | +``` |
| 68 | + |
| 69 | +### Key Source Directories |
| 70 | + |
| 71 | +- **`src/operations/`** — Each database command is an `AbstractOperation` subclass. Operations declare aspects (retryable, read/write, explainable) via Symbols. `execute_operation.ts` is the central execution engine handling retries, sessions, server selection. |
| 72 | +- **`src/sdam/`** — Topology discovery and monitoring. `topology.ts` manages servers, `server_selection.ts` picks the best server based on read preference and latency, `monitor.ts` sends periodic heartbeats. |
| 73 | +- **`src/cmap/`** — Connection pooling per server, wire protocol encoding/decoding, authentication handshakes. `auth/` contains implementations for each auth mechanism (SCRAM, X.509, AWS, OIDC, Kerberos, PLAIN). |
| 74 | +- **`src/cursor/`** — `AbstractCursor` base with lazy evaluation, async iteration, and streaming. Specialized cursors: `FindCursor`, `AggregationCursor`, `ChangeStreamCursor`, etc. |
| 75 | +- **`src/bulk/`** — Ordered and unordered bulk write operations. |
| 76 | +- **`src/client-side-encryption/`** — Auto-encryption and explicit encryption (CSFLE/Queryable Encryption). |
| 77 | +- **`src/gridfs/`** — GridFS file storage using upload/download streams. |
| 78 | + |
| 79 | +### How Operations Execute |
| 80 | + |
| 81 | +1. User calls a method (e.g., `collection.insertOne()`) |
| 82 | +2. An operation object is created (e.g., `InsertOperation`) |
| 83 | +3. `executeOperation()` handles: implicit session creation → server selection → connection checkout → command building → wire protocol send → response handling → retry on transient errors |
| 84 | +4. Connection returned to pool, session cleaned up |
| 85 | + |
| 86 | +### Test Structure |
| 87 | + |
| 88 | +- **`test/unit/`** — Mirrors `src/` structure. No database interaction, uses mocks. |
| 89 | +- **`test/integration/`** — Real database tests organized by feature area. |
| 90 | +- **`test/spec/`** — YAML/JSON test specifications from the cross-driver specs. Implemented by spec runners in integration tests. Files named `*.spec.test.ts` use standardized runners; `*.prose.test.ts` are hand-written prose test implementations. |
| 91 | +- **`test/mongodb.ts`** — Central re-export of all `src/` internals for test access. Tests import from `../../mongodb` (or appropriate depth), never directly from `src/`. |
| 92 | + |
| 93 | +## Code Conventions |
| 94 | + |
| 95 | +- **No `export default`** — All exports must be named. |
| 96 | +- **No TypeScript enums** — Use string unions or `as const` objects instead. |
| 97 | +- **No `node:` import prefix** — Use bare module names (e.g., `import { setTimeout } from 'timers'`). |
| 98 | +- **Timer/process imports** — Must import `setTimeout`, `setInterval`, `clearTimeout`, `process`, etc. from their modules, not use globals. |
| 99 | +- **No `Buffer`** — Use `Uint8Array` in source code. |
| 100 | +- **BSON imports** — Source code must import from `src/bson.ts`, not from the `bson` package directly. |
| 101 | +- **Null/undefined checks** — Use loose equality (`== null`) not strict (`=== null` or `=== undefined`). |
| 102 | +- **Type imports** — Use `import { type Foo }` (inline type imports). |
| 103 | +- **`return await`** — Required in `src/` (enforced by `@typescript-eslint/return-await: always`). |
| 104 | +- **Error messages** — Sentence case, no trailing period. Use driver-specific error types extending `MongoError`. |
| 105 | +- **Formatting** — Prettier with single quotes, 2-space tabs, 100-char width, no trailing commas. |
| 106 | + |
| 107 | +## Commit Messages |
| 108 | + |
| 109 | +Follow [Conventional Commits](https://www.conventionalcommits.org/): `<type>(NODE-XXXX): <subject>` |
| 110 | + |
| 111 | +Types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `chore` |
| 112 | + |
| 113 | +Breaking changes use `!`: `feat(NODE-XXXX)!: description` |
0 commit comments