@nxgt/mongo 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -46,8 +46,23 @@ const db = client.db('app');
46
46
  ## Definition
47
47
 
48
48
  `defineCollection` takes the collection's name, the Zod schema of its
49
- documents, its indexes as the driver describes them, and how its validator is
50
- applied.
49
+ documents, its indexes, and how its validator is applied.
50
+
51
+ An index is keyed on the schema's own fields, so an editor completes them and a
52
+ typo does not compile. A path into a field is allowed too, since that is how
53
+ MongoDB indexes a nested key. Everything else is the driver's own
54
+ `IndexDescription` — `unique`, `name`, `collation`, `expireAfterSeconds`,
55
+ `partialFilterExpression`:
56
+
57
+ ```ts
58
+ indexes: [
59
+ { key: { email: 1 }, unique: true, name: 'users_email_unique' },
60
+ { key: { createdAt: -1 } },
61
+ { key: { 'address.city': 1 } },
62
+ // @ts-expect-error there is no such field
63
+ { key: { emial: 1 } },
64
+ ]
65
+ ```
51
66
 
52
67
  The schema is the one source of truth. `z.output` is what a read gives back,
53
68
  `z.input` what a write takes: a field with a default — `_id`, `createdAt`,
@@ -99,7 +114,7 @@ import { createRepository } from '@nxgt/mongo';
99
114
  const repo = createRepository(db, users);
100
115
 
101
116
  const ada = await repo.create({ email: 'ada@example.com' });
102
- // → { _id: ObjectId, email, name: null, createdAt: Date, version: 0, … }
117
+ // → { _id: ObjectId, id: '507f…', email, name: null, createdAt: Date, version: 0, … }
103
118
 
104
119
  await repo.findById(ada._id); // the document, or undefined
105
120
  await repo.getById(ada._id); // or NotFoundError
@@ -122,6 +137,36 @@ also what fills its defaults. `update` checks each field of a patch — the
122
137
  driver's own `UpdateFilter` is intersected with `Document` and accepts any key
123
138
  whatsoever, including a typo.
124
139
 
140
+ ## Ids
141
+
142
+ Every document a repository gives back carries `id`: its `_id` as a string. It
143
+ is computed, never stored — the collection holds `_id` alone — and it is an
144
+ ordinary enumerable property, so `JSON.stringify` and a spread carry it and a
145
+ handler can return the document as it is.
146
+
147
+ Because it is not a stored field, nothing can be filtered or patched on it: the
148
+ server would match nothing, and TypeScript refuses it. To go the other way,
149
+ from a string that arrived over HTTP:
150
+
151
+ ```ts
152
+ import { toObjectId, tryObjectId, isValidObjectId, objectIdParam } from '@nxgt/mongo';
153
+
154
+ await repo.getById(toObjectId(params.id)); // an ObjectId, or InvalidIdError
155
+ tryObjectId(params.id); // an ObjectId, or undefined
156
+ isValidObjectId(params.id); // a boolean
157
+ toObjectIds(query.ids); // for a `$in` filter
158
+
159
+ // Or as part of a schema, where the parameters are parsed:
160
+ const route = z.object({ id: objectIdParam() });
161
+ const { id } = route.parse(params); // ObjectId
162
+ ```
163
+
164
+ **Do not call `new ObjectId(value)` on input you did not produce.** Given
165
+ `null` or `undefined` the driver does not throw: it invents a fresh id, so a
166
+ parameter that never arrived becomes a perfectly valid id that matches nothing.
167
+ `toObjectId` throws `InvalidIdError`, which a handler can turn into a 400 or a
168
+ 404.
169
+
125
170
  ## Pagination
126
171
 
127
172
  ```ts
@@ -190,6 +235,7 @@ application never reads a numeric code:
190
235
  | `ValidationError` | `VALIDATION` | the collection's validator refused it (121) |
191
236
  | `OptimisticLockError` | `OPTIMISTIC_LOCK` | `expectedVersion` no longer matches |
192
237
  | `InvalidCursorError` | `INVALID_CURSOR` | a cursor this package did not write |
238
+ | `InvalidIdError` | `INVALID_ID` | a value that is no `ObjectId`, nor the string of one |
193
239
  | `DataError` | `DATABASE` | any other server error, with its `serverCode` |
194
240
 
195
241
  `ConflictError` carries `index`, `keys` and, when the server gives them,
@@ -211,6 +257,8 @@ server error reaches you untouched.
211
257
  | --- | --- |
212
258
  | `defineCollection(config)` | a collection: name, schema, indexes, validation |
213
259
  | `id`, `objectId`, `timestamps`, `softDelete`, `optimisticLock`, `actors` | the field helpers |
260
+ | `toObjectId`, `toObjectIds`, `tryObjectId`, `objectIdParam` | a string from outside as an `ObjectId` |
261
+ | `isValidObjectId`, `isObjectIdString`, `isObjectId` | the checks behind them |
214
262
  | `createRepository(db, definition, options?)` | the typed repository |
215
263
  | `syncCollection`, `syncCollections` | create and bring in line, with `dryRun` |
216
264
  | `withTransaction(clientOrSession, fn, options?)` | a transaction, joined when nested |
@@ -255,6 +303,15 @@ server error reaches you untouched.
255
303
  - **Rebuilding an index drops it first.** MongoDB cannot alter an index in
256
304
  place, so `sync` drops and recreates one whose options changed: there is a
257
305
  window with no index, and on a large collection the rebuild is not free.
306
+ - **`new ObjectId(undefined)` is a fresh id, not an error.** So is
307
+ `new ObjectId(null)`. A missing route parameter turns into a valid id that
308
+ matches nothing, and the bug surfaces as an empty result rather than as a
309
+ failure. Use `toObjectId`, which throws, or `tryObjectId`, which answers
310
+ `undefined`.
311
+ - **`id` is computed, not stored.** It is on every document a repository
312
+ returns, and on none in the collection: a filter or a patch keyed on it would
313
+ match nothing, so both are compile errors. Query on `_id`. A schema that
314
+ declares an `id` field of its own keeps it, untouched.
258
315
  - **`validate: 'off'` also turns the defaults off.** Nothing fills `_id`,
259
316
  `createdAt` or `version` any more, because filling them is what parsing does.
260
317
  - **The driver retries a transaction's callback** on a transient error, for up
@@ -1,4 +1,4 @@
1
- import type { IndexDescription, ObjectId } from 'mongodb';
1
+ import type { IndexDescription, IndexDirection, ObjectId } from 'mongodb';
2
2
  import type { z } from 'zod';
3
3
  /** What MongoDB does with a document that fails the validator. */
4
4
  export type ValidationAction = 'error' | 'warn';
@@ -13,6 +13,23 @@ export interface ValidationConfig {
13
13
  /** Default `'error'`. `'warn'` logs and lets the write through. */
14
14
  action?: ValidationAction;
15
15
  }
16
+ /**
17
+ * What an index may be keyed on: a field of the documents, which an editor
18
+ * completes, or a path into one — `{ 'address.city': 1 }` is how MongoDB
19
+ * indexes a nested field, and there is no way to check the tail of a path
20
+ * against a schema without rejecting the paths Mongo allows.
21
+ */
22
+ export type IndexKey<Doc> = {
23
+ [Field in (keyof Doc & string) | `${keyof Doc & string}.${string}`]?: IndexDirection;
24
+ } | Map<string, IndexDirection>;
25
+ /**
26
+ * An index, keyed on the schema's own fields. Everything else — `unique`,
27
+ * `name`, `collation`, `partialFilterExpression`, the TTL — is the driver's
28
+ * `IndexDescription`, unchanged.
29
+ */
30
+ export interface CollectionIndex<Doc> extends Omit<IndexDescription, 'key'> {
31
+ key: IndexKey<Doc>;
32
+ }
16
33
  /** What `defineCollection` takes. */
17
34
  export interface CollectionConfig<Schema extends z.ZodObject> {
18
35
  /** The collection's name on the server. */
@@ -22,13 +39,16 @@ export interface CollectionConfig<Schema extends z.ZodObject> {
22
39
  * `z.input` what a write takes. It must have an `_id`.
23
40
  */
24
41
  schema: Schema;
25
- /** The indexes `sync` creates, as the driver describes them. */
26
- indexes?: readonly IndexDescription[];
42
+ /** The indexes `sync` creates, keyed on the schema's fields. */
43
+ indexes?: readonly CollectionIndex<z.output<Schema>>[];
27
44
  /** The `$jsonSchema` validator `sync` writes from the schema. */
28
45
  validation?: ValidationConfig;
29
46
  }
30
47
  /** A collection, as `defineCollection` returns it: frozen, with its defaults. */
31
- export interface CollectionDefinition<Schema extends z.ZodObject = z.ZodObject> extends Readonly<CollectionConfig<Schema>> {
48
+ export interface CollectionDefinition<Schema extends z.ZodObject = z.ZodObject> {
49
+ readonly name: string;
50
+ readonly schema: Schema;
51
+ /** As the driver takes them: `sync` hands these straight to MongoDB. */
32
52
  readonly indexes: readonly IndexDescription[];
33
53
  readonly validation: Required<ValidationConfig>;
34
54
  }
@@ -38,6 +58,18 @@ export type AnyCollectionDefinition = CollectionDefinition<any>;
38
58
  export type DocumentOf<Def> = Def extends {
39
59
  schema: infer Schema;
40
60
  } ? Schema extends z.ZodType ? z.output<Schema> : never : never;
61
+ /**
62
+ * A document as a repository gives it back: the stored document, plus `id`.
63
+ *
64
+ * `id` is `_id` as a string, computed rather than stored — the collection
65
+ * holds `_id` alone. It is enumerable, so `JSON.stringify` and a spread carry
66
+ * it, which is what makes a document ready to return from an API; it is not
67
+ * part of `DocumentOf`, so a filter or a patch cannot be keyed on it, because
68
+ * the server would match nothing.
69
+ */
70
+ export type ReadDocumentOf<Def> = DocumentOf<Def> & {
71
+ readonly id: string;
72
+ };
41
73
  /** What a write takes: the documents before their defaults are filled. */
42
74
  export type NewDocumentOf<Def> = Def extends {
43
75
  schema: infer Schema;
@@ -1 +1 @@
1
- {"version":3,"file":"define-collection.d.ts","sourceRoot":"","sources":["../../src/definition/define-collection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,kEAAkE;AAClE,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,MAAM,CAAC;AAEhD;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE5D,MAAM,WAAW,gBAAgB;IAChC,0BAA0B;IAC1B,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,mEAAmE;IACnE,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC1B;AAED,qCAAqC;AACrC,MAAM,WAAW,gBAAgB,CAAC,MAAM,SAAS,CAAC,CAAC,SAAS;IAC3D,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,OAAO,CAAC,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACtC,iEAAiE;IACjE,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC9B;AAED,iFAAiF;AACjF,MAAM,WAAW,oBAAoB,CAAC,MAAM,SAAS,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAC7E,SAAQ,QAAQ,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC9C,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC;CAChD;AAED,8CAA8C;AAC9C,MAAM,MAAM,uBAAuB,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;AAEhE,4DAA4D;AAC5D,MAAM,MAAM,UAAU,CAAC,GAAG,IAAI,GAAG,SAAS;IAAE,MAAM,EAAE,MAAM,MAAM,CAAA;CAAE,GAC/D,MAAM,SAAS,CAAC,CAAC,OAAO,GACvB,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAChB,KAAK,GACN,KAAK,CAAC;AAET,0EAA0E;AAC1E,MAAM,MAAM,aAAa,CAAC,GAAG,IAAI,GAAG,SAAS;IAAE,MAAM,EAAE,MAAM,MAAM,CAAA;CAAE,GAClE,MAAM,SAAS,CAAC,CAAC,OAAO,GACvB,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,GACf,KAAK,GACN,KAAK,CAAC;AAET,yBAAyB;AACzB,MAAM,MAAM,IAAI,CAAC,GAAG,IACnB,UAAU,CAAC,GAAG,CAAC,SAAS;IAAE,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,EAAE,GAAG,QAAQ,CAAC;AAE3D,oDAAoD;AACpD,MAAM,MAAM,OAAO,CAAC,GAAG,IAAI,MAAM,UAAU,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,SAAS,CAAC,CAAC,SAAS,EAC1D,MAAM,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAC9B,oBAAoB,CAAC,MAAM,CAAC,CAgB9B;AAED,gFAAgF;AAChF,wBAAgB,QAAQ,CAAC,UAAU,EAAE,uBAAuB,GAAG;IAC9D,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACnB,CAYA"}
1
+ {"version":3,"file":"define-collection.d.ts","sourceRoot":"","sources":["../../src/definition/define-collection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC1E,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,kEAAkE;AAClE,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,MAAM,CAAC;AAEhD;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE5D,MAAM,WAAW,gBAAgB;IAChC,0BAA0B;IAC1B,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,mEAAmE;IACnE,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC1B;AAED;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,CAAC,GAAG,IACrB;KACC,KAAK,IACH,CAAC,MAAM,GAAG,GAAG,MAAM,CAAC,GACpB,GAAG,MAAM,GAAG,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC,CAAC,EAAE,cAAc;CACrD,GAGD,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AAE/B;;;;GAIG;AACH,MAAM,WAAW,eAAe,CAAC,GAAG,CAAE,SAAQ,IAAI,CAAC,gBAAgB,EAAE,KAAK,CAAC;IAC1E,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;CACnB;AAED,qCAAqC;AACrC,MAAM,WAAW,gBAAgB,CAAC,MAAM,SAAS,CAAC,CAAC,SAAS;IAC3D,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,OAAO,CAAC,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;IACvD,iEAAiE;IACjE,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC9B;AAED,iFAAiF;AACjF,MAAM,WAAW,oBAAoB,CACpC,MAAM,SAAS,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS;IAExC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,wEAAwE;IACxE,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC9C,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC;CAChD;AAED,8CAA8C;AAC9C,MAAM,MAAM,uBAAuB,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;AAEhE,4DAA4D;AAC5D,MAAM,MAAM,UAAU,CAAC,GAAG,IAAI,GAAG,SAAS;IAAE,MAAM,EAAE,MAAM,MAAM,CAAA;CAAE,GAC/D,MAAM,SAAS,CAAC,CAAC,OAAO,GACvB,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAChB,KAAK,GACN,KAAK,CAAC;AAET;;;;;;;;GAQG;AACH,MAAM,MAAM,cAAc,CAAC,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5E,0EAA0E;AAC1E,MAAM,MAAM,aAAa,CAAC,GAAG,IAAI,GAAG,SAAS;IAAE,MAAM,EAAE,MAAM,MAAM,CAAA;CAAE,GAClE,MAAM,SAAS,CAAC,CAAC,OAAO,GACvB,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,GACf,KAAK,GACN,KAAK,CAAC;AAET,yBAAyB;AACzB,MAAM,MAAM,IAAI,CAAC,GAAG,IACnB,UAAU,CAAC,GAAG,CAAC,SAAS;IAAE,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,EAAE,GAAG,QAAQ,CAAC;AAE3D,oDAAoD;AACpD,MAAM,MAAM,OAAO,CAAC,GAAG,IAAI,MAAM,UAAU,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,SAAS,CAAC,CAAC,SAAS,EAC1D,MAAM,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAC9B,oBAAoB,CAAC,MAAM,CAAC,CAgB9B;AAED,gFAAgF;AAChF,wBAAgB,QAAQ,CAAC,UAAU,EAAE,uBAAuB,GAAG;IAC9D,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACnB,CAYA"}
@@ -1 +1 @@
1
- {"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../../src/definition/fields.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB;;;GAGG;AACH,wBAAgB,QAAQ,oCAIvB;AAED;;;GAGG;AACH,wBAAgB,EAAE,kDAEjB;AAED;;;GAGG;AACH,wBAAgB,UAAU;;;EAKzB;AAED;;;GAGG;AACH,wBAAgB,UAAU;;EAEzB;AAED;;;;GAIG;AACH,wBAAgB,cAAc;;EAE7B;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,EAC3E,KAAK,GAAE,KAAsC;;;;EAO7C;AAED,6DAA6D;AAC7D,eAAO,MAAM,YAAY;;;;;;;;;CASf,CAAC"}
1
+ {"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../../src/definition/fields.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;GAGG;AACH,wBAAgB,QAAQ,oCAIvB;AAED;;;GAGG;AACH,wBAAgB,EAAE,kDAEjB;AAED;;;GAGG;AACH,wBAAgB,UAAU;;;EAKzB;AAED;;;GAGG;AACH,wBAAgB,UAAU;;EAEzB;AAED;;;;GAIG;AACH,wBAAgB,cAAc;;EAE7B;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,EAC3E,KAAK,GAAE,KAAsC;;;;EAO7C;AAED,6DAA6D;AAC7D,eAAO,MAAM,YAAY;;;;;;;;;CASf,CAAC"}
@@ -0,0 +1,51 @@
1
+ import { ObjectId } from 'mongodb';
2
+ import { z } from 'zod';
3
+ /**
4
+ * An `ObjectId`, read by its BSON tag rather than with `instanceof`, which
5
+ * answers `false` across two copies of the driver in one tree.
6
+ */
7
+ export declare function isObjectId(value: unknown): value is ObjectId;
8
+ /** Is this the 24-character hex string an `ObjectId` is written as? */
9
+ export declare function isObjectIdString(value: unknown): value is string;
10
+ /** An `ObjectId`, or a string that stands for one. */
11
+ export declare function isValidObjectId(value: unknown): boolean;
12
+ /**
13
+ * The `ObjectId` this value stands for, or `undefined`. Never throws.
14
+ *
15
+ * Prefer it to `new ObjectId(value)`, which **invents a fresh id** when it is
16
+ * given `null` or `undefined` — a missing route parameter then reads as a
17
+ * perfectly valid id that matches nothing.
18
+ */
19
+ export declare function tryObjectId(value: unknown): ObjectId | undefined;
20
+ /**
21
+ * The `ObjectId` this value stands for. Throws `InvalidIdError` for anything
22
+ * else, `null` and `undefined` included.
23
+ *
24
+ * ```ts
25
+ * const user = await users.getById(toObjectId(request.params.id));
26
+ * ```
27
+ */
28
+ export declare function toObjectId(value: unknown, field?: string): ObjectId;
29
+ /**
30
+ * The same, for a list — a `$in` filter built from query parameters.
31
+ *
32
+ * ```ts
33
+ * await users.findMany({ filter: { _id: { $in: toObjectIds(ids) } } });
34
+ * ```
35
+ */
36
+ export declare function toObjectIds(values: Iterable<unknown>, field?: string): ObjectId[];
37
+ /**
38
+ * A Zod schema for an id that arrives from outside: it takes an `ObjectId` or
39
+ * its hex string and gives back an `ObjectId`.
40
+ *
41
+ * It belongs in the schema of a route's parameters, **not** in a collection's:
42
+ * a field that parses one type into another has no honest `$jsonSchema`, and
43
+ * what a collection stores is `objectId()`.
44
+ *
45
+ * ```ts
46
+ * const params = z.object({ id: objectIdParam() });
47
+ * const { id } = params.parse(request.params); // ObjectId
48
+ * ```
49
+ */
50
+ export declare function objectIdParam(): z.ZodPipe<z.ZodCustom<string | ObjectId, string | ObjectId>, z.ZodTransform<ObjectId, string | ObjectId>>;
51
+ //# sourceMappingURL=object-id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"object-id.d.ts","sourceRoot":"","sources":["../../src/definition/object-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAM5D;AAED,uEAAuE;AACvE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAEhE;AAED,sDAAsD;AACtD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEvD;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,CAIhE;AASD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,SAAQ,GAAG,QAAQ,CAOlE;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAC1B,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,EACzB,KAAK,SAAQ,GACX,QAAQ,EAAE,CAEZ;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,8GAM5B"}
@@ -1,5 +1,5 @@
1
1
  /** What went wrong, as a string a caller can switch on. */
2
- export type DataErrorCode = 'DATABASE' | 'NOT_FOUND' | 'CONFLICT' | 'VALIDATION' | 'OPTIMISTIC_LOCK' | 'INVALID_CURSOR';
2
+ export type DataErrorCode = 'DATABASE' | 'NOT_FOUND' | 'CONFLICT' | 'VALIDATION' | 'OPTIMISTIC_LOCK' | 'INVALID_CURSOR' | 'INVALID_ID';
3
3
  /** One reason a document failed the collection's `$jsonSchema` validator. */
4
4
  export interface ValidationIssue {
5
5
  /** The dotted path of the field, empty for the document itself. */
@@ -83,6 +83,18 @@ export declare class OptimisticLockError extends DataError {
83
83
  readonly code: "OPTIMISTIC_LOCK";
84
84
  constructor(message?: string, options?: DataErrorOptions);
85
85
  }
86
+ /**
87
+ * A value that is not an `ObjectId` and not the string of one.
88
+ *
89
+ * It is a `DataError` rather than a `TypeError` because it is usually data,
90
+ * not a mistake in the code: an id off a URL or a form reaches `toObjectId`,
91
+ * and a handler wants to answer 400 or 404 rather than crash.
92
+ */
93
+ export declare class InvalidIdError extends DataError {
94
+ name: string;
95
+ readonly code: "INVALID_ID";
96
+ constructor(message?: string, options?: DataErrorOptions);
97
+ }
86
98
  /** A cursor this package did not write, or one for another ordering. */
87
99
  export declare class InvalidCursorError extends DataError {
88
100
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"data-error.d.ts","sourceRoot":"","sources":["../../src/errors/data-error.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,MAAM,MAAM,aAAa,GACtB,UAAU,GACV,WAAW,GACX,UAAU,GACV,YAAY,GACZ,iBAAiB,GACjB,gBAAgB,CAAC;AAEpB,6EAA6E;AAC7E,MAAM,WAAW,eAAe;IAC/B,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4DAA4D;IAC5D,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,0EAA0E;IAC1E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAChC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,0CAA0C;IAC1C,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,6DAA6D;IAC7D,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,8EAA8E;IAC9E,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAC7C,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;GAMG;AACH,qBAAa,SAAU,SAAQ,KAAK;IAC1B,IAAI,SAAe;IAC5B,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAc;IAC1C,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5C,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IACrD,QAAQ,CAAC,MAAM,EAAE,eAAe,EAAE,CAAC;IACnC,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;gBAE/B,OAAO,SAAmB,EAAE,OAAO,GAAE,gBAAqB;CAgBtE;AAED,mDAAmD;AACnD,qBAAa,aAAc,SAAQ,SAAS;IAClC,IAAI,SAAmB;IAChC,SAAkB,IAAI,EAAG,WAAW,CAAU;gBAElC,OAAO,SAAc,EAAE,OAAO,GAAE,gBAAqB;CAGjE;AAED,4DAA4D;AAC5D,qBAAa,aAAc,SAAQ,SAAS;IAClC,IAAI,SAAmB;IAChC,SAAkB,IAAI,EAAG,UAAU,CAAU;gBAEjC,OAAO,SAAkB,EAAE,OAAO,GAAE,gBAAqB;CAGrE;AAED,+EAA+E;AAC/E,qBAAa,eAAgB,SAAQ,SAAS;IACpC,IAAI,SAAqB;IAClC,SAAkB,IAAI,EAAG,YAAY,CAAU;gBAG9C,OAAO,SAA+B,EACtC,OAAO,GAAE,gBAAqB;CAI/B;AAED;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,SAAS;IACxC,IAAI,SAAyB;IACtC,SAAkB,IAAI,EAAG,iBAAiB,CAAU;gBAExC,OAAO,SAAqB,EAAE,OAAO,GAAE,gBAAqB;CAGxE;AAED,wEAAwE;AACxE,qBAAa,kBAAmB,SAAQ,SAAS;IACvC,IAAI,SAAwB;IACrC,SAAkB,IAAI,EAAG,gBAAgB,CAAU;gBAEvC,OAAO,SAAmB,EAAE,OAAO,GAAE,gBAAqB;CAGtE"}
1
+ {"version":3,"file":"data-error.d.ts","sourceRoot":"","sources":["../../src/errors/data-error.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
- export { type AnyCollectionDefinition, type CollectionConfig, type CollectionDefinition, type DocumentOf, defineCollection, type FieldOf, type IdOf, type NewDocumentOf, stampsOf, type ValidationAction, type ValidationConfig, type ValidationLevel, } from './definition/define-collection';
1
+ export { type AnyCollectionDefinition, type CollectionConfig, type CollectionDefinition, type CollectionIndex, type DocumentOf, defineCollection, type FieldOf, type IdOf, type IndexKey, type NewDocumentOf, type ReadDocumentOf, stampsOf, type ValidationAction, type ValidationConfig, type ValidationLevel, } from './definition/define-collection';
2
2
  export { actors, id, objectId, optimisticLock, STAMP_FIELDS, softDelete, timestamps, } from './definition/fields';
3
3
  export { MONGO_JSON_SCHEMA_KEYWORDS, toMongoJsonSchema, } from './definition/json-schema';
4
- export { ConflictError, DataError, type DataErrorCode, type DataErrorOptions, InvalidCursorError, NotFoundError, OptimisticLockError, ValidationError, type ValidationIssue, } from './errors/data-error';
4
+ export { isObjectId, isObjectIdString, isValidObjectId, objectIdParam, toObjectId, toObjectIds, tryObjectId, } from './definition/object-id';
5
+ export { ConflictError, DataError, type DataErrorCode, type DataErrorOptions, InvalidCursorError, InvalidIdError, NotFoundError, OptimisticLockError, ValidationError, type ValidationIssue, } from './errors/data-error';
5
6
  export { toDataError } from './errors/to-data-error';
6
7
  export { type CursorPayload, decodeCursor, encodeCursor, } from './pagination/cursor';
7
8
  export { type CursorPage, cursorLimit, DEFAULT_MAX_PAGE_SIZE, DEFAULT_PAGE_SIZE, type Page, type PageOptions, type PageWindow, pageWindow, toPage, } from './pagination/page';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,UAAU,EACf,gBAAgB,EAChB,KAAK,OAAO,EACZ,KAAK,IAAI,EACT,KAAK,aAAa,EAClB,QAAQ,EACR,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACpB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACN,MAAM,EACN,EAAE,EACF,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,UAAU,EACV,UAAU,GACV,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,0BAA0B,EAC1B,iBAAiB,GACjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACN,aAAa,EACb,SAAS,EACT,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACnB,eAAe,EACf,KAAK,eAAe,GACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EACN,KAAK,aAAa,EAClB,YAAY,EACZ,YAAY,GACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,KAAK,UAAU,EACf,WAAW,EACX,qBAAqB,EACrB,iBAAiB,EACjB,KAAK,IAAI,EACT,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,UAAU,EACV,MAAM,GACN,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,YAAY,EACX,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,eAAe,EACf,KAAK,EACL,WAAW,EACX,UAAU,EACV,iBAAiB,EACjB,aAAa,GACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACN,WAAW,EACX,KAAK,SAAS,EACd,YAAY,EACZ,WAAW,EACX,KAAK,eAAe,EACpB,cAAc,GACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,cAAc,EACd,eAAe,GACf,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACN,YAAY,EACZ,KAAK,cAAc,EACnB,iBAAiB,EACjB,KAAK,gBAAgB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACN,KAAK,eAAe,EACpB,eAAe,GACf,MAAM,gCAAgC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,gBAAgB,EAChB,KAAK,OAAO,EACZ,KAAK,IAAI,EACT,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,QAAQ,EACR,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACpB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACN,MAAM,EACN,EAAE,EACF,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,UAAU,EACV,UAAU,GACV,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,0BAA0B,EAC1B,iBAAiB,GACjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACN,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,UAAU,EACV,WAAW,EACX,WAAW,GACX,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACN,aAAa,EACb,SAAS,EACT,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,eAAe,EACf,KAAK,eAAe,GACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EACN,KAAK,aAAa,EAClB,YAAY,EACZ,YAAY,GACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,KAAK,UAAU,EACf,WAAW,EACX,qBAAqB,EACrB,iBAAiB,EACjB,KAAK,IAAI,EACT,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,UAAU,EACV,MAAM,GACN,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,YAAY,EACX,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,eAAe,EACf,KAAK,EACL,WAAW,EACX,UAAU,EACV,iBAAiB,EACjB,aAAa,GACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACN,WAAW,EACX,KAAK,SAAS,EACd,YAAY,EACZ,WAAW,EACX,KAAK,eAAe,EACpB,cAAc,GACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,cAAc,EACd,eAAe,GACf,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACN,YAAY,EACZ,KAAK,cAAc,EACnB,iBAAiB,EACjB,KAAK,gBAAgB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACN,KAAK,eAAe,EACpB,eAAe,GACf,MAAM,gCAAgC,CAAC"}
package/dist/index.js CHANGED
@@ -26,28 +26,140 @@ function stampsOf(definition) {
26
26
  };
27
27
  }
28
28
  // src/definition/fields.ts
29
+ import { ObjectId as ObjectId2 } from "mongodb";
30
+ import { z as z2 } from "zod";
31
+
32
+ // src/definition/object-id.ts
29
33
  import { ObjectId } from "mongodb";
30
34
  import { z } from "zod";
35
+
36
+ // src/errors/data-error.ts
37
+ class DataError extends Error {
38
+ constructor(message = "Database error", options = {}) {
39
+ super(message, options.cause === undefined ? undefined : { cause: options.cause });
40
+ this.name = "DataError";
41
+ this.code = "DATABASE";
42
+ this.collection = options.collection;
43
+ this.id = options.id;
44
+ this.serverCode = options.serverCode;
45
+ this.serverCodeName = options.serverCodeName;
46
+ this.index = options.index;
47
+ this.keys = options.keys ?? [];
48
+ this.values = options.values;
49
+ this.issues = options.issues ?? [];
50
+ this.expectedVersion = options.expectedVersion;
51
+ this.actualVersion = options.actualVersion;
52
+ }
53
+ }
54
+
55
+ class NotFoundError extends DataError {
56
+ constructor(message = "Not found", options = {}) {
57
+ super(message, options);
58
+ this.name = "NotFoundError";
59
+ this.code = "NOT_FOUND";
60
+ }
61
+ }
62
+
63
+ class ConflictError extends DataError {
64
+ constructor(message = "Duplicate key", options = {}) {
65
+ super(message, { serverCode: 11000, ...options });
66
+ this.name = "ConflictError";
67
+ this.code = "CONFLICT";
68
+ }
69
+ }
70
+
71
+ class ValidationError extends DataError {
72
+ constructor(message = "Document failed validation", options = {}) {
73
+ super(message, { serverCode: 121, ...options });
74
+ this.name = "ValidationError";
75
+ this.code = "VALIDATION";
76
+ }
77
+ }
78
+
79
+ class OptimisticLockError extends DataError {
80
+ constructor(message = "Version conflict", options = {}) {
81
+ super(message, options);
82
+ this.name = "OptimisticLockError";
83
+ this.code = "OPTIMISTIC_LOCK";
84
+ }
85
+ }
86
+
87
+ class InvalidIdError extends DataError {
88
+ constructor(message = "Invalid id", options = {}) {
89
+ super(message, options);
90
+ this.name = "InvalidIdError";
91
+ this.code = "INVALID_ID";
92
+ }
93
+ }
94
+
95
+ class InvalidCursorError extends DataError {
96
+ constructor(message = "Invalid cursor", options = {}) {
97
+ super(message, options);
98
+ this.name = "InvalidCursorError";
99
+ this.code = "INVALID_CURSOR";
100
+ }
101
+ }
102
+
103
+ // src/definition/object-id.ts
104
+ var HEX_24 = /^[0-9a-fA-F]{24}$/;
31
105
  function isObjectId(value) {
32
106
  return typeof value === "object" && value !== null && value._bsontype === "ObjectId";
33
107
  }
108
+ function isObjectIdString(value) {
109
+ return typeof value === "string" && HEX_24.test(value);
110
+ }
111
+ function isValidObjectId(value) {
112
+ return isObjectId(value) || isObjectIdString(value);
113
+ }
114
+ function tryObjectId(value) {
115
+ if (isObjectId(value))
116
+ return value;
117
+ if (isObjectIdString(value))
118
+ return ObjectId.createFromHexString(value);
119
+ return;
120
+ }
121
+ function describe(value) {
122
+ if (value === null)
123
+ return "null";
124
+ if (value === undefined)
125
+ return "undefined";
126
+ if (typeof value === "string")
127
+ return `the string ${JSON.stringify(value)}`;
128
+ return `a ${typeof value}`;
129
+ }
130
+ function toObjectId(value, field = "_id") {
131
+ const made = tryObjectId(value);
132
+ if (made)
133
+ return made;
134
+ throw new InvalidIdError(`${field}: expected an ObjectId or its 24-character hex string, got ${describe(value)}`, { id: value, keys: [field] });
135
+ }
136
+ function toObjectIds(values, field = "_id") {
137
+ return [...values].map((value) => toObjectId(value, field));
138
+ }
139
+ function objectIdParam() {
140
+ return z.custom(isValidObjectId, {
141
+ error: "must be an ObjectId or its 24-character hex string"
142
+ }).transform((value) => toObjectId(value));
143
+ }
144
+
145
+ // src/definition/fields.ts
34
146
  function objectId() {
35
- return z.custom(isObjectId, { error: "must be an ObjectId" }).meta({ bsonType: "objectId" });
147
+ return z2.custom(isObjectId, { error: "must be an ObjectId" }).meta({ bsonType: "objectId" });
36
148
  }
37
149
  function id() {
38
- return objectId().default(() => new ObjectId);
150
+ return objectId().default(() => new ObjectId2);
39
151
  }
40
152
  function timestamps() {
41
153
  return {
42
- createdAt: z.date().default(() => new Date),
43
- updatedAt: z.date().default(() => new Date)
154
+ createdAt: z2.date().default(() => new Date),
155
+ updatedAt: z2.date().default(() => new Date)
44
156
  };
45
157
  }
46
158
  function softDelete() {
47
- return { deletedAt: z.date().nullable().default(null) };
159
+ return { deletedAt: z2.date().nullable().default(null) };
48
160
  }
49
161
  function optimisticLock() {
50
- return { version: z.int().nonnegative().default(0) };
162
+ return { version: z2.int().nonnegative().default(0) };
51
163
  }
52
164
  function actors(actor = objectId()) {
53
165
  return {
@@ -67,7 +179,7 @@ var STAMP_FIELDS = {
67
179
  deletedBy: "deletedBy"
68
180
  };
69
181
  // src/definition/json-schema.ts
70
- import { z as z2 } from "zod";
182
+ import { z as z3 } from "zod";
71
183
  var MONGO_JSON_SCHEMA_KEYWORDS = new Set([
72
184
  "additionalItems",
73
185
  "additionalProperties",
@@ -167,7 +279,7 @@ function inline(value, defs, stack) {
167
279
  return out;
168
280
  }
169
281
  function toMongoJsonSchema(schema) {
170
- const json = z2.toJSONSchema(schema, {
282
+ const json = z3.toJSONSchema(schema, {
171
283
  target: "draft-4",
172
284
  io: "output",
173
285
  unrepresentable: "any",
@@ -181,64 +293,6 @@ function toMongoJsonSchema(schema) {
181
293
  const definitions = isRecord(json.definitions) ? json.definitions : isRecord(json.$defs) ? json.$defs : {};
182
294
  return inline(json, definitions, []);
183
295
  }
184
- // src/errors/data-error.ts
185
- class DataError extends Error {
186
- constructor(message = "Database error", options = {}) {
187
- super(message, options.cause === undefined ? undefined : { cause: options.cause });
188
- this.name = "DataError";
189
- this.code = "DATABASE";
190
- this.collection = options.collection;
191
- this.id = options.id;
192
- this.serverCode = options.serverCode;
193
- this.serverCodeName = options.serverCodeName;
194
- this.index = options.index;
195
- this.keys = options.keys ?? [];
196
- this.values = options.values;
197
- this.issues = options.issues ?? [];
198
- this.expectedVersion = options.expectedVersion;
199
- this.actualVersion = options.actualVersion;
200
- }
201
- }
202
-
203
- class NotFoundError extends DataError {
204
- constructor(message = "Not found", options = {}) {
205
- super(message, options);
206
- this.name = "NotFoundError";
207
- this.code = "NOT_FOUND";
208
- }
209
- }
210
-
211
- class ConflictError extends DataError {
212
- constructor(message = "Duplicate key", options = {}) {
213
- super(message, { serverCode: 11000, ...options });
214
- this.name = "ConflictError";
215
- this.code = "CONFLICT";
216
- }
217
- }
218
-
219
- class ValidationError extends DataError {
220
- constructor(message = "Document failed validation", options = {}) {
221
- super(message, { serverCode: 121, ...options });
222
- this.name = "ValidationError";
223
- this.code = "VALIDATION";
224
- }
225
- }
226
-
227
- class OptimisticLockError extends DataError {
228
- constructor(message = "Version conflict", options = {}) {
229
- super(message, options);
230
- this.name = "OptimisticLockError";
231
- this.code = "OPTIMISTIC_LOCK";
232
- }
233
- }
234
-
235
- class InvalidCursorError extends DataError {
236
- constructor(message = "Invalid cursor", options = {}) {
237
- super(message, options);
238
- this.name = "InvalidCursorError";
239
- this.code = "INVALID_CURSOR";
240
- }
241
- }
242
296
  // src/errors/to-data-error.ts
243
297
  function isRecord2(value) {
244
298
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -344,7 +398,7 @@ function toDataError(error, context = {}) {
344
398
  return new DataError(message || `MongoDB error ${code}`, common);
345
399
  }
346
400
  // src/pagination/cursor.ts
347
- import { ObjectId as ObjectId2 } from "mongodb";
401
+ import { ObjectId as ObjectId3 } from "mongodb";
348
402
  function isObjectId2(value) {
349
403
  return typeof value === "object" && value !== null && value._bsontype === "ObjectId";
350
404
  }
@@ -368,7 +422,7 @@ function reviver(_key, value) {
368
422
  if (typeof tagged.$bigint === "string")
369
423
  return BigInt(tagged.$bigint);
370
424
  if (typeof tagged.$oid === "string")
371
- return new ObjectId2(tagged.$oid);
425
+ return new ObjectId3(tagged.$oid);
372
426
  }
373
427
  }
374
428
  return value;
@@ -678,6 +732,7 @@ function build(db, definition, options) {
678
732
  const name = definition.name;
679
733
  const collection = db.collection(name);
680
734
  const shape = definition.schema.shape;
735
+ const hasOwnId = "id" in shape;
681
736
  const stamps = stampsOf(definition);
682
737
  const session = options.session;
683
738
  const actor = options.actor;
@@ -702,6 +757,17 @@ function build(db, definition, options) {
702
757
  const sessionOption = session ? { session } : {};
703
758
  const live = (withDeleted) => softDeletes && !withDeleted ? { deletedAt: null } : undefined;
704
759
  const scoped = (filter, withDeleted) => mergeFilters(isRecord3(filter) ? filter : undefined, live(withDeleted));
760
+ const withId = (document) => {
761
+ if (hasOwnId || !isRecord3(document) || document._id === undefined || Object.hasOwn(document, "id")) {
762
+ return document;
763
+ }
764
+ Object.defineProperty(document, "id", {
765
+ get: () => String(document._id),
766
+ enumerable: true,
767
+ configurable: true
768
+ });
769
+ return document;
770
+ };
705
771
  const notFound = (id) => new NotFoundError(`No document in "${name}" with _id ${String(id)}`, {
706
772
  collection: name,
707
773
  id
@@ -713,6 +779,8 @@ function build(db, definition, options) {
713
779
  };
714
780
  const toDocument = (values) => {
715
781
  const stamped = { ...values };
782
+ if (!hasOwnId)
783
+ delete stamped.id;
716
784
  if (actor !== undefined) {
717
785
  if (stamps.createdBy && stamped.createdBy === undefined) {
718
786
  stamped.createdBy = actor;
@@ -754,10 +822,13 @@ function build(db, definition, options) {
754
822
  }
755
823
  return update;
756
824
  };
757
- const findOne = async (filter, projection) => run(async () => collection.findOne(filter, {
758
- ...sessionOption,
759
- ...projection ? { projection } : {}
760
- }));
825
+ const findOne = async (filter, projection) => run(async () => {
826
+ const found = await collection.findOne(filter, {
827
+ ...sessionOption,
828
+ ...projection ? { projection } : {}
829
+ });
830
+ return found === null ? null : withId(found);
831
+ });
761
832
  async function findById(id, opts = {}) {
762
833
  const found = await findOne(scoped({ _id: id }, opts.withDeleted));
763
834
  return found ?? undefined;
@@ -780,7 +851,8 @@ function build(db, definition, options) {
780
851
  cursor = cursor.skip(opts.skip);
781
852
  if (opts.limit !== undefined)
782
853
  cursor = cursor.limit(opts.limit);
783
- return cursor.toArray();
854
+ const found = await cursor.toArray();
855
+ return found.map((document) => withId(document));
784
856
  });
785
857
  }
786
858
  async function countDocuments(filter, opts = {}) {
@@ -794,7 +866,7 @@ function build(db, definition, options) {
794
866
  returnDocument: "after"
795
867
  }));
796
868
  if (updated)
797
- return updated;
869
+ return withId(updated);
798
870
  if (expectedVersion !== undefined) {
799
871
  const current = await findOne({ _id: id });
800
872
  if (current) {
@@ -812,7 +884,7 @@ function build(db, definition, options) {
812
884
  const deleted = await run(async () => collection.findOneAndDelete({ _id: id }, { ...sessionOption }));
813
885
  if (!deleted)
814
886
  throw notFound(id);
815
- return deleted;
887
+ return withId(deleted);
816
888
  }
817
889
  async function hardDeleteMany(filter) {
818
890
  requireFilter("hardDeleteMany", filter);
@@ -842,7 +914,7 @@ function build(db, definition, options) {
842
914
  const document = toDocument(values);
843
915
  return run(async () => {
844
916
  await collection.insertOne(document, { ...sessionOption });
845
- return document;
917
+ return withId(document);
846
918
  });
847
919
  },
848
920
  async createMany(values) {
@@ -853,7 +925,7 @@ function build(db, definition, options) {
853
925
  await collection.insertMany(documents, {
854
926
  ...sessionOption
855
927
  });
856
- return documents;
928
+ return documents.map((document) => withId(document));
857
929
  });
858
930
  },
859
931
  async update(id, patch, opts = {}) {
@@ -1021,6 +1093,7 @@ export {
1021
1093
  DEFAULT_PAGE_SIZE,
1022
1094
  DataError,
1023
1095
  InvalidCursorError,
1096
+ InvalidIdError,
1024
1097
  MONGO_JSON_SCHEMA_KEYWORDS,
1025
1098
  NotFoundError,
1026
1099
  OptimisticLockError,
@@ -1037,8 +1110,12 @@ export {
1037
1110
  id,
1038
1111
  indexMatches,
1039
1112
  indexNameOf,
1113
+ isObjectId,
1114
+ isObjectIdString,
1115
+ isValidObjectId,
1040
1116
  normalizeIndex,
1041
1117
  objectId,
1118
+ objectIdParam,
1042
1119
  optimisticLock,
1043
1120
  pageWindow,
1044
1121
  softDelete,
@@ -1048,10 +1125,13 @@ export {
1048
1125
  timestamps,
1049
1126
  toDataError,
1050
1127
  toMongoJsonSchema,
1128
+ toObjectId,
1129
+ toObjectIds,
1051
1130
  toPage,
1131
+ tryObjectId,
1052
1132
  validationMatches,
1053
1133
  withTransaction
1054
1134
  };
1055
1135
 
1056
- //# debugId=44372BBBC1BF50A464756E2164756E21
1136
+ //# debugId=5C569B791BADEA5664756E2164756E21
1057
1137
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1,21 +1,22 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/definition/define-collection.ts", "../src/definition/fields.ts", "../src/definition/json-schema.ts", "../src/errors/data-error.ts", "../src/errors/to-data-error.ts", "../src/pagination/cursor.ts", "../src/pagination/page.ts", "../src/sync/index-diff.ts", "../src/sync/validator-diff.ts", "../src/sync/sync-collection.ts", "../src/repository/create-repository.ts", "../src/transaction/with-transaction.ts"],
3
+ "sources": ["../src/definition/define-collection.ts", "../src/definition/fields.ts", "../src/definition/object-id.ts", "../src/errors/data-error.ts", "../src/definition/json-schema.ts", "../src/errors/to-data-error.ts", "../src/pagination/cursor.ts", "../src/pagination/page.ts", "../src/sync/index-diff.ts", "../src/sync/validator-diff.ts", "../src/sync/sync-collection.ts", "../src/repository/create-repository.ts", "../src/transaction/with-transaction.ts"],
4
4
  "sourcesContent": [
5
- "import type { IndexDescription, ObjectId } from 'mongodb';\nimport type { z } from 'zod';\n\n/** What MongoDB does with a document that fails the validator. */\nexport type ValidationAction = 'error' | 'warn';\n\n/**\n * Which documents the validator applies to. `off` writes no validator at all;\n * `moderate` exempts documents that were already invalid from updates.\n */\nexport type ValidationLevel = 'off' | 'moderate' | 'strict';\n\nexport interface ValidationConfig {\n\t/** Default `'strict'`. */\n\tlevel?: ValidationLevel;\n\t/** Default `'error'`. `'warn'` logs and lets the write through. */\n\taction?: ValidationAction;\n}\n\n/** What `defineCollection` takes. */\nexport interface CollectionConfig<Schema extends z.ZodObject> {\n\t/** The collection's name on the server. */\n\tname: string;\n\t/**\n\t * The documents, as they are stored: `z.output` is what a read gives back,\n\t * `z.input` what a write takes. It must have an `_id`.\n\t */\n\tschema: Schema;\n\t/** The indexes `sync` creates, as the driver describes them. */\n\tindexes?: readonly IndexDescription[];\n\t/** The `$jsonSchema` validator `sync` writes from the schema. */\n\tvalidation?: ValidationConfig;\n}\n\n/** A collection, as `defineCollection` returns it: frozen, with its defaults. */\nexport interface CollectionDefinition<Schema extends z.ZodObject = z.ZodObject>\n\textends Readonly<CollectionConfig<Schema>> {\n\treadonly indexes: readonly IndexDescription[];\n\treadonly validation: Required<ValidationConfig>;\n}\n\n/** Any definition, whatever its documents. */\nexport type AnyCollectionDefinition = CollectionDefinition<any>;\n\n/** The documents of a definition, as they are read back. */\nexport type DocumentOf<Def> = Def extends { schema: infer Schema }\n\t? Schema extends z.ZodType\n\t\t? z.output<Schema>\n\t\t: never\n\t: never;\n\n/** What a write takes: the documents before their defaults are filled. */\nexport type NewDocumentOf<Def> = Def extends { schema: infer Schema }\n\t? Schema extends z.ZodType\n\t\t? z.input<Schema>\n\t\t: never\n\t: never;\n\n/** The type of `_id`. */\nexport type IdOf<Def> =\n\tDocumentOf<Def> extends { _id: infer Id } ? Id : ObjectId;\n\n/** A field of the documents, as a top-level key. */\nexport type FieldOf<Def> = keyof DocumentOf<Def> & string;\n\n/**\n * Defines a collection: its name, the Zod schema of its documents, its\n * indexes, and how its validator is applied.\n *\n * The schema is the one source: it types every read and write, and `sync`\n * derives the collection's `$jsonSchema` validator from it.\n *\n * ```ts\n * export const users = defineCollection({\n * \tname: 'users',\n * \tschema: z.object({\n * \t\t_id: id(),\n * \t\temail: z.email(),\n * \t\t...timestamps(),\n * \t\t...softDelete(),\n * \t}),\n * \tindexes: [{ key: { email: 1 }, unique: true, name: 'users_email_unique' }],\n * });\n * ```\n */\nexport function defineCollection<Schema extends z.ZodObject>(\n\tconfig: CollectionConfig<Schema>,\n): CollectionDefinition<Schema> {\n\tif (!('_id' in config.schema.shape)) {\n\t\tthrow new TypeError(\n\t\t\t`defineCollection: \"${config.name}\"'s schema has no _id. Add ` +\n\t\t\t\t'`_id: id()`, which fills a new ObjectId on create, or declare the ' +\n\t\t\t\t'key your documents use.',\n\t\t);\n\t}\n\treturn Object.freeze({\n\t\t...config,\n\t\tindexes: Object.freeze([...(config.indexes ?? [])]),\n\t\tvalidation: Object.freeze({\n\t\t\tlevel: config.validation?.level ?? 'strict',\n\t\t\taction: config.validation?.action ?? 'error',\n\t\t}),\n\t}) as CollectionDefinition<Schema>;\n}\n\n/** Which of the fields the repository knows about a definition's schema has. */\nexport function stampsOf(definition: AnyCollectionDefinition): {\n\tcreatedAt: boolean;\n\tupdatedAt: boolean;\n\tdeletedAt: boolean;\n\tversion: boolean;\n\tcreatedBy: boolean;\n\tupdatedBy: boolean;\n\tdeletedBy: boolean;\n} {\n\tconst shape = definition.schema.shape as Record<string, unknown>;\n\tconst has = (name: string) => name in shape;\n\treturn {\n\t\tcreatedAt: has('createdAt'),\n\t\tupdatedAt: has('updatedAt'),\n\t\tdeletedAt: has('deletedAt'),\n\t\tversion: has('version'),\n\t\tcreatedBy: has('createdBy'),\n\t\tupdatedBy: has('updatedBy'),\n\t\tdeletedBy: has('deletedBy'),\n\t};\n}\n",
6
- "import { ObjectId } from 'mongodb';\nimport { z } from 'zod';\n\n/** An `ObjectId`, read without `instanceof`: two copies of the driver. */\nfunction isObjectId(value: unknown): value is ObjectId {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\t(value as { _bsontype?: unknown })._bsontype === 'ObjectId'\n\t);\n}\n\n/**\n * An `ObjectId`, declared to MongoDB as `bsonType: 'objectId'`. JSON Schema\n * has no type for one, so the metadata is how the validator learns of it.\n */\nexport function objectId() {\n\treturn z\n\t\t.custom<ObjectId>(isObjectId, { error: 'must be an ObjectId' })\n\t\t.meta({ bsonType: 'objectId' });\n}\n\n/**\n * `_id`, filled with a new `ObjectId` when a document is created: optional to\n * write, always there once read.\n */\nexport function id() {\n\treturn objectId().default(() => new ObjectId());\n}\n\n/**\n * `createdAt` and `updatedAt`, filled on create. A repository sets `updatedAt`\n * on every update.\n */\nexport function timestamps() {\n\treturn {\n\t\tcreatedAt: z.date().default(() => new Date()),\n\t\tupdatedAt: z.date().default(() => new Date()),\n\t};\n}\n\n/**\n * `deletedAt`, `null` while the document is live. A repository on a collection\n * with it soft-deletes, and leaves deleted documents out of every read.\n */\nexport function softDelete() {\n\treturn { deletedAt: z.date().nullable().default(null) };\n}\n\n/**\n * `version`, raised by one on every update. A repository with it takes\n * `expectedVersion` and throws `OptimisticLockError` when it no longer\n * matches.\n */\nexport function optimisticLock() {\n\treturn { version: z.int().nonnegative().default(0) };\n}\n\n/**\n * `createdBy`, `updatedBy` and `deletedBy`, stamped from the actor a\n * repository was given with `as(actor)`. The actor's own type is the schema\n * passed in, an `ObjectId` by default.\n */\nexport function actors<Actor extends z.ZodType = ReturnType<typeof objectId>>(\n\tactor: Actor = objectId() as unknown as Actor,\n) {\n\treturn {\n\t\tcreatedBy: actor.nullable().default(null),\n\t\tupdatedBy: actor.nullable().default(null),\n\t\tdeletedBy: actor.nullable().default(null),\n\t};\n}\n\n/** The fields the repository gives a meaning to, by name. */\nexport const STAMP_FIELDS = {\n\tid: '_id',\n\tcreatedAt: 'createdAt',\n\tupdatedAt: 'updatedAt',\n\tdeletedAt: 'deletedAt',\n\tversion: 'version',\n\tcreatedBy: 'createdBy',\n\tupdatedBy: 'updatedBy',\n\tdeletedBy: 'deletedBy',\n} as const;\n",
5
+ "import type { IndexDescription, IndexDirection, ObjectId } from 'mongodb';\nimport type { z } from 'zod';\n\n/** What MongoDB does with a document that fails the validator. */\nexport type ValidationAction = 'error' | 'warn';\n\n/**\n * Which documents the validator applies to. `off` writes no validator at all;\n * `moderate` exempts documents that were already invalid from updates.\n */\nexport type ValidationLevel = 'off' | 'moderate' | 'strict';\n\nexport interface ValidationConfig {\n\t/** Default `'strict'`. */\n\tlevel?: ValidationLevel;\n\t/** Default `'error'`. `'warn'` logs and lets the write through. */\n\taction?: ValidationAction;\n}\n\n/**\n * What an index may be keyed on: a field of the documents, which an editor\n * completes, or a path into one — `{ 'address.city': 1 }` is how MongoDB\n * indexes a nested field, and there is no way to check the tail of a path\n * against a schema without rejecting the paths Mongo allows.\n */\nexport type IndexKey<Doc> =\n\t| {\n\t\t\t[Field in\n\t\t\t\t| (keyof Doc & string)\n\t\t\t\t| `${keyof Doc & string}.${string}`]?: IndexDirection;\n\t }\n\t// The driver takes a `Map` too, and an index read back off the server comes\n\t// as one: refusing it here would refuse a definition built from a live one.\n\t| Map<string, IndexDirection>;\n\n/**\n * An index, keyed on the schema's own fields. Everything else — `unique`,\n * `name`, `collation`, `partialFilterExpression`, the TTL — is the driver's\n * `IndexDescription`, unchanged.\n */\nexport interface CollectionIndex<Doc> extends Omit<IndexDescription, 'key'> {\n\tkey: IndexKey<Doc>;\n}\n\n/** What `defineCollection` takes. */\nexport interface CollectionConfig<Schema extends z.ZodObject> {\n\t/** The collection's name on the server. */\n\tname: string;\n\t/**\n\t * The documents, as they are stored: `z.output` is what a read gives back,\n\t * `z.input` what a write takes. It must have an `_id`.\n\t */\n\tschema: Schema;\n\t/** The indexes `sync` creates, keyed on the schema's fields. */\n\tindexes?: readonly CollectionIndex<z.output<Schema>>[];\n\t/** The `$jsonSchema` validator `sync` writes from the schema. */\n\tvalidation?: ValidationConfig;\n}\n\n/** A collection, as `defineCollection` returns it: frozen, with its defaults. */\nexport interface CollectionDefinition<\n\tSchema extends z.ZodObject = z.ZodObject,\n> {\n\treadonly name: string;\n\treadonly schema: Schema;\n\t/** As the driver takes them: `sync` hands these straight to MongoDB. */\n\treadonly indexes: readonly IndexDescription[];\n\treadonly validation: Required<ValidationConfig>;\n}\n\n/** Any definition, whatever its documents. */\nexport type AnyCollectionDefinition = CollectionDefinition<any>;\n\n/** The documents of a definition, as they are read back. */\nexport type DocumentOf<Def> = Def extends { schema: infer Schema }\n\t? Schema extends z.ZodType\n\t\t? z.output<Schema>\n\t\t: never\n\t: never;\n\n/**\n * A document as a repository gives it back: the stored document, plus `id`.\n *\n * `id` is `_id` as a string, computed rather than stored — the collection\n * holds `_id` alone. It is enumerable, so `JSON.stringify` and a spread carry\n * it, which is what makes a document ready to return from an API; it is not\n * part of `DocumentOf`, so a filter or a patch cannot be keyed on it, because\n * the server would match nothing.\n */\nexport type ReadDocumentOf<Def> = DocumentOf<Def> & { readonly id: string };\n\n/** What a write takes: the documents before their defaults are filled. */\nexport type NewDocumentOf<Def> = Def extends { schema: infer Schema }\n\t? Schema extends z.ZodType\n\t\t? z.input<Schema>\n\t\t: never\n\t: never;\n\n/** The type of `_id`. */\nexport type IdOf<Def> =\n\tDocumentOf<Def> extends { _id: infer Id } ? Id : ObjectId;\n\n/** A field of the documents, as a top-level key. */\nexport type FieldOf<Def> = keyof DocumentOf<Def> & string;\n\n/**\n * Defines a collection: its name, the Zod schema of its documents, its\n * indexes, and how its validator is applied.\n *\n * The schema is the one source: it types every read and write, and `sync`\n * derives the collection's `$jsonSchema` validator from it.\n *\n * ```ts\n * export const users = defineCollection({\n * \tname: 'users',\n * \tschema: z.object({\n * \t\t_id: id(),\n * \t\temail: z.email(),\n * \t\t...timestamps(),\n * \t\t...softDelete(),\n * \t}),\n * \tindexes: [{ key: { email: 1 }, unique: true, name: 'users_email_unique' }],\n * });\n * ```\n */\nexport function defineCollection<Schema extends z.ZodObject>(\n\tconfig: CollectionConfig<Schema>,\n): CollectionDefinition<Schema> {\n\tif (!('_id' in config.schema.shape)) {\n\t\tthrow new TypeError(\n\t\t\t`defineCollection: \"${config.name}\"'s schema has no _id. Add ` +\n\t\t\t\t'`_id: id()`, which fills a new ObjectId on create, or declare the ' +\n\t\t\t\t'key your documents use.',\n\t\t);\n\t}\n\treturn Object.freeze({\n\t\t...config,\n\t\tindexes: Object.freeze([...(config.indexes ?? [])]),\n\t\tvalidation: Object.freeze({\n\t\t\tlevel: config.validation?.level ?? 'strict',\n\t\t\taction: config.validation?.action ?? 'error',\n\t\t}),\n\t}) as CollectionDefinition<Schema>;\n}\n\n/** Which of the fields the repository knows about a definition's schema has. */\nexport function stampsOf(definition: AnyCollectionDefinition): {\n\tcreatedAt: boolean;\n\tupdatedAt: boolean;\n\tdeletedAt: boolean;\n\tversion: boolean;\n\tcreatedBy: boolean;\n\tupdatedBy: boolean;\n\tdeletedBy: boolean;\n} {\n\tconst shape = definition.schema.shape as Record<string, unknown>;\n\tconst has = (name: string) => name in shape;\n\treturn {\n\t\tcreatedAt: has('createdAt'),\n\t\tupdatedAt: has('updatedAt'),\n\t\tdeletedAt: has('deletedAt'),\n\t\tversion: has('version'),\n\t\tcreatedBy: has('createdBy'),\n\t\tupdatedBy: has('updatedBy'),\n\t\tdeletedBy: has('deletedBy'),\n\t};\n}\n",
6
+ "import { ObjectId } from 'mongodb';\nimport { z } from 'zod';\nimport { isObjectId } from './object-id';\n\n/**\n * An `ObjectId`, declared to MongoDB as `bsonType: 'objectId'`. JSON Schema\n * has no type for one, so the metadata is how the validator learns of it.\n */\nexport function objectId() {\n\treturn z\n\t\t.custom<ObjectId>(isObjectId, { error: 'must be an ObjectId' })\n\t\t.meta({ bsonType: 'objectId' });\n}\n\n/**\n * `_id`, filled with a new `ObjectId` when a document is created: optional to\n * write, always there once read.\n */\nexport function id() {\n\treturn objectId().default(() => new ObjectId());\n}\n\n/**\n * `createdAt` and `updatedAt`, filled on create. A repository sets `updatedAt`\n * on every update.\n */\nexport function timestamps() {\n\treturn {\n\t\tcreatedAt: z.date().default(() => new Date()),\n\t\tupdatedAt: z.date().default(() => new Date()),\n\t};\n}\n\n/**\n * `deletedAt`, `null` while the document is live. A repository on a collection\n * with it soft-deletes, and leaves deleted documents out of every read.\n */\nexport function softDelete() {\n\treturn { deletedAt: z.date().nullable().default(null) };\n}\n\n/**\n * `version`, raised by one on every update. A repository with it takes\n * `expectedVersion` and throws `OptimisticLockError` when it no longer\n * matches.\n */\nexport function optimisticLock() {\n\treturn { version: z.int().nonnegative().default(0) };\n}\n\n/**\n * `createdBy`, `updatedBy` and `deletedBy`, stamped from the actor a\n * repository was given with `as(actor)`. The actor's own type is the schema\n * passed in, an `ObjectId` by default.\n */\nexport function actors<Actor extends z.ZodType = ReturnType<typeof objectId>>(\n\tactor: Actor = objectId() as unknown as Actor,\n) {\n\treturn {\n\t\tcreatedBy: actor.nullable().default(null),\n\t\tupdatedBy: actor.nullable().default(null),\n\t\tdeletedBy: actor.nullable().default(null),\n\t};\n}\n\n/** The fields the repository gives a meaning to, by name. */\nexport const STAMP_FIELDS = {\n\tid: '_id',\n\tcreatedAt: 'createdAt',\n\tupdatedAt: 'updatedAt',\n\tdeletedAt: 'deletedAt',\n\tversion: 'version',\n\tcreatedBy: 'createdBy',\n\tupdatedBy: 'updatedBy',\n\tdeletedBy: 'deletedBy',\n} as const;\n",
7
+ "import { ObjectId } from 'mongodb';\nimport { z } from 'zod';\nimport { InvalidIdError } from '../errors/data-error';\n\n/** The 24 hex characters an `ObjectId` is written as. */\nconst HEX_24 = /^[0-9a-fA-F]{24}$/;\n\n/**\n * An `ObjectId`, read by its BSON tag rather than with `instanceof`, which\n * answers `false` across two copies of the driver in one tree.\n */\nexport function isObjectId(value: unknown): value is ObjectId {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\t(value as { _bsontype?: unknown })._bsontype === 'ObjectId'\n\t);\n}\n\n/** Is this the 24-character hex string an `ObjectId` is written as? */\nexport function isObjectIdString(value: unknown): value is string {\n\treturn typeof value === 'string' && HEX_24.test(value);\n}\n\n/** An `ObjectId`, or a string that stands for one. */\nexport function isValidObjectId(value: unknown): boolean {\n\treturn isObjectId(value) || isObjectIdString(value);\n}\n\n/**\n * The `ObjectId` this value stands for, or `undefined`. Never throws.\n *\n * Prefer it to `new ObjectId(value)`, which **invents a fresh id** when it is\n * given `null` or `undefined` — a missing route parameter then reads as a\n * perfectly valid id that matches nothing.\n */\nexport function tryObjectId(value: unknown): ObjectId | undefined {\n\tif (isObjectId(value)) return value;\n\tif (isObjectIdString(value)) return ObjectId.createFromHexString(value);\n\treturn undefined;\n}\n\nfunction describe(value: unknown): string {\n\tif (value === null) return 'null';\n\tif (value === undefined) return 'undefined';\n\tif (typeof value === 'string') return `the string ${JSON.stringify(value)}`;\n\treturn `a ${typeof value}`;\n}\n\n/**\n * The `ObjectId` this value stands for. Throws `InvalidIdError` for anything\n * else, `null` and `undefined` included.\n *\n * ```ts\n * const user = await users.getById(toObjectId(request.params.id));\n * ```\n */\nexport function toObjectId(value: unknown, field = '_id'): ObjectId {\n\tconst made = tryObjectId(value);\n\tif (made) return made;\n\tthrow new InvalidIdError(\n\t\t`${field}: expected an ObjectId or its 24-character hex string, got ${describe(value)}`,\n\t\t{ id: value, keys: [field] },\n\t);\n}\n\n/**\n * The same, for a list — a `$in` filter built from query parameters.\n *\n * ```ts\n * await users.findMany({ filter: { _id: { $in: toObjectIds(ids) } } });\n * ```\n */\nexport function toObjectIds(\n\tvalues: Iterable<unknown>,\n\tfield = '_id',\n): ObjectId[] {\n\treturn [...values].map((value) => toObjectId(value, field));\n}\n\n/**\n * A Zod schema for an id that arrives from outside: it takes an `ObjectId` or\n * its hex string and gives back an `ObjectId`.\n *\n * It belongs in the schema of a route's parameters, **not** in a collection's:\n * a field that parses one type into another has no honest `$jsonSchema`, and\n * what a collection stores is `objectId()`.\n *\n * ```ts\n * const params = z.object({ id: objectIdParam() });\n * const { id } = params.parse(request.params); // ObjectId\n * ```\n */\nexport function objectIdParam() {\n\treturn z\n\t\t.custom<ObjectId | string>(isValidObjectId, {\n\t\t\terror: 'must be an ObjectId or its 24-character hex string',\n\t\t})\n\t\t.transform((value) => toObjectId(value));\n}\n",
8
+ "/** What went wrong, as a string a caller can switch on. */\nexport type DataErrorCode =\n\t| 'DATABASE'\n\t| 'NOT_FOUND'\n\t| 'CONFLICT'\n\t| 'VALIDATION'\n\t| 'OPTIMISTIC_LOCK'\n\t| 'INVALID_CURSOR'\n\t| 'INVALID_ID';\n\n/** One reason a document failed the collection's `$jsonSchema` validator. */\nexport interface ValidationIssue {\n\t/** The dotted path of the field, empty for the document itself. */\n\tpath: string;\n\t/** The rule it broke: `bsonType`, `required`, `minimum`… */\n\treason: string;\n\t/** What the schema asked for, as MongoDB reports it. */\n\tspecifiedAs?: unknown;\n\t/** The value that was refused, when the server names it. */\n\tconsideredValue?: unknown;\n\t/** Its BSON type, when the server names it: `string`, `int`, `double`… */\n\tconsideredType?: string;\n\t/** The schema's `description` for the field, when it has one. */\n\tdescription?: string;\n}\n\nexport interface DataErrorOptions {\n\tcollection?: string | undefined;\n\t/** The `_id` a method by id was given. */\n\tid?: unknown;\n\t/** MongoDB's numeric error code: 11000, 121, 26… */\n\tserverCode?: number | undefined;\n\t/** MongoDB's `codeName`, which write errors do not carry. */\n\tserverCodeName?: string | undefined;\n\t/** The index a conflict names, when the server names one. */\n\tindex?: string | undefined;\n\t/** The fields the error is about: an index's keys, or a validator's paths. */\n\tkeys?: string[];\n\t/** Those fields' values, when the server gives them. */\n\tvalues?: Record<string, unknown> | undefined;\n\tissues?: ValidationIssue[];\n\texpectedVersion?: number | undefined;\n\tactualVersion?: number | undefined;\n\tcause?: unknown;\n}\n\n/**\n * What this package throws. Every method turns a driver error into one of\n * these, so an application catches `ConflictError` instead of reading `11000`\n * off an error whose shape changes with the operation that produced it.\n *\n * A driver error that is none of them reaches the caller as it is.\n */\nexport class DataError extends Error {\n\toverride name = 'DataError';\n\treadonly code: DataErrorCode = 'DATABASE';\n\treadonly collection: string | undefined;\n\treadonly id: unknown;\n\treadonly serverCode: number | undefined;\n\treadonly serverCodeName: string | undefined;\n\treadonly index: string | undefined;\n\treadonly keys: string[];\n\treadonly values: Record<string, unknown> | undefined;\n\treadonly issues: ValidationIssue[];\n\treadonly expectedVersion: number | undefined;\n\treadonly actualVersion: number | undefined;\n\n\tconstructor(message = 'Database error', options: DataErrorOptions = {}) {\n\t\tsuper(\n\t\t\tmessage,\n\t\t\toptions.cause === undefined ? undefined : { cause: options.cause },\n\t\t);\n\t\tthis.collection = options.collection;\n\t\tthis.id = options.id;\n\t\tthis.serverCode = options.serverCode;\n\t\tthis.serverCodeName = options.serverCodeName;\n\t\tthis.index = options.index;\n\t\tthis.keys = options.keys ?? [];\n\t\tthis.values = options.values;\n\t\tthis.issues = options.issues ?? [];\n\t\tthis.expectedVersion = options.expectedVersion;\n\t\tthis.actualVersion = options.actualVersion;\n\t}\n}\n\n/** No document matched, where one was required. */\nexport class NotFoundError extends DataError {\n\toverride name = 'NotFoundError';\n\toverride readonly code = 'NOT_FOUND' as const;\n\n\tconstructor(message = 'Not found', options: DataErrorOptions = {}) {\n\t\tsuper(message, options);\n\t}\n}\n\n/** A unique index refused the write: MongoDB's `E11000`. */\nexport class ConflictError extends DataError {\n\toverride name = 'ConflictError';\n\toverride readonly code = 'CONFLICT' as const;\n\n\tconstructor(message = 'Duplicate key', options: DataErrorOptions = {}) {\n\t\tsuper(message, { serverCode: 11000, ...options });\n\t}\n}\n\n/** The collection's `$jsonSchema` validator refused the document: code 121. */\nexport class ValidationError extends DataError {\n\toverride name = 'ValidationError';\n\toverride readonly code = 'VALIDATION' as const;\n\n\tconstructor(\n\t\tmessage = 'Document failed validation',\n\t\toptions: DataErrorOptions = {},\n\t) {\n\t\tsuper(message, { serverCode: 121, ...options });\n\t}\n}\n\n/**\n * The document changed since it was read: its `version` is no longer the one\n * the update expected, and nothing was written.\n */\nexport class OptimisticLockError extends DataError {\n\toverride name = 'OptimisticLockError';\n\toverride readonly code = 'OPTIMISTIC_LOCK' as const;\n\n\tconstructor(message = 'Version conflict', options: DataErrorOptions = {}) {\n\t\tsuper(message, options);\n\t}\n}\n\n/**\n * A value that is not an `ObjectId` and not the string of one.\n *\n * It is a `DataError` rather than a `TypeError` because it is usually data,\n * not a mistake in the code: an id off a URL or a form reaches `toObjectId`,\n * and a handler wants to answer 400 or 404 rather than crash.\n */\nexport class InvalidIdError extends DataError {\n\toverride name = 'InvalidIdError';\n\toverride readonly code = 'INVALID_ID' as const;\n\n\tconstructor(message = 'Invalid id', options: DataErrorOptions = {}) {\n\t\tsuper(message, options);\n\t}\n}\n\n/** A cursor this package did not write, or one for another ordering. */\nexport class InvalidCursorError extends DataError {\n\toverride name = 'InvalidCursorError';\n\toverride readonly code = 'INVALID_CURSOR' as const;\n\n\tconstructor(message = 'Invalid cursor', options: DataErrorOptions = {}) {\n\t\tsuper(message, options);\n\t}\n}\n",
7
9
  "import { z } from 'zod';\n\n/**\n * Every keyword MongoDB's `$jsonSchema` knows. It **rejects** a document that\n * uses any other, rather than ignoring it, so anything not in here is dropped\n * on the way out.\n */\nexport const MONGO_JSON_SCHEMA_KEYWORDS: ReadonlySet<string> = new Set([\n\t'additionalItems',\n\t'additionalProperties',\n\t'allOf',\n\t'anyOf',\n\t'bsonType',\n\t'dependencies',\n\t'description',\n\t'enum',\n\t'exclusiveMaximum',\n\t'exclusiveMinimum',\n\t'items',\n\t'maxItems',\n\t'maxLength',\n\t'maxProperties',\n\t'maximum',\n\t'minItems',\n\t'minLength',\n\t'minProperties',\n\t'minimum',\n\t'multipleOf',\n\t'not',\n\t'oneOf',\n\t'pattern',\n\t'patternProperties',\n\t'properties',\n\t'required',\n\t'title',\n\t'type',\n\t'uniqueItems',\n]);\n\n/** Keywords whose value is a map of names to schemas, not a schema. */\nconst SCHEMA_MAPS = new Set([\n\t'properties',\n\t'patternProperties',\n\t'dependencies',\n]);\n\ntype Node = Record<string, unknown>;\n\nfunction isRecord(value: unknown): value is Node {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * A JavaScript number reaches BSON as an `int` when it is a whole number that\n * fits in 32 bits, and as a `double` otherwise — never as a `long`, unless the\n * caller wrapped it. `type: \"integer\"`, which MongoDB has no equivalent for,\n * therefore becomes the three types a whole number can arrive as, with\n * `multipleOf: 1` to refuse a fractional double.\n */\nconst INTEGER_BSON_TYPES = ['int', 'long', 'double'];\n\nfunction convertIntegerType(node: Node): void {\n\tconst type = node.type;\n\tif (type === 'integer') {\n\t\tdelete node.type;\n\t\tnode.bsonType = [...INTEGER_BSON_TYPES];\n\t\tnode.multipleOf ??= 1;\n\t\treturn;\n\t}\n\tif (Array.isArray(type) && type.includes('integer')) {\n\t\tdelete node.type;\n\t\tnode.bsonType = [\n\t\t\t...type.filter((one) => one !== 'integer'),\n\t\t\t...INTEGER_BSON_TYPES,\n\t\t];\n\t\tnode.multipleOf ??= 1;\n\t}\n}\n\nfunction refName(ref: string): string {\n\treturn ref.replace(/^#\\/(definitions|\\$defs)\\//, '');\n}\n\nfunction inline(value: unknown, defs: Node, stack: string[]): unknown {\n\tif (Array.isArray(value)) {\n\t\treturn value.map((one) => inline(one, defs, stack));\n\t}\n\tif (!isRecord(value)) return value;\n\n\tif (typeof value.$ref === 'string') {\n\t\tconst name = refName(value.$ref);\n\t\tif (stack.includes(name)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`toMongoJsonSchema: \"${name}\" refers to itself. MongoDB's $jsonSchema ` +\n\t\t\t\t\t'has no $ref, so a recursive schema cannot be a validator. Give the ' +\n\t\t\t\t\t'collection no validator, or model the field as an object with no ' +\n\t\t\t\t\t'schema of its own.',\n\t\t\t);\n\t\t}\n\t\tconst target = defs[name];\n\t\tif (!isRecord(target)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`toMongoJsonSchema: cannot resolve ${value.$ref}, which zod emitted`,\n\t\t\t);\n\t\t}\n\t\tconst { $ref: _ref, ...siblings } = value;\n\t\treturn {\n\t\t\t...(inline(target, defs, [...stack, name]) as Node),\n\t\t\t...(inline(siblings, defs, stack) as Node),\n\t\t};\n\t}\n\n\tconst out: Node = {};\n\tfor (const [key, inner] of Object.entries(value)) {\n\t\tif (!MONGO_JSON_SCHEMA_KEYWORDS.has(key)) continue;\n\t\tif (SCHEMA_MAPS.has(key) && isRecord(inner)) {\n\t\t\tconst mapped: Node = {};\n\t\t\tfor (const [name, schema] of Object.entries(inner)) {\n\t\t\t\tmapped[name] = inline(schema, defs, stack);\n\t\t\t}\n\t\t\tout[key] = mapped;\n\t\t\tcontinue;\n\t\t}\n\t\tout[key] = inline(inner, defs, stack);\n\t}\n\tconvertIntegerType(out);\n\treturn out;\n}\n\n/**\n * A Zod schema as a MongoDB `$jsonSchema`, ready for a collection's validator.\n *\n * `z.toJSONSchema` alone is not one: MongoDB rejects `$schema`, `$ref`,\n * `definitions`, `default`, `format` and `id`, has no `integer` type, and\n * treats a keyword it does not know as an error rather than ignoring it. This\n * resolves every `$ref` by inlining it, keeps only the keywords MongoDB\n * knows, and maps `integer`.\n *\n * `Date` and `ObjectId` have no JSON Schema type: they are declared with\n * `bsonType`, which `date()` and `objectId()` already carry in their metadata.\n * Any schema can do the same with `.meta({ bsonType: 'decimal' })`.\n *\n * ```ts\n * toMongoJsonSchema(z.object({ _id: objectId(), email: z.string() }));\n * // { type: 'object', properties: { … }, required: ['_id', 'email'], … }\n * ```\n */\nexport function toMongoJsonSchema(schema: z.ZodType): Record<string, unknown> {\n\tconst json = z.toJSONSchema(schema, {\n\t\ttarget: 'draft-4',\n\t\tio: 'output',\n\t\t// A `Date` is unrepresentable in JSON Schema; the override below gives\n\t\t// it a bsonType instead, and `{}` is what it starts from.\n\t\tunrepresentable: 'any',\n\t\toverride: (ctx) => {\n\t\t\tconst type = (ctx.zodSchema as { _zod: { def: { type: string } } })._zod\n\t\t\t\t.def.type;\n\t\t\tif (type === 'date' && ctx.jsonSchema.bsonType === undefined) {\n\t\t\t\tctx.jsonSchema.bsonType = 'date';\n\t\t\t}\n\t\t},\n\t}) as Node;\n\n\tconst definitions = isRecord(json.definitions)\n\t\t? json.definitions\n\t\t: isRecord(json.$defs)\n\t\t\t? json.$defs\n\t\t\t: {};\n\treturn inline(json, definitions, []) as Record<string, unknown>;\n}\n",
8
- "/** What went wrong, as a string a caller can switch on. */\nexport type DataErrorCode =\n\t| 'DATABASE'\n\t| 'NOT_FOUND'\n\t| 'CONFLICT'\n\t| 'VALIDATION'\n\t| 'OPTIMISTIC_LOCK'\n\t| 'INVALID_CURSOR';\n\n/** One reason a document failed the collection's `$jsonSchema` validator. */\nexport interface ValidationIssue {\n\t/** The dotted path of the field, empty for the document itself. */\n\tpath: string;\n\t/** The rule it broke: `bsonType`, `required`, `minimum`… */\n\treason: string;\n\t/** What the schema asked for, as MongoDB reports it. */\n\tspecifiedAs?: unknown;\n\t/** The value that was refused, when the server names it. */\n\tconsideredValue?: unknown;\n\t/** Its BSON type, when the server names it: `string`, `int`, `double`… */\n\tconsideredType?: string;\n\t/** The schema's `description` for the field, when it has one. */\n\tdescription?: string;\n}\n\nexport interface DataErrorOptions {\n\tcollection?: string | undefined;\n\t/** The `_id` a method by id was given. */\n\tid?: unknown;\n\t/** MongoDB's numeric error code: 11000, 121, 26… */\n\tserverCode?: number | undefined;\n\t/** MongoDB's `codeName`, which write errors do not carry. */\n\tserverCodeName?: string | undefined;\n\t/** The index a conflict names, when the server names one. */\n\tindex?: string | undefined;\n\t/** The fields the error is about: an index's keys, or a validator's paths. */\n\tkeys?: string[];\n\t/** Those fields' values, when the server gives them. */\n\tvalues?: Record<string, unknown> | undefined;\n\tissues?: ValidationIssue[];\n\texpectedVersion?: number | undefined;\n\tactualVersion?: number | undefined;\n\tcause?: unknown;\n}\n\n/**\n * What this package throws. Every method turns a driver error into one of\n * these, so an application catches `ConflictError` instead of reading `11000`\n * off an error whose shape changes with the operation that produced it.\n *\n * A driver error that is none of them reaches the caller as it is.\n */\nexport class DataError extends Error {\n\toverride name = 'DataError';\n\treadonly code: DataErrorCode = 'DATABASE';\n\treadonly collection: string | undefined;\n\treadonly id: unknown;\n\treadonly serverCode: number | undefined;\n\treadonly serverCodeName: string | undefined;\n\treadonly index: string | undefined;\n\treadonly keys: string[];\n\treadonly values: Record<string, unknown> | undefined;\n\treadonly issues: ValidationIssue[];\n\treadonly expectedVersion: number | undefined;\n\treadonly actualVersion: number | undefined;\n\n\tconstructor(message = 'Database error', options: DataErrorOptions = {}) {\n\t\tsuper(\n\t\t\tmessage,\n\t\t\toptions.cause === undefined ? undefined : { cause: options.cause },\n\t\t);\n\t\tthis.collection = options.collection;\n\t\tthis.id = options.id;\n\t\tthis.serverCode = options.serverCode;\n\t\tthis.serverCodeName = options.serverCodeName;\n\t\tthis.index = options.index;\n\t\tthis.keys = options.keys ?? [];\n\t\tthis.values = options.values;\n\t\tthis.issues = options.issues ?? [];\n\t\tthis.expectedVersion = options.expectedVersion;\n\t\tthis.actualVersion = options.actualVersion;\n\t}\n}\n\n/** No document matched, where one was required. */\nexport class NotFoundError extends DataError {\n\toverride name = 'NotFoundError';\n\toverride readonly code = 'NOT_FOUND' as const;\n\n\tconstructor(message = 'Not found', options: DataErrorOptions = {}) {\n\t\tsuper(message, options);\n\t}\n}\n\n/** A unique index refused the write: MongoDB's `E11000`. */\nexport class ConflictError extends DataError {\n\toverride name = 'ConflictError';\n\toverride readonly code = 'CONFLICT' as const;\n\n\tconstructor(message = 'Duplicate key', options: DataErrorOptions = {}) {\n\t\tsuper(message, { serverCode: 11000, ...options });\n\t}\n}\n\n/** The collection's `$jsonSchema` validator refused the document: code 121. */\nexport class ValidationError extends DataError {\n\toverride name = 'ValidationError';\n\toverride readonly code = 'VALIDATION' as const;\n\n\tconstructor(\n\t\tmessage = 'Document failed validation',\n\t\toptions: DataErrorOptions = {},\n\t) {\n\t\tsuper(message, { serverCode: 121, ...options });\n\t}\n}\n\n/**\n * The document changed since it was read: its `version` is no longer the one\n * the update expected, and nothing was written.\n */\nexport class OptimisticLockError extends DataError {\n\toverride name = 'OptimisticLockError';\n\toverride readonly code = 'OPTIMISTIC_LOCK' as const;\n\n\tconstructor(message = 'Version conflict', options: DataErrorOptions = {}) {\n\t\tsuper(message, options);\n\t}\n}\n\n/** A cursor this package did not write, or one for another ordering. */\nexport class InvalidCursorError extends DataError {\n\toverride name = 'InvalidCursorError';\n\toverride readonly code = 'INVALID_CURSOR' as const;\n\n\tconstructor(message = 'Invalid cursor', options: DataErrorOptions = {}) {\n\t\tsuper(message, options);\n\t}\n}\n",
9
10
  "import {\n\tConflictError,\n\tDataError,\n\ttype DataErrorOptions,\n\tValidationError,\n\ttype ValidationIssue,\n} from './data-error';\n\ntype Record_ = Record<string, unknown>;\n\nfunction isRecord(value: unknown): value is Record_ {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction asArray(value: unknown): unknown[] {\n\tif (Array.isArray(value)) return value;\n\treturn value === undefined || value === null ? [] : [value];\n}\n\nfunction text(value: unknown): string | undefined {\n\treturn typeof value === 'string' ? value : undefined;\n}\n\n/**\n * The index a duplicate key names. The message is the only place it is:\n * `E11000 duplicate key error collection: db.users index: users_email_unique\n * dup key: { email: \"a@b.c\" }`.\n */\nfunction indexFromMessage(message: string | undefined): string | undefined {\n\treturn message?.match(/index:\\s*(\\S+)\\s+dup key/)?.[1];\n}\n\n/**\n * The keys of a duplicate key. `keyPattern` carries them for a single write;\n * a bulk write carries neither it nor `keyValue`, and the message is all there\n * is: `dup key: { email: \"a@b.c\", tenant: 1 }`.\n */\nfunction keysOfDuplicate(error: Record_): {\n\tkeys: string[];\n\tvalues: Record_ | undefined;\n} {\n\tconst pattern = error.keyPattern;\n\tif (isRecord(pattern)) {\n\t\tconst values = isRecord(error.keyValue) ? error.keyValue : undefined;\n\t\treturn { keys: Object.keys(pattern), values };\n\t}\n\tconst inMessage = text(error.errmsg)?.match(/dup key:\\s*\\{([^}]*)\\}/)?.[1];\n\tif (!inMessage) return { keys: [], values: undefined };\n\tconst keys = [...inMessage.matchAll(/([\\w.$]+)\\s*:/g)].map(\n\t\t(match) => match[1] as string,\n\t);\n\treturn { keys, values: undefined };\n}\n\n/** The first write error of a bulk result, which may be one object or a list. */\nfunction firstWriteError(error: Record_): Record_ | undefined {\n\tfor (const write of asArray(error.writeErrors)) {\n\t\t// The driver wraps each one; its fields sit on `err` there.\n\t\tconst inner = isRecord(write) && isRecord(write.err) ? write.err : write;\n\t\tif (isRecord(inner)) return inner;\n\t}\n\treturn undefined;\n}\n\n/**\n * The issues of a `$jsonSchema` failure, from `errInfo.details`. The server\n * nests them: `schemaRulesNotSatisfied` holds `propertiesNotSatisfied`, whose\n * `details` hold either leaf rules or another level of properties.\n */\nfunction issuesOf(details: unknown, path: string[] = []): ValidationIssue[] {\n\tconst issues: ValidationIssue[] = [];\n\tfor (const rule of asArray(details)) {\n\t\tif (!isRecord(rule)) continue;\n\n\t\tif (rule.propertiesNotSatisfied !== undefined) {\n\t\t\tfor (const property of asArray(rule.propertiesNotSatisfied)) {\n\t\t\t\tif (!isRecord(property)) continue;\n\t\t\t\tconst name = text(property.propertyName) ?? '';\n\t\t\t\tconst nested = issuesOf(property.details, [...path, name]);\n\t\t\t\tconst description = text(property.description);\n\t\t\t\tissues.push(\n\t\t\t\t\t...(description === undefined\n\t\t\t\t\t\t? nested\n\t\t\t\t\t\t: nested.map((issue) => ({ description, ...issue }))),\n\t\t\t\t);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (rule.missingProperties !== undefined) {\n\t\t\tfor (const missing of asArray(rule.missingProperties)) {\n\t\t\t\tissues.push({\n\t\t\t\t\tpath: [...path, String(missing)].join('.'),\n\t\t\t\t\treason: 'required',\n\t\t\t\t\tspecifiedAs: rule.specifiedAs,\n\t\t\t\t});\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (rule.schemaRulesNotSatisfied !== undefined) {\n\t\t\tissues.push(...issuesOf(rule.schemaRulesNotSatisfied, path));\n\t\t\tcontinue;\n\t\t}\n\n\t\tissues.push({\n\t\t\tpath: path.join('.'),\n\t\t\treason: text(rule.reason) ?? text(rule.operatorName) ?? 'invalid',\n\t\t\t...(rule.specifiedAs === undefined\n\t\t\t\t? {}\n\t\t\t\t: { specifiedAs: rule.specifiedAs }),\n\t\t\t...(rule.consideredValue === undefined\n\t\t\t\t? {}\n\t\t\t\t: { consideredValue: rule.consideredValue }),\n\t\t\t...(text(rule.consideredType) === undefined\n\t\t\t\t? {}\n\t\t\t\t: { consideredType: text(rule.consideredType) }),\n\t\t});\n\t}\n\treturn issues;\n}\n\n/**\n * A MongoDB error as one of this package's, or the error itself when it is\n * none of them.\n *\n * It reads the error's fields rather than its class: a duplicate key arrives\n * as a `MongoServerError` with `keyPattern` from `insertOne`, and as a\n * `MongoBulkWriteError` whose `writeErrors` carry neither `keyPattern` nor\n * `keyValue` from `insertMany` and `bulkWrite`. Both become a `ConflictError`\n * with the same fields. Reading fields also survives two copies of the driver\n * in one tree, where `instanceof` does not.\n */\nexport function toDataError(\n\terror: unknown,\n\tcontext: { collection?: string | undefined } = {},\n): unknown {\n\tif (error instanceof DataError) return error;\n\tif (!isRecord(error)) return error;\n\n\t// A bulk write carries the detail on its write errors, and only a message\n\t// at the top; a single write carries everything at the top.\n\tconst source = firstWriteError(error) ?? error;\n\tconst code =\n\t\ttypeof source.code === 'number'\n\t\t\t? source.code\n\t\t\t: typeof error.code === 'number'\n\t\t\t\t? error.code\n\t\t\t\t: undefined;\n\tif (typeof code !== 'number') return error;\n\n\tconst message =\n\t\ttext(source.errmsg) ??\n\t\ttext(source.message) ??\n\t\ttext((error as { message?: unknown }).message) ??\n\t\t'';\n\tconst common: DataErrorOptions = {\n\t\tcollection: context.collection,\n\t\tserverCode: code,\n\t\tserverCodeName: text(error.codeName) ?? text(source.codeName),\n\t\tcause: error,\n\t};\n\n\tif (code === 11000) {\n\t\tconst { keys, values } = keysOfDuplicate(source);\n\t\tconst index = indexFromMessage(message);\n\t\tconst named =\n\t\t\tkeys.length > 0 ? keys.join(', ') : (index ?? 'a unique index');\n\t\treturn new ConflictError(\n\t\t\t`Duplicate key on ${named}${\n\t\t\t\tcontext.collection ? ` in \"${context.collection}\"` : ''\n\t\t\t}`,\n\t\t\t{ ...common, index, keys, values },\n\t\t);\n\t}\n\n\tif (code === 121) {\n\t\tconst errInfo = isRecord(source.errInfo) ? source.errInfo : undefined;\n\t\tconst issues = issuesOf(errInfo?.details);\n\t\treturn new ValidationError(\n\t\t\t`Document failed validation${\n\t\t\t\tcontext.collection ? ` in \"${context.collection}\"` : ''\n\t\t\t}${issues.length > 0 ? `: ${issues.map((i) => `${i.path} ${i.reason}`).join(', ')}` : ''}`,\n\t\t\t{ ...common, issues, keys: issues.map((issue) => issue.path) },\n\t\t);\n\t}\n\n\treturn new DataError(message || `MongoDB error ${code}`, common);\n}\n",
10
11
  "import { ObjectId } from 'mongodb';\nimport { InvalidCursorError } from '../errors/data-error';\n\n/** What a cursor holds: the ordering values of the last document of a page. */\nexport interface CursorPayload {\n\t/** The ordering it was written for: `<field>:<asc|desc>`. */\n\treadonly key: string;\n\treadonly values: readonly unknown[];\n}\n\n/** An `ObjectId`, read without `instanceof`: two copies of the driver. */\nfunction isObjectId(value: unknown): value is ObjectId {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\t(value as { _bsontype?: unknown })._bsontype === 'ObjectId'\n\t);\n}\n\n// JSON has no Date, no bigint and no ObjectId, and a cursor must give back the\n// very value it was written from: a Date compares with a date field, an\n// ObjectId with `_id`. `JSON.stringify` has already called `toJSON` by the time\n// the replacer runs, so the raw value is read off `this`.\nfunction replacer(this: Record<string, unknown>, key: string, value: unknown) {\n\tconst raw = this[key];\n\tif (raw instanceof Date) return { $date: raw.toISOString() };\n\tif (typeof raw === 'bigint') return { $bigint: raw.toString() };\n\tif (isObjectId(raw)) return { $oid: raw.toHexString() };\n\treturn value;\n}\n\nfunction reviver(_key: string, value: unknown): unknown {\n\tif (value && typeof value === 'object' && !Array.isArray(value)) {\n\t\tconst keys = Object.keys(value);\n\t\tif (keys.length === 1) {\n\t\t\tconst tagged = value as {\n\t\t\t\t$date?: unknown;\n\t\t\t\t$bigint?: unknown;\n\t\t\t\t$oid?: unknown;\n\t\t\t};\n\t\t\tif (typeof tagged.$date === 'string') return new Date(tagged.$date);\n\t\t\tif (typeof tagged.$bigint === 'string') return BigInt(tagged.$bigint);\n\t\t\tif (typeof tagged.$oid === 'string') return new ObjectId(tagged.$oid);\n\t\t}\n\t}\n\treturn value;\n}\n\nfunction toBase64Url(text: string): string {\n\tlet binary = '';\n\tfor (const byte of new TextEncoder().encode(text)) {\n\t\tbinary += String.fromCharCode(byte);\n\t}\n\treturn btoa(binary)\n\t\t.replace(/\\+/g, '-')\n\t\t.replace(/\\//g, '_')\n\t\t.replace(/=+$/, '');\n}\n\nfunction fromBase64Url(text: string): string {\n\tconst base64 = text.replace(/-/g, '+').replace(/_/g, '/');\n\tconst binary = atob(base64 + '='.repeat((4 - (base64.length % 4)) % 4));\n\treturn new TextDecoder().decode(\n\t\tUint8Array.from(binary, (char) => char.charCodeAt(0)),\n\t);\n}\n\n/**\n * Writes an opaque, URL-safe cursor. `Date`, `bigint` and `ObjectId` values\n * survive the round trip. It is encoded, not signed: a client can read it,\n * and forge one.\n */\nexport function encodeCursor(payload: CursorPayload): string {\n\treturn toBase64Url(JSON.stringify([payload.key, payload.values], replacer));\n}\n\n/**\n * Reads a cursor `encodeCursor` wrote. Throws `InvalidCursorError` for\n * anything else, and for a cursor written for another ordering when\n * `expectedKey` is given.\n */\nexport function decodeCursor(\n\tcursor: string,\n\texpectedKey?: string,\n): CursorPayload {\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(fromBase64Url(cursor), reviver);\n\t} catch (cause) {\n\t\tthrow new InvalidCursorError('Invalid cursor: it cannot be decoded', {\n\t\t\tcause,\n\t\t});\n\t}\n\tif (\n\t\t!Array.isArray(parsed) ||\n\t\tparsed.length !== 2 ||\n\t\ttypeof parsed[0] !== 'string' ||\n\t\t!Array.isArray(parsed[1])\n\t) {\n\t\tthrow new InvalidCursorError('Invalid cursor: unexpected shape');\n\t}\n\tconst [key, values] = parsed as [string, unknown[]];\n\tif (expectedKey !== undefined && key !== expectedKey) {\n\t\tthrow new InvalidCursorError(\n\t\t\t`Invalid cursor: it was written for the ordering ${key}, not ${expectedKey}`,\n\t\t);\n\t}\n\treturn { key, values };\n}\n",
11
12
  "/** One page of an offset pagination. */\nexport interface Page<T> {\n\titems: T[];\n\t/** Every document that matches, across all pages. */\n\ttotal: number;\n\t/** 1-based. */\n\tpage: number;\n\tpageSize: number;\n\t/** `Math.ceil(total / pageSize)`: 0 when nothing matches. */\n\tpageCount: number;\n}\n\n/** One page of a cursor pagination. */\nexport interface CursorPage<T> {\n\titems: T[];\n\t/** Pass it as `after` for the next page; `null` on the last one. */\n\tnextCursor: string | null;\n}\n\nexport interface PageOptions {\n\t/** 1-based. Default `1`. */\n\tpage?: number;\n\t/** Default `20`, at most `maxPageSize`. */\n\tpageSize?: number;\n}\n\nexport interface PageWindow {\n\tpage: number;\n\tpageSize: number;\n\tlimit: number;\n\tskip: number;\n}\n\nexport const DEFAULT_PAGE_SIZE = 20;\nexport const DEFAULT_MAX_PAGE_SIZE = 100;\n\nfunction positiveInteger(name: string, value: number): number {\n\tif (!Number.isInteger(value) || value < 1) {\n\t\tthrow new RangeError(\n\t\t\t`${name} must be an integer of at least 1, not ${value}`,\n\t\t);\n\t}\n\treturn value;\n}\n\n/**\n * Checks `page` and `pageSize` and turns them into a `limit` and a `skip`.\n * A `pageSize` above `maxPageSize` is lowered to it; one that is not a\n * positive integer throws a `RangeError`.\n */\nexport function pageWindow(\n\toptions: PageOptions = {},\n\tmaxPageSize = DEFAULT_MAX_PAGE_SIZE,\n): PageWindow {\n\tconst page = positiveInteger('page', options.page ?? 1);\n\tconst pageSize = Math.min(\n\t\tpositiveInteger('pageSize', options.pageSize ?? DEFAULT_PAGE_SIZE),\n\t\tmaxPageSize,\n\t);\n\treturn { page, pageSize, limit: pageSize, skip: (page - 1) * pageSize };\n}\n\n/** Assembles a `Page` from its documents and the total. */\nexport function toPage<T>(\n\titems: T[],\n\ttotal: number,\n\twindow: PageWindow,\n): Page<T> {\n\treturn {\n\t\titems,\n\t\ttotal,\n\t\tpage: window.page,\n\t\tpageSize: window.pageSize,\n\t\tpageCount: Math.ceil(total / window.pageSize),\n\t};\n}\n\n/** Checks a cursor page's `limit`, as `pageWindow` checks a `pageSize`. */\nexport function cursorLimit(\n\tlimit: number | undefined,\n\tmaxPageSize = DEFAULT_MAX_PAGE_SIZE,\n): number {\n\treturn Math.min(\n\t\tpositiveInteger('limit', limit ?? DEFAULT_PAGE_SIZE),\n\t\tmaxPageSize,\n\t);\n}\n",
12
13
  "import type { IndexDescription, IndexDescriptionInfo } from 'mongodb';\n\n/**\n * What MongoDB fills a collation in with. It reads an index's collation back\n * canonical — every field, plus the ICU `version` — so a wanted collation is\n * compared against its own defaults, and `version` is left out: it changes\n * with the server's ICU, and recreating every index over it would be absurd.\n */\nconst COLLATION_DEFAULTS: Record<string, unknown> = {\n\tcaseLevel: false,\n\tcaseFirst: 'off',\n\tstrength: 3,\n\tnumericOrdering: false,\n\talternate: 'non-ignorable',\n\tmaxVariable: 'punct',\n\tnormalization: false,\n\tbackwards: false,\n};\n\n/**\n * Options the server does not read back when they are false, but does when\n * they were sent explicitly. Compared against the default either way.\n */\nconst OPTION_DEFAULTS: Record<string, unknown> = {\n\tunique: false,\n\tsparse: false,\n\thidden: false,\n\tbackground: false,\n};\n\n/** Never part of an index's identity: the server's own bookkeeping. */\nconst IGNORED = new Set(['v', 'ns', 'key', 'name']);\n\ntype Fields = Record<string, unknown>;\n\nfunction keyOf(index: IndexDescription | IndexDescriptionInfo): Fields {\n\tconst key = index.key;\n\treturn key instanceof Map ? Object.fromEntries(key) : { ...key };\n}\n\n/**\n * The name MongoDB gives an index that names none: every field and direction,\n * joined by `_`.\n */\nexport function indexNameOf(key: Fields): string {\n\treturn Object.entries(key)\n\t\t.map(([field, direction]) => `${field}_${String(direction)}`)\n\t\t.join('_');\n}\n\nfunction canonicalCollation(value: unknown): unknown {\n\tif (typeof value !== 'object' || value === null) return value;\n\tconst collation = value as Fields;\n\tconst out: Fields = {};\n\tfor (const [field, fallback] of Object.entries(COLLATION_DEFAULTS)) {\n\t\tout[field] = collation[field] ?? fallback;\n\t}\n\tout.locale = collation.locale;\n\t// `version` is the server's ICU version, never something to sync on.\n\treturn out;\n}\n\n/** An index reduced to what makes two of them the same. */\nexport interface NormalizedIndex {\n\tname: string;\n\t/** In order: a compound index on `{a, b}` is not one on `{b, a}`. */\n\tkey: Fields;\n\toptions: Fields;\n}\n\nexport function normalizeIndex(\n\tindex: IndexDescription | IndexDescriptionInfo,\n): NormalizedIndex {\n\tconst key = keyOf(index);\n\tconst options: Fields = {};\n\tfor (const [name, value] of Object.entries(index)) {\n\t\tif (IGNORED.has(name) || value === undefined) continue;\n\t\tif (name === 'collation') {\n\t\t\toptions.collation = canonicalCollation(value);\n\t\t\tcontinue;\n\t\t}\n\t\tif (OPTION_DEFAULTS[name] === value) continue;\n\t\toptions[name] = value;\n\t}\n\treturn { name: index.name ?? indexNameOf(key), key, options };\n}\n\nfunction canonical(value: unknown): string {\n\treturn JSON.stringify(value, (_name, inner) =>\n\t\tinner && typeof inner === 'object' && !Array.isArray(inner)\n\t\t\t? Object.fromEntries(\n\t\t\t\t\tObject.entries(inner).sort(([a], [b]) => (a < b ? -1 : 1)),\n\t\t\t\t)\n\t\t\t: inner,\n\t);\n}\n\n/** Are two indexes the same index, with the same options? */\nexport function indexMatches(\n\twanted: IndexDescription,\n\tlive: IndexDescriptionInfo,\n): boolean {\n\tconst a = normalizeIndex(wanted);\n\tconst b = normalizeIndex(live);\n\treturn (\n\t\t// The key's order counts, so it is compared as it was written.\n\t\tJSON.stringify(Object.entries(a.key)) ===\n\t\t\tJSON.stringify(Object.entries(b.key)) &&\n\t\tcanonical(a.options) === canonical(b.options)\n\t);\n}\n\nexport interface IndexDiff {\n\t/** Not on the server yet. */\n\tcreate: IndexDescription[];\n\t/**\n\t * There under this name, with other options: MongoDB refuses to change\n\t * one, so it is dropped and created again.\n\t */\n\trecreate: IndexDescription[];\n\t/** Already as the definition wants it. */\n\tunchanged: string[];\n\t/** On the server and in no definition. `_id_` is never one. */\n\textra: string[];\n}\n\n/**\n * What an index sync has to do. Indexes are matched by name, which is what\n * MongoDB keys them on: the same name with other options is error 86, and the\n * same key under another name is error 85.\n */\nexport function diffIndexes(\n\twanted: readonly IndexDescription[],\n\tlive: readonly IndexDescriptionInfo[],\n): IndexDiff {\n\tconst byName = new Map(\n\t\tlive.map((index) => [normalizeIndex(index).name, index]),\n\t);\n\tconst diff: IndexDiff = {\n\t\tcreate: [],\n\t\trecreate: [],\n\t\tunchanged: [],\n\t\textra: [],\n\t};\n\tconst named = new Set<string>();\n\n\tfor (const index of wanted) {\n\t\tconst name = normalizeIndex(index).name;\n\t\tnamed.add(name);\n\t\tconst existing = byName.get(name);\n\t\tif (!existing) diff.create.push({ ...index, name });\n\t\telse if (indexMatches(index, existing)) diff.unchanged.push(name);\n\t\telse diff.recreate.push({ ...index, name });\n\t}\n\n\tfor (const name of byName.keys()) {\n\t\t// The `_id_` index is created with the collection and cannot be dropped.\n\t\tif (name !== '_id_' && !named.has(name)) diff.extra.push(name);\n\t}\n\treturn diff;\n}\n",
13
14
  "import type {\n\tValidationAction,\n\tValidationLevel,\n} from '../definition/define-collection';\n\n/** A collection's validation, as `listCollections` reports it in `options`. */\nexport interface LiveValidation {\n\tvalidator?: Record<string, unknown>;\n\tvalidationLevel?: string;\n\tvalidationAction?: string;\n}\n\n/** The validation a definition asks for. `validator` is absent for `off`. */\nexport interface WantedValidation {\n\tvalidator: Record<string, unknown> | undefined;\n\tlevel: ValidationLevel;\n\taction: ValidationAction;\n}\n\nfunction canonical(value: unknown): string {\n\treturn JSON.stringify(value ?? null, (_name, inner) =>\n\t\tinner && typeof inner === 'object' && !Array.isArray(inner)\n\t\t\t? Object.fromEntries(\n\t\t\t\t\tObject.entries(inner).sort(([a], [b]) => (a < b ? -1 : 1)),\n\t\t\t\t)\n\t\t\t: inner,\n\t);\n}\n\n/** Has a collection a validator at all? An empty one is no validator. */\nexport function hasValidator(live: LiveValidation): boolean {\n\treturn live.validator !== undefined && Object.keys(live.validator).length > 0;\n}\n\n/**\n * Does the collection already validate the way the definition says?\n *\n * MongoDB reads a `$jsonSchema` back exactly as it was sent, so the two are\n * compared whole. What it does not read back is a validator that was removed:\n * `collMod` with `validator: {}` leaves **no `validator` key at all**, while\n * `validationLevel` and `validationAction` stay behind. And a collection\n * created without one reports `options: {}`, where the level is `strict` and\n * the action `error` by default.\n */\nexport function validationMatches(\n\twanted: WantedValidation,\n\tlive: LiveValidation,\n): boolean {\n\tif (wanted.validator === undefined) return !hasValidator(live);\n\tif (!hasValidator(live)) return false;\n\treturn (\n\t\tcanonical(live.validator) === canonical(wanted.validator) &&\n\t\t(live.validationLevel ?? 'strict') === wanted.level &&\n\t\t(live.validationAction ?? 'error') === wanted.action\n\t);\n}\n",
14
15
  "import type {\n\tClientSession,\n\tDb,\n\tDocument,\n\tIndexDescription,\n\tIndexDescriptionInfo,\n} from 'mongodb';\nimport type { AnyCollectionDefinition } from '../definition/define-collection';\nimport { toMongoJsonSchema } from '../definition/json-schema';\nimport { DataError } from '../errors/data-error';\nimport { toDataError } from '../errors/to-data-error';\nimport { diffIndexes, normalizeIndex } from './index-diff';\nimport {\n\thasValidator,\n\ttype LiveValidation,\n\tvalidationMatches,\n\ttype WantedValidation,\n} from './validator-diff';\n\nexport interface SyncOptions {\n\t/**\n\t * Compare and report, but send nothing: no collection is created, no\n\t * validator written, no index touched. For a check in CI, or a look before\n\t * a deploy.\n\t */\n\tdryRun?: boolean;\n\t/**\n\t * Drop the indexes the server has and no definition names. Off by default:\n\t * an index someone added on purpose is not this package's to remove.\n\t * `_id_` is never dropped, and cannot be.\n\t */\n\tdropUnknownIndexes?: boolean;\n\t/**\n\t * A session for the reads. MongoDB does not allow `collMod` or an index\n\t * build inside a transaction, so do not pass one that is in a transaction.\n\t */\n\tsession?: ClientSession;\n}\n\n/** What `sync` found and did to one collection. */\nexport interface SyncReport {\n\tname: string;\n\t/** The collection did not exist, and was created. */\n\tcreated: boolean;\n\t/** What the `$jsonSchema` validator needed. */\n\tvalidator: 'unchanged' | 'created' | 'updated' | 'removed';\n\tindexes: {\n\t\tcreated: string[];\n\t\t/** There with other options: MongoDB cannot change one, so it is dropped and built again. */\n\t\trecreated: string[];\n\t\tdropped: string[];\n\t\tunchanged: string[];\n\t};\n\tdryRun: boolean;\n}\n\nfunction serverCode(error: unknown): number | undefined {\n\tconst code = (error as { code?: unknown } | null)?.code;\n\treturn typeof code === 'number' ? code : undefined;\n}\n\nasync function collectionOptions(\n\tdb: Db,\n\tname: string,\n\tsession: ClientSession | undefined,\n): Promise<LiveValidation | undefined> {\n\t// `nameOnly: false` is what types the answer as the whole entry: without\n\t// it the driver's overload gives back a name and a type alone.\n\tconst [info] = await db\n\t\t.listCollections(\n\t\t\t{ name },\n\t\t\t{ ...(session ? { session } : {}), nameOnly: false },\n\t\t)\n\t\t.toArray();\n\treturn info ? ((info.options ?? {}) as LiveValidation) : undefined;\n}\n\n/** The indexes of a collection, or none when it does not exist yet. */\nasync function liveIndexes(\n\tdb: Db,\n\tname: string,\n\tsession: ClientSession | undefined,\n): Promise<IndexDescriptionInfo[]> {\n\ttry {\n\t\treturn await db.collection(name).indexes({ session });\n\t} catch (error) {\n\t\t// NamespaceNotFound: nothing is there, so nothing is indexed.\n\t\tif (serverCode(error) === 26) return [];\n\t\tthrow error;\n\t}\n}\n\nfunction validationFor(definition: AnyCollectionDefinition): WantedValidation {\n\tconst { level, action } = definition.validation;\n\treturn {\n\t\tvalidator:\n\t\t\tlevel === 'off'\n\t\t\t\t? undefined\n\t\t\t\t: { $jsonSchema: toMongoJsonSchema(definition.schema) },\n\t\tlevel,\n\t\taction,\n\t};\n}\n\nfunction creationOptions(wanted: WantedValidation): Document {\n\treturn wanted.validator === undefined\n\t\t? {}\n\t\t: {\n\t\t\t\tvalidator: wanted.validator,\n\t\t\t\tvalidationLevel: wanted.level,\n\t\t\t\tvalidationAction: wanted.action,\n\t\t\t};\n}\n\nasync function writeValidation(\n\tdb: Db,\n\tname: string,\n\twanted: WantedValidation,\n\tsession: ClientSession | undefined,\n): Promise<void> {\n\ttry {\n\t\tawait db.command(\n\t\t\t{\n\t\t\t\tcollMod: name,\n\t\t\t\t// An empty validator is how one is removed: the key then goes\n\t\t\t\t// away entirely, and the level and the action stay behind.\n\t\t\t\tvalidator: wanted.validator ?? {},\n\t\t\t\t...(wanted.validator === undefined\n\t\t\t\t\t? {}\n\t\t\t\t\t: { validationLevel: wanted.level, validationAction: wanted.action }),\n\t\t\t},\n\t\t\tsession ? { session } : undefined,\n\t\t);\n\t} catch (error) {\n\t\tif (serverCode(error) === 13) {\n\t\t\tthrow new DataError(\n\t\t\t\t`sync: not allowed to run collMod on \"${name}\". Writing a validator ` +\n\t\t\t\t\t'needs the `collMod` action, which `readWrite` does not grant and ' +\n\t\t\t\t\t'`dbAdmin` does: sync with a role that has it, not with the ' +\n\t\t\t\t\t'application’s own user.',\n\t\t\t\t{ collection: name, serverCode: 13, cause: error },\n\t\t\t);\n\t\t}\n\t\tthrow toDataError(error, { collection: name });\n\t}\n}\n\n/**\n * Brings one collection in line with its definition, and says what it changed:\n *\n * 1. creates the collection, with its validator, when it is missing;\n * 2. writes the validator with `collMod` when it differs from the definition's;\n * 3. creates the indexes that are missing, and rebuilds those whose options\n * changed — MongoDB refuses to alter an index in place.\n *\n * Run it twice and the second run sends nothing.\n *\n * ```ts\n * const report = await syncCollection(db, users);\n * // { created: true, validator: 'created', indexes: { created: ['users_email_unique'], … } }\n * ```\n *\n * It is a deployment step, not a request-time one: `collMod` needs the\n * `dbAdmin` role, and neither it nor an index build may run in a transaction.\n */\nexport async function syncCollection(\n\tdb: Db,\n\tdefinition: AnyCollectionDefinition,\n\toptions: SyncOptions = {},\n): Promise<SyncReport> {\n\tconst { name } = definition;\n\tconst dryRun = options.dryRun ?? false;\n\tconst session = options.session;\n\tconst wanted = validationFor(definition);\n\n\tlet live = await collectionOptions(db, name, session);\n\tlet created = false;\n\tlet validator: SyncReport['validator'] = 'unchanged';\n\n\tif (!live) {\n\t\tcreated = true;\n\t\tif (wanted.validator !== undefined) validator = 'created';\n\t\tif (!dryRun) {\n\t\t\ttry {\n\t\t\t\tawait db.createCollection(name, {\n\t\t\t\t\t...creationOptions(wanted),\n\t\t\t\t\t...(session ? { session } : {}),\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\t// NamespaceExists: another sync created it between the lookup and\n\t\t\t\t// the creation. Go on with theirs, which is compared below.\n\t\t\t\tif (serverCode(error) !== 48) {\n\t\t\t\t\tthrow toDataError(error, { collection: name });\n\t\t\t\t}\n\t\t\t\tcreated = false;\n\t\t\t\tvalidator = 'unchanged';\n\t\t\t\tlive = await collectionOptions(db, name, session);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (live && !validationMatches(wanted, live)) {\n\t\tvalidator =\n\t\t\twanted.validator === undefined\n\t\t\t\t? 'removed'\n\t\t\t\t: hasValidator(live)\n\t\t\t\t\t? 'updated'\n\t\t\t\t\t: 'created';\n\t\tif (!dryRun) await writeValidation(db, name, wanted, session);\n\t}\n\n\tconst existing =\n\t\tdryRun && created ? [] : await liveIndexes(db, name, session);\n\tconst diff = diffIndexes(definition.indexes, existing);\n\tconst dropped = options.dropUnknownIndexes ? diff.extra : [];\n\tconst build: IndexDescription[] = [...diff.create, ...diff.recreate];\n\n\tif (!dryRun) {\n\t\tconst collection = db.collection(name);\n\t\tfor (const index of [\n\t\t\t...diff.recreate.map((i) => normalizeIndex(i).name),\n\t\t\t...dropped,\n\t\t]) {\n\t\t\tawait collection.dropIndex(index, session ? { session } : undefined);\n\t\t}\n\t\tif (build.length > 0) {\n\t\t\ttry {\n\t\t\t\tawait collection.createIndexes(\n\t\t\t\t\tbuild,\n\t\t\t\t\tsession ? { session } : undefined,\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\tthrow toDataError(error, { collection: name });\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tname,\n\t\tcreated,\n\t\tvalidator,\n\t\tindexes: {\n\t\t\tcreated: diff.create.map((index) => normalizeIndex(index).name),\n\t\t\trecreated: diff.recreate.map((index) => normalizeIndex(index).name),\n\t\t\tdropped,\n\t\t\tunchanged: diff.unchanged,\n\t\t},\n\t\tdryRun,\n\t};\n}\n\n/**\n * `syncCollection` for each definition, one after the other, in the order\n * given. The first that throws stops the rest.\n */\nexport async function syncCollections(\n\tdb: Db,\n\tdefinitions: readonly AnyCollectionDefinition[],\n\toptions: SyncOptions = {},\n): Promise<SyncReport[]> {\n\tconst reports: SyncReport[] = [];\n\tfor (const definition of definitions) {\n\t\treports.push(await syncCollection(db, definition, options));\n\t}\n\treturn reports;\n}\n",
15
- "import type { ClientSession, Db, Document } from 'mongodb';\nimport type { z } from 'zod';\nimport {\n\ttype AnyCollectionDefinition,\n\ttype CollectionDefinition,\n\tstampsOf,\n} from '../definition/define-collection';\nimport {\n\tDataError,\n\tNotFoundError,\n\tOptimisticLockError,\n} from '../errors/data-error';\nimport { toDataError } from '../errors/to-data-error';\nimport { decodeCursor, encodeCursor } from '../pagination/cursor';\nimport {\n\ttype CursorPage,\n\tcursorLimit,\n\tDEFAULT_MAX_PAGE_SIZE,\n\ttype Page,\n\tpageWindow,\n\ttoPage,\n} from '../pagination/page';\nimport { type SyncOptions, syncCollection } from '../sync/sync-collection';\nimport type { OrderDirection, Repository, RepositoryOptions } from './types';\n\ntype Fields = Record<string, unknown>;\n\nfunction isRecord(value: unknown): value is Fields {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Does this patch speak in MongoDB's operators rather than in fields? */\nfunction isUpdateFilter(patch: Fields): boolean {\n\treturn Object.keys(patch).some((key) => key.startsWith('$'));\n}\n\n/** `a` and `b`, without letting one's `$or` swallow the other's. */\nfunction mergeFilters(a: Fields | undefined, b: Fields | undefined): Fields {\n\tconst left = a && Object.keys(a).length > 0 ? a : undefined;\n\tconst right = b && Object.keys(b).length > 0 ? b : undefined;\n\tif (!left) return right ?? {};\n\tif (!right) return left;\n\treturn { $and: [left, right] };\n}\n\n/**\n * A repository over one collection: typed reads and writes by `_id` or by\n * filter, pagination, soft delete, optimistic locking, audit stamps, and\n * MongoDB errors turned into this package's.\n *\n * ```ts\n * const users = createRepository(db, usersCollection);\n * const ada = await users.create({ email: 'ada@example.com' });\n * await users.update(ada._id, { name: 'Ada' }, { expectedVersion: ada.version });\n * ```\n *\n * Every operation runs in the repository's session, which `with(session)`\n * sets: MongoDB has no ambient session, so a write inside a transaction that\n * was not given one is not part of it and is not rolled back.\n */\nexport function createRepository<Schema extends z.ZodObject>(\n\tdb: Db,\n\tdefinition: CollectionDefinition<Schema>,\n\toptions: RepositoryOptions = {},\n): Repository<CollectionDefinition<Schema>> {\n\treturn build(db, definition, options) as unknown as Repository<\n\t\tCollectionDefinition<Schema>\n\t>;\n}\n\nfunction build(\n\tdb: Db,\n\tdefinition: AnyCollectionDefinition,\n\toptions: RepositoryOptions,\n) {\n\tconst name = definition.name;\n\t// The driver types a collection by its documents; this body works on any\n\t// collection, and the public type above is what callers see.\n\tconst collection = db.collection<any>(name);\n\tconst shape = definition.schema.shape as Record<string, z.ZodType>;\n\tconst stamps = stampsOf(definition);\n\tconst session = options.session;\n\tconst actor = options.actor;\n\tconst maxPageSize = options.maxPageSize ?? DEFAULT_MAX_PAGE_SIZE;\n\tconst parses = (options.validate ?? 'parse') === 'parse';\n\tconst softDeletes = options.softDelete ?? stamps.deletedAt;\n\tconst touches = options.touchUpdatedAt ?? stamps.updatedAt;\n\tconst locks = options.optimisticLock ?? stamps.version;\n\n\tif (options.softDelete === true && !stamps.deletedAt) {\n\t\tthrow new TypeError(\n\t\t\t`createRepository: softDelete needs a \"deletedAt\" field, and \"${name}\" has none`,\n\t\t);\n\t}\n\tif (options.optimisticLock === true && !stamps.version) {\n\t\tthrow new TypeError(\n\t\t\t`createRepository: optimisticLock needs a \"version\" field, and \"${name}\" has none`,\n\t\t);\n\t}\n\n\tconst run = async <T>(fn: () => Promise<T>): Promise<T> => {\n\t\ttry {\n\t\t\treturn await fn();\n\t\t} catch (error) {\n\t\t\tthrow toDataError(error, { collection: name });\n\t\t}\n\t};\n\n\tconst sessionOption = session ? { session } : {};\n\n\t/** The filter that leaves soft-deleted documents out. */\n\tconst live = (withDeleted?: boolean): Fields | undefined =>\n\t\tsoftDeletes && !withDeleted ? { deletedAt: null } : undefined;\n\n\tconst scoped = (filter: unknown, withDeleted?: boolean): Fields =>\n\t\tmergeFilters(isRecord(filter) ? filter : undefined, live(withDeleted));\n\n\tconst notFound = (id: unknown) =>\n\t\tnew NotFoundError(`No document in \"${name}\" with _id ${String(id)}`, {\n\t\t\tcollection: name,\n\t\t\tid,\n\t\t});\n\n\tconst requireFilter = (method: string, filter: unknown): void => {\n\t\tif (!isRecord(filter) || Object.keys(filter).length === 0) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`${method} needs a filter. Pass \\`{ _id: { $exists: true } }\\` to target every document of \"${name}\".`,\n\t\t\t);\n\t\t}\n\t};\n\n\t/** The document to insert: checked against the schema, defaults filled. */\n\tconst toDocument = (values: unknown): Fields => {\n\t\tconst stamped: Fields = { ...(values as Fields) };\n\t\tif (actor !== undefined) {\n\t\t\tif (stamps.createdBy && stamped.createdBy === undefined) {\n\t\t\t\tstamped.createdBy = actor;\n\t\t\t}\n\t\t\tif (stamps.updatedBy && stamped.updatedBy === undefined) {\n\t\t\t\tstamped.updatedBy = actor;\n\t\t\t}\n\t\t}\n\t\treturn parses ? (definition.schema.parse(stamped) as Fields) : stamped;\n\t};\n\n\t/**\n\t * The update to send: a patch of fields becomes `$set`, checked field by\n\t * field against the schema, with the stamps this repository keeps. A patch\n\t * that already speaks in operators is sent as it is, with the stamps added.\n\t */\n\tconst toUpdate = (patch: unknown): Fields => {\n\t\tif (!isRecord(patch)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`update: expected the document's fields or MongoDB's operators, not ${String(patch)}`,\n\t\t\t);\n\t\t}\n\t\tconst update: Fields = isUpdateFilter(patch) ? { ...patch } : {};\n\t\tconst set: Fields = isRecord(update.$set) ? { ...update.$set } : {};\n\n\t\tif (!isUpdateFilter(patch)) {\n\t\t\tfor (const [field, value] of Object.entries(patch)) {\n\t\t\t\tif (value === undefined) continue;\n\t\t\t\tconst schema = shape[field];\n\t\t\t\tif (!schema) {\n\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t`update: \"${name}\" has no field \"${field}\" in its schema`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tset[field] = parses ? schema.parse(value) : value;\n\t\t\t}\n\t\t}\n\n\t\tif (touches && set.updatedAt === undefined) set.updatedAt = new Date();\n\t\tif (\n\t\t\tactor !== undefined &&\n\t\t\tstamps.updatedBy &&\n\t\t\tset.updatedBy === undefined\n\t\t) {\n\t\t\tset.updatedBy = actor;\n\t\t}\n\t\tif (Object.keys(set).length > 0) update.$set = set;\n\n\t\tif (locks) {\n\t\t\tconst inc = isRecord(update.$inc) ? { ...update.$inc } : {};\n\t\t\tinc.version = (inc.version as number | undefined) ?? 1;\n\t\t\tupdate.$inc = inc;\n\t\t}\n\t\treturn update;\n\t};\n\n\tconst findOne = async (filter: Fields, projection?: unknown) =>\n\t\trun(async () =>\n\t\t\tcollection.findOne(filter, {\n\t\t\t\t...sessionOption,\n\t\t\t\t...(projection ? { projection } : {}),\n\t\t\t}),\n\t\t);\n\n\tasync function findById(id: unknown, opts: { withDeleted?: boolean } = {}) {\n\t\tconst found = await findOne(scoped({ _id: id }, opts.withDeleted));\n\t\treturn found ?? undefined;\n\t}\n\n\tasync function getById(id: unknown, opts: { withDeleted?: boolean } = {}) {\n\t\tconst found = await findById(id, opts);\n\t\tif (!found) throw notFound(id);\n\t\treturn found;\n\t}\n\n\tasync function findMany(opts: Fields = {}): Promise<Fields[]> {\n\t\treturn run(async () => {\n\t\t\tlet cursor = collection.find(\n\t\t\t\tscoped(opts.filter, opts.withDeleted as boolean | undefined),\n\t\t\t\t{\n\t\t\t\t\t...sessionOption,\n\t\t\t\t\t...(opts.projection ? { projection: opts.projection } : {}),\n\t\t\t\t},\n\t\t\t);\n\t\t\tif (opts.sort !== undefined) cursor = cursor.sort(opts.sort as never);\n\t\t\tif (opts.skip !== undefined) cursor = cursor.skip(opts.skip as number);\n\t\t\tif (opts.limit !== undefined) cursor = cursor.limit(opts.limit as number);\n\t\t\treturn cursor.toArray();\n\t\t});\n\t}\n\n\tasync function countDocuments(\n\t\tfilter?: unknown,\n\t\topts: { withDeleted?: boolean } = {},\n\t) {\n\t\treturn run(async () =>\n\t\t\tcollection.countDocuments(scoped(filter, opts.withDeleted), {\n\t\t\t\t...sessionOption,\n\t\t\t}),\n\t\t);\n\t}\n\n\t/**\n\t * `findOneAndUpdate` answers `null` for a document that is not there, one\n\t * that is soft-deleted, and one whose version moved. Only a second read\n\t * tells them apart.\n\t */\n\tasync function updatedOrThrow(\n\t\tid: unknown,\n\t\tfilter: Fields,\n\t\tupdate: Fields,\n\t\texpectedVersion: number | undefined,\n\t): Promise<Fields> {\n\t\tconst updated = await run(async () =>\n\t\t\tcollection.findOneAndUpdate(filter, update, {\n\t\t\t\t...sessionOption,\n\t\t\t\treturnDocument: 'after',\n\t\t\t}),\n\t\t);\n\t\tif (updated) return updated as Fields;\n\n\t\tif (expectedVersion !== undefined) {\n\t\t\tconst current = await findOne({ _id: id });\n\t\t\tif (current) {\n\t\t\t\tthrow new OptimisticLockError(\n\t\t\t\t\t`Document ${String(id)} of \"${name}\" is at version ${String(\n\t\t\t\t\t\tcurrent.version,\n\t\t\t\t\t)}, not ${expectedVersion}: it changed since it was read`,\n\t\t\t\t\t{\n\t\t\t\t\t\tcollection: name,\n\t\t\t\t\t\tid,\n\t\t\t\t\t\texpectedVersion,\n\t\t\t\t\t\tactualVersion:\n\t\t\t\t\t\t\ttypeof current.version === 'number' ? current.version : undefined,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tthrow notFound(id);\n\t}\n\n\tasync function hardDelete(id: unknown): Promise<Fields> {\n\t\tconst deleted = await run(async () =>\n\t\t\tcollection.findOneAndDelete({ _id: id }, { ...sessionOption }),\n\t\t);\n\t\tif (!deleted) throw notFound(id);\n\t\treturn deleted as Fields;\n\t}\n\n\tasync function hardDeleteMany(filter: unknown): Promise<number> {\n\t\trequireFilter('hardDeleteMany', filter);\n\t\treturn run(async () => {\n\t\t\tconst result = await collection.deleteMany(filter as Fields, {\n\t\t\t\t...sessionOption,\n\t\t\t});\n\t\t\treturn result.deletedCount;\n\t\t});\n\t}\n\n\tconst repository = {\n\t\tdefinition,\n\t\tdb,\n\t\tcollection,\n\t\tsession,\n\n\t\twith: (other: ClientSession | undefined) =>\n\t\t\tbuild(db, definition, { ...options, session: other }),\n\t\tas: (who: unknown) => build(db, definition, { ...options, actor: who }),\n\t\tsync: (syncOptions: SyncOptions = {}) =>\n\t\t\tsyncCollection(db, definition, { ...sessionOption, ...syncOptions }),\n\n\t\tfindById,\n\t\tgetById,\n\n\t\tasync findFirst(filter?: unknown, opts: Fields = {}) {\n\t\t\tconst [first] = await findMany({ ...opts, filter, limit: 1 });\n\t\t\treturn first;\n\t\t},\n\n\t\tfindMany,\n\n\t\tasync create(values: unknown) {\n\t\t\tconst document = toDocument(values);\n\t\t\treturn run(async () => {\n\t\t\t\tawait collection.insertOne(document as Document, { ...sessionOption });\n\t\t\t\treturn document;\n\t\t\t});\n\t\t},\n\n\t\tasync createMany(values: readonly unknown[]) {\n\t\t\tif (values.length === 0) return [];\n\t\t\tconst documents = values.map(toDocument);\n\t\t\treturn run(async () => {\n\t\t\t\tawait collection.insertMany(documents as Document[], {\n\t\t\t\t\t...sessionOption,\n\t\t\t\t});\n\t\t\t\treturn documents;\n\t\t\t});\n\t\t},\n\n\t\tasync update(id: unknown, patch: unknown, opts: Fields = {}) {\n\t\t\tconst expectedVersion = opts.expectedVersion as number | undefined;\n\t\t\tif (expectedVersion !== undefined && !locks) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t`update: expectedVersion needs a \"version\" field, and \"${name}\" has none`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst update = toUpdate(patch);\n\t\t\tconst filter = mergeFilters(\n\t\t\t\t{\n\t\t\t\t\t_id: id,\n\t\t\t\t\t...(expectedVersion === undefined\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: { version: expectedVersion }),\n\t\t\t\t},\n\t\t\t\tlive(),\n\t\t\t);\n\t\t\treturn updatedOrThrow(id, filter, update, expectedVersion);\n\t\t},\n\n\t\tasync updateMany(filter: unknown, patch: unknown) {\n\t\t\trequireFilter('updateMany', filter);\n\t\t\tconst update = toUpdate(patch);\n\t\t\treturn run(async () => {\n\t\t\t\tconst result = await collection.updateMany(scoped(filter), update, {\n\t\t\t\t\t...sessionOption,\n\t\t\t\t});\n\t\t\t\treturn result.modifiedCount;\n\t\t\t});\n\t\t},\n\n\t\tasync delete(id: unknown) {\n\t\t\tif (!softDeletes) return hardDelete(id);\n\t\t\tconst set: Fields = { deletedAt: new Date() };\n\t\t\tif (actor !== undefined && stamps.deletedBy) set.deletedBy = actor;\n\t\t\tconst update: Fields = { $set: set };\n\t\t\tif (locks) update.$inc = { version: 1 };\n\t\t\treturn updatedOrThrow(\n\t\t\t\tid,\n\t\t\t\tmergeFilters({ _id: id }, live()),\n\t\t\t\tupdate,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t},\n\n\t\tasync deleteMany(filter: unknown) {\n\t\t\trequireFilter('deleteMany', filter);\n\t\t\tif (!softDeletes) return hardDeleteMany(filter);\n\t\t\tconst set: Fields = { deletedAt: new Date() };\n\t\t\tif (actor !== undefined && stamps.deletedBy) set.deletedBy = actor;\n\t\t\tconst update: Fields = { $set: set };\n\t\t\tif (locks) update.$inc = { version: 1 };\n\t\t\treturn run(async () => {\n\t\t\t\tconst result = await collection.updateMany(scoped(filter), update, {\n\t\t\t\t\t...sessionOption,\n\t\t\t\t});\n\t\t\t\treturn result.modifiedCount;\n\t\t\t});\n\t\t},\n\n\t\thardDelete,\n\t\thardDeleteMany,\n\n\t\tasync restore(id: unknown) {\n\t\t\tif (!stamps.deletedAt) {\n\t\t\t\tthrow new TypeError(`restore: \"${name}\" has no soft delete`);\n\t\t\t}\n\t\t\tconst set: Fields = { deletedAt: null };\n\t\t\tif (stamps.deletedBy) set.deletedBy = null;\n\t\t\tif (touches) set.updatedAt = new Date();\n\t\t\tconst update: Fields = { $set: set };\n\t\t\tif (locks) update.$inc = { version: 1 };\n\t\t\treturn updatedOrThrow(id, { _id: id }, update, undefined);\n\t\t},\n\n\t\tcount: countDocuments,\n\n\t\tasync exists(filter: unknown, opts: { withDeleted?: boolean } = {}) {\n\t\t\tconst found = await findOne(scoped(filter, opts.withDeleted), { _id: 1 });\n\t\t\treturn found !== null && found !== undefined;\n\t\t},\n\n\t\tasync paginate(opts: Fields = {}): Promise<Page<Fields>> {\n\t\t\tconst window = pageWindow(opts, maxPageSize);\n\t\t\tconst [items, total] = await Promise.all([\n\t\t\t\tfindMany({\n\t\t\t\t\tfilter: opts.filter,\n\t\t\t\t\tsort: opts.sort ?? { _id: 1 },\n\t\t\t\t\tlimit: window.limit,\n\t\t\t\t\tskip: window.skip,\n\t\t\t\t\twithDeleted: opts.withDeleted,\n\t\t\t\t}),\n\t\t\t\tcountDocuments(opts.filter, {\n\t\t\t\t\twithDeleted: opts.withDeleted as boolean | undefined,\n\t\t\t\t}),\n\t\t\t]);\n\t\t\treturn toPage(items, total, window);\n\t\t},\n\n\t\tasync paginateByCursor(opts: Fields = {}): Promise<CursorPage<Fields>> {\n\t\t\tconst sortField = (opts.orderBy as string | undefined) ?? '_id';\n\t\t\tif (!shape[sortField] && sortField !== '_id') {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t`paginateByCursor: \"${name}\" has no field \"${sortField}\" in its schema`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst direction = (opts.direction as OrderDirection | undefined) ?? 'asc';\n\t\t\tconst fields = sortField === '_id' ? ['_id'] : [sortField, '_id'];\n\t\t\tconst cursorKey = `${sortField}:${direction}`;\n\t\t\tconst limit = cursorLimit(opts.limit as number | undefined, maxPageSize);\n\t\t\tconst past = direction === 'asc' ? '$gt' : '$lt';\n\n\t\t\tlet after: Fields | undefined;\n\t\t\tif (opts.after) {\n\t\t\t\tconst { values } = decodeCursor(opts.after as string, cursorKey);\n\t\t\t\tif (values.length !== fields.length) {\n\t\t\t\t\tthrow new DataError(\n\t\t\t\t\t\t`Invalid cursor: expected ${fields.length} value(s), got ${values.length}`,\n\t\t\t\t\t\t{ collection: name },\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t// `a > x OR (a = x AND b > y)`, the keyset of the ordering.\n\t\t\t\tafter = {\n\t\t\t\t\t$or: fields.map((field, index) => ({\n\t\t\t\t\t\t...Object.fromEntries(\n\t\t\t\t\t\t\tfields\n\t\t\t\t\t\t\t\t.slice(0, index)\n\t\t\t\t\t\t\t\t.map((previous, i) => [previous, values[i]]),\n\t\t\t\t\t\t),\n\t\t\t\t\t\t[field]: { [past]: values[index] },\n\t\t\t\t\t})),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst sort = Object.fromEntries(\n\t\t\t\tfields.map((field) => [field, direction === 'asc' ? 1 : -1]),\n\t\t\t);\n\t\t\tconst documents = await findMany({\n\t\t\t\tfilter: mergeFilters(\n\t\t\t\t\tisRecord(opts.filter) ? opts.filter : undefined,\n\t\t\t\t\tafter,\n\t\t\t\t),\n\t\t\t\tsort,\n\t\t\t\tlimit: limit + 1,\n\t\t\t\twithDeleted: opts.withDeleted,\n\t\t\t});\n\n\t\t\tconst items = documents.slice(0, limit);\n\t\t\tconst last = items.at(-1);\n\t\t\tif (documents.length <= limit || !last) {\n\t\t\t\treturn { items, nextCursor: null };\n\t\t\t}\n\n\t\t\tconst values = fields.map((field) => {\n\t\t\t\tconst value = last[field];\n\t\t\t\tif (value === null || value === undefined) {\n\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t`paginateByCursor: \"${field}\" is null in a document of \"${name}\". ` +\n\t\t\t\t\t\t\t'Page along a field every document has.',\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t});\n\t\t\treturn { items, nextCursor: encodeCursor({ key: cursorKey, values }) };\n\t\t},\n\t};\n\n\treturn repository;\n}\n",
16
+ "import type { ClientSession, Db, Document } from 'mongodb';\nimport type { z } from 'zod';\nimport {\n\ttype AnyCollectionDefinition,\n\ttype CollectionDefinition,\n\tstampsOf,\n} from '../definition/define-collection';\nimport {\n\tDataError,\n\tNotFoundError,\n\tOptimisticLockError,\n} from '../errors/data-error';\nimport { toDataError } from '../errors/to-data-error';\nimport { decodeCursor, encodeCursor } from '../pagination/cursor';\nimport {\n\ttype CursorPage,\n\tcursorLimit,\n\tDEFAULT_MAX_PAGE_SIZE,\n\ttype Page,\n\tpageWindow,\n\ttoPage,\n} from '../pagination/page';\nimport { type SyncOptions, syncCollection } from '../sync/sync-collection';\nimport type { OrderDirection, Repository, RepositoryOptions } from './types';\n\ntype Fields = Record<string, unknown>;\n\nfunction isRecord(value: unknown): value is Fields {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Does this patch speak in MongoDB's operators rather than in fields? */\nfunction isUpdateFilter(patch: Fields): boolean {\n\treturn Object.keys(patch).some((key) => key.startsWith('$'));\n}\n\n/** `a` and `b`, without letting one's `$or` swallow the other's. */\nfunction mergeFilters(a: Fields | undefined, b: Fields | undefined): Fields {\n\tconst left = a && Object.keys(a).length > 0 ? a : undefined;\n\tconst right = b && Object.keys(b).length > 0 ? b : undefined;\n\tif (!left) return right ?? {};\n\tif (!right) return left;\n\treturn { $and: [left, right] };\n}\n\n/**\n * A repository over one collection: typed reads and writes by `_id` or by\n * filter, pagination, soft delete, optimistic locking, audit stamps, and\n * MongoDB errors turned into this package's.\n *\n * ```ts\n * const users = createRepository(db, usersCollection);\n * const ada = await users.create({ email: 'ada@example.com' });\n * await users.update(ada._id, { name: 'Ada' }, { expectedVersion: ada.version });\n * ```\n *\n * Every operation runs in the repository's session, which `with(session)`\n * sets: MongoDB has no ambient session, so a write inside a transaction that\n * was not given one is not part of it and is not rolled back.\n */\nexport function createRepository<Schema extends z.ZodObject>(\n\tdb: Db,\n\tdefinition: CollectionDefinition<Schema>,\n\toptions: RepositoryOptions = {},\n): Repository<CollectionDefinition<Schema>> {\n\treturn build(db, definition, options) as unknown as Repository<\n\t\tCollectionDefinition<Schema>\n\t>;\n}\n\nfunction build(\n\tdb: Db,\n\tdefinition: AnyCollectionDefinition,\n\toptions: RepositoryOptions,\n) {\n\tconst name = definition.name;\n\t// The driver types a collection by its documents; this body works on any\n\t// collection, and the public type above is what callers see.\n\tconst collection = db.collection<any>(name);\n\tconst shape = definition.schema.shape as Record<string, z.ZodType>;\n\t// A schema may declare an `id` field of its own; then it is that field's,\n\t// and the repository neither computes it nor drops it.\n\tconst hasOwnId = 'id' in shape;\n\tconst stamps = stampsOf(definition);\n\tconst session = options.session;\n\tconst actor = options.actor;\n\tconst maxPageSize = options.maxPageSize ?? DEFAULT_MAX_PAGE_SIZE;\n\tconst parses = (options.validate ?? 'parse') === 'parse';\n\tconst softDeletes = options.softDelete ?? stamps.deletedAt;\n\tconst touches = options.touchUpdatedAt ?? stamps.updatedAt;\n\tconst locks = options.optimisticLock ?? stamps.version;\n\n\tif (options.softDelete === true && !stamps.deletedAt) {\n\t\tthrow new TypeError(\n\t\t\t`createRepository: softDelete needs a \"deletedAt\" field, and \"${name}\" has none`,\n\t\t);\n\t}\n\tif (options.optimisticLock === true && !stamps.version) {\n\t\tthrow new TypeError(\n\t\t\t`createRepository: optimisticLock needs a \"version\" field, and \"${name}\" has none`,\n\t\t);\n\t}\n\n\tconst run = async <T>(fn: () => Promise<T>): Promise<T> => {\n\t\ttry {\n\t\t\treturn await fn();\n\t\t} catch (error) {\n\t\t\tthrow toDataError(error, { collection: name });\n\t\t}\n\t};\n\n\tconst sessionOption = session ? { session } : {};\n\n\t/** The filter that leaves soft-deleted documents out. */\n\tconst live = (withDeleted?: boolean): Fields | undefined =>\n\t\tsoftDeletes && !withDeleted ? { deletedAt: null } : undefined;\n\n\tconst scoped = (filter: unknown, withDeleted?: boolean): Fields =>\n\t\tmergeFilters(isRecord(filter) ? filter : undefined, live(withDeleted));\n\n\t/**\n\t * `id` on a document the repository gives back: `_id` as a string, computed\n\t * rather than stored — the collection holds `_id` alone.\n\t *\n\t * It is enumerable, so `JSON.stringify` and a spread carry it and a handler\n\t * can return the document as it is. `toDocument` drops it again on a write,\n\t * and it is no part of `DocumentOf`, so nothing can filter on it: the server\n\t * would match nothing.\n\t */\n\tconst withId = <T>(document: T): T => {\n\t\tif (\n\t\t\thasOwnId ||\n\t\t\t!isRecord(document) ||\n\t\t\tdocument._id === undefined ||\n\t\t\tObject.hasOwn(document, 'id')\n\t\t) {\n\t\t\treturn document;\n\t\t}\n\t\tObject.defineProperty(document, 'id', {\n\t\t\tget: () => String((document as Fields)._id),\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\t\t});\n\t\treturn document;\n\t};\n\n\tconst notFound = (id: unknown) =>\n\t\tnew NotFoundError(`No document in \"${name}\" with _id ${String(id)}`, {\n\t\t\tcollection: name,\n\t\t\tid,\n\t\t});\n\n\tconst requireFilter = (method: string, filter: unknown): void => {\n\t\tif (!isRecord(filter) || Object.keys(filter).length === 0) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`${method} needs a filter. Pass \\`{ _id: { $exists: true } }\\` to target every document of \"${name}\".`,\n\t\t\t);\n\t\t}\n\t};\n\n\t/** The document to insert: checked against the schema, defaults filled. */\n\tconst toDocument = (values: unknown): Fields => {\n\t\tconst stamped: Fields = { ...(values as Fields) };\n\t\t// A document that was read carries `id`, which is this repository's view\n\t\t// of `_id` and not a field: writing it back would be refused by the\n\t\t// validator, which allows no property the schema does not declare.\n\t\t// Parsing strips it too, but `validate: 'off'` does not parse.\n\t\tif (!hasOwnId) delete stamped.id;\n\t\tif (actor !== undefined) {\n\t\t\tif (stamps.createdBy && stamped.createdBy === undefined) {\n\t\t\t\tstamped.createdBy = actor;\n\t\t\t}\n\t\t\tif (stamps.updatedBy && stamped.updatedBy === undefined) {\n\t\t\t\tstamped.updatedBy = actor;\n\t\t\t}\n\t\t}\n\t\treturn parses ? (definition.schema.parse(stamped) as Fields) : stamped;\n\t};\n\n\t/**\n\t * The update to send: a patch of fields becomes `$set`, checked field by\n\t * field against the schema, with the stamps this repository keeps. A patch\n\t * that already speaks in operators is sent as it is, with the stamps added.\n\t */\n\tconst toUpdate = (patch: unknown): Fields => {\n\t\tif (!isRecord(patch)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`update: expected the document's fields or MongoDB's operators, not ${String(patch)}`,\n\t\t\t);\n\t\t}\n\t\tconst update: Fields = isUpdateFilter(patch) ? { ...patch } : {};\n\t\tconst set: Fields = isRecord(update.$set) ? { ...update.$set } : {};\n\n\t\tif (!isUpdateFilter(patch)) {\n\t\t\tfor (const [field, value] of Object.entries(patch)) {\n\t\t\t\tif (value === undefined) continue;\n\t\t\t\tconst schema = shape[field];\n\t\t\t\tif (!schema) {\n\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t`update: \"${name}\" has no field \"${field}\" in its schema`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tset[field] = parses ? schema.parse(value) : value;\n\t\t\t}\n\t\t}\n\n\t\tif (touches && set.updatedAt === undefined) set.updatedAt = new Date();\n\t\tif (\n\t\t\tactor !== undefined &&\n\t\t\tstamps.updatedBy &&\n\t\t\tset.updatedBy === undefined\n\t\t) {\n\t\t\tset.updatedBy = actor;\n\t\t}\n\t\tif (Object.keys(set).length > 0) update.$set = set;\n\n\t\tif (locks) {\n\t\t\tconst inc = isRecord(update.$inc) ? { ...update.$inc } : {};\n\t\t\tinc.version = (inc.version as number | undefined) ?? 1;\n\t\t\tupdate.$inc = inc;\n\t\t}\n\t\treturn update;\n\t};\n\n\tconst findOne = async (filter: Fields, projection?: unknown) =>\n\t\trun(async () => {\n\t\t\tconst found = await collection.findOne(filter, {\n\t\t\t\t...sessionOption,\n\t\t\t\t...(projection ? { projection } : {}),\n\t\t\t});\n\t\t\treturn found === null ? null : withId(found as Fields);\n\t\t});\n\n\tasync function findById(id: unknown, opts: { withDeleted?: boolean } = {}) {\n\t\tconst found = await findOne(scoped({ _id: id }, opts.withDeleted));\n\t\treturn found ?? undefined;\n\t}\n\n\tasync function getById(id: unknown, opts: { withDeleted?: boolean } = {}) {\n\t\tconst found = await findById(id, opts);\n\t\tif (!found) throw notFound(id);\n\t\treturn found;\n\t}\n\n\tasync function findMany(opts: Fields = {}): Promise<Fields[]> {\n\t\treturn run(async () => {\n\t\t\tlet cursor = collection.find(\n\t\t\t\tscoped(opts.filter, opts.withDeleted as boolean | undefined),\n\t\t\t\t{\n\t\t\t\t\t...sessionOption,\n\t\t\t\t\t...(opts.projection ? { projection: opts.projection } : {}),\n\t\t\t\t},\n\t\t\t);\n\t\t\tif (opts.sort !== undefined) cursor = cursor.sort(opts.sort as never);\n\t\t\tif (opts.skip !== undefined) cursor = cursor.skip(opts.skip as number);\n\t\t\tif (opts.limit !== undefined) cursor = cursor.limit(opts.limit as number);\n\t\t\tconst found = await cursor.toArray();\n\t\t\treturn found.map((document) => withId(document as Fields));\n\t\t});\n\t}\n\n\tasync function countDocuments(\n\t\tfilter?: unknown,\n\t\topts: { withDeleted?: boolean } = {},\n\t) {\n\t\treturn run(async () =>\n\t\t\tcollection.countDocuments(scoped(filter, opts.withDeleted), {\n\t\t\t\t...sessionOption,\n\t\t\t}),\n\t\t);\n\t}\n\n\t/**\n\t * `findOneAndUpdate` answers `null` for a document that is not there, one\n\t * that is soft-deleted, and one whose version moved. Only a second read\n\t * tells them apart.\n\t */\n\tasync function updatedOrThrow(\n\t\tid: unknown,\n\t\tfilter: Fields,\n\t\tupdate: Fields,\n\t\texpectedVersion: number | undefined,\n\t): Promise<Fields> {\n\t\tconst updated = await run(async () =>\n\t\t\tcollection.findOneAndUpdate(filter, update, {\n\t\t\t\t...sessionOption,\n\t\t\t\treturnDocument: 'after',\n\t\t\t}),\n\t\t);\n\t\tif (updated) return withId(updated as Fields);\n\n\t\tif (expectedVersion !== undefined) {\n\t\t\tconst current = await findOne({ _id: id });\n\t\t\tif (current) {\n\t\t\t\tthrow new OptimisticLockError(\n\t\t\t\t\t`Document ${String(id)} of \"${name}\" is at version ${String(\n\t\t\t\t\t\tcurrent.version,\n\t\t\t\t\t)}, not ${expectedVersion}: it changed since it was read`,\n\t\t\t\t\t{\n\t\t\t\t\t\tcollection: name,\n\t\t\t\t\t\tid,\n\t\t\t\t\t\texpectedVersion,\n\t\t\t\t\t\tactualVersion:\n\t\t\t\t\t\t\ttypeof current.version === 'number' ? current.version : undefined,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tthrow notFound(id);\n\t}\n\n\tasync function hardDelete(id: unknown): Promise<Fields> {\n\t\tconst deleted = await run(async () =>\n\t\t\tcollection.findOneAndDelete({ _id: id }, { ...sessionOption }),\n\t\t);\n\t\tif (!deleted) throw notFound(id);\n\t\treturn withId(deleted as Fields);\n\t}\n\n\tasync function hardDeleteMany(filter: unknown): Promise<number> {\n\t\trequireFilter('hardDeleteMany', filter);\n\t\treturn run(async () => {\n\t\t\tconst result = await collection.deleteMany(filter as Fields, {\n\t\t\t\t...sessionOption,\n\t\t\t});\n\t\t\treturn result.deletedCount;\n\t\t});\n\t}\n\n\tconst repository = {\n\t\tdefinition,\n\t\tdb,\n\t\tcollection,\n\t\tsession,\n\n\t\twith: (other: ClientSession | undefined) =>\n\t\t\tbuild(db, definition, { ...options, session: other }),\n\t\tas: (who: unknown) => build(db, definition, { ...options, actor: who }),\n\t\tsync: (syncOptions: SyncOptions = {}) =>\n\t\t\tsyncCollection(db, definition, { ...sessionOption, ...syncOptions }),\n\n\t\tfindById,\n\t\tgetById,\n\n\t\tasync findFirst(filter?: unknown, opts: Fields = {}) {\n\t\t\tconst [first] = await findMany({ ...opts, filter, limit: 1 });\n\t\t\treturn first;\n\t\t},\n\n\t\tfindMany,\n\n\t\tasync create(values: unknown) {\n\t\t\tconst document = toDocument(values);\n\t\t\treturn run(async () => {\n\t\t\t\tawait collection.insertOne(document as Document, { ...sessionOption });\n\t\t\t\treturn withId(document);\n\t\t\t});\n\t\t},\n\n\t\tasync createMany(values: readonly unknown[]) {\n\t\t\tif (values.length === 0) return [];\n\t\t\tconst documents = values.map(toDocument);\n\t\t\treturn run(async () => {\n\t\t\t\tawait collection.insertMany(documents as Document[], {\n\t\t\t\t\t...sessionOption,\n\t\t\t\t});\n\t\t\t\treturn documents.map((document) => withId(document));\n\t\t\t});\n\t\t},\n\n\t\tasync update(id: unknown, patch: unknown, opts: Fields = {}) {\n\t\t\tconst expectedVersion = opts.expectedVersion as number | undefined;\n\t\t\tif (expectedVersion !== undefined && !locks) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t`update: expectedVersion needs a \"version\" field, and \"${name}\" has none`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst update = toUpdate(patch);\n\t\t\tconst filter = mergeFilters(\n\t\t\t\t{\n\t\t\t\t\t_id: id,\n\t\t\t\t\t...(expectedVersion === undefined\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: { version: expectedVersion }),\n\t\t\t\t},\n\t\t\t\tlive(),\n\t\t\t);\n\t\t\treturn updatedOrThrow(id, filter, update, expectedVersion);\n\t\t},\n\n\t\tasync updateMany(filter: unknown, patch: unknown) {\n\t\t\trequireFilter('updateMany', filter);\n\t\t\tconst update = toUpdate(patch);\n\t\t\treturn run(async () => {\n\t\t\t\tconst result = await collection.updateMany(scoped(filter), update, {\n\t\t\t\t\t...sessionOption,\n\t\t\t\t});\n\t\t\t\treturn result.modifiedCount;\n\t\t\t});\n\t\t},\n\n\t\tasync delete(id: unknown) {\n\t\t\tif (!softDeletes) return hardDelete(id);\n\t\t\tconst set: Fields = { deletedAt: new Date() };\n\t\t\tif (actor !== undefined && stamps.deletedBy) set.deletedBy = actor;\n\t\t\tconst update: Fields = { $set: set };\n\t\t\tif (locks) update.$inc = { version: 1 };\n\t\t\treturn updatedOrThrow(\n\t\t\t\tid,\n\t\t\t\tmergeFilters({ _id: id }, live()),\n\t\t\t\tupdate,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t},\n\n\t\tasync deleteMany(filter: unknown) {\n\t\t\trequireFilter('deleteMany', filter);\n\t\t\tif (!softDeletes) return hardDeleteMany(filter);\n\t\t\tconst set: Fields = { deletedAt: new Date() };\n\t\t\tif (actor !== undefined && stamps.deletedBy) set.deletedBy = actor;\n\t\t\tconst update: Fields = { $set: set };\n\t\t\tif (locks) update.$inc = { version: 1 };\n\t\t\treturn run(async () => {\n\t\t\t\tconst result = await collection.updateMany(scoped(filter), update, {\n\t\t\t\t\t...sessionOption,\n\t\t\t\t});\n\t\t\t\treturn result.modifiedCount;\n\t\t\t});\n\t\t},\n\n\t\thardDelete,\n\t\thardDeleteMany,\n\n\t\tasync restore(id: unknown) {\n\t\t\tif (!stamps.deletedAt) {\n\t\t\t\tthrow new TypeError(`restore: \"${name}\" has no soft delete`);\n\t\t\t}\n\t\t\tconst set: Fields = { deletedAt: null };\n\t\t\tif (stamps.deletedBy) set.deletedBy = null;\n\t\t\tif (touches) set.updatedAt = new Date();\n\t\t\tconst update: Fields = { $set: set };\n\t\t\tif (locks) update.$inc = { version: 1 };\n\t\t\treturn updatedOrThrow(id, { _id: id }, update, undefined);\n\t\t},\n\n\t\tcount: countDocuments,\n\n\t\tasync exists(filter: unknown, opts: { withDeleted?: boolean } = {}) {\n\t\t\tconst found = await findOne(scoped(filter, opts.withDeleted), { _id: 1 });\n\t\t\treturn found !== null && found !== undefined;\n\t\t},\n\n\t\tasync paginate(opts: Fields = {}): Promise<Page<Fields>> {\n\t\t\tconst window = pageWindow(opts, maxPageSize);\n\t\t\tconst [items, total] = await Promise.all([\n\t\t\t\tfindMany({\n\t\t\t\t\tfilter: opts.filter,\n\t\t\t\t\tsort: opts.sort ?? { _id: 1 },\n\t\t\t\t\tlimit: window.limit,\n\t\t\t\t\tskip: window.skip,\n\t\t\t\t\twithDeleted: opts.withDeleted,\n\t\t\t\t}),\n\t\t\t\tcountDocuments(opts.filter, {\n\t\t\t\t\twithDeleted: opts.withDeleted as boolean | undefined,\n\t\t\t\t}),\n\t\t\t]);\n\t\t\treturn toPage(items, total, window);\n\t\t},\n\n\t\tasync paginateByCursor(opts: Fields = {}): Promise<CursorPage<Fields>> {\n\t\t\tconst sortField = (opts.orderBy as string | undefined) ?? '_id';\n\t\t\tif (!shape[sortField] && sortField !== '_id') {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t`paginateByCursor: \"${name}\" has no field \"${sortField}\" in its schema`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst direction = (opts.direction as OrderDirection | undefined) ?? 'asc';\n\t\t\tconst fields = sortField === '_id' ? ['_id'] : [sortField, '_id'];\n\t\t\tconst cursorKey = `${sortField}:${direction}`;\n\t\t\tconst limit = cursorLimit(opts.limit as number | undefined, maxPageSize);\n\t\t\tconst past = direction === 'asc' ? '$gt' : '$lt';\n\n\t\t\tlet after: Fields | undefined;\n\t\t\tif (opts.after) {\n\t\t\t\tconst { values } = decodeCursor(opts.after as string, cursorKey);\n\t\t\t\tif (values.length !== fields.length) {\n\t\t\t\t\tthrow new DataError(\n\t\t\t\t\t\t`Invalid cursor: expected ${fields.length} value(s), got ${values.length}`,\n\t\t\t\t\t\t{ collection: name },\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t// `a > x OR (a = x AND b > y)`, the keyset of the ordering.\n\t\t\t\tafter = {\n\t\t\t\t\t$or: fields.map((field, index) => ({\n\t\t\t\t\t\t...Object.fromEntries(\n\t\t\t\t\t\t\tfields\n\t\t\t\t\t\t\t\t.slice(0, index)\n\t\t\t\t\t\t\t\t.map((previous, i) => [previous, values[i]]),\n\t\t\t\t\t\t),\n\t\t\t\t\t\t[field]: { [past]: values[index] },\n\t\t\t\t\t})),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst sort = Object.fromEntries(\n\t\t\t\tfields.map((field) => [field, direction === 'asc' ? 1 : -1]),\n\t\t\t);\n\t\t\tconst documents = await findMany({\n\t\t\t\tfilter: mergeFilters(\n\t\t\t\t\tisRecord(opts.filter) ? opts.filter : undefined,\n\t\t\t\t\tafter,\n\t\t\t\t),\n\t\t\t\tsort,\n\t\t\t\tlimit: limit + 1,\n\t\t\t\twithDeleted: opts.withDeleted,\n\t\t\t});\n\n\t\t\tconst items = documents.slice(0, limit);\n\t\t\tconst last = items.at(-1);\n\t\t\tif (documents.length <= limit || !last) {\n\t\t\t\treturn { items, nextCursor: null };\n\t\t\t}\n\n\t\t\tconst values = fields.map((field) => {\n\t\t\t\tconst value = last[field];\n\t\t\t\tif (value === null || value === undefined) {\n\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t`paginateByCursor: \"${field}\" is null in a document of \"${name}\". ` +\n\t\t\t\t\t\t\t'Page along a field every document has.',\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t});\n\t\t\treturn { items, nextCursor: encodeCursor({ key: cursorKey, values }) };\n\t\t},\n\t};\n\n\treturn repository;\n}\n",
16
17
  "import type { ClientSession, MongoClient, TransactionOptions } from 'mongodb';\nimport { toDataError } from '../errors/to-data-error';\n\n/** What a transaction can be started from: a client, or a session. */\nexport type TransactionHost = MongoClient | ClientSession;\n\n/** A session, read without `instanceof`: two copies of the driver. */\nfunction isSession(host: TransactionHost): host is ClientSession {\n\treturn typeof (host as ClientSession).inTransaction === 'function';\n}\n\n/**\n * Runs `fn` in a transaction: committed when it resolves, aborted when it\n * throws, and a MongoDB error turned into a `DataError` on the way out. The\n * session is the argument, and **every operation inside has to be given it**:\n * MongoDB has no ambient session, so an operation without one runs outside the\n * transaction and is not rolled back. `repository.with(session)` is how a\n * repository takes it.\n *\n * ```ts\n * await withTransaction(client, async (session) => {\n * \tconst team = await teams.with(session).create({ name: 'Core' });\n * \tawait users.with(session).update(userId, { teamId: team._id });\n * });\n * ```\n *\n * Given a session that is already in a transaction, it **joins** it: `fn` runs\n * with that session and nothing is committed until the outer one commits.\n * MongoDB has no savepoints, so an inner failure cannot be rolled back on its\n * own, and starting a second transaction on one session throws\n * `MongoTransactionError`.\n *\n * Two things the driver does that are easy to be surprised by:\n *\n * - it **retries `fn`** from the start on a `TransientTransactionError`, and\n * the commit alone on an `UnknownTransactionCommitResult`, until 120 seconds\n * have passed. `fn` must therefore be safe to run twice.\n * - `session.abortTransaction()` inside `fn` ends the transaction without\n * throwing: `withTransaction` then resolves.\n */\nexport async function withTransaction<T>(\n\thost: TransactionHost,\n\tfn: (session: ClientSession) => Promise<T>,\n\toptions?: TransactionOptions,\n): Promise<T> {\n\ttry {\n\t\tif (isSession(host)) {\n\t\t\tif (host.inTransaction()) {\n\t\t\t\tif (options) {\n\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t'withTransaction: this session is already in a transaction, which ' +\n\t\t\t\t\t\t\t'this call joins. MongoDB has no savepoints, so the read ' +\n\t\t\t\t\t\t\t'concern, the write concern and the read preference are the ' +\n\t\t\t\t\t\t\t'outer transaction’s.',\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn await fn(host);\n\t\t\t}\n\t\t\treturn await host.withTransaction(fn, options);\n\t\t}\n\n\t\tconst session = host.startSession();\n\t\ttry {\n\t\t\treturn await session.withTransaction(fn, options);\n\t\t} finally {\n\t\t\tawait session.endSession();\n\t\t}\n\t} catch (error) {\n\t\tthrow toDataError(error);\n\t}\n}\n"
17
18
  ],
18
- "mappings": "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",
19
- "debugId": "44372BBBC1BF50A464756E2164756E21",
19
+ "mappings": "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",
20
+ "debugId": "5C569B791BADEA5664756E2164756E21",
20
21
  "names": []
21
22
  }
@@ -1,5 +1,5 @@
1
1
  import type { ClientSession, Collection, Db, Filter, Sort, UpdateFilter } from 'mongodb';
2
- import type { DocumentOf, FieldOf, IdOf, NewDocumentOf } from '../definition/define-collection';
2
+ import type { DocumentOf, FieldOf, IdOf, NewDocumentOf, ReadDocumentOf } from '../definition/define-collection';
3
3
  import type { CursorPage, Page, PageOptions } from '../pagination/page';
4
4
  import type { SyncOptions, SyncReport } from '../sync/sync-collection';
5
5
  export type OrderDirection = 'asc' | 'desc';
@@ -44,6 +44,8 @@ export interface CursorPaginateOptions<Def> extends ReadOptions {
44
44
  */
45
45
  export type Patch<Def> = Partial<DocumentOf<Def>> | (UpdateFilter<DocumentOf<Def>> & {
46
46
  [K in keyof DocumentOf<Def>]?: never;
47
+ } & {
48
+ id?: never;
47
49
  });
48
50
  export interface UpdateOptions {
49
51
  /**
@@ -105,41 +107,41 @@ export interface Repository<Def> {
105
107
  /** Creates the collection, its validator and its indexes. See `syncCollection`. */
106
108
  sync(options?: SyncOptions): Promise<SyncReport>;
107
109
  /** The document with this `_id`, or `undefined`. */
108
- findById(id: IdOf<Def>, options?: ReadOptions): Promise<DocumentOf<Def> | undefined>;
110
+ findById(id: IdOf<Def>, options?: ReadOptions): Promise<ReadDocumentOf<Def> | undefined>;
109
111
  /** The document with this `_id`. Throws `NotFoundError`. */
110
- getById(id: IdOf<Def>, options?: ReadOptions): Promise<DocumentOf<Def>>;
112
+ getById(id: IdOf<Def>, options?: ReadOptions): Promise<ReadDocumentOf<Def>>;
111
113
  /** The first document that matches, or `undefined`. */
112
- findFirst(filter?: Filter<DocumentOf<Def>>, options?: FindFirstOptions<Def>): Promise<DocumentOf<Def> | undefined>;
114
+ findFirst(filter?: Filter<DocumentOf<Def>>, options?: FindFirstOptions<Def>): Promise<ReadDocumentOf<Def> | undefined>;
113
115
  /** Every document that matches. */
114
- findMany(options?: FindManyOptions<Def>): Promise<DocumentOf<Def>[]>;
116
+ findMany(options?: FindManyOptions<Def>): Promise<ReadDocumentOf<Def>[]>;
115
117
  /** Checks the document against the schema, fills its defaults, inserts it. */
116
- create(values: NewDocumentOf<Def>): Promise<DocumentOf<Def>>;
118
+ create(values: NewDocumentOf<Def>): Promise<ReadDocumentOf<Def>>;
117
119
  /** The same, in one insert. `[]` sends nothing. */
118
- createMany(values: readonly NewDocumentOf<Def>[]): Promise<DocumentOf<Def>[]>;
120
+ createMany(values: readonly NewDocumentOf<Def>[]): Promise<ReadDocumentOf<Def>[]>;
119
121
  /** Updates the document with this `_id` and returns it. Throws `NotFoundError`. */
120
- update(id: IdOf<Def>, patch: Patch<Def>, options?: UpdateOptions): Promise<DocumentOf<Def>>;
122
+ update(id: IdOf<Def>, patch: Patch<Def>, options?: UpdateOptions): Promise<ReadDocumentOf<Def>>;
121
123
  /** Updates every document that matches, and returns how many changed. */
122
124
  updateMany(filter: Filter<DocumentOf<Def>>, patch: Patch<Def>): Promise<number>;
123
125
  /**
124
126
  * Deletes the document with this `_id` and returns it: a soft delete on a
125
127
  * collection with `deletedAt`. Throws `NotFoundError`.
126
128
  */
127
- delete(id: IdOf<Def>): Promise<DocumentOf<Def>>;
129
+ delete(id: IdOf<Def>): Promise<ReadDocumentOf<Def>>;
128
130
  /** Deletes every document that matches, and returns how many. */
129
131
  deleteMany(filter: Filter<DocumentOf<Def>>): Promise<number>;
130
132
  /** A real delete, of a live or a soft-deleted document. */
131
- hardDelete(id: IdOf<Def>): Promise<DocumentOf<Def>>;
133
+ hardDelete(id: IdOf<Def>): Promise<ReadDocumentOf<Def>>;
132
134
  /** A real delete of every document that matches, soft-deleted ones included. */
133
135
  hardDeleteMany(filter: Filter<DocumentOf<Def>>): Promise<number>;
134
136
  /** Clears `deletedAt` and returns the document. Throws `NotFoundError`. */
135
- restore(id: IdOf<Def>): Promise<DocumentOf<Def>>;
137
+ restore(id: IdOf<Def>): Promise<ReadDocumentOf<Def>>;
136
138
  /** How many documents match. */
137
139
  count(filter?: Filter<DocumentOf<Def>>, options?: ReadOptions): Promise<number>;
138
140
  /** Whether any document matches. */
139
141
  exists(filter: Filter<DocumentOf<Def>>, options?: ReadOptions): Promise<boolean>;
140
142
  /** One page of the documents that match, and how many there are. */
141
- paginate(options?: PaginateOptions<Def>): Promise<Page<DocumentOf<Def>>>;
143
+ paginate(options?: PaginateOptions<Def>): Promise<Page<ReadDocumentOf<Def>>>;
142
144
  /** One page of the documents that match, after a cursor. */
143
- paginateByCursor(options?: CursorPaginateOptions<Def>): Promise<CursorPage<DocumentOf<Def>>>;
145
+ paginateByCursor(options?: CursorPaginateOptions<Def>): Promise<CursorPage<ReadDocumentOf<Def>>>;
144
146
  }
145
147
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/repository/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/repository/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxgt/mongo",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "A typed MongoDB collection from a Zod schema: its indexes and $jsonSchema validator synced idempotently, a typed repository with pagination, transactions, optimistic locking, soft delete and its own errors",
5
5
  "license": "MIT",
6
6
  "type": "module",