@owlmeans/mongo 0.1.18-rc.10 → 0.1.18-rc.11

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
@@ -6,7 +6,7 @@ MongoDB service for OwlMeans server contexts — connection management with repl
6
6
 
7
7
  - `makeMongoDbService(alias?)` — creates a MongoDB connection service
8
8
  - `appendMongo(context, alias?)` — registers the service in the context
9
- - Reads connection config from `context.cfg.dbs[alias]` (supports `kluster:` directives)
9
+ - Reads connection config from the `dbs` entry whose alias matches (supports `kluster:` directives)
10
10
  - Used as the database provider for `@owlmeans/mongo-resource`
11
11
 
12
12
  ## Installation
@@ -24,16 +24,20 @@ import { appendMongo, DEFAULT_ALIAS as MONGO_SERVICE } from '@owlmeans/mongo'
24
24
  appendMongo<C, T>(context)
25
25
  ```
26
26
 
27
- Config (`config.json`):
27
+ Config (`config.json`) — `dbs` is a list, and `schema` names the database every resource on this
28
+ connection reads and writes (falling back to the config `alias`, then the service alias):
28
29
 
29
30
  ```json
30
31
  {
31
- "dbs": {
32
- "mongo": {
33
- "url": "mongodb://localhost:27017",
34
- "dbName": "myapp"
32
+ "dbs": [
33
+ {
34
+ "service": "mongo",
35
+ "alias": "mongo",
36
+ "host": "localhost",
37
+ "port": 27017,
38
+ "schema": "myapp"
35
39
  }
36
- }
40
+ ]
37
41
  }
38
42
  ```
39
43
 
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@owlmeans/mongo",
4
- "version": "0.1.18-rc.10",
5
- "generatedAt": "2026-09-01T12:04:42.743Z",
4
+ "version": "0.1.18-rc.11",
5
+ "generatedAt": "2026-09-01T16:28:56.992Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: mongo
3
- description: How to use @owlmeans/mongo — MongoDB connection service (makeMongoDbService / appendMongo) registered on a server context; cluster setup, layer sensitivity, field encryption backend. Auto-invoked when wiring MongoDB into a server app.
3
+ description: How to use @owlmeans/mongo — MongoDB connection service (makeMongoDbService / appendMongo) registered on a server context; cluster setup, field encryption backend. Auto-invoked when wiring MongoDB into a server app.
4
4
  user-invocable: false
5
5
  ---
6
6
  <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
@@ -8,7 +8,7 @@ user-invocable: false
8
8
  # @owlmeans/mongo
9
9
 
10
10
  **Layer:** Infra
11
- **Install:** `"@owlmeans/mongo": "^0.1.18-rc.10"` in `dependencies` (peer `mongodb`)
11
+ **Install:** `"@owlmeans/mongo": "^0.1.18-rc.11"` in `dependencies` (peer `mongodb`)
12
12
 
13
13
  ## Key Exports
14
14
 
@@ -31,9 +31,8 @@ cfg.dbs = [{
31
31
  host: '127.0.0.1', // or string[] for a cluster — triggers replica set setup
32
32
  port: 27017,
33
33
  user: 'admin', secret: '...',
34
- schema: 'my-app', // the DATABASE name (layer-suffixed by dbName())
34
+ schema: 'my-app', // the DATABASE name
35
35
  encryptionKey: '...', // enables lock()/unlock() field encryption
36
- entitySensitive: true, // per-Entity-layer databases
37
36
  }]
38
37
  ```
39
38
 
@@ -41,9 +40,9 @@ cfg.dbs = [{
41
40
  replica-set bootstrap (`setUpCluster`) first.
42
41
  - `lock`/`unlock` encrypt/decrypt record fields with `encryptionKey` via
43
42
  `@owlmeans/basic-keys` — the backend behind `MongoResource.lock()`.
44
- - Layer sensitivity: `serviceSensitive`/`entitySensitive` add `Layer.Service`/`Layer.Entity`
45
- to the service's layers, which makes `dbName()` derive per-layer database names — each
46
- such database carries its own data **and its own migration ledger**.
43
+ - The database name is `dbName()` — `config.schema ?? config.alias ?? service.alias`, taken as
44
+ given. One database per config entry, each carrying its own data **and its own migration
45
+ ledger**; a second database is a second `cfg.dbs` entry.
47
46
 
48
47
  ## Tests
49
48
 
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAK3E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAI9D,KAAK,MAAM,GAAG,YAAY,CAAA;AAC1B,UAAU,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC;CAAI;AAEzE,eAAO,MAAM,kBAAkB,WAAW,MAAM,KAAmB,cA2HlE,CAAA;AAED,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,WACpE,CAAC,UAAS,MAAM,KACxB,CAMF,CAAA"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAK3E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAI9D,KAAK,MAAM,GAAG,YAAY,CAAA;AAC1B,UAAU,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC;CAAI;AAEzE,eAAO,MAAM,kBAAkB,GAAI,QAAO,MAAsB,KAAG,cAuGlE,CAAA;AAED,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAC7E,SAAS,CAAC,EAAE,QAAO,MAAsB,KACxC,CAMF,CAAA"}
package/build/service.js CHANGED
@@ -1,4 +1,4 @@
1
- import { assertContext, Layer } from '@owlmeans/context';
1
+ import { assertContext } from '@owlmeans/context';
2
2
  import { DEFAULT_ALIAS } from './consts.js';
3
3
  import { MongoClient } from 'mongodb';
4
4
  import { prepareConfig } from './utils/config.js';
@@ -19,15 +19,6 @@ export const makeMongoDbService = (alias = DEFAULT_ALIAS) => {
19
19
  if (service.clients[configAlias] != null) {
20
20
  return;
21
21
  }
22
- if (service.layers == null) {
23
- service.layers = [Layer.Global];
24
- }
25
- if (config.serviceSensitive && service.layers.includes(Layer.Service)) {
26
- service.layers.push(Layer.Service);
27
- }
28
- if (config.entitySensitive && service.layers.includes(Layer.Entity)) {
29
- service.layers.push(Layer.Entity);
30
- }
31
22
  let [url, options] = prepareConfig(config);
32
23
  let client = new MongoClient(url, options);
33
24
  if (Array.isArray(config.host)) {
@@ -78,12 +69,6 @@ export const makeMongoDbService = (alias = DEFAULT_ALIAS) => {
78
69
  field,
79
70
  fields.includes(field) ? await key.decrypt(value).catch(() => value) : value
80
71
  ])));
81
- },
82
- reinitializeContext: (context) => {
83
- const _service = makeMongoDbService(alias);
84
- _service.ctx = context;
85
- _service.layers = service.layers;
86
- return _service;
87
72
  }
88
73
  }, service => async () => {
89
74
  const context = assertContext(service.ctx, location);
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"cluster.d.ts","sourceRoot":"","sources":["../../src/utils/cluster.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAE1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAMlD,eAAO,MAAM,YAAY,WAAkB,WAAW,UAAU,QAAQ,KAAG,OAAO,CAAC,OAAO,CA6DzF,CAAA"}
1
+ {"version":3,"file":"cluster.d.ts","sourceRoot":"","sources":["../../src/utils/cluster.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAE1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAMlD,eAAO,MAAM,YAAY,GAAU,QAAQ,WAAW,EAAE,QAAQ,QAAQ,KAAG,OAAO,CAAC,OAAO,CA6DzF,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAEjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAIlD,eAAO,MAAM,aAAa,WAAY,QAAQ,WAAU,OAAO,KAAU,CAAC,MAAM,EAAE,kBAAkB,CAuBnG,CAAA;AAED,eAAO,MAAM,IAAI,SAAU,MAAM,UAAU,QAAQ,KAAG,MACC,CAAA"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAEjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAIlD,eAAO,MAAM,aAAa,GAAI,QAAQ,QAAQ,EAAE,SAAQ,OAAc,KAAG,CAAC,MAAM,EAAE,kBAAkB,CAuBnG,CAAA;AAED,eAAO,MAAM,IAAI,GAAI,MAAM,MAAM,EAAE,QAAQ,QAAQ,KAAG,MACC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE1C,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAAgB,EAAE,MAAM,GAAY,IAAI,EAAgC,EAAE;IACtG,IAAI,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAA;IACpE,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAEtE,IAAI,MAAM,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,IAAI,GAAG,aAAa,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAA;IACrG,CAAC;IAED,MAAM,IAAI,GAA0B,MAAM,CAAC,IAAI,CAAA;IAE/C,2EAA2E;IAC3E,6EAA6E;IAC7E,6EAA6E;IAC7E,0EAA0E;IAC1E,gFAAgF;IAChF,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,IAAI,GAAG,GAAG,IAAI,gBAAgB,IAAI,EAAE,UAAU,IAAI,WAAW,EAAE,CAAA;IACjE,CAAC;IAED,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC;YAClC,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;YACxD,gBAAgB,EAAE,MAAM;SACzB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;AACT,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,MAAgB,EAAU,EAAE,CAC7D,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,CAAA"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE1C,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAAgB,EAAE,SAAkB,IAAI,EAAgC,EAAE;IACtG,IAAI,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAA;IACpE,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAEtE,IAAI,MAAM,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,IAAI,GAAG,aAAa,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAA;IACrG,CAAC;IAED,MAAM,IAAI,GAA0B,MAAM,CAAC,IAAI,CAAA;IAE/C,2EAA2E;IAC3E,6EAA6E;IAC7E,6EAA6E;IAC7E,0EAA0E;IAC1E,gFAAgF;IAChF,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,IAAI,GAAG,GAAG,IAAI,gBAAgB,IAAI,EAAE,UAAU,IAAI,WAAW,EAAE,CAAA;IACjE,CAAC;IAED,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC;YAClC,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;YACxD,gBAAgB,EAAE,MAAM;SACzB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;AACT,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,MAAgB,EAAU,EAAE,CAC7D,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/mongo",
3
- "version": "0.1.18-rc.10",
3
+ "version": "0.1.18-rc.11",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -23,7 +23,7 @@
23
23
  },
24
24
  "devDependencies": {
25
25
  "@owlmeans/dep-config": "workspace:*",
26
- "@owlmeans/test-integration": "^0.1.18-rc.6",
26
+ "@owlmeans/test-integration": "^0.1.18-rc.7",
27
27
  "@types/bun": "^1.4.0",
28
28
  "@types/node": "^26.1.0",
29
29
  "nodemon": "^3.1.14",
@@ -31,11 +31,11 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@noble/hashes": "^1.5.0",
34
- "@owlmeans/basic-keys": "^0.1.18-rc.9",
35
- "@owlmeans/context": "^0.1.18-rc.6",
36
- "@owlmeans/mongo-resource": "^0.1.18-rc.8",
37
- "@owlmeans/resource": "^0.1.18-rc.7",
38
- "@owlmeans/server-context": "^0.1.18-rc.8",
34
+ "@owlmeans/basic-keys": "^0.1.18-rc.10",
35
+ "@owlmeans/context": "^0.1.18-rc.7",
36
+ "@owlmeans/mongo-resource": "^0.1.18-rc.10",
37
+ "@owlmeans/resource": "^0.1.18-rc.8",
38
+ "@owlmeans/server-context": "^0.1.18-rc.10",
39
39
  "@scure/base": "^2.3.0",
40
40
  "mongodb": "^7.5.0"
41
41
  },
package/src/service.ts CHANGED
@@ -1,5 +1,4 @@
1
- import { assertContext, Layer } from '@owlmeans/context'
2
- import type { BasicContext } from '@owlmeans/context'
1
+ import { assertContext } from '@owlmeans/context'
3
2
  import { DEFAULT_ALIAS } from './consts.js'
4
3
  import type { ServerContext, ServerConfig } from '@owlmeans/server-context'
5
4
  import { MongoClient } from 'mongodb'
@@ -33,16 +32,6 @@ export const makeMongoDbService = (alias: string = DEFAULT_ALIAS): MongoDbServic
33
32
  return
34
33
  }
35
34
 
36
- if (service.layers == null) {
37
- service.layers = [Layer.Global]
38
- }
39
- if (config.serviceSensitive && service.layers.includes(Layer.Service)) {
40
- service.layers.push(Layer.Service)
41
- }
42
- if (config.entitySensitive && service.layers.includes(Layer.Entity)) {
43
- service.layers.push(Layer.Entity)
44
- }
45
-
46
35
  let [url, options] = prepareConfig(config)
47
36
 
48
37
  let client = new MongoClient(url, options)
@@ -112,16 +101,6 @@ export const makeMongoDbService = (alias: string = DEFAULT_ALIAS): MongoDbServic
112
101
  ]
113
102
  ))
114
103
  )
115
- },
116
-
117
- reinitializeContext: <T>(context: BasicContext<ServerConfig>) => {
118
- const _service = makeMongoDbService(alias)
119
-
120
- _service.ctx = context
121
-
122
- _service.layers = service.layers
123
-
124
- return _service as T
125
104
  }
126
105
  }, service => async () => {
127
106
  const context = assertContext<Config, Context>(service.ctx as Context, location)
@@ -0,0 +1,153 @@
1
+ import { afterAll, describe, expect, test } from 'bun:test'
2
+ import { makeMongoResource } from '@owlmeans/mongo-resource'
3
+ import { UnknownRecordError, UnsupportedArgumentError } from '@owlmeans/resource'
4
+
5
+ import { gate, makeSuite } from './context.js'
6
+ import type { MongoResource, Note } from './context.js'
7
+
8
+ const noteSchema = {
9
+ type: 'object',
10
+ properties: {
11
+ title: { type: 'string' },
12
+ slug: { type: 'string', nullable: true }
13
+ },
14
+ required: ['title']
15
+ }
16
+
17
+ const suite = makeSuite('crud')
18
+ const it = gate.skip ? test.skip : test
19
+
20
+ /** One alias — and so one collection — per test, so the sets never interfere. */
21
+ const notes = async (alias: string): Promise<MongoResource<Note>> => {
22
+ const resource = makeMongoResource<Note, MongoResource<Note>>(alias)
23
+ resource.schema = noteSchema as never
24
+ const { context } = await suite.boot({ resources: [resource] })
25
+
26
+ return context.resource<MongoResource<Note>>(alias)
27
+ }
28
+
29
+ describe('@owlmeans/mongo — the resource contract', () => {
30
+ if (gate.skip) {
31
+ test.skip(gate.reason ?? 'mongo gate closed', () => {})
32
+
33
+ return
34
+ }
35
+
36
+ afterAll(async () => {
37
+ await suite.teardown()
38
+ })
39
+
40
+ it('reads one record by id and by criteria', async () => {
41
+ const res = await notes('crud-read')
42
+ const note = await res.create({ title: 'first', slug: 'one' })
43
+ expect(typeof note.id).toBe('string')
44
+
45
+ expect((await res.get(note.id!)).title).toBe('first')
46
+ /** Several fields at once, without listing and taking the first element. */
47
+ expect((await res.get({ title: 'first', slug: 'one' })).id).toBe(note.id!)
48
+ expect(await res.load({ slug: 'nope' })).toBeNull()
49
+ })
50
+
51
+ it('answers an id that is not a mongo id rather than throwing a driver error', async () => {
52
+ const res = await notes('crud-badid')
53
+
54
+ expect(await res.load('not-an-object-id')).toBeNull()
55
+ await expect(res.get('not-an-object-id')).rejects.toThrow(UnknownRecordError)
56
+ })
57
+
58
+ it('pages and sorts, and always reports the total', async () => {
59
+ const res = await notes('crud-page')
60
+ for (const title of ['c', 'a', 'd', 'b']) {
61
+ await res.create({ title })
62
+ }
63
+
64
+ const first = await res.list({}, { size: 2, sort: ['title'] })
65
+ expect(first.items.map(note => note.title)).toEqual(['a', 'b'])
66
+ expect(first.total).toBe(4)
67
+ expect(first.page).toBe(0)
68
+ expect(first.size).toBe(2)
69
+
70
+ const second = await res.list({}, { page: 1, size: 2, sort: ['title'] })
71
+ expect(second.items.map(note => note.title)).toEqual(['c', 'd'])
72
+ expect(second.total).toBe(4)
73
+
74
+ const newest = await res.list(undefined, { size: 1, sort: [{ field: 'title', order: 'desc' }] })
75
+ expect(newest.items.map(note => note.title)).toEqual(['d'])
76
+
77
+ /** `size: 0` is the explicit ask for the whole result set. */
78
+ const all = await res.list({}, { size: 0, sort: ['title'] })
79
+ expect(all.items).toHaveLength(4)
80
+ expect(all.total).toBe(4)
81
+ expect(all.size).toBeUndefined()
82
+ })
83
+
84
+ it('counts without reading the records', async () => {
85
+ const res = await notes('crud-count')
86
+ await res.create({ title: 'x', slug: 'keep' })
87
+ await res.create({ title: 'y', slug: 'keep' })
88
+ await res.create({ title: 'z', slug: 'drop' })
89
+
90
+ expect(await res.count()).toBe(3)
91
+ expect(await res.count({ slug: 'keep' })).toBe(2)
92
+ expect(await res.count({ slug: 'absent' })).toBe(0)
93
+ })
94
+
95
+ it('answers the shared operators the same way the other stores do', async () => {
96
+ const res = await notes('crud-ops')
97
+ await res.create({ title: 'Alpha', slug: 'a-1' })
98
+ await res.create({ title: 'beta', slug: 'b-2' })
99
+ await res.create({ title: 'gamma' })
100
+
101
+ expect((await res.list({ title: { $ilike: 'al%' } })).items.map(note => note.title))
102
+ .toEqual(['Alpha'])
103
+ expect((await res.list({ slug: { $startsWith: 'b-' } })).items.map(note => note.title))
104
+ .toEqual(['beta'])
105
+ expect((await res.list({ slug: { $null: true } })).items.map(note => note.title))
106
+ .toEqual(['gamma'])
107
+ expect((await res.list({ title: ['Alpha', 'beta'] })).total).toBe(2)
108
+ expect((await res.list({ $or: [{ title: 'Alpha' }, { slug: 'b-2' }] })).total).toBe(2)
109
+ expect((await res.list({ $not: { title: 'gamma' } })).total).toBe(2)
110
+ })
111
+
112
+ it('purges by criteria and refuses to empty the collection', async () => {
113
+ const res = await notes('crud-purge')
114
+ await res.create({ title: 'x', slug: 'drop' })
115
+ await res.create({ title: 'y', slug: 'drop' })
116
+ await res.create({ title: 'z', slug: 'keep' })
117
+
118
+ /** An empty criteria object would delete everything — one call replacing a page loop. */
119
+ await expect(res.purge({})).rejects.toThrow(UnsupportedArgumentError)
120
+
121
+ expect(await res.purge({ slug: 'drop' })).toBe(2)
122
+ expect(await res.count()).toBe(1)
123
+ })
124
+
125
+ it('takes a record out and hands it back, where delete tolerates absence', async () => {
126
+ const res = await notes('crud-take')
127
+ const note = await res.create({ title: 'once' })
128
+
129
+ expect((await res.take(note.id!)).title).toBe('once')
130
+ await expect(res.take(note.id!)).rejects.toThrow(UnknownRecordError)
131
+ expect(await res.delete(note.id!)).toBeNull()
132
+ })
133
+
134
+ it('creates without an id, replaces with one', async () => {
135
+ const res = await notes('crud-save')
136
+ const created = await res.save({ title: 'draft', slug: 'kept' })
137
+ expect(typeof created.id).toBe('string')
138
+
139
+ const replaced = await res.save({ id: created.id, title: 'final' })
140
+ expect(replaced.id).toBe(created.id!)
141
+ expect(replaced.title).toBe('final')
142
+ /** A replace, not a patch — the field the new record omits is gone from the document. */
143
+ expect(replaced.slug).toBeUndefined()
144
+ expect(await res.count()).toBe(1)
145
+ })
146
+
147
+ it('refuses an expiry it cannot honour', async () => {
148
+ const res = await notes('crud-ttl')
149
+
150
+ await expect(res.create({ title: 'ephemeral' }, { ttl: 60 })).rejects
151
+ .toThrow(UnsupportedArgumentError)
152
+ })
153
+ })
@@ -108,7 +108,7 @@ describe('@owlmeans/mongo — ObjectId references', () => {
108
108
  expect(listed.items.map(i => i.title)).toEqual(['a'])
109
109
  expect(listed.items[0].ownerId).toBe(owner.id!)
110
110
 
111
- const viaIn = await items.list({ ownerId: { $in: [owner.id!, other.id!] } } as never)
111
+ const viaIn = await items.list({ ownerId: { $in: [owner.id!, other.id!] } })
112
112
  expect(viaIn.items).toHaveLength(2)
113
113
 
114
114
  /** `id` criteria address `_id` — documents never store an `id` field. */
@@ -119,7 +119,8 @@ describe('@owlmeans/mongo — ObjectId references', () => {
119
119
  const none = await items.list({ ownerId: 'ext:not-an-id' })
120
120
  expect(none.items).toHaveLength(0)
121
121
 
122
- const loaded = await items.load(owner.id!, 'ownerId')
122
+ /** A criteria read addresses the reference field directly — no list to take a first from. */
123
+ const loaded = await items.load({ ownerId: owner.id! })
123
124
  expect(loaded?.title).toBe('a')
124
125
  })
125
126
 
@@ -150,7 +151,7 @@ describe('@owlmeans/mongo — ObjectId references', () => {
150
151
  expect((stored?.ownerIds as unknown[]).every(v => v instanceof ObjectId)).toBe(true)
151
152
 
152
153
  /** Multikey criteria hit the converted elements. */
153
- const listed = await items.list({ ownerIds: second.id! })
154
+ const listed = await items.list({ ownerIds: { $contains: [second.id!] } })
154
155
  expect(listed.items.map(i => i.title)).toEqual(['multi'])
155
156
  })
156
157
 
@@ -281,15 +282,16 @@ describe('@owlmeans/mongo — ObjectId references', () => {
281
282
  expect(updated.ownerId).toBe(next.id!)
282
283
 
283
284
  /** Addressing the record BY its reference field converts the lookup value too. */
284
- const byRef = await items.update({ ...updated, title: 'by-ref' }, 'ownerId')
285
+ const byRef = await items.update({ ...await items.get({ ownerId: next.id! }), title: 'by-ref' })
285
286
  expect(byRef.title).toBe('by-ref')
286
287
 
287
288
  const stored = await raw(async client =>
288
289
  await client.db(suite.database).collection('ref-upd').findOne({ _id: new ObjectId(item.id!) }))
289
290
  expect(stored?.ownerId).toBeInstanceOf(ObjectId)
290
291
 
291
- const gone = await items.delete(next.id!, 'ownerId')
292
- expect(gone?.title).toBe('by-ref')
292
+ /** And the delete-and-return reached through the same converted lookup. */
293
+ const gone = await items.take((await items.get({ ownerId: next.id! })).id!)
294
+ expect(gone.title).toBe('by-ref')
293
295
  })
294
296
 
295
297
  it('survives redeclaration and reboot without conflicts', async () => {