@nxgt/mongo-kit 0.1.4 → 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 +56 -4
- package/dist/config/checks.d.ts.map +1 -1
- package/dist/config/define-config.d.ts.map +1 -1
- package/dist/discover.d.ts.map +1 -1
- package/dist/errors/kit-error.d.ts +41 -0
- package/dist/errors/kit-error.d.ts.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +44 -30
- package/dist/index.js.map +11 -10
- package/dist/kit/context.d.ts.map +1 -1
- package/dist/kit/create-kit.d.ts.map +1 -1
- package/dist/kit/derive.d.ts.map +1 -1
- package/dist/kit/transaction.d.ts.map +1 -1
- package/docs/README.md +15 -0
- package/docs/guide/actor-and-transactions.md +196 -0
- package/docs/guide/configuration.md +230 -0
- package/docs/guide/db-scope.md +174 -0
- package/docs/guide/discover-collections.md +85 -0
- package/docs/guide/errors.md +198 -0
- package/docs/guide/sync.md +108 -0
- package/docs/roadmap.md +68 -0
- package/docs/troubleshooting.md +595 -0
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -218,6 +218,40 @@ definition under it; without `export`, every export that is a definition is
|
|
|
218
218
|
taken. Two files defining the same server collection are refused. It needs
|
|
219
219
|
the Bun runtime, and it is for scripts.
|
|
220
220
|
|
|
221
|
+
## Errors
|
|
222
|
+
|
|
223
|
+
`KitError` is what this package refuses: a configuration, a name or a call
|
|
224
|
+
that cannot work. It carries a `code`, and the `database` and `key` it is
|
|
225
|
+
about — never a URI, which may hold a password.
|
|
226
|
+
|
|
227
|
+
```ts
|
|
228
|
+
import { KitError } from '@nxgt/mongo-kit';
|
|
229
|
+
|
|
230
|
+
if (error instanceof KitError && error.code === 'CONFIG') {
|
|
231
|
+
console.error(`mongo: "${error.database}" is misconfigured`, error.message);
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
| `KitErrorCode` | |
|
|
236
|
+
| --- | --- |
|
|
237
|
+
| `CONFIG` | `defineConfig` refused the configuration |
|
|
238
|
+
| `COLLISION` | a collection is wired under a name the driver's `Db` has |
|
|
239
|
+
| `NO_DATABASE` | `transaction(fn, { on })` named a database this kit does not hold |
|
|
240
|
+
| `SEVERAL_DATABASES` | `kit.db` was read on a kit that holds more than one |
|
|
241
|
+
| `TRANSACTION` | no client named where one is needed, or `{ on }` inside a session |
|
|
242
|
+
| `DERIVED` | `close()` on a kit `as`, `withSession` or a transaction derived |
|
|
243
|
+
| `DISCOVERY` | `discoverCollections` could not make a set of definitions |
|
|
244
|
+
|
|
245
|
+
It extends **`TypeError`**, not `Error`: each of these is a call or a
|
|
246
|
+
configuration written wrong, and this package threw bare `TypeError`s before
|
|
247
|
+
the class existed, so a `catch` that tests for `TypeError` still matches.
|
|
248
|
+
|
|
249
|
+
The collections are `@nxgt/mongo`'s, so what a *query* throws is its
|
|
250
|
+
`DataError` and its subclasses, unchanged. MongoDB's own refusal to connect
|
|
251
|
+
reaches the caller from `createKit` as the driver's error. Every code, with
|
|
252
|
+
the call that raises it, is in
|
|
253
|
+
[docs/guide/errors.md](docs/guide/errors.md).
|
|
254
|
+
|
|
221
255
|
## What does not compile
|
|
222
256
|
|
|
223
257
|
Each is a `@ts-expect-error` case in this package's type tests.
|
|
@@ -250,7 +284,7 @@ Each is a `@ts-expect-error` case in this package's type tests.
|
|
|
250
284
|
deployment step: it needs `dbAdmin`, and an index build is not in a
|
|
251
285
|
transaction.
|
|
252
286
|
- **A kit from `as` or `withSession` cannot be closed**, and `close()` on it
|
|
253
|
-
throws
|
|
287
|
+
throws `KitError` with the code `DERIVED`: the clients are the root kit's.
|
|
254
288
|
- **`discoverCollections` runs under Bun**, has no types, and does not
|
|
255
289
|
survive bundling. It is for scripts run from the repository; a Node script
|
|
256
290
|
calling it gets `Bun is not defined`.
|
|
@@ -258,15 +292,33 @@ Each is a `@ts-expect-error` case in this package's type tests.
|
|
|
258
292
|
uncallable: one call could not stamp both.
|
|
259
293
|
- **`{ on }` is required at run time, not by the types**, and cannot be: two
|
|
260
294
|
databases on one URI share a client and need none, so what decides is the
|
|
261
|
-
number of *clients*. Without it, a kit holding two throws
|
|
295
|
+
number of *clients*. Without it, a kit holding two throws `TRANSACTION`.
|
|
262
296
|
- **A transaction body may run twice.** The driver retries it from the start
|
|
263
297
|
on a transient error, so it must hold nothing that MongoDB would not roll
|
|
264
298
|
back.
|
|
265
299
|
- **A transaction reaches one client's databases.** With `{ on: 'main' }`,
|
|
266
300
|
an operation on a database of another client carries a session that client
|
|
267
301
|
does not own, and the driver refuses it.
|
|
268
|
-
- **`kit.db` throws on a kit with several databases**,
|
|
269
|
-
already `never`: the message names the databases to read
|
|
302
|
+
- **`kit.db` throws `SEVERAL_DATABASES` on a kit with several databases**,
|
|
303
|
+
where its type is already `never`: the message names the databases to read
|
|
304
|
+
instead.
|
|
305
|
+
|
|
306
|
+
## Documentation
|
|
307
|
+
|
|
308
|
+
- [Guide index](docs/README.md) — every page, and when to read it.
|
|
309
|
+
- [Configuration](docs/guide/configuration.md) — the databases, the
|
|
310
|
+
collections, and the options each is built with.
|
|
311
|
+
- [The `db` scope](docs/guide/db-scope.md) — the collections on the driver's
|
|
312
|
+
`Db`, and the kit in a request.
|
|
313
|
+
- [The actor, sessions and transactions](docs/guide/actor-and-transactions.md)
|
|
314
|
+
— `as`, `withSession` and `transaction`.
|
|
315
|
+
- [Syncing](docs/guide/sync.md) — the deployment step, and `dryRun`.
|
|
316
|
+
- [Errors](docs/guide/errors.md) — `KitError`, its codes, and what each one
|
|
317
|
+
is thrown by.
|
|
318
|
+
- [`discoverCollections`](docs/guide/discover-collections.md) — definitions
|
|
319
|
+
from a glob, for scripts.
|
|
320
|
+
- [Troubleshooting](docs/troubleshooting.md) — the errors, by their message.
|
|
321
|
+
- [Roadmap](docs/roadmap.md) — what is next, and what is not planned.
|
|
270
322
|
|
|
271
323
|
## License
|
|
272
324
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../../src/config/checks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../../src/config/checks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAE3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,yEAAyE;AACzE,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,uBAAuB,CAU7E;AAED,+EAA+E;AAC/E,wBAAgB,aAAa,CAC5B,WAAW,EAAE,MAAM,GACjB,CAAC,MAAM,EAAE,uBAAuB,CAAC,EAAE,CAKrC;AAsCD,6EAA6E;AAC7E,wBAAgB,aAAa,CAC5B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,cAAc,CAAC,MAAM,CAAC,GAC5B,CAAC,MAAM,EAAE,uBAAuB,CAAC,EAAE,CA6DrC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define-config.d.ts","sourceRoot":"","sources":["../../src/config/define-config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"define-config.d.ts","sourceRoot":"","sources":["../../src/config/define-config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACX,OAAO,EAEP,SAAS,EACT,cAAc,EACd,MAAM,SAAS,CAAC;AAmCjB;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,YAAY,CAAC,KAAK,CAAC,CAAC,SAAS,cAAc,EAC1D,MAAM,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GACpB,SAAS,CAAC,CAAC,CAAC,CAQd"}
|
package/dist/discover.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../src/discover.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../src/discover.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAI3D,4DAA4D;AAC5D,MAAM,WAAW,eAAe;IAC/B,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,mBAAmB,CACxC,OAAO,EAAE,eAAe,GACtB,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAqCpC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/** What the kit refused, as a string a caller can switch on. */
|
|
2
|
+
export type KitErrorCode =
|
|
3
|
+
/** The configuration object itself is wrong, and nothing connected. */
|
|
4
|
+
'CONFIG'
|
|
5
|
+
/** A collection is wired under a name that is a member of the driver's `Db`. */
|
|
6
|
+
| 'COLLISION'
|
|
7
|
+
/** A database was read by a name this kit does not hold. */
|
|
8
|
+
| 'NO_DATABASE'
|
|
9
|
+
/** `kit.db` was read on a kit that holds more than one database. */
|
|
10
|
+
| 'SEVERAL_DATABASES'
|
|
11
|
+
/** A transaction that cannot be opened: no client named, or already in one. */
|
|
12
|
+
| 'TRANSACTION'
|
|
13
|
+
/** `close()` on a kit that `as`, `withSession` or a transaction derived. */
|
|
14
|
+
| 'DERIVED'
|
|
15
|
+
/** `discoverCollections` could not make a set of definitions from a glob. */
|
|
16
|
+
| 'DISCOVERY';
|
|
17
|
+
export interface KitErrorOptions {
|
|
18
|
+
/** The database it is about, when one is named. */
|
|
19
|
+
database?: string | undefined;
|
|
20
|
+
/** The config key, the collection key or the path it is about. */
|
|
21
|
+
key?: string | undefined;
|
|
22
|
+
cause?: unknown;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* What this package refuses, with a code beside the sentence.
|
|
26
|
+
*
|
|
27
|
+
* It extends `TypeError` rather than `Error`, unlike `DataError`,
|
|
28
|
+
* `RedisError` and `S3Error`: every one of these is a call or a
|
|
29
|
+
* configuration written wrong, which is what `TypeError` means, and this
|
|
30
|
+
* package threw bare `TypeError`s before it existed. Extending one keeps
|
|
31
|
+
* every `catch` that tests for `TypeError` working, and adds a `code` to
|
|
32
|
+
* switch on instead of matching the message text.
|
|
33
|
+
*/
|
|
34
|
+
export declare class KitError extends TypeError {
|
|
35
|
+
name: string;
|
|
36
|
+
readonly code: KitErrorCode;
|
|
37
|
+
readonly database: string | undefined;
|
|
38
|
+
readonly key: string | undefined;
|
|
39
|
+
constructor(code: KitErrorCode, message: string, options?: KitErrorOptions);
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=kit-error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kit-error.d.ts","sourceRoot":"","sources":["../../src/errors/kit-error.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,MAAM,MAAM,YAAY;AACvB,uEAAuE;AACrE,QAAQ;AACV,gFAAgF;GAC9E,WAAW;AACb,4DAA4D;GAC1D,aAAa;AACf,oEAAoE;GAClE,mBAAmB;AACrB,+EAA+E;GAC7E,aAAa;AACf,4EAA4E;GAC1E,SAAS;AACX,6EAA6E;GAC3E,WAAW,CAAC;AAEf,MAAM,WAAW,eAAe;IAC/B,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,kEAAkE;IAClE,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;;;GASG;AACH,qBAAa,QAAS,SAAQ,SAAS;IAC7B,IAAI,SAAc;IAC3B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;gBAErB,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe;CAM1E"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { defineConfig } from './config/define-config';
|
|
2
2
|
export type { CollectionsIn, CollectionsOf, DatabaseConfig, DbName, KitCollectionOptions, KitConfig, KitConfigInput, NoCollision, ReservedName, Unwired, } from './config/types';
|
|
3
3
|
export { type DiscoverOptions, discoverCollections } from './discover';
|
|
4
|
+
export { KitError, type KitErrorCode, type KitErrorOptions, } from './errors/kit-error';
|
|
4
5
|
export { createKit } from './kit/create-kit';
|
|
5
6
|
export type { DbScope, KitActor, KitOf, KitTransactionOptions, MongoKit, SoleScope, } from './kit/types';
|
|
6
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,YAAY,EACX,aAAa,EACb,aAAa,EACb,cAAc,EACd,MAAM,EACN,oBAAoB,EACpB,SAAS,EACT,cAAc,EACd,WAAW,EACX,YAAY,EACZ,OAAO,GACP,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,eAAe,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,YAAY,EACX,OAAO,EACP,QAAQ,EACR,KAAK,EACL,qBAAqB,EACrB,QAAQ,EACR,SAAS,GACT,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,YAAY,EACX,aAAa,EACb,aAAa,EACb,cAAc,EACd,MAAM,EACN,oBAAoB,EACpB,SAAS,EACT,cAAc,EACd,WAAW,EACX,YAAY,EACZ,OAAO,GACP,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,eAAe,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EACN,QAAQ,EACR,KAAK,YAAY,EACjB,KAAK,eAAe,GACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,YAAY,EACX,OAAO,EACP,QAAQ,EACR,KAAK,EACL,qBAAqB,EACrB,QAAQ,EACR,SAAS,GACT,MAAM,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
// src/errors/kit-error.ts
|
|
2
|
+
class KitError extends TypeError {
|
|
3
|
+
constructor(code, message, options) {
|
|
4
|
+
super(message, { cause: options?.cause });
|
|
5
|
+
this.name = "KitError";
|
|
6
|
+
this.code = code;
|
|
7
|
+
this.database = options?.database;
|
|
8
|
+
this.key = options?.key;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
1
12
|
// src/config/checks.ts
|
|
2
13
|
function isDefinition(value) {
|
|
3
14
|
if (typeof value !== "object" || value === null)
|
|
@@ -8,65 +19,67 @@ function isDefinition(value) {
|
|
|
8
19
|
function definitionsOf(collections) {
|
|
9
20
|
return Object.entries(collections).filter((entry) => isDefinition(entry[1]));
|
|
10
21
|
}
|
|
11
|
-
var refuse = (
|
|
12
|
-
throw new
|
|
22
|
+
var refuse = (name, said, key) => {
|
|
23
|
+
throw new KitError("CONFIG", `defineConfig: database "${name}" ${said}`, {
|
|
24
|
+
database: name,
|
|
25
|
+
key
|
|
26
|
+
});
|
|
13
27
|
};
|
|
14
28
|
var OWNED = ["db", "session", "actor", "autoSync"];
|
|
15
|
-
function checkOwned(
|
|
29
|
+
function checkOwned(name, what, options, forKey) {
|
|
16
30
|
if (typeof options !== "object" || options === null)
|
|
17
31
|
return;
|
|
18
32
|
for (const key of OWNED) {
|
|
19
33
|
if (key in options) {
|
|
20
|
-
refuse(
|
|
34
|
+
refuse(name, `has "${key}" in ${what}, which the kit decides: ` + "a database is named by its key, `as` and `withSession` carry the " + "actor and the session, and `autoSync` is the database's", forKey);
|
|
21
35
|
}
|
|
22
36
|
}
|
|
23
37
|
}
|
|
24
38
|
function checkDatabase(name, config) {
|
|
25
|
-
const where = `database "${name}"`;
|
|
26
39
|
if (typeof config !== "object" || config === null) {
|
|
27
|
-
refuse(
|
|
40
|
+
refuse(name, "is not a configuration object");
|
|
28
41
|
}
|
|
29
42
|
const hasUri = config.uri !== undefined;
|
|
30
43
|
const hasClient = config.client !== undefined;
|
|
31
44
|
if (hasUri === hasClient) {
|
|
32
|
-
refuse(
|
|
45
|
+
refuse(name, hasUri ? "has both a uri and a client: pass the one it should use" : "has neither a uri nor a client");
|
|
33
46
|
}
|
|
34
47
|
if (hasUri && (typeof config.uri !== "string" || config.uri === "")) {
|
|
35
|
-
refuse(
|
|
48
|
+
refuse(name, "has a uri that is not a string");
|
|
36
49
|
}
|
|
37
50
|
if (hasClient && typeof config.client?.db !== "function") {
|
|
38
|
-
refuse(
|
|
51
|
+
refuse(name, "has a client that is not a MongoClient");
|
|
39
52
|
}
|
|
40
53
|
if (hasClient && config.clientOptions !== undefined) {
|
|
41
|
-
refuse(
|
|
54
|
+
refuse(name, "has client options beside a client it did not open: pass them where the client is made");
|
|
42
55
|
}
|
|
43
56
|
if (config.database !== undefined && config.database === "") {
|
|
44
|
-
refuse(
|
|
57
|
+
refuse(name, "has an empty database name");
|
|
45
58
|
}
|
|
46
59
|
if (typeof config.collections !== "object" || config.collections === null) {
|
|
47
|
-
refuse(
|
|
60
|
+
refuse(name, "has no collections object");
|
|
48
61
|
}
|
|
49
62
|
const definitions = definitionsOf(config.collections);
|
|
50
63
|
if (definitions.length === 0) {
|
|
51
|
-
refuse(
|
|
64
|
+
refuse(name, "has a collections object with no definition in it: pass the module, as in `import * as collections`");
|
|
52
65
|
}
|
|
53
66
|
const byName = new Map;
|
|
54
67
|
for (const [key, definition] of definitions) {
|
|
55
68
|
const seen = byName.get(definition.name);
|
|
56
69
|
if (seen !== undefined) {
|
|
57
|
-
refuse(
|
|
70
|
+
refuse(name, `wires "${seen}" and "${key}" to the same collection, "${definition.name}"`);
|
|
58
71
|
}
|
|
59
72
|
byName.set(definition.name, key);
|
|
60
73
|
}
|
|
61
74
|
const keys = new Set(definitions.map(([key]) => key));
|
|
62
75
|
for (const key of Object.keys(config.optionsFor ?? {})) {
|
|
63
76
|
if (!keys.has(key)) {
|
|
64
|
-
refuse(
|
|
77
|
+
refuse(name, `has options for "${key}", which it does not wire`, key);
|
|
65
78
|
}
|
|
66
79
|
}
|
|
67
|
-
checkOwned(
|
|
80
|
+
checkOwned(name, "options", config.options);
|
|
68
81
|
for (const [key, options] of Object.entries(config.optionsFor ?? {})) {
|
|
69
|
-
checkOwned(
|
|
82
|
+
checkOwned(name, `the options of "${key}"`, options, key);
|
|
70
83
|
}
|
|
71
84
|
return definitions;
|
|
72
85
|
}
|
|
@@ -74,18 +87,18 @@ function checkDatabase(name, config) {
|
|
|
74
87
|
// src/config/define-config.ts
|
|
75
88
|
function databasesOf(config) {
|
|
76
89
|
if (typeof config !== "object" || config === null) {
|
|
77
|
-
throw new
|
|
90
|
+
throw new KitError("CONFIG", "defineConfig: a configuration object is required");
|
|
78
91
|
}
|
|
79
92
|
if (!("databases" in config)) {
|
|
80
93
|
return { default: config };
|
|
81
94
|
}
|
|
82
95
|
const { databases } = config;
|
|
83
96
|
if (typeof databases !== "object" || databases === null) {
|
|
84
|
-
throw new
|
|
97
|
+
throw new KitError("CONFIG", "defineConfig: databases must be an object of databases by name, " + "as `{ databases: { main: … } }`. One database is the " + "configuration itself, and names itself with `database`.");
|
|
85
98
|
}
|
|
86
99
|
const names = Object.keys(databases);
|
|
87
100
|
if (names.length === 0) {
|
|
88
|
-
throw new
|
|
101
|
+
throw new KitError("CONFIG", "defineConfig: databases names none. Give it at least one, " + "as `{ databases: { main: … } }`.");
|
|
89
102
|
}
|
|
90
103
|
return databases;
|
|
91
104
|
}
|
|
@@ -102,7 +115,7 @@ function defineConfig(config) {
|
|
|
102
115
|
async function discoverCollections(options) {
|
|
103
116
|
const { glob, cwd = process.cwd(), export: name } = options;
|
|
104
117
|
if (typeof glob !== "string" || glob === "") {
|
|
105
|
-
throw new
|
|
118
|
+
throw new KitError("DISCOVERY", "discoverCollections: a glob is required");
|
|
106
119
|
}
|
|
107
120
|
const paths = await Array.fromAsync(new Bun.Glob(glob).scan({ cwd }));
|
|
108
121
|
const found = [];
|
|
@@ -111,12 +124,12 @@ async function discoverCollections(options) {
|
|
|
111
124
|
const module = await import(`${cwd}/${path}`);
|
|
112
125
|
const definitions = name === undefined ? definitionsOf(module) : isDefinition(module[name]) ? [[name, module[name]]] : [];
|
|
113
126
|
if (name !== undefined && definitions.length === 0) {
|
|
114
|
-
throw new
|
|
127
|
+
throw new KitError("DISCOVERY", `discoverCollections: ${path} exports no definition named "${name}"`, { key: path });
|
|
115
128
|
}
|
|
116
129
|
for (const [, definition] of definitions) {
|
|
117
130
|
const seen = byName.get(definition.name);
|
|
118
131
|
if (seen !== undefined && seen !== path) {
|
|
119
|
-
throw new
|
|
132
|
+
throw new KitError("DISCOVERY", `discoverCollections: ${seen} and ${path} both define the collection "${definition.name}"`, { key: path });
|
|
120
133
|
}
|
|
121
134
|
byName.set(definition.name, path);
|
|
122
135
|
found.push(definition);
|
|
@@ -140,7 +153,7 @@ function derived(ctx, change) {
|
|
|
140
153
|
function databaseOf(ctx, name) {
|
|
141
154
|
const found = ctx.databases.find((database) => database.name === name);
|
|
142
155
|
if (!found) {
|
|
143
|
-
throw new
|
|
156
|
+
throw new KitError("NO_DATABASE", `This kit has no database "${name}": it has ${ctx.databases.map((database) => `"${database.name}"`).join(", ")}.`, { database: name });
|
|
144
157
|
}
|
|
145
158
|
return found;
|
|
146
159
|
}
|
|
@@ -208,13 +221,13 @@ function clientFor(ctx, on) {
|
|
|
208
221
|
const [only] = clients;
|
|
209
222
|
if (clients.size === 1 && only)
|
|
210
223
|
return only;
|
|
211
|
-
throw new
|
|
224
|
+
throw new KitError("TRANSACTION", "transaction: this kit holds more than one client, and a transaction " + "lives on one. Name the database it runs on, as `{ on: 'main' }`.");
|
|
212
225
|
}
|
|
213
226
|
function hostFor(ctx, on) {
|
|
214
227
|
if (!ctx.session)
|
|
215
228
|
return clientFor(ctx, on);
|
|
216
229
|
if (on !== undefined) {
|
|
217
|
-
throw new
|
|
230
|
+
throw new KitError("TRANSACTION", "transaction: this kit is already in a session, which this call " + "joins, so `on` has no client left to choose.");
|
|
218
231
|
}
|
|
219
232
|
return ctx.session;
|
|
220
233
|
}
|
|
@@ -228,7 +241,7 @@ async function transact(ctx, build, fn, options) {
|
|
|
228
241
|
// src/kit/derive.ts
|
|
229
242
|
async function closeKit(ctx) {
|
|
230
243
|
if (!ctx.root) {
|
|
231
|
-
throw new
|
|
244
|
+
throw new KitError("DERIVED", "close: this kit came from `as`, `withSession` or a transaction. " + "Close the kit `createKit` returned — the clients are shared.");
|
|
232
245
|
}
|
|
233
246
|
for (const database of ctx.databases) {
|
|
234
247
|
await database.connection?.close();
|
|
@@ -260,7 +273,7 @@ function kitOf(ctx) {
|
|
|
260
273
|
get db() {
|
|
261
274
|
const [only] = ctx.databases;
|
|
262
275
|
if (ctx.databases.length !== 1 || !only) {
|
|
263
|
-
throw new
|
|
276
|
+
throw new KitError("SEVERAL_DATABASES", "kit.db: this kit has several databases. Read the one you mean, " + `as \`kit.databases.${ctx.databases[0]?.name ?? "main"}\`.`);
|
|
264
277
|
}
|
|
265
278
|
return scopeFor(only.name);
|
|
266
279
|
},
|
|
@@ -312,7 +325,7 @@ async function open(config) {
|
|
|
312
325
|
function checkCollisions(name, db, keys) {
|
|
313
326
|
for (const key of keys) {
|
|
314
327
|
if (key in db) {
|
|
315
|
-
throw new
|
|
328
|
+
throw new KitError("COLLISION", `createKit: database "${name}" wires a collection under "${key}", ` + "which is a member of the driver's Db: it would be unreachable. " + "Export that definition under another name.", { database: name, key });
|
|
316
329
|
}
|
|
317
330
|
}
|
|
318
331
|
}
|
|
@@ -350,10 +363,11 @@ async function createKit(config) {
|
|
|
350
363
|
return kitOf(ctx);
|
|
351
364
|
}
|
|
352
365
|
export {
|
|
366
|
+
KitError,
|
|
353
367
|
createKit,
|
|
354
368
|
defineConfig,
|
|
355
369
|
discoverCollections
|
|
356
370
|
};
|
|
357
371
|
|
|
358
|
-
//# debugId=
|
|
372
|
+
//# debugId=D45C9A203331820F64756E2164756E21
|
|
359
373
|
//# sourceMappingURL=index.js.map
|