From 87e1a28090e6c97ba98548d4b7097aaa5f8707a3 Mon Sep 17 00:00:00 2001 From: Jorge Cortes Date: Wed, 8 May 2024 19:05:21 -0500 Subject: [PATCH] Tested components --- .../execute-aggregation.mjs | 64 ++++++++++++++++ .../actions/find-document/find-document.mjs | 75 +++++++++++++++++++ .../update-documents/update-documents.mjs | 69 +++++++++++++++++ components/mongodb/common/utils.mjs | 63 ++++++++++++++++ components/mongodb/package.json | 4 +- pnpm-lock.yaml | 4 +- 6 files changed, 275 insertions(+), 4 deletions(-) create mode 100644 components/mongodb/actions/execute-aggregation/execute-aggregation.mjs create mode 100644 components/mongodb/actions/find-document/find-document.mjs create mode 100644 components/mongodb/actions/update-documents/update-documents.mjs create mode 100644 components/mongodb/common/utils.mjs diff --git a/components/mongodb/actions/execute-aggregation/execute-aggregation.mjs b/components/mongodb/actions/execute-aggregation/execute-aggregation.mjs new file mode 100644 index 0000000000000..47c731cb8266b --- /dev/null +++ b/components/mongodb/actions/execute-aggregation/execute-aggregation.mjs @@ -0,0 +1,64 @@ +import app from "../../mongodb.app.mjs"; +import utils from "../../common/utils.mjs"; + +export default { + key: "mongodb-execute-aggregation", + name: "Execute Aggregation", + description: "Execute an aggregation pipeline on a MongoDB collection. [See the documentation](https://www.mongodb.com/docs/drivers/node/current/fundamentals/aggregation/)", + version: "0.0.1", + type: "action", + props: { + app, + database: { + propDefinition: [ + app, + "database", + ], + }, + collectionName: { + propDefinition: [ + app, + "collection", + ({ database }) => ({ + database, + }), + ], + }, + pipeline: { + type: "string[]", + label: "Pipeline", + description: "The aggregation pipeline to execute where each row represents a stage as a JSON string. Eg. `[ { \"$match\": { \"categories\": \"Bakery\" } }, { \"$group\": { \"_id\": \"$stars\", \"count\": { \"$sum\": 1 } } } ]`", + }, + }, + methods: { + async excecuteAggregation({ + database, collectionName, pipeline, + } = {}) { + const { app } = this; + const client = await app.getClient(); + const collection = app.getCollection(client, database, collectionName); + const cursor = collection.aggregate(pipeline); + const result = await utils.iterate(cursor); + await client.close(); + return result; + }, + }, + async run({ $ }) { + const { + excecuteAggregation, + database, + collectionName, + pipeline, + } = this; + + const response = await excecuteAggregation({ + database, + collectionName, + pipeline: utils.parseArray(pipeline), + }); + + $.export("$summary", `Successfully executed aggregation pipeline on collection with \`${response.length}\` document(s).`); + + return response; + }, +}; diff --git a/components/mongodb/actions/find-document/find-document.mjs b/components/mongodb/actions/find-document/find-document.mjs new file mode 100644 index 0000000000000..3286b349f851b --- /dev/null +++ b/components/mongodb/actions/find-document/find-document.mjs @@ -0,0 +1,75 @@ +import app from "../../mongodb.app.mjs"; +import utils from "../../common/utils.mjs"; + +export default { + key: "mongodb-find-document", + name: "Find Document", + description: "Finds a document by a query filter. [See the documentation](https://docs.mongodb.com/manual/reference/method/db.collection.find/)", + version: "0.0.1", + type: "action", + props: { + app, + database: { + propDefinition: [ + app, + "database", + ], + }, + collectionName: { + propDefinition: [ + app, + "collection", + ({ database }) => ({ + database, + }), + ], + }, + filter: { + type: "string", + label: "Filter", + description: "JSON string to use as a filter. Eg. `{ \"name\": \"Twitter\" }`", + }, + options: { + type: "string", + label: "Options", + description: "JSON string to use as options. Eg. `{ \"projection\": { \"_id\": 0, \"title\": 1 } }`", + optional: true, + }, + }, + methods: { + async findDocument({ + database, collectionName, filter, options, + } = {}) { + const { app } = this; + const client = await app.getClient(); + const collection = app.getCollection(client, database, collectionName); + const result = await collection.findOne(filter, options); + await client.close(); + return result; + }, + }, + async run({ $ }) { + const { + findDocument, + database, + collectionName, + filter, + options, + } = this; + + const response = await findDocument({ + database, + collectionName, + filter: utils.valueToObject(filter), + options: utils.valueToObject(options), + }); + + if (!response) { + $.export("$summary", "Document not found in the collection."); + return; + } + + $.export("$summary", "Successfully found a document in the collection."); + return response; + }, +}; diff --git a/components/mongodb/actions/update-documents/update-documents.mjs b/components/mongodb/actions/update-documents/update-documents.mjs new file mode 100644 index 0000000000000..5ad3bec2acaf6 --- /dev/null +++ b/components/mongodb/actions/update-documents/update-documents.mjs @@ -0,0 +1,69 @@ +import app from "../../mongodb.app.mjs"; +import utils from "../../common/utils.mjs"; + +export default { + key: "mongodb-update-documents", + name: "Update Documents", + description: "Updates many documents by query filter. [See the documentation](https://www.mongodb.com/docs/drivers/node/current/usage-examples/updateMany/)", + version: "0.0.1", + type: "action", + props: { + app, + database: { + propDefinition: [ + app, + "database", + ], + }, + collectionName: { + propDefinition: [ + app, + "collection", + ({ database }) => ({ + database, + }), + ], + }, + filter: { + type: "string", + label: "Filter", + description: "JSON string to use as a filter. Eg. `{ \"rated\": \"G\" }`", + }, + data: { + label: "Data To Update", + type: "string", + description: "JSON data to use as the update. Eg. `{ \"$set\": { \"rating\": \"Everyone\" } }`", + }, + }, + methods: { + async updateDocuments({ + database, collectionName, filter, data, + } = {}) { + const { app } = this; + const client = await app.getClient(); + const collection = app.getCollection(client, database, collectionName); + const result = await collection.updateMany(filter, data); + await client.close(); + return result; + }, + }, + async run({ $ }) { + const { + updateDocuments, + database, + collectionName, + filter, + data, + } = this; + + const response = await updateDocuments({ + database, + collectionName, + filter: utils.valueToObject(filter), + data: utils.valueToObject(data), + }); + + $.export("$summary", `Successfully updated \`${response.modifiedCount}\` document(s) in the collection.`); + return response; + }, +}; diff --git a/components/mongodb/common/utils.mjs b/components/mongodb/common/utils.mjs new file mode 100644 index 0000000000000..16af2678bc5b2 --- /dev/null +++ b/components/mongodb/common/utils.mjs @@ -0,0 +1,63 @@ +import { ConfigurationError } from "@pipedream/platform"; + +function isJson(value) { + if (typeof(value) !== "string") { + return false; + } + + try { + JSON.parse(value); + } catch (e) { + return false; + } + + return true; +} + +function valueToObject(value) { + if (value === undefined || typeof(value) === "object") { + return value; + } + + if (!isJson(value)) { + throw new ConfigurationError(`Make sure the value contains a valid JSON string: ${value}`); + } + return JSON.parse(value); +} + +function parseArray(value) { + try { + if (!value) { + return []; + } + + if (Array.isArray(value)) { + return value; + } + + const parsedValue = JSON.parse(value); + + if (!Array.isArray(parsedValue)) { + throw new Error("Not an array"); + } + + return parsedValue; + + } catch (e) { + throw new ConfigurationError("Make sure the value contains a valid JSON array"); + } +} + +async function iterate(iterations) { + const items = []; + for await (const item of iterations) { + items.push(item); + } + return items; +} + +export default { + valueToObject, + parseArray: (value) => parseArray(value).map(valueToObject), + iterate, +}; diff --git a/components/mongodb/package.json b/components/mongodb/package.json index 7152f670adbcf..975efc996701c 100644 --- a/components/mongodb/package.json +++ b/components/mongodb/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/mongodb", - "version": "0.0.8", + "version": "0.1.0", "description": "Pipedream MongoDB Components", "main": "mongodb.app.mjs", "keywords": [ @@ -14,7 +14,7 @@ "access": "public" }, "dependencies": { - "@pipedream/platform": "^1.2.0", + "@pipedream/platform": "^1.6.5", "mongodb": "^4.6.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4c8522b844106..507ce51b6e013 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5302,10 +5302,10 @@ importers: components/mongodb: specifiers: - '@pipedream/platform': ^1.2.0 + '@pipedream/platform': ^1.6.5 mongodb: ^4.6.0 dependencies: - '@pipedream/platform': 1.5.1 + '@pipedream/platform': 1.6.5 mongodb: 4.17.1 components/monkeylearn: