Skip to content

Commit 823132b

Browse files
committed
fix: support nested cursors and projection alias
1 parent 4275ed8 commit 823132b

35 files changed

Lines changed: 212 additions & 79 deletions

‎changelogs/unreleased.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Unreleased
22

3+
- Fixed `findPage` cursor anchors for nested dot-path sort fields, accepted `project` as a query projection alias across read helpers, and documented process-level Model registration plus ObjectId `maxDepth` conversion boundaries.
34
- Fixed `incrementOne` driver-option forwarding, closed runtime-owned Redis cache adapters on `runtime.close()`, made SSH tunnels fail fast for multi-host/SRV MongoDB URIs and post-ready disconnects, enforced slow-query batch `maxBufferSize` during in-flight flushes, wired prewarmed `findPage` bookmarks into page-jump reads, and reduced redundant rebuilds in the memory-server validation matrix.
45
- Fixed model mutable defaults cloning, preserved model aggregation-pipeline updates when timestamps/versioning are enabled, restored aggregate/distinct read-through cache plus targeted invalidation, and prevented sync resume tokens from advancing when any eligible target fails.
56
- Clarified hooks return-value compatibility and sync transform/delete-event boundaries in bilingual documentation, with regression coverage for the documented behavior.

‎changelogs/v2.0.7.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ v2.0.7 closes the release-readiness gap after the v2.0.6 review and hardens the
2828
- `dropDatabase()` now treats `NODE_ENV=production`, `prod`, and `live` as production-like environments that require `allowProduction: true`.
2929
- Aggregate pipelines ending in `$out` or `$merge` now bypass aggregate result caching and invalidate the target collection's read caches after successful execution.
3030
- Fire-and-forget distributed cache invalidation and transaction timeout abort paths now catch/log failures instead of leaving unhandled rejections.
31+
- `findPage` cursor anchors now read nested dot-path sort fields correctly, query read helpers accept `project` as a projection alias, and documentation clarifies ObjectId `maxDepth` conversion limits plus process-level Model registration.
3132

3233
## Verification
3334

‎docs/en/chaining-api.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,8 +347,8 @@ Chained methods automatically validate parameter types and values:
347347
.sort({ price: -1 })
348348

349349
//❌ Error - will throw an exception
350-
.limit(-1) // Error: limit() requires a non-negative number
351-
.skip("5") // Error: skip() requires a non-negative number
350+
.limit(-1) // Error: limit() requires a non-negative integer
351+
.skip("5") // Error: skip() requires a non-negative integer
352352
.sort("invalid") // Error: sort() requires an object or array
353353
```
354354

‎docs/en/chaining-methods.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,8 @@ const results = await collection('products')
241241
.skip(5)
242242

243243
//❌ Error - automatically throw exception
244-
.limit(-1) // Error: limit() requires a non-negative number
245-
.skip("invalid") // Error: skip() requires a non-negative number
244+
.limit(-1) // Error: limit() requires a non-negative integer
245+
.skip("invalid") // Error: skip() requires a non-negative integer
246246
.sort("invalid") // Error: sort() requires an object or array
247247
```
248248

‎docs/en/find-and-count.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ Query criteria, identical to `find()`.
3535
### options (Object)
3636
Query options:
3737

38-
- `projection` (Object) - field projection
38+
- `projection` / `project` (Object) - field projection. `project` is an alias for `projection`; `projection` wins when both are provided.
3939
- `sort` (Object) - sort rules
4040
- `limit` (Number) - maximum number of returned documents (`undefined` means no limit)
4141
- `skip` (Number) - number of documents to skip

‎docs/en/find-by-ids.md‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ async findByIds(
7070
|------|------|------|------|
7171
| `ids` | Array<string \| ObjectId> | ✅ | _id array (supports mixed string and ObjectId) |
7272
| `options` | Object | ❌ | Query Options |
73-
| `options.projection` | Object | ❌ | Field projection (same as find) |
73+
| `options.projection` / `options.project` | Object | ❌ | Field projection (same as find). `project` is an alias for `projection`; `projection` wins when both are provided. |
7474
| `options.sort` | Object | ❌ | Sort by |
7575
| `options.cache` | number | ❌ | cache time (milliseconds) |
7676
| `options.maxTimeMS` | number | ❌ | Query timeout (milliseconds) |
@@ -652,4 +652,3 @@ const users = await collection('users').findByIds(ids, {
652652
- [find()](./find.md) - Basic query method
653653
- [findOne()](./findOne.md) - Query a single document
654654
- [MongoDB official documentation: $in operator](https://www.mongodb.com/docs/manual/reference/operator/query/in/)
655-

‎docs/en/find-one-by-id.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ async findOneById(id, options = {})
6666

6767
| Parameters | Type | Required | Default value | Description |
6868
|------|------|------|--------|------|
69-
| `projection` | Object/Array | No | - | Field projection configuration |
69+
| `projection` / `project` | Object/Array | No | - | Field projection configuration. `project` is an alias for `projection`; `projection` wins when both are provided. |
7070
| `cache` | Number | No | `0` | Cache TTL (milliseconds) |
7171
| `maxTimeMS` | Number | No | Global configuration | Query timeout (milliseconds) |
7272
| `comment` | String | No | - | Query comments (for log tracking) |

‎docs/en/find.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ MongoDB standard query condition object, supporting all MongoDB query operators.
134134

135135
| Parameters | Type | Required | Default | Source | Description |
136136
|------|------|------|--------|------|------|
137-
| `projection` | Object/Array | No | - | MongoDB native ✅ | Field projection configuration, specify the returned fields |
137+
| `projection` / `project` | Object/Array | No | - | MongoDB native ✅ | Field projection configuration, specify the returned fields. `project` is an alias for `projection`; `projection` wins when both are provided. |
138138
| `sort` | Object | No | - | MongoDB native ✅ | Collation, such as `{ createdAt: -1, name: 1 }` |
139139
| `limit` | Number | No | Global Configuration | MongoDB Native ✅ | Limit the number of documents returned |
140140
| `skip` | Number | No | - | MongoDB native ✅ | Skip the specified number of documents (not recommended for large data volumes) |

‎docs/en/findOne.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ MongoDB query criteria object. All MongoDB query operators are supported.
4545

4646
| Parameter | Type | Required | Default | Source | Description |
4747
|------|------|------|--------|------|------|
48-
| `projection` | Object/Array | No | - | MongoDB native ✅ | Field projection configuration that controls which fields are returned |
48+
| `projection` / `project` | Object/Array | No | - | MongoDB native ✅ | Field projection configuration that controls which fields are returned. `project` is an alias for `projection`; `projection` wins when both are provided. |
4949
| `sort` | Object | No | - | MongoDB native ✅ | Sort rules, such as `{ createdAt: -1, name: 1 }` |
5050
| `hint` | Object/String | No | - | MongoDB native ✅ | Specifies the index to use for the query |
5151
| `collation` | Object | No | - | MongoDB native ✅ | Specifies collation rules for string comparison and sorting |

‎docs/en/findPage.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ async findPage(options = {})
3737
| `after` | String | No | - | Cursor paging: Get the data after the specified cursor |
3838
| `before` | String | No | - | Cursor paging: Get the data before the specified cursor |
3939
| `page` | Number | No | - | Page jump mode: Specify the page number to be obtained (starting from 1) |
40-
| `projection` | Object/Array | No | - | Field projection: Specifies the fields returned. Supports inclusive type `{ field: 1 }` and exclusive type `{ field: 0 }`, and also supports array form `['field1', 'field2']`. **NOTE**: The sort field is automatically preserved to ensure the cursor is generated correctly, no manual inclusion is required. |
40+
| `projection` / `project` | Object/Array | No | - | Field projection: Specifies the fields returned. `project` is an alias for `projection`; `projection` wins when both are provided. Supports inclusive type `{ field: 1 }` and exclusive type `{ field: 0 }`, and also supports array form `['field1', 'field2']`. **NOTE**: The sort field is automatically preserved to ensure the cursor is generated correctly, no manual inclusion is required. |
4141
| `pipeline` | Array | No | `[]` | Additional MongoDB aggregation pipeline stage (only effective for current page data, executed before projection) |
4242
| `hint` | Object/String | No | - | Specify the index used by the query |
4343
| `collation` | Object | No | - | Specify collation |
@@ -212,6 +212,7 @@ const page0 = await collection('orders').findPage({
212212
- The cursor contains the value of the sorting field, and the sorting rules must be consistent
213213
- When `cursorSecret` is not configured, the cursor is purely Base64url encoded, and the client can decode the content; after configuration, an HMAC-SHA256 signature is appended, and the tampered cursor will be rejected by the server.
214214
- Cursor comparison restores JSON-round-tripped values before building the MongoDB filter: by default, 24-character hexadecimal strings are treated as ObjectId values, and ISO timestamp-like strings are treated as Date values. Use `cursorTypes` or `cursorValueNormalizer` when a string sort field intentionally contains ObjectId-like or ISO-like values.
215+
- Cursor anchors read sort values by dot path, so nested sort fields such as `{ 'metrics.rank': 1 }` are supported.
215216
- Do not splice or modify the cursor on the client side
216217
- If you need long-term cross-session persistence of the cursor, please also cooperate with the server's own expiration control.
217218

0 commit comments

Comments
 (0)