@nxgt/mongo-kit 0.1.4 → 0.1.5

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.
@@ -0,0 +1,565 @@
1
+ # Troubleshooting
2
+
3
+ Every heading is the text the error prints, so the page can be searched with
4
+ what you have in front of you. Stacks, ids and paths are cut.
5
+
6
+ | Area | Entries |
7
+ | --- | --- |
8
+ | [Install](#install) | [ERESOLVE](#npm-error-eresolve-unable-to-resolve-dependency-tree) · [incorrect peer dependency](#warn-incorrect-peer-dependency-nxgtmongo0140) · [TS2307](#error-ts2307-cannot-find-module-nxgtmongo-or-its-corresponding-type-declarations) |
9
+ | [Types](#types) | [a key the `Db` has](#command-is-a-member-of-the-drivers-db-wire-this-collection-under-another-key) · [options for a key that is not wired](#posts-is-not-wired-by-this-database-there-are-no-options-for-it) |
10
+ | [Configuration](#configuration) | [no configuration at all](#defineconfig-a-configuration-object-is-required) · [`databases` is not an object](#defineconfig-databases-is-not-an-object) · [neither a uri nor a client](#defineconfig-database-main-has-neither-a-uri-nor-a-client) · [both](#defineconfig-database-main-has-both-a-uri-and-a-client-pass-the-one-it-should-use) · [client options](#defineconfig-database-main-has-client-options-beside-a-client-it-did-not-open-pass-them-where-the-client-is-made) · [no definition in it](#defineconfig-database-main-has-a-collections-object-with-no-definition-in-it-pass-the-module-as-in-import--as-collections) · [two keys, one collection](#defineconfig-database-main-wires-users-and-people-to-the-same-collection-users) · [an option the kit decides](#defineconfig-database-main-has-session-in-options-which-the-kit-decides-) · [options for a key it does not wire](#defineconfig-database-main-has-options-for-posts-which-it-does-not-wire) · [no databases](#defineconfig-databases-names-none) |
11
+ | [Runtime](#runtime) | [a key the `Db` has, at creation](#createkit-database-main-wires-a-collection-under-command-which-is-a-member-of-the-drivers-db-it-would-be-unreachable-export-that-definition-under-another-name) · [ECONNREFUSED](#mongoserverselectionerror-connect-econnrefused-12700127017) · [one URI, two option sets](#connectmongo-this-uri-is-already-connected-with-other-options-pass-the-same-options-everywhere-or-close-the-first-connection) · [`kit.db` with several databases](#kitdb-this-kit-has-several-databases-read-the-one-you-mean-as-kitdatabasesmain) · [an unknown database](#this-kit-has-no-database-reporting-it-has-main-analytics) · [closing a derived kit](#close-this-kit-came-from-as-withsession-or-a-transaction-close-the-kit-createkit-returned--the-clients-are-shared) · [`sync()` and privileges](#not-authorized-on-app-to-execute-command--collmod-users--) |
12
+ | [Transactions](#transactions) | [more than one client](#transaction-this-kit-holds-more-than-one-client-and-a-transaction-lives-on-one-name-the-database-it-runs-on-as--on-main-) · [already in a session](#transaction-this-kit-is-already-in-a-session-which-this-call-joins-so-on-has-no-client-left-to-choose) · [a session from another client](#clientsession-must-be-from-the-same-mongoclient) · [no replica set](#this-mongodb-deployment-does-not-support-retryable-writes-please-add-retrywritesfalse-to-your-connection-string) |
13
+ | [Scripts](#scripts) | [`Bun is not defined`](#referenceerror-bun-is-not-defined) · [no glob](#discovercollections-a-glob-is-required) · [two files, one collection](#discovercollections-srcmodelsonemodelts-and-srcmodelstwomodelts-both-define-the-collection-twice) · [no definition of that name](#discovercollections-srcmodelsnotests-exports-no-definition-named-definition) |
14
+
15
+ ## Install
16
+
17
+ ### `npm error ERESOLVE unable to resolve dependency tree`
18
+
19
+ ```
20
+ npm error Found: @nxgt/mongo@0.14.0
21
+ npm error Could not resolve dependency:
22
+ npm error peer @nxgt/mongo@"^0.15.0" from @nxgt/mongo-kit@0.1.4
23
+ ```
24
+
25
+ **When:** `npm install`, before anything is downloaded.
26
+
27
+ **Why:** `@nxgt/mongo` is a **required peer**, and the range is a caret on a
28
+ 0.x version, so it accepts one minor only. The collections, their options and
29
+ their behaviour are `@nxgt/mongo`'s; this package only wires them, and the two
30
+ have to be the same copy. `mongodb` (`>=7.0.0 <8`) and `typescript` (`^6.0.3`)
31
+ are peers on the same terms.
32
+
33
+ **Fix:**
34
+
35
+ ```sh
36
+ npm install @nxgt/mongo@^0.15.0 @nxgt/mongo-kit mongodb zod
37
+ ```
38
+
39
+ Raise the sibling rather than install past the conflict: `--force` and
40
+ `--legacy-peer-deps` leave two copies of `@nxgt/mongo` in the tree, and the
41
+ definitions one of them builds are not the ones the other wires.
42
+
43
+ ### `warn: incorrect peer dependency "@nxgt/mongo@0.14.0"`
44
+
45
+ **When:** `bun install`, which prints it and carries on.
46
+
47
+ **Why:** bun does not fail on an unmet peer — it warns and installs what the
48
+ manifest asked for. The kit then runs against a `@nxgt/mongo` it was not built
49
+ against: a stamp option or a collection option added in the newer minor is
50
+ missing at run time, with no error until the call that needs it.
51
+
52
+ **Fix:**
53
+
54
+ ```sh
55
+ bun add @nxgt/mongo@^0.15.0
56
+ ```
57
+
58
+ Treat that warning as an error. `bun pm ls` shows which version was resolved.
59
+
60
+ ### `error TS2307: Cannot find module '@nxgt/mongo' or its corresponding type declarations.`
61
+
62
+ At run time the same tree gives
63
+ `Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@nxgt/mongo'` under Node,
64
+ and `error: Cannot find module '@nxgt/mongo'` under Bun.
65
+
66
+ **When:** the first build or the first import of your own code, typically
67
+ under pnpm or npm with a strict `node_modules` layout.
68
+
69
+ **Why:** a peer installed *for* the kit is not a dependency of **your**
70
+ package. pnpm hoists it under the kit alone, so `@nxgt/mongo-kit` resolves it
71
+ and your `import { defineCollection } from '@nxgt/mongo'` does not.
72
+
73
+ **Fix:**
74
+
75
+ ```sh
76
+ bun add @nxgt/mongo @nxgt/mongo-kit mongodb zod
77
+ ```
78
+
79
+ Declare every peer you import from yourself — you import `@nxgt/mongo` as soon
80
+ as you write a `defineCollection`.
81
+
82
+ ## Types
83
+
84
+ ### `"command" is a member of the driver's Db: wire this collection under another key`
85
+
86
+ The whole line is a `TS2322`:
87
+
88
+ ```
89
+ error TS2322: Type 'CollectionDefinition<…>' is not assignable to type
90
+ 'CollectionDefinition<…> & "\"command\" is a member of the driver's Db: wire this collection under another key"'.
91
+ ```
92
+
93
+ **When:** compiling the file that calls `defineConfig`.
94
+
95
+ **Why:** `kit.db` is the driver's `Db` with the collections on it, so a key the
96
+ `Db` already answers to — `command`, `watch`, `collection`, `admin`,
97
+ `databaseName`… — would be unreachable, and reading it would give the driver's
98
+ member instead of your collection. The reserved names are read from the
99
+ driver's own type (`ReservedName = keyof Db`), so a member a later driver
100
+ release adds is refused the day the pin moves.
101
+
102
+ **Fix:** export the definition under another name.
103
+
104
+ ```ts
105
+ // src/models/commands.model.ts
106
+ export const commandLog = defineCollection({ name: 'commands', schema });
107
+ // ^ the key on `kit.db`; `name` is the collection on the server
108
+ ```
109
+
110
+ The key is the **export name**, not the collection's `name`: only the export
111
+ name has to change.
112
+
113
+ ### `"posts" is not wired by this database: there are no options for it`
114
+
115
+ **When:** compiling a `defineConfig` whose `optionsFor` names a key its
116
+ `collections` does not hold.
117
+
118
+ **Why:** `optionsFor` is keyed by the same export names as `collections`, and
119
+ options written for a key that is not wired would silently do nothing —
120
+ usually a renamed or moved model.
121
+
122
+ **Fix:**
123
+
124
+ ```ts
125
+ defineConfig({
126
+ uri: process.env.MONGO_URI!,
127
+ collections, // `import * as collections from './models'`
128
+ optionsFor: { articles: { maxPageSize: 200 } }, // a key `collections` exports
129
+ });
130
+ ```
131
+
132
+ ## Configuration
133
+
134
+ `defineConfig` connects to nothing: everything below throws where the
135
+ configuration is written, before the application starts.
136
+
137
+ ### `defineConfig: a configuration object is required`
138
+
139
+ **When:** calling `defineConfig` with nothing, `undefined` or `null` — usually
140
+ a config read from a module that exports it under another name, or a value
141
+ built at run time that came out empty.
142
+
143
+ **Why:** the configuration is read as an object before anything else is
144
+ checked, so there is nothing to name a database with. A `defineConfig(config)`
145
+ where `config` is `undefined` is most often an import that resolved to
146
+ `undefined`: a default export read as a named one, or two modules importing
147
+ each other, so one of them is still empty when the other runs.
148
+
149
+ **Fix:** write the config as a literal, where the compiler sees its shape:
150
+
151
+ ```ts
152
+ import * as collections from './models';
153
+
154
+ export const config = defineConfig({ uri, collections });
155
+ ```
156
+
157
+ ### `defineConfig: databases is not an object`
158
+
159
+ **When:** calling `defineConfig` with a `databases` that is a string, a number
160
+ or `null`.
161
+
162
+ **Why:** `databases` is the multi-database shape, and its **keys** are the
163
+ names — `databases: 'main'` looks like naming the one database, which is what
164
+ `database` does. A single database says `database`, several say `databases`.
165
+
166
+ **Fix:**
167
+
168
+ ```ts
169
+ defineConfig({ uri, database: 'analytics', collections }); // one database
170
+ defineConfig({ databases: { main: { uri, collections } } }); // several
171
+ ```
172
+
173
+ `database` is the database on the server; the key under `databases` is the
174
+ name your code reads it by, as `kit.databases.main`.
175
+
176
+ ### `defineConfig: database "main" has neither a uri nor a client`
177
+
178
+ **When:** calling `defineConfig`.
179
+
180
+ **Why:** a database says where it is exactly once. This is most often an
181
+ environment variable that was not read — `process.env.MONGO_URI` is
182
+ `undefined`, so the property is absent.
183
+
184
+ **Fix:**
185
+
186
+ ```ts
187
+ const uri = process.env.MONGO_URI;
188
+ if (!uri) throw new Error('MONGO_URI is not set');
189
+ export const config = defineConfig({ uri, collections });
190
+ ```
191
+
192
+ ### `defineConfig: database "main" has both a uri and a client: pass the one it should use`
193
+
194
+ **When:** calling `defineConfig`.
195
+
196
+ **Why:** the two mean different things about closing: with a `uri` the kit
197
+ opens the client and `close()` gives it back, with a `client` it uses yours and
198
+ never closes it. It will not guess which you meant.
199
+
200
+ **Fix:**
201
+
202
+ ```ts
203
+ defineConfig({ client, database: 'main', collections }); // yours to close
204
+ ```
205
+
206
+ ### `defineConfig: database "main" has client options beside a client it did not open: pass them where the client is made`
207
+
208
+ **When:** calling `defineConfig` with both `client` and `clientOptions`.
209
+
210
+ **Why:** `clientOptions` is what the kit passes to the driver when it opens a
211
+ client. A client that is already open cannot take them, so they would be
212
+ ignored.
213
+
214
+ **Fix:**
215
+
216
+ ```ts
217
+ const client = new MongoClient(uri, { maxPoolSize: 50 }); // here
218
+ defineConfig({ client, collections });
219
+ ```
220
+
221
+ ### `` defineConfig: database "main" has a collections object with no definition in it: pass the module, as in `import * as collections` ``
222
+
223
+ **When:** calling `defineConfig`.
224
+
225
+ **Why:** the object holds no value that looks like a `defineCollection` —
226
+ usually a module of *types* only, a default export, or a barrel whose files
227
+ export builders rather than definitions.
228
+
229
+ **Fix:**
230
+
231
+ ```ts
232
+ // src/models/index.ts
233
+ export * from './users.model'; // `export const users = defineCollection(…)`
234
+ export * from './posts.model';
235
+
236
+ // src/db.ts
237
+ import * as collections from './models';
238
+ defineConfig({ uri, collections });
239
+ ```
240
+
241
+ Anything in that module that is not a definition — a function, a constant, a
242
+ type — is left out of the scope rather than refused.
243
+
244
+ ### `defineConfig: database "main" wires "users" and "people" to the same collection, "users"`
245
+
246
+ **When:** calling `defineConfig`.
247
+
248
+ **Why:** two exports carry definitions with the same `name`, so two keys on
249
+ `kit.db` would write to one server collection with two schemas and two sets of
250
+ options. Usually a copy-and-pasted model whose `name` was not changed.
251
+
252
+ **Fix:**
253
+
254
+ ```ts
255
+ export const people = defineCollection({ name: 'people', schema });
256
+ // ^ one `name` per collection
257
+ ```
258
+
259
+ ### `defineConfig: database "main" has "session" in options, which the kit decides: …`
260
+
261
+ The full message names what to use instead:
262
+
263
+ ```text
264
+ defineConfig: database "main" has "session" in options, which the kit decides:
265
+ a database is named by its key, `as` and `withSession` carry the actor and the
266
+ session, and `autoSync` is the database's
267
+ ```
268
+
269
+ The same refusal covers `db`, `actor` and `autoSync`, in `options` and under
270
+ `optionsFor` — where the text reads `has "session" in the options of "users"`.
271
+
272
+ **When:** calling `defineConfig`.
273
+
274
+ **Why:** those four are the kit's. A `session` pinned in the config would
275
+ outrank the one a transaction hands the collection, and the write would land
276
+ outside the transaction.
277
+
278
+ **Fix:**
279
+
280
+ ```ts
281
+ const kit = await createKit(config);
282
+ await kit.transaction(async (tx) => { // the session is the kit's
283
+ await tx.db.users.create({ email: 'ada@example.com' });
284
+ });
285
+ ```
286
+
287
+ `autoSync` belongs to the database, beside `collections`, not to a collection's
288
+ options.
289
+
290
+ ### `defineConfig: database "main" has options for "posts", which it does not wire`
291
+
292
+ **When:** calling `defineConfig`, when the types were bypassed — an `as never`,
293
+ a config built at run time, or JavaScript.
294
+
295
+ **Why:** the same cause as the type error
296
+ [above](#posts-is-not-wired-by-this-database-there-are-no-options-for-it):
297
+ `optionsFor` names a key `collections` does not export.
298
+
299
+ **Fix:** write the config as a literal, so the compiler refuses it first:
300
+
301
+ ```ts
302
+ export const config = defineConfig({ uri, collections, optionsFor: { users: {} } });
303
+ ```
304
+
305
+ ### `defineConfig: databases names none`
306
+
307
+ **When:** calling `defineConfig` with `databases: {}`.
308
+
309
+ **Why:** the multi-database shape was used and the object came out empty —
310
+ typically built from environment variables that were not set.
311
+
312
+ **Fix:**
313
+
314
+ ```ts
315
+ defineConfig({ databases: { main: { uri, collections } } });
316
+ ```
317
+
318
+ ## Runtime
319
+
320
+ ### `createKit: database "main" wires a collection under "command", which is a member of the driver's Db: it would be unreachable. Export that definition under another name.`
321
+
322
+ **When:** `await createKit(config)`, and the connections opened before it are
323
+ given back before it throws.
324
+
325
+ **Why:** the same collision as the
326
+ [type error](#command-is-a-member-of-the-drivers-db-wire-this-collection-under-another-key),
327
+ asked of the live `Db` object rather than of its type. It fires when the types
328
+ were bypassed, and when a driver release adds a member your key already uses.
329
+
330
+ **Fix:** rename the export, as above. If the driver added the member, raising
331
+ `mongodb` is what surfaced it — the check is deliberate, not a regression.
332
+
333
+ ### `MongoServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017`
334
+
335
+ **When:** `await createKit(config)` — never at `defineConfig`.
336
+
337
+ **Why:** `defineConfig` connects to nothing; `createKit` is the one call that
338
+ opens clients. A wrong URI, a server that is not up, or an unreachable host
339
+ therefore fails at start-up, not at the first query.
340
+
341
+ **Fix:** check the connection where the application starts, and let it fail
342
+ there:
343
+
344
+ ```ts
345
+ export const kit = await createKit(config); // top level: a bad URI stops the boot
346
+ ```
347
+
348
+ ### `connectMongo: this URI is already connected with other options. Pass the same options everywhere, or close the first connection.`
349
+
350
+ **When:** `createKit`, or a second `createKit` in the same process.
351
+
352
+ **Why:** `@nxgt/mongo` shares one client per URI, and a shared client can only
353
+ have one set of options. Two databases on one URI with different
354
+ `clientOptions` — or a test that builds a second kit with other options —
355
+ ask for two.
356
+
357
+ **Fix:** give the same options on that URI, and name the databases instead:
358
+
359
+ ```ts
360
+ defineConfig({
361
+ databases: {
362
+ main: { uri, database: 'main', collections },
363
+ analytics: { uri, database: 'analytics', collections: events },
364
+ },
365
+ });
366
+ ```
367
+
368
+ Both databases then share the one client, which is the point.
369
+
370
+ ### ``kit.db: this kit has several databases. Read the one you mean, as `kit.databases.main`.``
371
+
372
+ **When:** reading `kit.db` on a kit built from a `databases` config.
373
+
374
+ **Why:** `db` is the sole database's scope. With several there is no sole one,
375
+ so its type is already `never` — this is what a cast or a JavaScript call-site
376
+ gets at run time.
377
+
378
+ **Fix:**
379
+
380
+ ```ts
381
+ await kit.databases.main.users.create({ email: 'ada@example.com' });
382
+ ```
383
+
384
+ ### `This kit has no database "reporting": it has "main", "analytics".`
385
+
386
+ **When:** `transaction(fn, { on })` with a name the config does not hold.
387
+
388
+ **Why:** the names are the keys of `databases` in the config, nothing else —
389
+ not the database names on the server. (Reading `kit.databases.<name>` for a
390
+ name that is not there does not throw: it does not compile, and gives
391
+ `undefined` where the types were bypassed.)
392
+
393
+ **Fix:**
394
+
395
+ ```ts
396
+ await kit.transaction(fn, { on: 'main' }); // a key of `config.databases`
397
+ ```
398
+
399
+ ### ``close: this kit came from `as`, `withSession` or a transaction. Close the kit `createKit` returned — the clients are shared.``
400
+
401
+ **When:** `close()` — including the implicit one of `await using` — on a kit
402
+ that came from `as`, `withSession`, or the one handed to a transaction body.
403
+
404
+ **Why:** a derived kit shares the databases and the clients of the kit
405
+ `createKit` returned. Closing it would take the connections from every other
406
+ kit derived from the same root.
407
+
408
+ **Fix:** keep `await using` for the root, and let the derived ones fall away:
409
+
410
+ ```ts
411
+ await using kit = await createKit(config); // the only one to close
412
+ const actorKit = kit.as(userId); // no close, nothing to give back
413
+ ```
414
+
415
+ ### `not authorized on app to execute command { collMod: "users", … }`
416
+
417
+ **When:** `kit.sync()`, or the first operation of a collection when
418
+ `autoSync: true`.
419
+
420
+ **Why:** applying a `$jsonSchema` validator and the collection options is
421
+ `collMod`, which needs `dbAdmin`; `readWrite` alone is enough for the indexes
422
+ and every data operation but not for that.
423
+
424
+ **Fix:** run `sync()` as a deployment step, with a user that has `dbAdmin`, and
425
+ leave the application's own user on `readWrite`:
426
+
427
+ ```ts
428
+ // scripts/sync.ts — run with the migration user, not the app's
429
+ await using kit = await createKit(config);
430
+ await kit.sync();
431
+ ```
432
+
433
+ `autoSync` is for tests and development for the same reason.
434
+
435
+ ## Transactions
436
+
437
+ ### ``transaction: this kit holds more than one client, and a transaction lives on one. Name the database it runs on, as `{ on: 'main' }`.``
438
+
439
+ **When:** `kit.transaction(fn)` on a kit whose databases are on more than one
440
+ client.
441
+
442
+ **Why:** a transaction lives on a single client, and the types cannot decide:
443
+ two databases on one URI share a client and need no `on`, so what matters is
444
+ the number of *clients*, which is known only once they are open.
445
+
446
+ **Fix:**
447
+
448
+ ```ts
449
+ await kit.transaction((tx) => tx.databases.main.users.create(user), { on: 'main' });
450
+ ```
451
+
452
+ ### ``transaction: this kit is already in a session, which this call joins, so `on` has no client left to choose.``
453
+
454
+ **When:** `transaction({ on })` inside a transaction body, or on a kit from
455
+ `withSession`.
456
+
457
+ **Why:** a nested transaction **joins** the outer one rather than opening a
458
+ second beside it, so it runs on the session that is already open — there is no
459
+ client left to pick.
460
+
461
+ **Fix:**
462
+
463
+ ```ts
464
+ await kit.transaction(async (tx) => {
465
+ await service(tx); // its own `tx.transaction(fn)` joins this one
466
+ }, { on: 'main' }); // `on` belongs to the outermost call
467
+ ```
468
+
469
+ ### `ClientSession must be from the same MongoClient`
470
+
471
+ A `MongoInvalidArgumentError`, from the driver.
472
+
473
+ **When:** inside a transaction body, touching a database that is on another
474
+ client than the one the transaction runs on.
475
+
476
+ **Why:** a transaction reaches the databases of **one** client. With
477
+ `{ on: 'main' }`, an operation on a database of a second client carries a
478
+ session that client does not own, and the driver refuses it.
479
+
480
+ **Fix:** put the two databases on one client, or write two transactions and
481
+ accept that they do not commit together:
482
+
483
+ ```ts
484
+ await kit.transaction((tx) => tx.databases.main.users.create(user), { on: 'main' });
485
+ await kit.databases.analytics.events.create({ kind: 'signup' }); // outside it
486
+ ```
487
+
488
+ ### `This MongoDB deployment does not support retryable writes. Please add retryWrites=false to your connection string.`
489
+
490
+ **When:** the first `kit.transaction(…)` against a standalone `mongod`.
491
+
492
+ **Why:** the message is the driver's, and it is misleading: transactions need a
493
+ **replica set**, and a standalone has no transactions with or without retryable
494
+ writes. Turning `retryWrites` off does not help.
495
+
496
+ **Fix:** run a replica set — a single node is enough, and is what this
497
+ package's own specs use:
498
+
499
+ ```sh
500
+ mongod --replSet rs0 --dbpath ./data # then, once: rs.initiate()
501
+ ```
502
+
503
+ ## Scripts
504
+
505
+ `discoverCollections` is for scripts run from the repository: it reads a glob
506
+ from the file system, gives no types, and does not survive bundling.
507
+
508
+ ### `ReferenceError: Bun is not defined`
509
+
510
+ **When:** calling `discoverCollections` from a script run by Node.
511
+
512
+ **Why:** the glob is `Bun.Glob`. This one function needs the Bun runtime;
513
+ everything else in the package runs anywhere.
514
+
515
+ **Fix:** run the script with Bun, or wire the collections statically — which is
516
+ what an application does anyway:
517
+
518
+ ```ts
519
+ import * as collections from './models'; // a bundler follows this, Bun.Glob is not needed
520
+ ```
521
+
522
+ ### `discoverCollections: a glob is required`
523
+
524
+ **When:** running the script, with `glob` empty or absent — typically an
525
+ argument the script was not given, or an environment variable that is unset.
526
+
527
+ **Why:** the glob is the only thing that says which files to read. An empty
528
+ one matches nothing, and a discovery that came back empty would sync no
529
+ collection at all without saying so, so it is refused instead.
530
+
531
+ **Fix:** give the option a default the script can run with:
532
+
533
+ ```ts
534
+ const glob = process.argv[2] ?? 'src/models/*.model.ts';
535
+ const definitions = await discoverCollections({ glob });
536
+ ```
537
+
538
+ ### `discoverCollections: src/models/one.model.ts and src/models/two.model.ts both define the collection "twice"`
539
+
540
+ **When:** running the script, while reading the files the glob matched.
541
+
542
+ **Why:** two matched files export definitions with the same collection `name`.
543
+ A sync driven from them would apply two schemas to one server collection.
544
+
545
+ **Fix:** give each collection its own `name`, or narrow the glob so only the
546
+ files you mean are read:
547
+
548
+ ```ts
549
+ await discoverCollections({ glob: 'src/models/*.model.ts' });
550
+ ```
551
+
552
+ ### `discoverCollections: src/models/notes.ts exports no definition named "definition"`
553
+
554
+ **When:** running the script with the `export` option set.
555
+
556
+ **Why:** `export` names the single export to read in each matched file, and one
557
+ of them does not have it — or has it under that name holding something that is
558
+ not a definition.
559
+
560
+ **Fix:** drop the option and let every definition in each file be read, which
561
+ is what `import * as collections` gives:
562
+
563
+ ```ts
564
+ await discoverCollections({ glob: 'src/models/*.model.ts' });
565
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxgt/mongo-kit",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "An application's MongoDB wiring in one object: a validated config, the clients it opens from it, and every collection typed on the database it lives in",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -8,6 +8,7 @@
8
8
  "types": "./dist/index.d.ts",
9
9
  "files": [
10
10
  "dist",
11
+ "docs",
11
12
  "README.md",
12
13
  "package.json",
13
14
  "LICENSE"
@@ -47,14 +48,14 @@
47
48
  ]
48
49
  },
49
50
  "devDependencies": {
50
- "@nxgt/mongo": "^0.15.0",
51
+ "@nxgt/mongo": "^0.15.1",
51
52
  "@types/bun": "^1.4.0",
52
53
  "mongodb": "7.6.0",
53
54
  "mongodb-memory-server-core": "11.2.0",
54
55
  "zod": "4.6.5"
55
56
  },
56
57
  "peerDependencies": {
57
- "@nxgt/mongo": "^0.15.0",
58
+ "@nxgt/mongo": "^0.15.1",
58
59
  "mongodb": ">=7.0.0 <8",
59
60
  "typescript": "^6.0.3"
60
61
  }