@furystack/mongodb-store 10.0.18 → 10.0.20
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 +5 -6
- package/esm/mongodb-store.d.ts.map +1 -1
- package/esm/mongodb-store.js +25 -27
- package/esm/mongodb-store.js.map +1 -1
- package/esm/mongodb-store.spec.js +52 -0
- package/esm/mongodb-store.spec.js.map +1 -1
- package/package.json +7 -7
- package/src/mongodb-store.spec.ts +57 -0
- package/src/mongodb-store.ts +41 -52
package/README.md
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
# mongodb-store
|
|
2
2
|
|
|
3
|
-
MongoDB
|
|
3
|
+
MongoDB physical store implementation for FuryStack.
|
|
4
4
|
|
|
5
|
-
Initialization
|
|
5
|
+
## Initialization
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
|
-
|
|
9
8
|
import '@furystack/mongodb-store'
|
|
10
9
|
|
|
11
10
|
export class TestEntry {
|
|
@@ -13,9 +12,9 @@ export class TestEntry {
|
|
|
13
12
|
declare value: string
|
|
14
13
|
}
|
|
15
14
|
|
|
16
|
-
myInjector
|
|
17
|
-
.
|
|
18
|
-
|
|
15
|
+
myInjector.setupStores((sm) => {
|
|
16
|
+
sm.useMongoDb(TestEntry, 'mongodb://localhost:27017', 'test', 'TestEntries')
|
|
17
|
+
})
|
|
19
18
|
|
|
20
19
|
const myMongoStore = myInjector.getInstance(StoreManager).getStoreFor(TestEntry)
|
|
21
20
|
```
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mongodb-store.d.ts","sourceRoot":"","sources":["../src/mongodb-store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mongodb-store.d.ts","sourceRoot":"","sources":["../src/mongodb-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EACV,WAAW,EACX,aAAa,EACb,aAAa,EACb,cAAc,EACf,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAU,WAAW,EAAgD,MAAM,SAAS,CAAA;AAS5G;;GAEG;AACH,qBAAa,YAAY,CACrB,CAAC,SAAS,MAAM,EAChB,WAAW,SAAS,MAAM,CAAC,EAC3B,cAAc,GAAG,cAAc,CAAC,CAAC,EAAE,WAAW,CAAC,CAEjD,SAAQ,QAAQ,CAAC;IACf,aAAa,EAAE;QAAE,MAAM,EAAE,CAAC,CAAA;KAAE,CAAA;IAC5B,eAAe,EAAE;QAAE,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC;QAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;KAAE,CAAA;IAC3D,eAAe,EAAE;QAAE,GAAG,EAAE,CAAC,CAAC,WAAW,CAAC,CAAA;KAAE,CAAA;CACzC,CACD,YAAW,aAAa,CAAC,CAAC,EAAE,WAAW,EAAE,cAAc,CAAC;IA2EtD,OAAO,CAAC,QAAQ,CAAC,OAAO;IAzE1B,SAAgB,UAAU,EAAE,WAAW,CAAA;IACvC,SAAgB,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,CAAA;IACvC,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,UAAU,CAAC,CAAe;IAElC,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,WAAW;IA0BN,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBAsBjC,OAAO,EAAE;QACxB,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,CAAA;QACvB,UAAU,EAAE,WAAW,CAAA;QACvB,EAAE,EAAE,MAAM,CAAA;QACV,UAAU,EAAE,MAAM,CAAA;QAClB,WAAW,EAAE,MAAM,WAAW,CAAA;KAC/B;IAOU,GAAG,CAAC,GAAG,OAAO,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAmB3D,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAS3D,KAAK,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAK9C,IAAI,CAAC,OAAO,SAAS,KAAK,CAAC,MAAM,CAAC,CAAC,EAC9C,MAAM,EAAE,WAAW,CAAC,CAAC,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IAe5C,OAAO,CAAC,aAAa;IAOR,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAOzE,MAAM,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAKnE"}
|
package/esm/mongodb-store.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { EventHub } from '@furystack/utils';
|
|
2
2
|
import { ObjectId } from 'mongodb';
|
|
3
3
|
import { Lock } from 'semaphore-async-await';
|
|
4
|
-
|
|
4
|
+
// Improved type safety for hasObjectId
|
|
5
|
+
const hasObjectId = (value) => {
|
|
6
|
+
return value && typeof value === 'object' && value._id instanceof ObjectId;
|
|
7
|
+
};
|
|
5
8
|
/**
|
|
6
9
|
* MongoDB Store implementation for FuryStack
|
|
7
10
|
*/
|
|
@@ -12,6 +15,7 @@ export class MongodbStore extends EventHub {
|
|
|
12
15
|
initLock = new Lock();
|
|
13
16
|
collection;
|
|
14
17
|
createIdFilter(...values) {
|
|
18
|
+
// If primaryKey is _id, convert string values to ObjectId
|
|
15
19
|
return {
|
|
16
20
|
[this.primaryKey]: {
|
|
17
21
|
$in: this.primaryKey === '_id' ? values.map((value) => new ObjectId(value)) : values,
|
|
@@ -19,6 +23,7 @@ export class MongodbStore extends EventHub {
|
|
|
19
23
|
};
|
|
20
24
|
}
|
|
21
25
|
stringifyResultId(item) {
|
|
26
|
+
// If _id is ObjectId, convert to string
|
|
22
27
|
if (this.primaryKey === '_id' && hasObjectId(item)) {
|
|
23
28
|
return {
|
|
24
29
|
...item,
|
|
@@ -31,23 +36,22 @@ export class MongodbStore extends EventHub {
|
|
|
31
36
|
if (!filter) {
|
|
32
37
|
return {};
|
|
33
38
|
}
|
|
34
|
-
|
|
39
|
+
// Only handle _id conversion if present
|
|
40
|
+
if (Object.prototype.hasOwnProperty.call(filter, '_id')) {
|
|
35
41
|
const f = { ...filter };
|
|
36
42
|
if (typeof f._id === 'string') {
|
|
37
|
-
|
|
38
|
-
...f,
|
|
39
|
-
_id: new ObjectId(f._id),
|
|
40
|
-
};
|
|
43
|
+
f._id = new ObjectId(f._id);
|
|
41
44
|
}
|
|
42
|
-
if (typeof f._id === 'object') {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
else if (typeof f._id === 'object' && f._id !== null) {
|
|
46
|
+
const idObj = f._id;
|
|
47
|
+
if (idObj.$eq && typeof idObj.$eq === 'string') {
|
|
48
|
+
idObj.$eq = new ObjectId(idObj.$eq);
|
|
45
49
|
}
|
|
46
|
-
if (
|
|
47
|
-
|
|
50
|
+
if (Array.isArray(idObj.$in)) {
|
|
51
|
+
idObj.$in = idObj.$in.map((id) => new ObjectId(id));
|
|
48
52
|
}
|
|
49
|
-
if (
|
|
50
|
-
|
|
53
|
+
if (Array.isArray(idObj.$nin)) {
|
|
54
|
+
idObj.$nin = idObj.$nin.map((id) => new ObjectId(id));
|
|
51
55
|
}
|
|
52
56
|
}
|
|
53
57
|
return f;
|
|
@@ -85,22 +89,23 @@ export class MongodbStore extends EventHub {
|
|
|
85
89
|
const collection = await this.getCollection();
|
|
86
90
|
const result = await collection.insertMany(entries.map((e) => ({ ...e })));
|
|
87
91
|
const created = this.primaryKey === '_id'
|
|
88
|
-
? Object.values(result.insertedIds).map((insertedId, index) =>
|
|
92
|
+
? Object.values(result.insertedIds).map((insertedId, index) =>
|
|
93
|
+
// Use 'unknown' as intermediate cast to satisfy TypeScript
|
|
94
|
+
this.stringifyResultId({ _id: insertedId, ...entries[index] }))
|
|
89
95
|
: Object.values(result.insertedIds).map((insertedId, index) => {
|
|
96
|
+
// Use 'unknown' as intermediate cast to satisfy TypeScript
|
|
90
97
|
const entity = { _id: insertedId, ...entries[index] };
|
|
91
98
|
const { _id, ...r } = entity;
|
|
92
99
|
return r;
|
|
93
100
|
});
|
|
94
101
|
created.forEach((entity) => this.emit('onEntityAdded', { entity }));
|
|
95
|
-
return {
|
|
96
|
-
created,
|
|
97
|
-
};
|
|
102
|
+
return { created };
|
|
98
103
|
}
|
|
99
104
|
async update(id, data) {
|
|
100
105
|
const collection = await this.getCollection();
|
|
101
106
|
const updateResult = await collection.updateOne(this.createIdFilter(id), { $set: data });
|
|
102
107
|
if (updateResult.matchedCount < 1) {
|
|
103
|
-
throw Error(`Entity not found with id '${id}', cannot update!`);
|
|
108
|
+
throw Error(`Entity not found with id '${String(id)}', cannot update!`);
|
|
104
109
|
}
|
|
105
110
|
this.emit('onEntityUpdated', { id, change: data });
|
|
106
111
|
}
|
|
@@ -111,12 +116,7 @@ export class MongodbStore extends EventHub {
|
|
|
111
116
|
async find(filter) {
|
|
112
117
|
const collection = await this.getCollection();
|
|
113
118
|
const sort = filter.order
|
|
114
|
-
? Object.fromEntries([
|
|
115
|
-
...Object.keys(filter.order).map((key) => [
|
|
116
|
-
key,
|
|
117
|
-
filter.order[key] === 'ASC' ? 1 : -1,
|
|
118
|
-
]),
|
|
119
|
-
])
|
|
119
|
+
? Object.fromEntries(Object.entries(filter.order).map(([key, value]) => [key, value === 'ASC' ? 1 : -1]))
|
|
120
120
|
: {};
|
|
121
121
|
const result = await collection
|
|
122
122
|
.find(this.parseFilter(filter.filter))
|
|
@@ -136,9 +136,7 @@ export class MongodbStore extends EventHub {
|
|
|
136
136
|
async get(key, select) {
|
|
137
137
|
const collection = await this.getCollection();
|
|
138
138
|
const projection = this.getProjection(select);
|
|
139
|
-
const result = await collection.findOne(this.createIdFilter(key), {
|
|
140
|
-
projection,
|
|
141
|
-
});
|
|
139
|
+
const result = await collection.findOne(this.createIdFilter(key), { projection });
|
|
142
140
|
return result ? this.stringifyResultId(result) : undefined;
|
|
143
141
|
}
|
|
144
142
|
async remove(...keys) {
|
package/esm/mongodb-store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mongodb-store.js","sourceRoot":"","sources":["../src/mongodb-store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mongodb-store.js","sourceRoot":"","sources":["../src/mongodb-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -60,5 +60,57 @@ describe('MongoDB Store', () => {
|
|
|
60
60
|
expect(retrieved).toEqual(created);
|
|
61
61
|
});
|
|
62
62
|
});
|
|
63
|
+
it('Should filter by _id as a string', async () => {
|
|
64
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
65
|
+
useMongoDb({ ...getMongoOptions(injector), model: TestClassWithId, primaryKey: '_id' });
|
|
66
|
+
const store = injector.getInstance(StoreManager).getStoreFor(TestClassWithId, '_id');
|
|
67
|
+
const { created } = await store.add({ value: 'value1' });
|
|
68
|
+
const retrieved = await store.find({ filter: { _id: { $eq: created[0]._id } } });
|
|
69
|
+
expect(retrieved.length).toBe(1);
|
|
70
|
+
expect(retrieved[0]).toEqual(created[0]);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
it('Should filter by _id.$eq as a string', async () => {
|
|
74
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
75
|
+
useMongoDb({ ...getMongoOptions(injector), model: TestClassWithId, primaryKey: '_id' });
|
|
76
|
+
const store = injector.getInstance(StoreManager).getStoreFor(TestClassWithId, '_id');
|
|
77
|
+
const { created } = await store.add({ value: 'value1' });
|
|
78
|
+
const retrieved = await store.find({ filter: { _id: { $eq: created[0]._id } } });
|
|
79
|
+
expect(retrieved.length).toBe(1);
|
|
80
|
+
expect(retrieved[0]).toEqual(created[0]);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
it('Should filter by _id.$in as array of strings', async () => {
|
|
84
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
85
|
+
useMongoDb({ ...getMongoOptions(injector), model: TestClassWithId, primaryKey: '_id' });
|
|
86
|
+
const store = injector.getInstance(StoreManager).getStoreFor(TestClassWithId, '_id');
|
|
87
|
+
const { created } = await store.add({ value: 'value1' }, { value: 'value2' });
|
|
88
|
+
const ids = created.map((c) => c._id);
|
|
89
|
+
const retrieved = await store.find({ filter: { _id: { $in: ids } } });
|
|
90
|
+
expect(retrieved.length).toBe(2);
|
|
91
|
+
expect(retrieved).toEqual(created);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
it('Should filter by _id.$nin as array of strings', async () => {
|
|
95
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
96
|
+
useMongoDb({ ...getMongoOptions(injector), model: TestClassWithId, primaryKey: '_id' });
|
|
97
|
+
const store = injector.getInstance(StoreManager).getStoreFor(TestClassWithId, '_id');
|
|
98
|
+
const { created } = await store.add({ value: 'value1' }, { value: 'value2' });
|
|
99
|
+
const ids = created.map((c) => c._id);
|
|
100
|
+
const retrieved = await store.find({ filter: { _id: { $nin: [ids[0]] } } });
|
|
101
|
+
expect(retrieved.length).toBe(1);
|
|
102
|
+
expect(retrieved[0]).toEqual(created[1]);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
it('Should filter by a non-_id field', async () => {
|
|
106
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
107
|
+
useMongoDb({ ...getMongoOptions(injector), model: TestClassWithId, primaryKey: '_id' });
|
|
108
|
+
const store = injector.getInstance(StoreManager).getStoreFor(TestClassWithId, '_id');
|
|
109
|
+
await store.add({ value: 'value1' }, { value: 'value2' });
|
|
110
|
+
const retrieved = await store.find({ filter: { value: { $eq: 'value2' } } });
|
|
111
|
+
expect(retrieved.length).toBe(1);
|
|
112
|
+
expect(retrieved[0].value).toBe('value2');
|
|
113
|
+
});
|
|
114
|
+
});
|
|
63
115
|
});
|
|
64
116
|
//# sourceMappingURL=mongodb-store.spec.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mongodb-store.spec.js","sourceRoot":"","sources":["../src/mongodb-store.spec.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mongodb-store.spec.js","sourceRoot":"","sources":["../src/mongodb-store.spec.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@furystack/mongodb-store",
|
|
3
|
-
"version": "10.0.
|
|
3
|
+
"version": "10.0.20",
|
|
4
4
|
"description": "MongoDB Store implementation for FuryStack",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -37,16 +37,16 @@
|
|
|
37
37
|
},
|
|
38
38
|
"homepage": "https://github.com/furystack/furystack",
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@furystack/core": "^15.0.
|
|
41
|
-
"@furystack/inject": "^12.0.
|
|
42
|
-
"@furystack/utils": "^8.0.
|
|
43
|
-
"mongodb": "6.
|
|
40
|
+
"@furystack/core": "^15.0.20",
|
|
41
|
+
"@furystack/inject": "^12.0.17",
|
|
42
|
+
"@furystack/utils": "^8.0.16",
|
|
43
|
+
"mongodb": "6.17.0",
|
|
44
44
|
"semaphore-async-await": "^1.5.1"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@types/node": "^
|
|
47
|
+
"@types/node": "^24.0.1",
|
|
48
48
|
"typescript": "^5.8.3",
|
|
49
|
-
"vitest": "^3.
|
|
49
|
+
"vitest": "^3.2.3"
|
|
50
50
|
},
|
|
51
51
|
"gitHead": "1045d854bfd8c475b7035471d130d401417a2321"
|
|
52
52
|
}
|
|
@@ -73,4 +73,61 @@ describe('MongoDB Store', () => {
|
|
|
73
73
|
expect(retrieved).toEqual(created)
|
|
74
74
|
})
|
|
75
75
|
})
|
|
76
|
+
|
|
77
|
+
it('Should filter by _id as a string', async () => {
|
|
78
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
79
|
+
useMongoDb({ ...getMongoOptions(injector), model: TestClassWithId, primaryKey: '_id' })
|
|
80
|
+
const store = injector.getInstance(StoreManager).getStoreFor(TestClassWithId, '_id')
|
|
81
|
+
const { created } = await store.add({ value: 'value1' })
|
|
82
|
+
const retrieved = await store.find({ filter: { _id: { $eq: created[0]._id } } })
|
|
83
|
+
expect(retrieved.length).toBe(1)
|
|
84
|
+
expect(retrieved[0]).toEqual(created[0])
|
|
85
|
+
})
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
it('Should filter by _id.$eq as a string', async () => {
|
|
89
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
90
|
+
useMongoDb({ ...getMongoOptions(injector), model: TestClassWithId, primaryKey: '_id' })
|
|
91
|
+
const store = injector.getInstance(StoreManager).getStoreFor(TestClassWithId, '_id')
|
|
92
|
+
const { created } = await store.add({ value: 'value1' })
|
|
93
|
+
const retrieved = await store.find({ filter: { _id: { $eq: created[0]._id } } })
|
|
94
|
+
expect(retrieved.length).toBe(1)
|
|
95
|
+
expect(retrieved[0]).toEqual(created[0])
|
|
96
|
+
})
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
it('Should filter by _id.$in as array of strings', async () => {
|
|
100
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
101
|
+
useMongoDb({ ...getMongoOptions(injector), model: TestClassWithId, primaryKey: '_id' })
|
|
102
|
+
const store = injector.getInstance(StoreManager).getStoreFor(TestClassWithId, '_id')
|
|
103
|
+
const { created } = await store.add({ value: 'value1' }, { value: 'value2' })
|
|
104
|
+
const ids = created.map((c) => c._id)
|
|
105
|
+
const retrieved = await store.find({ filter: { _id: { $in: ids } } })
|
|
106
|
+
expect(retrieved.length).toBe(2)
|
|
107
|
+
expect(retrieved).toEqual(created)
|
|
108
|
+
})
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
it('Should filter by _id.$nin as array of strings', async () => {
|
|
112
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
113
|
+
useMongoDb({ ...getMongoOptions(injector), model: TestClassWithId, primaryKey: '_id' })
|
|
114
|
+
const store = injector.getInstance(StoreManager).getStoreFor(TestClassWithId, '_id')
|
|
115
|
+
const { created } = await store.add({ value: 'value1' }, { value: 'value2' })
|
|
116
|
+
const ids = created.map((c) => c._id)
|
|
117
|
+
const retrieved = await store.find({ filter: { _id: { $nin: [ids[0]] } } })
|
|
118
|
+
expect(retrieved.length).toBe(1)
|
|
119
|
+
expect(retrieved[0]).toEqual(created[1])
|
|
120
|
+
})
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
it('Should filter by a non-_id field', async () => {
|
|
124
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
125
|
+
useMongoDb({ ...getMongoOptions(injector), model: TestClassWithId, primaryKey: '_id' })
|
|
126
|
+
const store = injector.getInstance(StoreManager).getStoreFor(TestClassWithId, '_id')
|
|
127
|
+
await store.add({ value: 'value1' }, { value: 'value2' })
|
|
128
|
+
const retrieved = await store.find({ filter: { value: { $eq: 'value2' } } })
|
|
129
|
+
expect(retrieved.length).toBe(1)
|
|
130
|
+
expect(retrieved[0].value).toBe('value2')
|
|
131
|
+
})
|
|
132
|
+
})
|
|
76
133
|
})
|
package/src/mongodb-store.ts
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
2
|
-
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
3
|
-
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
4
|
-
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
5
1
|
import type {
|
|
6
2
|
CreateResult,
|
|
7
3
|
FilterType,
|
|
@@ -16,7 +12,10 @@ import type { Collection, Filter, MongoClient, OptionalUnlessRequiredId, Sort, U
|
|
|
16
12
|
import { ObjectId } from 'mongodb'
|
|
17
13
|
import { Lock } from 'semaphore-async-await'
|
|
18
14
|
|
|
19
|
-
|
|
15
|
+
// Improved type safety for hasObjectId
|
|
16
|
+
const hasObjectId = <T extends { _id?: unknown }>(value: T): value is T & { _id: ObjectId } => {
|
|
17
|
+
return value && typeof value === 'object' && value._id instanceof ObjectId
|
|
18
|
+
}
|
|
20
19
|
|
|
21
20
|
/**
|
|
22
21
|
* MongoDB Store implementation for FuryStack
|
|
@@ -34,13 +33,12 @@ export class MongodbStore<
|
|
|
34
33
|
implements PhysicalStore<T, TPrimaryKey, TWriteableData>
|
|
35
34
|
{
|
|
36
35
|
public readonly primaryKey: TPrimaryKey
|
|
37
|
-
|
|
38
36
|
public readonly model: Constructable<T>
|
|
39
|
-
|
|
40
37
|
private initLock = new Lock()
|
|
41
38
|
private collection?: Collection<T>
|
|
42
39
|
|
|
43
40
|
private createIdFilter(...values: Array<T[TPrimaryKey]>): Filter<T> {
|
|
41
|
+
// If primaryKey is _id, convert string values to ObjectId
|
|
44
42
|
return {
|
|
45
43
|
[this.primaryKey]: {
|
|
46
44
|
$in: this.primaryKey === '_id' ? values.map((value) => new ObjectId(value as string)) : values,
|
|
@@ -48,40 +46,39 @@ export class MongodbStore<
|
|
|
48
46
|
} as Filter<T>
|
|
49
47
|
}
|
|
50
48
|
|
|
51
|
-
private stringifyResultId(item:
|
|
49
|
+
private stringifyResultId(item: T): T {
|
|
50
|
+
// If _id is ObjectId, convert to string
|
|
52
51
|
if (this.primaryKey === '_id' && hasObjectId(item)) {
|
|
53
52
|
return {
|
|
54
53
|
...item,
|
|
55
54
|
_id: item._id.toHexString(),
|
|
56
|
-
}
|
|
55
|
+
}
|
|
57
56
|
}
|
|
58
|
-
return item
|
|
57
|
+
return item
|
|
59
58
|
}
|
|
60
59
|
|
|
61
60
|
private parseFilter(filter?: FilterType<T>): Filter<T> {
|
|
62
61
|
if (!filter) {
|
|
63
62
|
return {}
|
|
64
63
|
}
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
// Only handle _id conversion if present
|
|
65
|
+
if (Object.prototype.hasOwnProperty.call(filter, '_id')) {
|
|
66
|
+
const f = { ...filter } as Record<string, unknown>
|
|
67
67
|
if (typeof f._id === 'string') {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (typeof f._id === 'object') {
|
|
74
|
-
if (f._id.$eq) {
|
|
75
|
-
f._id.$eq = new ObjectId(f._id.$eq)
|
|
68
|
+
f._id = new ObjectId(f._id)
|
|
69
|
+
} else if (typeof f._id === 'object' && f._id !== null) {
|
|
70
|
+
const idObj = f._id as Record<string, unknown>
|
|
71
|
+
if (idObj.$eq && typeof idObj.$eq === 'string') {
|
|
72
|
+
idObj.$eq = new ObjectId(idObj.$eq)
|
|
76
73
|
}
|
|
77
|
-
if (
|
|
78
|
-
|
|
74
|
+
if (Array.isArray(idObj.$in)) {
|
|
75
|
+
idObj.$in = idObj.$in.map((id: string) => new ObjectId(id))
|
|
79
76
|
}
|
|
80
|
-
if (
|
|
81
|
-
|
|
77
|
+
if (Array.isArray(idObj.$nin)) {
|
|
78
|
+
idObj.$nin = idObj.$nin.map((id: string) => new ObjectId(id))
|
|
82
79
|
}
|
|
83
80
|
}
|
|
84
|
-
return f
|
|
81
|
+
return f as Filter<T>
|
|
85
82
|
}
|
|
86
83
|
return filter as Filter<T>
|
|
87
84
|
}
|
|
@@ -120,54 +117,47 @@ export class MongodbStore<
|
|
|
120
117
|
this.primaryKey = options.primaryKey
|
|
121
118
|
this.model = options.model
|
|
122
119
|
}
|
|
120
|
+
|
|
123
121
|
public async add(...entries: TWriteableData[]): Promise<CreateResult<T>> {
|
|
124
122
|
const collection = await this.getCollection()
|
|
125
|
-
const result = await collection.insertMany(entries.map((e) => ({ ...e }) as
|
|
126
|
-
|
|
123
|
+
const result = await collection.insertMany(entries.map((e) => ({ ...e }) as OptionalUnlessRequiredId<T>))
|
|
127
124
|
const created =
|
|
128
125
|
this.primaryKey === '_id'
|
|
129
126
|
? Object.values(result.insertedIds).map((insertedId, index) =>
|
|
130
|
-
|
|
127
|
+
// Use 'unknown' as intermediate cast to satisfy TypeScript
|
|
128
|
+
this.stringifyResultId({ _id: insertedId, ...entries[index] } as unknown as T),
|
|
131
129
|
)
|
|
132
|
-
:
|
|
133
|
-
|
|
130
|
+
: Object.values(result.insertedIds).map((insertedId, index) => {
|
|
131
|
+
// Use 'unknown' as intermediate cast to satisfy TypeScript
|
|
132
|
+
const entity = { _id: insertedId, ...entries[index] } as unknown as T & { _id: unknown }
|
|
134
133
|
const { _id, ...r } = entity
|
|
135
|
-
return r
|
|
136
|
-
})
|
|
137
|
-
|
|
134
|
+
return r as T
|
|
135
|
+
})
|
|
138
136
|
created.forEach((entity) => this.emit('onEntityAdded', { entity }))
|
|
139
|
-
|
|
140
|
-
return {
|
|
141
|
-
created,
|
|
142
|
-
}
|
|
137
|
+
return { created }
|
|
143
138
|
}
|
|
139
|
+
|
|
144
140
|
public async update(id: T[TPrimaryKey], data: Partial<T>): Promise<void> {
|
|
145
141
|
const collection = await this.getCollection()
|
|
146
142
|
const updateResult = await collection.updateOne(this.createIdFilter(id), { $set: data } as UpdateFilter<T>)
|
|
147
|
-
|
|
148
143
|
if (updateResult.matchedCount < 1) {
|
|
149
|
-
throw Error(`Entity not found with id '${id
|
|
144
|
+
throw Error(`Entity not found with id '${String(id)}', cannot update!`)
|
|
150
145
|
}
|
|
151
146
|
this.emit('onEntityUpdated', { id, change: data })
|
|
152
147
|
}
|
|
148
|
+
|
|
153
149
|
public async count(filter?: FilterType<T>): Promise<number> {
|
|
154
150
|
const collection = await this.getCollection()
|
|
155
151
|
return await collection.countDocuments(this.parseFilter(filter), {})
|
|
156
152
|
}
|
|
153
|
+
|
|
157
154
|
public async find<TFields extends Array<keyof T>>(
|
|
158
155
|
filter: FindOptions<T, TFields>,
|
|
159
156
|
): Promise<Array<PartialResult<T, TFields>>> {
|
|
160
157
|
const collection = await this.getCollection()
|
|
161
|
-
|
|
162
158
|
const sort: Sort = filter.order
|
|
163
|
-
? Object.fromEntries([
|
|
164
|
-
...Object.keys(filter.order).map((key) => [
|
|
165
|
-
key,
|
|
166
|
-
(filter.order as any)[key] === 'ASC' ? (1 as const) : (-1 as const),
|
|
167
|
-
]),
|
|
168
|
-
])
|
|
159
|
+
? Object.fromEntries(Object.entries(filter.order).map(([key, value]) => [key, value === 'ASC' ? 1 : -1]))
|
|
169
160
|
: {}
|
|
170
|
-
|
|
171
161
|
const result = await collection
|
|
172
162
|
.find(this.parseFilter(filter.filter))
|
|
173
163
|
.project(this.getProjection(filter.select))
|
|
@@ -175,7 +165,7 @@ export class MongodbStore<
|
|
|
175
165
|
.limit(filter.top || Number.MAX_SAFE_INTEGER)
|
|
176
166
|
.sort(sort)
|
|
177
167
|
.toArray()
|
|
178
|
-
return result.map((entity) => this.stringifyResultId(entity))
|
|
168
|
+
return result.map((entity) => this.stringifyResultId(entity as T))
|
|
179
169
|
}
|
|
180
170
|
|
|
181
171
|
private getProjection(fields?: Array<keyof T>) {
|
|
@@ -188,11 +178,10 @@ export class MongodbStore<
|
|
|
188
178
|
public async get(key: T[TPrimaryKey], select?: Array<keyof T>): Promise<T | undefined> {
|
|
189
179
|
const collection = await this.getCollection()
|
|
190
180
|
const projection = this.getProjection(select)
|
|
191
|
-
const result = await collection.findOne(this.createIdFilter(key), {
|
|
192
|
-
|
|
193
|
-
})
|
|
194
|
-
return result ? this.stringifyResultId(result) : undefined
|
|
181
|
+
const result = await collection.findOne(this.createIdFilter(key), { projection })
|
|
182
|
+
return result ? this.stringifyResultId(result as T) : undefined
|
|
195
183
|
}
|
|
184
|
+
|
|
196
185
|
public async remove(...keys: Array<T[TPrimaryKey]>): Promise<void> {
|
|
197
186
|
const collection = await this.getCollection()
|
|
198
187
|
await collection.deleteMany(this.createIdFilter(...keys))
|