mongochangestream
Advanced tools
Comparing version 0.45.0 to 0.46.0
@@ -0,1 +1,5 @@ | ||
# 0.46.0 | ||
- Bumped peer dependencies for `ioredis` and `mongodb`. | ||
# 0.45.0 | ||
@@ -2,0 +6,0 @@ |
@@ -20,5 +20,21 @@ "use strict"; | ||
exports.setDefaults = setDefaults; | ||
/** | ||
* Dotted path updates like { $set: {'a.b.c': 'foo'} } result in the following: | ||
* ```ts | ||
* { | ||
* updatedDescription: { | ||
* updateFields: { | ||
* 'a.b.c': 'foo' | ||
* } | ||
* } | ||
* } | ||
* ``` | ||
* Therefore, to remove 'a.b' we have to convert the `updateFields` | ||
* object to an array, filter the array with a regex, and convert | ||
* the array back to an object. | ||
*/ | ||
const removeDottedPaths = (omit) => { | ||
const dottedFields = omit | ||
.filter((x) => x.includes('.')) | ||
// Escape periods | ||
.map((x) => x.replaceAll('.', '\\.')); | ||
@@ -25,0 +41,0 @@ if (dottedFields.length) { |
{ | ||
"name": "mongochangestream", | ||
"version": "0.45.0", | ||
"version": "0.46.0", | ||
"description": "Sync MongoDB collections via change streams into any database.", | ||
@@ -61,4 +61,4 @@ "author": "GovSpend", | ||
"peerDependencies": { | ||
"ioredis": ">= 5.2.3", | ||
"mongodb": ">= 4.10.0" | ||
"ioredis": ">= 5.4.1", | ||
"mongodb": ">= 6.6.1" | ||
}, | ||
@@ -65,0 +65,0 @@ "prettier": { |
@@ -57,2 +57,6 @@ /** | ||
zipCode: faker.location.zipCode(), | ||
geo: { | ||
lat: faker.location.latitude(), | ||
long: faker.location.longitude(), | ||
}, | ||
}, | ||
@@ -75,2 +79,13 @@ createdAt: faker.date.past(), | ||
zipCode: { bsonType: 'string' }, | ||
geo: { | ||
bsonType: 'object', | ||
properties: { | ||
lat: { | ||
bsonType: 'number', | ||
}, | ||
long: { | ||
bsonType: 'number', | ||
}, | ||
}, | ||
}, | ||
}, | ||
@@ -265,3 +280,3 @@ }, | ||
const { coll, db } = await getConns() | ||
const sync = await getSync({ omit: ['name'] }) | ||
const sync = await getSync({ omit: ['address.city', 'address.geo'] }) | ||
await initState(sync, db, coll) | ||
@@ -278,3 +293,4 @@ | ||
await initialScan.start() | ||
assert.equal(documents[0].name, undefined) | ||
assert.equal(documents[0]?.address?.city, undefined) | ||
assert.equal(documents[0]?.address?.geo, undefined) | ||
// Stop | ||
@@ -442,5 +458,6 @@ await initialScan.stop() | ||
test('should omit fields from change stream', async () => { | ||
test('should omit fields from change stream - dotted paths', async () => { | ||
const { coll, db } = await getConns() | ||
const sync = await getSync({ omit: ['address.city'] }) | ||
// address.geo is a path prefix relative to the paths being updated below | ||
const sync = await getSync({ omit: ['address.city', 'address.geo'] }) | ||
await initState(sync, db, coll) | ||
@@ -464,11 +481,23 @@ | ||
{}, | ||
{ $set: { name: 'unknown', 'address.city': 'San Diego' } } | ||
{ | ||
$set: { | ||
name: 'unknown', | ||
'address.city': 'San Diego', | ||
'address.geo.lat': 24, | ||
'address.geo.long': 25, | ||
}, | ||
} | ||
) | ||
// Wait for the change stream events to be processed | ||
await setTimeout(ms('2s')) | ||
// Assertions | ||
assert.equal(documents[0].fullDocument.address.city, undefined) | ||
assert.equal( | ||
documents[0].updateDescription.updatedFields['address.city'], | ||
undefined | ||
) | ||
assert.equal(documents[0].fullDocument.address.geo, undefined) | ||
const fields = ['address.city', 'address.geo.lat', 'address.geo.long'] | ||
for (const field of fields) { | ||
assert.equal( | ||
documents[0].updateDescription.updatedFields[field], | ||
undefined | ||
) | ||
} | ||
// Stop | ||
@@ -478,4 +507,5 @@ await changeStream.stop() | ||
test('should omit nested fields when parent field is omitted from change stream', async () => { | ||
test('should omit fields from change stream - object', async () => { | ||
const { coll, db } = await getConns() | ||
// address.geo is a path prefix relative to the paths being updated below | ||
const sync = await getSync({ omit: ['address'] }) | ||
@@ -489,3 +519,3 @@ await initState(sync, db, coll) | ||
if (doc.operationType === 'update' && doc.fullDocument) { | ||
documents.push(doc.fullDocument) | ||
documents.push(doc) | ||
} | ||
@@ -499,6 +529,18 @@ } | ||
// Update records | ||
coll.updateMany({}, { $set: { 'address.zipCode': '90210' } }) | ||
coll.updateMany( | ||
{}, | ||
{ | ||
$set: { | ||
address: { city: 'San Diego' }, | ||
}, | ||
} | ||
) | ||
// Wait for the change stream events to be processed | ||
await setTimeout(ms('2s')) | ||
assert.equal(documents[0].address?.zipCode, undefined) | ||
// Assertions | ||
assert.equal(documents[0].fullDocument.address, undefined) | ||
assert.equal( | ||
documents[0].updateDescription.updatedFields.address, | ||
undefined | ||
) | ||
// Stop | ||
@@ -505,0 +547,0 @@ await changeStream.stop() |
@@ -18,5 +18,21 @@ import _debug from 'debug' | ||
/** | ||
* Dotted path updates like { $set: {'a.b.c': 'foo'} } result in the following: | ||
* ```ts | ||
* { | ||
* updatedDescription: { | ||
* updateFields: { | ||
* 'a.b.c': 'foo' | ||
* } | ||
* } | ||
* } | ||
* ``` | ||
* Therefore, to remove 'a.b' we have to convert the `updateFields` | ||
* object to an array, filter the array with a regex, and convert | ||
* the array back to an object. | ||
*/ | ||
const removeDottedPaths = (omit: string[]) => { | ||
const dottedFields = omit | ||
.filter((x) => x.includes('.')) | ||
// Escape periods | ||
.map((x) => x.replaceAll('.', '\\.')) | ||
@@ -23,0 +39,0 @@ if (dottedFields.length) { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
104106
2608