assai 2.1.2 → 2.1.4
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/dist/src/usecases/mongo/transformers/object_id/index.d.mts +1 -0
- package/dist/src/usecases/mongo/transformers/object_id/transform_options.d.mts +12 -0
- package/package.json +1 -1
- package/src/usecases/mongo/operation/aggregate.mjs +2 -1
- package/src/usecases/mongo/operation/bulk_write.mjs +8 -1
- package/src/usecases/mongo/operation/find.mjs +3 -1
- package/src/usecases/mongo/operation/find_one_and_delete.mjs +3 -1
- package/src/usecases/mongo/operation/find_one_and_replace.mjs +3 -1
- package/src/usecases/mongo/operation/find_one_and_update.mjs +3 -1
- package/src/usecases/mongo/operation/insert_many.mjs +8 -2
- package/src/usecases/mongo/operation/insert_one.mjs +8 -3
- package/src/usecases/mongo/operation/update_many.mjs +3 -1
- package/src/usecases/mongo/operation/update_one.mjs +3 -1
- package/src/usecases/mongo/transformers/index.mjs +1 -1
- package/src/usecases/mongo/transformers/object_id/index.mjs +1 -0
- package/src/usecases/mongo/transformers/object_id/transform_options.mjs +52 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Applies `stringsIntoId` to the data-bearing fields of an operation's
|
|
3
|
+
* `options`, leaving metadata and special objects untouched.
|
|
4
|
+
*
|
|
5
|
+
* Does not mutate the caller's `options`: a shallow copy is created only when a
|
|
6
|
+
* field actually changes, otherwise the original reference is returned.
|
|
7
|
+
*
|
|
8
|
+
* @template {Record<string, any> | undefined} T
|
|
9
|
+
* @param {T} options
|
|
10
|
+
* @returns {T}
|
|
11
|
+
*/
|
|
12
|
+
export function transformOptions<T extends Record<string, any> | undefined>(options: T): T;
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Collection } from 'mongodb'
|
|
2
|
-
import { renameToMongoId, stringsIntoId } from '../transformers/index.mjs'
|
|
2
|
+
import { renameToMongoId, stringsIntoId, transformOptions } from '../transformers/index.mjs'
|
|
3
3
|
import { outputTransformer } from '../transformers/output_transformer.mjs'
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -15,6 +15,7 @@ export async function aggregate({ getCollection, pipeline, options, collectionOp
|
|
|
15
15
|
const finalPipeline = stringsIntoId(renameToMongoId(pipeline))
|
|
16
16
|
|
|
17
17
|
const col = await getCollection()
|
|
18
|
+
options = transformOptions(options)
|
|
18
19
|
const docs = await col.aggregate(finalPipeline, options).toArray()
|
|
19
20
|
// @ts-ignore
|
|
20
21
|
return docs.map((doc) => outputTransformer({ document: doc, collectionOptions }))
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Collection } from 'mongodb'
|
|
2
|
-
import { renameToMongoId, stringsIntoId } from '../transformers/index.mjs'
|
|
2
|
+
import { renameToMongoId, stringsIntoId, transformOptions } from '../transformers/index.mjs'
|
|
3
3
|
import { inputTransformer } from '../transformers/input_transformer.mjs'
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -23,10 +23,17 @@ export async function bulkWrite({ getCollection, operations, options, collection
|
|
|
23
23
|
o.updateOne.filter = renameToMongoId(o.updateOne.filter)
|
|
24
24
|
o.updateOne.filter = stringsIntoId(o.updateOne.filter)
|
|
25
25
|
o.updateOne.update = stringsIntoId(o.updateOne.update)
|
|
26
|
+
// `o.updateOne` is a bulk operation descriptor, not an `options` object,
|
|
27
|
+
// but it carries `arrayFilters` at the same top level that transformOptions
|
|
28
|
+
// looks for. `filter`/`update`/`upsert` aren't data-bearing keys, so they
|
|
29
|
+
// are left untouched — this reuses the same conversion without duplicating it.
|
|
30
|
+
o.updateOne = transformOptions(o.updateOne)
|
|
26
31
|
} else if (o.updateMany != null) {
|
|
27
32
|
o.updateMany.filter = renameToMongoId(o.updateMany.filter)
|
|
28
33
|
o.updateMany.filter = stringsIntoId(o.updateMany.filter)
|
|
29
34
|
o.updateMany.update = stringsIntoId(o.updateMany.update)
|
|
35
|
+
// See the note above: same reuse of transformOptions on the operation descriptor.
|
|
36
|
+
o.updateMany = transformOptions(o.updateMany)
|
|
30
37
|
} else if (o.deleteOne != null) {
|
|
31
38
|
o.deleteOne.filter = renameToMongoId(o.deleteOne.filter)
|
|
32
39
|
o.deleteOne.filter = stringsIntoId(o.deleteOne.filter)
|
|
@@ -2,7 +2,8 @@ import { Collection } from 'mongodb'
|
|
|
2
2
|
import {
|
|
3
3
|
renameFindOptions,
|
|
4
4
|
renameToMongoId,
|
|
5
|
-
stringsIntoId
|
|
5
|
+
stringsIntoId,
|
|
6
|
+
transformOptions
|
|
6
7
|
} from '../transformers/index.mjs'
|
|
7
8
|
import { outputTransformer } from '../transformers/output_transformer.mjs'
|
|
8
9
|
|
|
@@ -19,6 +20,7 @@ import { outputTransformer } from '../transformers/output_transformer.mjs'
|
|
|
19
20
|
export async function find({ getCollection, query, options, collectionOptions }) {
|
|
20
21
|
query = renameToMongoId(query)
|
|
21
22
|
options = renameFindOptions(options)
|
|
23
|
+
options = transformOptions(options)
|
|
22
24
|
|
|
23
25
|
query = stringsIntoId(query)
|
|
24
26
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Collection } from 'mongodb'
|
|
2
|
-
import { renameToMongoId, stringsIntoId } from '../transformers/index.mjs'
|
|
2
|
+
import { renameToMongoId, stringsIntoId, transformOptions } from '../transformers/index.mjs'
|
|
3
3
|
import { outputTransformer } from '../transformers/output_transformer.mjs'
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -16,6 +16,8 @@ export async function findOneAndDelete({ query, options, collectionOptions, getC
|
|
|
16
16
|
query = stringsIntoId(query)
|
|
17
17
|
const col = await getCollection()
|
|
18
18
|
|
|
19
|
+
options = transformOptions(options)
|
|
20
|
+
|
|
19
21
|
const doc = await col.findOneAndDelete(query, options ?? {})
|
|
20
22
|
if (doc == null) return null
|
|
21
23
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Collection } from 'mongodb'
|
|
2
|
-
import { renameToMongoId, stringsIntoId } from '../transformers/index.mjs'
|
|
2
|
+
import { renameToMongoId, stringsIntoId, transformOptions } from '../transformers/index.mjs'
|
|
3
3
|
import { outputTransformer } from '../transformers/output_transformer.mjs'
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -17,6 +17,8 @@ export async function findOneAndReplace({ query, replacement, options, collectio
|
|
|
17
17
|
query = stringsIntoId(query)
|
|
18
18
|
const col = await getCollection()
|
|
19
19
|
|
|
20
|
+
options = transformOptions(options)
|
|
21
|
+
|
|
20
22
|
const doc = await col.findOneAndReplace(query, replacement, options ?? {})
|
|
21
23
|
if (doc == null) return null
|
|
22
24
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Collection } from 'mongodb'
|
|
2
|
-
import { renameToMongoId, stringsIntoId } from '../transformers/index.mjs'
|
|
2
|
+
import { renameToMongoId, stringsIntoId, transformOptions } from '../transformers/index.mjs'
|
|
3
3
|
import { outputTransformer } from '../transformers/output_transformer.mjs'
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -33,6 +33,8 @@ export async function findOneAndUpdate({ query, update, options, collectionOptio
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
options = transformOptions(options)
|
|
37
|
+
|
|
36
38
|
const doc = await col.findOneAndUpdate(query, update, options ?? {})
|
|
37
39
|
if (doc == null) return null
|
|
38
40
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Collection, ObjectId } from 'mongodb'
|
|
2
2
|
import { inputTransformer } from '../transformers/input_transformer.mjs'
|
|
3
|
+
import { outputTransformer } from '../transformers/output_transformer.mjs'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* @template {import('../../../types.js').MongoDocument} T
|
|
@@ -30,11 +31,16 @@ export async function insertMany({ docs, collectionOptions, getCollection }) {
|
|
|
30
31
|
let { insertedIds } = result
|
|
31
32
|
const indexes = Object.keys(insertedIds)
|
|
32
33
|
for (const index of indexes) {
|
|
34
|
+
// @ts-ignore
|
|
33
35
|
const id = insertedIds[index]
|
|
34
36
|
if (id instanceof ObjectId) {
|
|
37
|
+
// @ts-ignore
|
|
35
38
|
docs[index].id = id.toHexString()
|
|
36
39
|
}
|
|
37
40
|
}
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
return docs.map(doc => outputTransformer({
|
|
42
|
+
// @ts-ignore
|
|
43
|
+
document: doc,
|
|
44
|
+
collectionOptions
|
|
45
|
+
}))
|
|
40
46
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Collection, ObjectId } from 'mongodb'
|
|
2
2
|
import { inputTransformer } from '../transformers/input_transformer.mjs'
|
|
3
|
+
import { outputTransformer } from '../transformers/output_transformer.mjs'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* @template {import('../../../types.js').MongoDocument} T
|
|
@@ -26,8 +27,12 @@ export async function insertOne({ doc, collectionOptions, getCollection }) {
|
|
|
26
27
|
id = id.toHexString()
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
delete doc._id
|
|
30
|
-
|
|
31
30
|
// @ts-ignore
|
|
32
|
-
|
|
31
|
+
doc.id = id
|
|
32
|
+
|
|
33
|
+
return outputTransformer({
|
|
34
|
+
// @ts-ignore
|
|
35
|
+
document: doc,
|
|
36
|
+
collectionOptions,
|
|
37
|
+
})
|
|
33
38
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Collection } from 'mongodb'
|
|
2
|
-
import { renameToMongoId, stringsIntoId } from '../transformers/index.mjs'
|
|
2
|
+
import { renameToMongoId, stringsIntoId, transformOptions } from '../transformers/index.mjs'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @template {import('../../../types.js').MongoDocument} T
|
|
@@ -34,6 +34,8 @@ export async function updateMany({ query, update, options, collectionOptions, ge
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
options = transformOptions(options)
|
|
38
|
+
|
|
37
39
|
const col = await getCollection()
|
|
38
40
|
const r = await col.updateMany(query, update, options)
|
|
39
41
|
return r
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Collection } from 'mongodb'
|
|
2
|
-
import { renameToMongoId, stringsIntoId } from '../transformers/index.mjs'
|
|
2
|
+
import { renameToMongoId, stringsIntoId, transformOptions } from '../transformers/index.mjs'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @template {import('../../../types.js').MongoDocument} T
|
|
@@ -36,6 +36,8 @@ export async function updateOne({ query, update, options, collectionOptions, get
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
options = transformOptions(options)
|
|
40
|
+
|
|
39
41
|
const r = await col.updateOne(query, update, options)
|
|
40
42
|
return r.matchedCount > 0
|
|
41
43
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export * from './id/index.mjs'
|
|
2
|
-
export * from './object_id/index.mjs'
|
|
2
|
+
export * from './object_id/index.mjs'
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { stringsIntoId } from './strings_into_id.mjs'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Option fields that carry actual data values (documents/queries that may
|
|
5
|
+
* contain ObjectId hex-strings), as opposed to metadata like sort directions,
|
|
6
|
+
* index names or write concerns. These are the only fields that need the same
|
|
7
|
+
* hex-string → `ObjectId` conversion applied to `query` and `update`.
|
|
8
|
+
*
|
|
9
|
+
* - `arrayFilters`: filters referencing filtered positional operators.
|
|
10
|
+
* - `let`: variables accessible via `$$var` in `$expr`/pipeline updates.
|
|
11
|
+
* - `min`/`max`: inclusive/exclusive index bounds (find only).
|
|
12
|
+
* - `projection`: normally inclusion/exclusion flags, but may embed a query
|
|
13
|
+
* through operators like `$elemMatch`.
|
|
14
|
+
*
|
|
15
|
+
* Fields such as `session` (`ClientSession`), `signal` (`AbortSignal`),
|
|
16
|
+
* `readPreference` and `writeConcern` are deliberately left out: `stringsIntoId`
|
|
17
|
+
* only preserves `Date`, so recursing into those class instances would deep-clone
|
|
18
|
+
* them into plain objects and break them. Scoping to data-bearing keys keeps the
|
|
19
|
+
* conversion safe.
|
|
20
|
+
*/
|
|
21
|
+
const DATA_BEARING_KEYS = ['arrayFilters', 'let', 'min', 'max', 'projection']
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Applies `stringsIntoId` to the data-bearing fields of an operation's
|
|
25
|
+
* `options`, leaving metadata and special objects untouched.
|
|
26
|
+
*
|
|
27
|
+
* Does not mutate the caller's `options`: a shallow copy is created only when a
|
|
28
|
+
* field actually changes, otherwise the original reference is returned.
|
|
29
|
+
*
|
|
30
|
+
* @template {Record<string, any> | undefined} T
|
|
31
|
+
* @param {T} options
|
|
32
|
+
* @returns {T}
|
|
33
|
+
*/
|
|
34
|
+
export function transformOptions(options) {
|
|
35
|
+
if (options == null) return options
|
|
36
|
+
|
|
37
|
+
let result = options
|
|
38
|
+
for (const key of DATA_BEARING_KEYS) {
|
|
39
|
+
const value = options[key]
|
|
40
|
+
if (value == null) continue
|
|
41
|
+
|
|
42
|
+
const transformed = stringsIntoId(value)
|
|
43
|
+
if (transformed !== value) {
|
|
44
|
+
if (result === options) {
|
|
45
|
+
result = { ...options }
|
|
46
|
+
}
|
|
47
|
+
result[key] = transformed
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return result
|
|
52
|
+
}
|