diff --git a/.changeset/perfect-trains-leave.md b/.changeset/perfect-trains-leave.md new file mode 100644 index 0000000..786928a --- /dev/null +++ b/.changeset/perfect-trains-leave.md @@ -0,0 +1,5 @@ +--- +'@lowdefy/community-plugin-mongodb': patch +--- + +Update dependency mongodb to v6.3.0. diff --git a/.changeset/short-rice-develop.md b/.changeset/short-rice-develop.md new file mode 100644 index 0000000..0e1667b --- /dev/null +++ b/.changeset/short-rice-develop.md @@ -0,0 +1,6 @@ +--- +'@lowdefy/community-plugin-mongodb': major +--- + +The `MongoDBUpdateOne` request now throws an error if no document was matched and updated. This behaviour can be disabled by setting the new `disableNoMatchError` property. + diff --git a/apps/docs/community-plugin-mongodb/MongoDB.yaml b/apps/docs/community-plugin-mongodb/MongoDB.yaml index 48c20f0..d3de46c 100644 --- a/apps/docs/community-plugin-mongodb/MongoDB.yaml +++ b/apps/docs/community-plugin-mongodb/MongoDB.yaml @@ -41,9 +41,75 @@ _ref: ## Requests Request types: + - MongoDBUpdateOne - MongoDBInsertConsecutiveId - MongoDBInsertManyConsecutiveIds + ### MongoDBUpdateOne + + #### Properties + + The `MongoDBUpdateOne` request modifies the standard [MongoDBUpdateOne](https://docs.lowdefy.com/MongoDB) to throw an error if no document was matched and updated. This behaviour can be disabled by setting the `disableNoMatchError` property. + + - `disableNoMatchError: boolean`: Set to true to disable the no match error when updating. It is set to false by default. _This is not the standard MongoDBUpdateOne behaviour and will throw an error when there is no matching document._ + + The request returns the following: + + If a log collection is not set on the connection + + - `acknowledged: boolean` - Acknowledgement of the insertion. + - `matchedCount: number` - The number of matched documents. + - `modifiedCount: number` - The number of modified documents. + - `upsertedId: string` - The ID of the upserted document. + - `upsertedCount: number` - The number of upserts. + + If a log collection is set on the connection + + - `lastErrorObject: object` - An object containing data on whether an existing document was updated or not. + - `ok: number` - Status of the request, 1 if the request was successful and 0 otherwise. + - `'$clusterTime': object` - An object containing data on the cluster time and signature. + - `operationTime: date` - Timestamp object of the operation time. + + #### Example + + ###### The disableNoMatchError property can be useful on a request that is in an action chain of other requests that should be executed whether or not it fails. + ```yaml + requests: + - id: item_request_1 + type: MongoDBUpdateOne + connectionId: items + payload: + id: + _state: item._id + properties: + disableNoMatchError: true + filter: + _id: + _payload: id + status: In Progress + update: + - $set: + ... + - id: item_request_2 + ... + ... + blocks: + - id: update_items + type: Button + properties: + title: Update Item + events: + onClick: + - id: item_request_1 + type: Request + params: item_request_1 + - id: item_request_2 + type: Request + params: item_request_2 + messages: + success: Item updated + ``` + ### MongoDBInsertConsecutiveId #### Properties diff --git a/plugins/community-plugin-mongodb/package.json b/plugins/community-plugin-mongodb/package.json index 901acc5..33b15ec 100644 --- a/plugins/community-plugin-mongodb/package.json +++ b/plugins/community-plugin-mongodb/package.json @@ -19,7 +19,7 @@ "dependencies": { "@lowdefy/connection-mongodb": "^4.0.0-rc.12", "@lowdefy/helpers": "^4.0.0-rc.12", - "mongodb": "5.6.0", + "mongodb": "6.3.0", "next-auth": "4", "saslprep": "1.0.3", "uuid": "9" diff --git a/plugins/community-plugin-mongodb/src/connections/MongoDBCollection/MongoDBDeleteOne/MongoDBDeleteOne.js b/plugins/community-plugin-mongodb/src/connections/MongoDBCollection/MongoDBDeleteOne/MongoDBDeleteOne.js index 85afbe4..ed4bddd 100644 --- a/plugins/community-plugin-mongodb/src/connections/MongoDBCollection/MongoDBDeleteOne/MongoDBDeleteOne.js +++ b/plugins/community-plugin-mongodb/src/connections/MongoDBCollection/MongoDBDeleteOne/MongoDBDeleteOne.js @@ -33,7 +33,10 @@ async function MongodbDeleteOne({ let response; try { if (logCollection) { - const { value, ...responseWithoutValue } = await collection.findOneAndDelete(filter, options); + const { value, ...responseWithoutValue } = await collection.findOneAndDelete(filter, { + ...options, + includeResultMetadata: true, + }); response = responseWithoutValue; await logCollection.insertOne({ args: { filter, options }, diff --git a/plugins/community-plugin-mongodb/src/connections/MongoDBCollection/MongoDBUpdateOne/MongoDBUpdateOne.js b/plugins/community-plugin-mongodb/src/connections/MongoDBCollection/MongoDBUpdateOne/MongoDBUpdateOne.js index 794ddb2..df36836 100644 --- a/plugins/community-plugin-mongodb/src/connections/MongoDBCollection/MongoDBUpdateOne/MongoDBUpdateOne.js +++ b/plugins/community-plugin-mongodb/src/connections/MongoDBCollection/MongoDBUpdateOne/MongoDBUpdateOne.js @@ -28,16 +28,15 @@ async function MongodbUpdateOne({ payload, }) { const deserializedRequest = deserialize(request); - const { filter, update, options } = deserializedRequest; + const { filter, update, options, disableNoMatchError } = deserializedRequest; const { collection, client, logCollection } = await getCollection({ connection }); let response; try { if (logCollection) { - const { value, ...responseWithoutValue } = await collection.findOneAndUpdate( - filter, - update, - options - ); + const { value, ...responseWithoutValue } = await collection.findOneAndUpdate(filter, update, { + ...options, + includeResultMetadata: true, + }); response = responseWithoutValue; const after = await collection.findOne({ _id: value ? value._id : response.lastErrorObject?.upserted, @@ -55,8 +54,14 @@ async function MongodbUpdateOne({ type: 'MongoDBUpdateOne', meta: connection.changeLog?.meta, }); + if (!disableNoMatchError && !response.lastErrorObject.updatedExisting) { + throw new Error('No matching record to update.'); + } } else { response = await collection.updateOne(filter, update, options); + if (!disableNoMatchError && response.matchedCount === 0) { + throw new Error('No matching record to update.'); + } } } catch (error) { await client.close(); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 95c0f18..1e13f8b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -286,8 +286,8 @@ importers: specifier: ^4.0.0-rc.12 version: 4.0.0-rc.12 mongodb: - specifier: 5.6.0 - version: 5.6.0 + specifier: 6.3.0 + version: 6.3.0 next-auth: specifier: '4' version: 4.22.1(next@13.5.4)(nodemailer@6.9.7)(react-dom@18.2.0)(react@18.2.0) @@ -303,7 +303,7 @@ importers: version: 4.0.0-rc.12 '@shelf/jest-mongodb': specifier: 4.1.4 - version: 4.1.4(jest-environment-node@28.1.3)(mongodb@5.6.0) + version: 4.1.4(jest-environment-node@28.1.3)(mongodb@6.3.0) '@swc/cli': specifier: 0.1.62 version: 0.1.62(@swc/core@1.3.96) @@ -2185,8 +2185,6 @@ packages: requiresBuild: true dependencies: sparse-bitfield: 3.0.3 - dev: false - optional: true /@next-auth/mongodb-adapter@1.1.3(mongodb@4.17.1)(next-auth@4.22.1): resolution: {integrity: sha512-nH/may8hntYBlcuxepSsR2b95w6SRnP+c/FFt3KKjdTScNjhrN0zZdlT90nisjG/3gK+MvzMbz/F4Rwpgr9RMA==} @@ -2330,7 +2328,7 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false - /@shelf/jest-mongodb@4.1.4(jest-environment-node@28.1.3)(mongodb@5.6.0): + /@shelf/jest-mongodb@4.1.4(jest-environment-node@28.1.3)(mongodb@6.3.0): resolution: {integrity: sha512-ccr9ujYN1gRSdO0v4LlJGp6dcne7UuxNgGMdqbdPbBgmUxz7L/CQy9x0olFPC0yCzAYEyF4Jh/zmMCnj8YUMXQ==} engines: {node: '>=16'} peerDependencies: @@ -2339,7 +2337,7 @@ packages: dependencies: debug: 4.3.4 jest-environment-node: 28.1.3 - mongodb: 5.6.0 + mongodb: 6.3.0 mongodb-memory-server: 8.9.3 transitivePeerDependencies: - supports-color @@ -3304,6 +3302,11 @@ packages: /@types/webidl-conversions@7.0.0: resolution: {integrity: sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==} + /@types/whatwg-url@11.0.3: + resolution: {integrity: sha512-z1ELvMijRL1QmU7QuzDkeYXSF2+dXI0ITKoQsIoVKcNBOiK5RMmWy+pYYxJTHFt8vkpZe7UsvRErQwcxZkjoUw==} + dependencies: + '@types/webidl-conversions': 7.0.0 + /@types/whatwg-url@8.2.2: resolution: {integrity: sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==} dependencies: @@ -4066,9 +4069,9 @@ packages: dependencies: buffer: 5.7.1 - /bson@5.4.0: - resolution: {integrity: sha512-WRZ5SQI5GfUuKnPTNmAYPiKIof3ORXAF4IRU5UcgmivNIon01rWQlw5RUH954dpu8yGL8T59YShVddIPaU/gFA==} - engines: {node: '>=14.20.1'} + /bson@6.2.0: + resolution: {integrity: sha512-ID1cI+7bazPDyL9wYy9GaQ8gEEohWvcUl/Yf0dIdutJxnmInEEyCsb4awy/OiBfall7zBA179Pahi3vCdFze3Q==} + engines: {node: '>=16.20.1'} /buffer-alloc-unsafe@1.1.0: resolution: {integrity: sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==} @@ -7820,6 +7823,12 @@ packages: '@types/whatwg-url': 8.2.2 whatwg-url: 11.0.0 + /mongodb-connection-string-url@3.0.0: + resolution: {integrity: sha512-t1Vf+m1I5hC2M5RJx/7AtxgABy1cZmIPQRMXw+gEIPn/cZNF3Oiy+l0UIypUwVB5trcWHq3crg2g3uAR9aAwsQ==} + dependencies: + '@types/whatwg-url': 11.0.3 + whatwg-url: 13.0.0 + /mongodb-memory-server-core@8.9.3: resolution: {integrity: sha512-z/UW/fHTDRA+qvcqBxibTonnwuxRPWsphO9BUGKvFweRxT9uj09/hCK96kjBdF9wQj6k7bj/Tqo9gkGG0XbDng==} engines: {node: '>=12.22.0'} @@ -7881,26 +7890,36 @@ packages: saslprep: 1.0.3 dev: true - /mongodb@5.6.0: - resolution: {integrity: sha512-z8qVs9NfobHJm6uzK56XBZF8XwM9H294iRnB7wNjF0SnY93si5HPziIJn+qqvUR5QOff/4L0gCD6SShdR/GtVQ==} - engines: {node: '>=14.20.1'} + /mongodb@6.3.0: + resolution: {integrity: sha512-tt0KuGjGtLUhLoU263+xvQmPHEGTw5LbcNC73EoFRYgSHwZt5tsoJC110hDyO1kjQzpgNrpdcSza9PknWN4LrA==} + engines: {node: '>=16.20.1'} peerDependencies: - '@aws-sdk/credential-providers': ^3.201.0 - mongodb-client-encryption: '>=2.3.0 <3' + '@aws-sdk/credential-providers': ^3.188.0 + '@mongodb-js/zstd': ^1.1.0 + gcp-metadata: ^5.2.0 + kerberos: ^2.0.1 + mongodb-client-encryption: '>=6.0.0 <7' snappy: ^7.2.2 + socks: ^2.7.1 peerDependenciesMeta: '@aws-sdk/credential-providers': optional: true + '@mongodb-js/zstd': + optional: true + gcp-metadata: + optional: true + kerberos: + optional: true mongodb-client-encryption: optional: true snappy: optional: true + socks: + optional: true dependencies: - bson: 5.4.0 - mongodb-connection-string-url: 2.6.0 - socks: 2.7.1 - optionalDependencies: - saslprep: 1.0.3 + '@mongodb-js/saslprep': 1.1.1 + bson: 6.2.0 + mongodb-connection-string-url: 3.0.0 /mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} @@ -10373,6 +10392,12 @@ packages: dependencies: punycode: 2.3.0 + /tr46@4.1.1: + resolution: {integrity: sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==} + engines: {node: '>=14'} + dependencies: + punycode: 2.3.0 + /trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} dev: false @@ -10805,6 +10830,13 @@ packages: tr46: 3.0.0 webidl-conversions: 7.0.0 + /whatwg-url@13.0.0: + resolution: {integrity: sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==} + engines: {node: '>=16'} + dependencies: + tr46: 4.1.1 + webidl-conversions: 7.0.0 + /which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} dependencies: