assai 2.1.0 → 2.1.2
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/__test/mock_get_collection.d.mts +2 -0
- package/dist/src/usecases/mongo/transformers/id/rename_to_dev_id.d.mts +3 -0
- package/dist/src/usecases/mongo/transformers/id/rename_to_mongo_id.d.mts +3 -0
- package/dist/src/usecases/mongo/transformers/object_id/ids_into_strings.d.mts +5 -0
- package/dist/src/usecases/mongo/transformers/object_id/strings_into_id.d.mts +3 -0
- package/dist/src/usecases/mongo/transformers/timestamps.d.mts +5 -0
- package/package.json +3 -3
- package/src/__test/mock_get_collection.mjs +2 -0
- package/src/usecases/mongo/operation/aggregate.mjs +2 -7
- package/src/usecases/mongo/operation/bulk_write.mjs +8 -8
- package/src/usecases/mongo/operation/count.mjs +1 -1
- package/src/usecases/mongo/operation/delete_many.mjs +1 -1
- package/src/usecases/mongo/operation/delete_one.mjs +1 -1
- package/src/usecases/mongo/operation/find.mjs +1 -1
- package/src/usecases/mongo/operation/find_one_and_delete.mjs +1 -1
- package/src/usecases/mongo/operation/find_one_and_replace.mjs +1 -1
- package/src/usecases/mongo/operation/find_one_and_update.mjs +2 -2
- package/src/usecases/mongo/operation/update_many.mjs +2 -2
- package/src/usecases/mongo/operation/update_one.mjs +2 -2
- package/src/usecases/mongo/transformers/id/rename_to_dev_id.mjs +28 -6
- package/src/usecases/mongo/transformers/id/rename_to_mongo_id.mjs +28 -6
- package/src/usecases/mongo/transformers/input_transformer.mjs +1 -1
- package/src/usecases/mongo/transformers/object_id/ids_into_strings.mjs +22 -5
- package/src/usecases/mongo/transformers/object_id/strings_into_id.mjs +55 -9
- package/src/usecases/mongo/transformers/timestamps.mjs +5 -0
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
* Convert the parameter from `ObjectId` into string whenever possible.
|
|
3
3
|
*
|
|
4
4
|
* If an object or array is given, this function will be applied recursively.
|
|
5
|
+
*
|
|
6
|
+
* Uses duck-typing (`_bsontype === 'ObjectId'`) instead of `instanceof` to
|
|
7
|
+
* safely identify ObjectId values across different instances of the `mongodb`
|
|
8
|
+
* / `bson` package (e.g. when the host project and this library resolve to
|
|
9
|
+
* separate copies of the package).
|
|
5
10
|
* @param {*} obj
|
|
6
11
|
*/
|
|
7
12
|
export function idsIntoString(obj: any): any;
|
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
* - An array;
|
|
7
7
|
*
|
|
8
8
|
* If the parameter is a string, then it is converted to `ObjectId` if possible.
|
|
9
|
+
*
|
|
10
|
+
* This function does not mutate the original input. It preserves reference equality for
|
|
11
|
+
* objects and special types (like Date) that don't need transformation.
|
|
9
12
|
* @param {*} obj
|
|
10
13
|
*/
|
|
11
14
|
export function stringsIntoId(obj: any): any;
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* Transforms a document by adding or updating timestamp fields (createdAt and updatedAt).
|
|
3
|
+
* If createdAt is not set, it can be generated as a new Date or extracted from the document's ObjectId.
|
|
4
|
+
* If updatedAt is not set, it is generated as a new Date.
|
|
5
|
+
* The document is modified in place.
|
|
6
|
+
*
|
|
2
7
|
* @template {import('../../../types.js').MongoDocument} T
|
|
3
8
|
* @param {import('mongodb').WithId<T> | import('../../../types.js').MongoDocument} doc
|
|
4
9
|
* @param {import('../../../factories/create_mongo_collection.mjs').IcreateCollectionOptions<T>} options
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "assai",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.2",
|
|
4
4
|
"repository": {
|
|
5
5
|
"url": "https://github.com/TimeLord2010/assai",
|
|
6
6
|
"type": "git"
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
],
|
|
29
29
|
"author": "Vinícius Gabriel",
|
|
30
30
|
"license": "ISC",
|
|
31
|
-
"
|
|
32
|
-
"mongodb": "
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"mongodb": ">=4.0.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@faker-js/faker": "^8.4.1",
|
|
@@ -17,5 +17,7 @@ export async function mockGetCollection(collectionName = 'test') {
|
|
|
17
17
|
* @property {string | ObjectId} [tag]
|
|
18
18
|
* @property {Date} [createdAt]
|
|
19
19
|
* @property {object[]} [posts]
|
|
20
|
+
* @property {number} [score]
|
|
21
|
+
* @property {string} [group]
|
|
20
22
|
* @property {object} [address]
|
|
21
23
|
*/
|
|
@@ -12,15 +12,10 @@ import { outputTransformer } from '../transformers/output_transformer.mjs'
|
|
|
12
12
|
* @returns {Promise<T[]>}
|
|
13
13
|
*/
|
|
14
14
|
export async function aggregate({ getCollection, pipeline, options, collectionOptions }) {
|
|
15
|
-
|
|
16
|
-
if (stage.$match != null) {
|
|
17
|
-
stage.$match = renameToMongoId(stage.$match)
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
pipeline = stringsIntoId(pipeline)
|
|
15
|
+
const finalPipeline = stringsIntoId(renameToMongoId(pipeline))
|
|
21
16
|
|
|
22
17
|
const col = await getCollection()
|
|
23
|
-
const docs = await col.aggregate(
|
|
18
|
+
const docs = await col.aggregate(finalPipeline, options).toArray()
|
|
24
19
|
// @ts-ignore
|
|
25
20
|
return docs.map((doc) => outputTransformer({ document: doc, collectionOptions }))
|
|
26
21
|
}
|
|
@@ -21,22 +21,22 @@ export async function bulkWrite({ getCollection, operations, options, collection
|
|
|
21
21
|
})
|
|
22
22
|
} else if (o.updateOne != null) {
|
|
23
23
|
o.updateOne.filter = renameToMongoId(o.updateOne.filter)
|
|
24
|
-
stringsIntoId(o.updateOne.filter)
|
|
25
|
-
stringsIntoId(o.updateOne.update)
|
|
24
|
+
o.updateOne.filter = stringsIntoId(o.updateOne.filter)
|
|
25
|
+
o.updateOne.update = stringsIntoId(o.updateOne.update)
|
|
26
26
|
} else if (o.updateMany != null) {
|
|
27
27
|
o.updateMany.filter = renameToMongoId(o.updateMany.filter)
|
|
28
|
-
stringsIntoId(o.updateMany.filter)
|
|
29
|
-
stringsIntoId(o.updateMany.update)
|
|
28
|
+
o.updateMany.filter = stringsIntoId(o.updateMany.filter)
|
|
29
|
+
o.updateMany.update = stringsIntoId(o.updateMany.update)
|
|
30
30
|
} else if (o.deleteOne != null) {
|
|
31
31
|
o.deleteOne.filter = renameToMongoId(o.deleteOne.filter)
|
|
32
|
-
stringsIntoId(o.deleteOne.filter)
|
|
32
|
+
o.deleteOne.filter = stringsIntoId(o.deleteOne.filter)
|
|
33
33
|
} else if (o.deleteMany != null) {
|
|
34
34
|
o.deleteMany.filter = renameToMongoId(o.deleteMany.filter)
|
|
35
|
-
stringsIntoId(o.deleteMany.filter)
|
|
35
|
+
o.deleteMany.filter = stringsIntoId(o.deleteMany.filter)
|
|
36
36
|
} else if (o.replaceOne != null) {
|
|
37
37
|
o.replaceOne.filter = renameToMongoId(o.replaceOne.filter)
|
|
38
|
-
stringsIntoId(o.replaceOne.filter)
|
|
39
|
-
stringsIntoId(o.replaceOne.replacement)
|
|
38
|
+
o.replaceOne.filter = stringsIntoId(o.replaceOne.filter)
|
|
39
|
+
o.replaceOne.replacement = stringsIntoId(o.replaceOne.replacement)
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
|
|
@@ -9,7 +9,7 @@ import { renameToMongoId, stringsIntoId } from '../transformers/index.mjs'
|
|
|
9
9
|
*/
|
|
10
10
|
export async function count({ getCollection, query }) {
|
|
11
11
|
query = renameToMongoId(query)
|
|
12
|
-
stringsIntoId(query)
|
|
12
|
+
query = stringsIntoId(query)
|
|
13
13
|
|
|
14
14
|
const col = await getCollection()
|
|
15
15
|
const count = await col.countDocuments(query)
|
|
@@ -9,7 +9,7 @@ import { renameToMongoId, stringsIntoId } from '../transformers/index.mjs'
|
|
|
9
9
|
*/
|
|
10
10
|
export async function deleteMany({ query, getCollection }) {
|
|
11
11
|
query = renameToMongoId(query)
|
|
12
|
-
stringsIntoId(query)
|
|
12
|
+
query = stringsIntoId(query)
|
|
13
13
|
const col = await getCollection()
|
|
14
14
|
const r = await col.deleteMany(query)
|
|
15
15
|
return r.deletedCount
|
|
@@ -10,7 +10,7 @@ import { renameToMongoId, stringsIntoId } from '../transformers/index.mjs'
|
|
|
10
10
|
*/
|
|
11
11
|
export async function deleteOne({ query, getCollection }) {
|
|
12
12
|
query = renameToMongoId(query)
|
|
13
|
-
stringsIntoId(query)
|
|
13
|
+
query = stringsIntoId(query)
|
|
14
14
|
const col = await getCollection()
|
|
15
15
|
const r = await col.deleteOne(query)
|
|
16
16
|
return r.deletedCount > 0
|
|
@@ -13,7 +13,7 @@ import { outputTransformer } from '../transformers/output_transformer.mjs'
|
|
|
13
13
|
*/
|
|
14
14
|
export async function findOneAndDelete({ query, options, collectionOptions, getCollection }) {
|
|
15
15
|
query = renameToMongoId(query)
|
|
16
|
-
stringsIntoId(query)
|
|
16
|
+
query = stringsIntoId(query)
|
|
17
17
|
const col = await getCollection()
|
|
18
18
|
|
|
19
19
|
const doc = await col.findOneAndDelete(query, options ?? {})
|
|
@@ -14,7 +14,7 @@ import { outputTransformer } from '../transformers/output_transformer.mjs'
|
|
|
14
14
|
*/
|
|
15
15
|
export async function findOneAndReplace({ query, replacement, options, collectionOptions, getCollection }) {
|
|
16
16
|
query = renameToMongoId(query)
|
|
17
|
-
stringsIntoId(query)
|
|
17
|
+
query = stringsIntoId(query)
|
|
18
18
|
const col = await getCollection()
|
|
19
19
|
|
|
20
20
|
const doc = await col.findOneAndReplace(query, replacement, options ?? {})
|
|
@@ -14,8 +14,8 @@ import { outputTransformer } from '../transformers/output_transformer.mjs'
|
|
|
14
14
|
*/
|
|
15
15
|
export async function findOneAndUpdate({ query, update, options, collectionOptions, getCollection }) {
|
|
16
16
|
query = renameToMongoId(query)
|
|
17
|
-
stringsIntoId(query)
|
|
18
|
-
stringsIntoId(update)
|
|
17
|
+
query = stringsIntoId(query)
|
|
18
|
+
update = stringsIntoId(update)
|
|
19
19
|
const col = await getCollection()
|
|
20
20
|
|
|
21
21
|
const { timestamps } = collectionOptions ?? {}
|
|
@@ -12,8 +12,8 @@ import { renameToMongoId, stringsIntoId } from '../transformers/index.mjs'
|
|
|
12
12
|
*/
|
|
13
13
|
export async function updateMany({ query, update, options, collectionOptions, getCollection }) {
|
|
14
14
|
query = renameToMongoId(query)
|
|
15
|
-
stringsIntoId(query)
|
|
16
|
-
stringsIntoId(update)
|
|
15
|
+
query = stringsIntoId(query)
|
|
16
|
+
update = stringsIntoId(update)
|
|
17
17
|
|
|
18
18
|
const { timestamps } = collectionOptions ?? {}
|
|
19
19
|
const { updatedAt } = timestamps ?? {
|
|
@@ -13,8 +13,8 @@ import { renameToMongoId, stringsIntoId } from '../transformers/index.mjs'
|
|
|
13
13
|
*/
|
|
14
14
|
export async function updateOne({ query, update, options, collectionOptions, getCollection }) {
|
|
15
15
|
query = renameToMongoId(query)
|
|
16
|
-
stringsIntoId(query)
|
|
17
|
-
stringsIntoId(update)
|
|
16
|
+
query = stringsIntoId(query)
|
|
17
|
+
update = stringsIntoId(update)
|
|
18
18
|
const col = await getCollection()
|
|
19
19
|
|
|
20
20
|
const { timestamps } = collectionOptions ?? {}
|
|
@@ -2,13 +2,35 @@
|
|
|
2
2
|
* ```
|
|
3
3
|
* "_id" -> "id"
|
|
4
4
|
* ```
|
|
5
|
+
* Recursively renames all `_id` keys to `id` in objects and arrays.
|
|
6
|
+
* Does not mutate the original input.
|
|
7
|
+
* @param {*} obj
|
|
5
8
|
*/
|
|
6
9
|
export function renameToDevId(obj) {
|
|
7
|
-
if (
|
|
8
|
-
|
|
9
|
-
if (
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
if (obj == null) return obj
|
|
11
|
+
if (typeof obj !== 'object') return obj
|
|
12
|
+
if (obj instanceof Date) return obj
|
|
13
|
+
|
|
14
|
+
if (Array.isArray(obj)) {
|
|
15
|
+
let hasChanges = false
|
|
16
|
+
const transformed = new Array(obj.length)
|
|
17
|
+
for (let i = 0; i < obj.length; i++) {
|
|
18
|
+
const item = obj[i]
|
|
19
|
+
const transformedItem = renameToDevId(item)
|
|
20
|
+
transformed[i] = transformedItem
|
|
21
|
+
if (transformedItem !== item) hasChanges = true
|
|
22
|
+
}
|
|
23
|
+
return hasChanges ? transformed : obj
|
|
13
24
|
}
|
|
25
|
+
|
|
26
|
+
let hasChanges = false
|
|
27
|
+
/** @type {Record<string, any>} */
|
|
28
|
+
const transformed = {}
|
|
29
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
30
|
+
const newKey = key === '_id' ? 'id' : key
|
|
31
|
+
const newValue = renameToDevId(value)
|
|
32
|
+
transformed[newKey] = newValue
|
|
33
|
+
if (newKey !== key || newValue !== value) hasChanges = true
|
|
34
|
+
}
|
|
35
|
+
return hasChanges ? transformed : obj
|
|
14
36
|
}
|
|
@@ -2,13 +2,35 @@
|
|
|
2
2
|
* ```
|
|
3
3
|
* "id" -> "_id"
|
|
4
4
|
* ```
|
|
5
|
+
* Recursively renames all `id` keys to `_id` in objects and arrays.
|
|
6
|
+
* Does not mutate the original input.
|
|
7
|
+
* @param {*} obj
|
|
5
8
|
*/
|
|
6
9
|
export function renameToMongoId(obj) {
|
|
7
|
-
if (
|
|
8
|
-
|
|
9
|
-
if (
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
if (obj == null) return obj
|
|
11
|
+
if (typeof obj !== 'object') return obj
|
|
12
|
+
if (obj instanceof Date) return obj
|
|
13
|
+
|
|
14
|
+
if (Array.isArray(obj)) {
|
|
15
|
+
let hasChanges = false
|
|
16
|
+
const transformed = new Array(obj.length)
|
|
17
|
+
for (let i = 0; i < obj.length; i++) {
|
|
18
|
+
const item = obj[i]
|
|
19
|
+
const transformedItem = renameToMongoId(item)
|
|
20
|
+
transformed[i] = transformedItem
|
|
21
|
+
if (transformedItem !== item) hasChanges = true
|
|
22
|
+
}
|
|
23
|
+
return hasChanges ? transformed : obj
|
|
13
24
|
}
|
|
25
|
+
|
|
26
|
+
let hasChanges = false
|
|
27
|
+
/** @type {Record<string, any>} */
|
|
28
|
+
const transformed = {}
|
|
29
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
30
|
+
const newKey = key === 'id' ? '_id' : key
|
|
31
|
+
const newValue = renameToMongoId(value)
|
|
32
|
+
transformed[newKey] = newValue
|
|
33
|
+
if (newKey !== key || newValue !== value) hasChanges = true
|
|
34
|
+
}
|
|
35
|
+
return hasChanges ? transformed : obj
|
|
14
36
|
}
|
|
@@ -11,7 +11,7 @@ export function inputTransformer({
|
|
|
11
11
|
document, collectionOptions,
|
|
12
12
|
}) {
|
|
13
13
|
document = renameToMongoId(document)
|
|
14
|
-
stringsIntoId(document)
|
|
14
|
+
document = stringsIntoId(document)
|
|
15
15
|
|
|
16
16
|
const { timestamps } = collectionOptions ?? {}
|
|
17
17
|
const { createdAt, updatedAt } = timestamps ?? {
|
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
import { ObjectId } from 'mongodb'
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* Convert the parameter from `ObjectId` into string whenever possible.
|
|
5
3
|
*
|
|
6
4
|
* If an object or array is given, this function will be applied recursively.
|
|
5
|
+
*
|
|
6
|
+
* Uses duck-typing (`_bsontype === 'ObjectId'`) instead of `instanceof` to
|
|
7
|
+
* safely identify ObjectId values across different instances of the `mongodb`
|
|
8
|
+
* / `bson` package (e.g. when the host project and this library resolve to
|
|
9
|
+
* separate copies of the package).
|
|
7
10
|
* @param {*} obj
|
|
8
11
|
*/
|
|
9
12
|
export function idsIntoString(obj) {
|
|
10
13
|
if (obj == null) return obj
|
|
11
14
|
if (typeof obj != 'object') return obj
|
|
12
|
-
if (obj
|
|
15
|
+
if (isObjectId(obj)) return obj.toHexString()
|
|
13
16
|
if (Array.isArray(obj)) {
|
|
14
17
|
for (let i = 0; i < obj.length; i++) {
|
|
15
18
|
const item = obj[i]
|
|
@@ -18,7 +21,7 @@ export function idsIntoString(obj) {
|
|
|
18
21
|
return obj
|
|
19
22
|
}
|
|
20
23
|
for (const [key, value] of Object.entries(obj)) {
|
|
21
|
-
if (value
|
|
24
|
+
if (isObjectId(value)) {
|
|
22
25
|
obj[key] = value.toHexString()
|
|
23
26
|
continue
|
|
24
27
|
}
|
|
@@ -27,4 +30,18 @@ export function idsIntoString(obj) {
|
|
|
27
30
|
}
|
|
28
31
|
}
|
|
29
32
|
return obj
|
|
30
|
-
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Duck-type check for BSON ObjectId values.
|
|
37
|
+
*
|
|
38
|
+
* Using `_bsontype` instead of `instanceof ObjectId` avoids false negatives
|
|
39
|
+
* that occur when the host project and this package resolve to different copies
|
|
40
|
+
* of the `mongodb` / `bson` module, which makes `instanceof` return `false`
|
|
41
|
+
* even for legitimate ObjectId instances.
|
|
42
|
+
* @param {*} value
|
|
43
|
+
* @returns {boolean}
|
|
44
|
+
*/
|
|
45
|
+
function isObjectId(value) {
|
|
46
|
+
return value != null && typeof value == 'object' && value._bsontype === 'ObjectId'
|
|
47
|
+
}
|
|
@@ -8,31 +8,77 @@ import { ObjectId } from 'mongodb'
|
|
|
8
8
|
* - An array;
|
|
9
9
|
*
|
|
10
10
|
* If the parameter is a string, then it is converted to `ObjectId` if possible.
|
|
11
|
+
*
|
|
12
|
+
* This function does not mutate the original input. It preserves reference equality for
|
|
13
|
+
* objects and special types (like Date) that don't need transformation.
|
|
11
14
|
* @param {*} obj
|
|
12
15
|
*/
|
|
13
16
|
export function stringsIntoId(obj) {
|
|
14
17
|
if (obj == null) return obj
|
|
15
18
|
if (isObjectIdString(obj)) return new ObjectId(obj)
|
|
16
19
|
if (typeof obj != 'object') return obj
|
|
20
|
+
|
|
21
|
+
// Check if this object/array needs any transformation
|
|
22
|
+
const transformed = _transformRecursive(obj)
|
|
23
|
+
return transformed
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Recursively transforms ObjectId hex strings to ObjectId instances.
|
|
28
|
+
* Returns the original reference if no changes are needed, or a new object if changes are made.
|
|
29
|
+
* @param {*} obj
|
|
30
|
+
* @returns {*}
|
|
31
|
+
*/
|
|
32
|
+
function _transformRecursive(obj) {
|
|
33
|
+
if (obj == null || typeof obj != 'object') return obj
|
|
34
|
+
|
|
35
|
+
// Don't clone or transform special objects like Date
|
|
36
|
+
if (obj instanceof Date) return obj
|
|
37
|
+
|
|
17
38
|
if (Array.isArray(obj)) {
|
|
18
|
-
|
|
19
|
-
|
|
39
|
+
let hasChanges = false
|
|
40
|
+
const transformed = new Array(obj.length)
|
|
20
41
|
|
|
21
42
|
for (let i = 0; i < obj.length; i++) {
|
|
22
43
|
const item = obj[i]
|
|
23
|
-
|
|
44
|
+
if (isObjectIdString(item)) {
|
|
45
|
+
transformed[i] = new ObjectId(item)
|
|
46
|
+
hasChanges = true
|
|
47
|
+
} else if (item != null && typeof item == 'object') {
|
|
48
|
+
const transformedItem = _transformRecursive(item)
|
|
49
|
+
transformed[i] = transformedItem
|
|
50
|
+
if (transformedItem !== item) {
|
|
51
|
+
hasChanges = true
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
transformed[i] = item
|
|
55
|
+
}
|
|
24
56
|
}
|
|
25
|
-
|
|
57
|
+
|
|
58
|
+
return hasChanges ? transformed : obj
|
|
26
59
|
}
|
|
60
|
+
|
|
61
|
+
// Handle plain objects
|
|
62
|
+
let hasChanges = false
|
|
63
|
+
/** @type {Record<string, any>} */
|
|
64
|
+
const transformed = {}
|
|
65
|
+
|
|
27
66
|
for (const [key, value] of Object.entries(obj)) {
|
|
28
67
|
if (isObjectIdString(value)) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (value != null && typeof value == 'object') {
|
|
32
|
-
|
|
68
|
+
transformed[key] = ObjectId.createFromHexString(value)
|
|
69
|
+
hasChanges = true
|
|
70
|
+
} else if (value != null && typeof value == 'object') {
|
|
71
|
+
const transformedValue = _transformRecursive(value)
|
|
72
|
+
transformed[key] = transformedValue
|
|
73
|
+
if (transformedValue !== value) {
|
|
74
|
+
hasChanges = true
|
|
75
|
+
}
|
|
76
|
+
} else {
|
|
77
|
+
transformed[key] = value
|
|
33
78
|
}
|
|
34
79
|
}
|
|
35
|
-
|
|
80
|
+
|
|
81
|
+
return hasChanges ? transformed : obj
|
|
36
82
|
}
|
|
37
83
|
|
|
38
84
|
/**
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { ObjectId } from 'mongodb'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
+
* Transforms a document by adding or updating timestamp fields (createdAt and updatedAt).
|
|
5
|
+
* If createdAt is not set, it can be generated as a new Date or extracted from the document's ObjectId.
|
|
6
|
+
* If updatedAt is not set, it is generated as a new Date.
|
|
7
|
+
* The document is modified in place.
|
|
8
|
+
*
|
|
4
9
|
* @template {import('../../../types.js').MongoDocument} T
|
|
5
10
|
* @param {import('mongodb').WithId<T> | import('../../../types.js').MongoDocument} doc
|
|
6
11
|
* @param {import('../../../factories/create_mongo_collection.mjs').IcreateCollectionOptions<T>} options
|